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-2017 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_SINGLETONSTUFFING TRUE /**< should stuffing of singleton continuous variables be performed? */
111 #define DEFAULT_SINGLEVARSTUFFING FALSE /**< should single variable stuffing be performed, which tries to fulfill
112  * constraints using the cheapest variable? */
113 #define DEFAULT_DETECTCUTOFFBOUND TRUE /**< should presolving try to detect constraints parallel to the objective
114  * function defining an upper bound and prevent these constraints from
115  * entering the LP */
116 #define DEFAULT_DETECTLOWERBOUND TRUE /**< should presolving try to detect constraints parallel to the objective
117  * function defining a lower bound and prevent these constraints from
118  * entering the LP */
119 #define DEFAULT_DETECTPARTIALOBJECTIVE TRUE/**< should presolving try to detect subsets of constraints parallel to the
120  * objective function */
121 #define DEFAULT_RANGEDROWPROPAGATION TRUE /**< should we perform ranged row propagation */
122 #define DEFAULT_RANGEDROWARTCONS TRUE /**< should presolving and propagation extract sub-constraints from ranged rows and equations? */
123 #define DEFAULT_RANGEDROWMAXDEPTH INT_MAX /**< maximum depth to apply ranged row propagation */
124 #define DEFAULT_RANGEDROWFREQ 1 /**< frequency for applying ranged row propagation */
125 
126 #define DEFAULT_MULTAGGRREMOVE FALSE /**< should multi-aggregations only be performed if the constraint can be
127  * removed afterwards? */
128 
129 #define MAXDNOM 10000LL /**< maximal denominator for simple rational fixed values */
130 #define MAXSCALEDCOEF 1e+03 /**< maximal coefficient value after scaling */
131 #define MAXSCALEDCOEFINTEGER 1e+05 /**< maximal coefficient value after scaling if all variables are of integral
132  * type
133  */
134 
135 #define HASHSIZE_LINEARCONS 500 /**< minimal size of hash table in linear constraint tables */
136 #define MAXVALRECOMP 1e+06 /**< maximal abolsute value we trust without recomputing the activity */
137 #define MINVALRECOMP 1e-05 /**< minimal abolsute value we trust without recomputing the activity */
139 
140 #define QUADCONSUPGD_PRIORITY 1000000 /**< priority of the constraint handler for upgrading of quadratic constraints */
141 #define NONLINCONSUPGD_PRIORITY 1000000 /**< priority of the constraint handler for upgrading of nonlinear constraints */
142 
143 #ifdef WITH_PRINTORIGCONSTYPES
144 /** constraint type */
145 enum SCIP_Constype
146 {
147  SCIP_CONSTYPE_EMPTY = 0, /**< */
148  SCIP_CONSTYPE_FREE = 1, /**< */
149  SCIP_CONSTYPE_SINGLETON = 2, /**< */
150  SCIP_CONSTYPE_AGGREGATION = 3, /**< */
151  SCIP_CONSTYPE_VARBOUND = 4, /**< */
152  SCIP_CONSTYPE_SETPARTITION = 5, /**< */
153  SCIP_CONSTYPE_SETPACKING = 6, /**< */
154  SCIP_CONSTYPE_SETCOVERING = 7, /**< */
155  SCIP_CONSTYPE_CARDINALITY = 8, /**< */
156  SCIP_CONSTYPE_INVKNAPSACK = 9, /**< */
157  SCIP_CONSTYPE_EQKNAPSACK = 10, /**< */
158  SCIP_CONSTYPE_BINPACKING = 11, /**< */
159  SCIP_CONSTYPE_KNAPSACK = 12, /**< */
160  SCIP_CONSTYPE_INTKNAPSACK = 13, /**< */
161  SCIP_CONSTYPE_MIXEDBINARY = 14, /**< */
162  SCIP_CONSTYPE_GENERAL = 15 /**< */
163 };
164 typedef enum SCIP_Constype SCIP_CONSTYPE;
165 #endif
166 
167 /* @todo add multi-aggregation of variables that are in exactly two equations (, if not numerically an issue),
168  * maybe in fullDualPresolve(), see convertLongEquality()
169  */
170 
171 
172 /** constraint data for linear constraints */
173 struct SCIP_ConsData
174 {
175  SCIP_Real lhs; /**< left hand side of row (for ranged rows) */
176  SCIP_Real rhs; /**< right hand side of row */
177  SCIP_Real maxabsval; /**< maximum absolute value of all coefficients */
178  SCIP_Real minabsval; /**< minimal absolute value of all coefficients */
179  SCIP_Real minactivity; /**< minimal value w.r.t. the variable's local bounds for the constraint's
180  * activity, ignoring the coefficients contributing with infinite value */
181  SCIP_Real maxactivity; /**< maximal value w.r.t. the variable's local bounds for the constraint's
182  * activity, ignoring the coefficients contributing with infinite value */
183  SCIP_Real lastminactivity; /**< last minimal activity which was computed by complete summation
184  * over all contributing values */
185  SCIP_Real lastmaxactivity; /**< last maximal activity which was computed by complete summation
186  * over all contributing values */
187  SCIP_Real glbminactivity; /**< minimal value w.r.t. the variable's global bounds for the constraint's
188  * activity, ignoring the coefficients contributing with infinite value */
189  SCIP_Real glbmaxactivity; /**< maximal value w.r.t. the variable's global bounds for the constraint's
190  * activity, ignoring the coefficients contributing with infinite value */
191  SCIP_Real lastglbminactivity; /**< last global minimal activity which was computed by complete summation
192  * over all contributing values */
193  SCIP_Real lastglbmaxactivity; /**< last global maximal activity which was computed by complete summation
194  * over all contributing values */
195  SCIP_Real maxactdelta; /**< maximal activity contribution of a single variable, or SCIP_INVALID if invalid */
196  SCIP_VAR* maxactdeltavar; /**< variable with maximal activity contribution, or NULL if invalid */
197  uint64_t possignature; /**< bit signature of coefficients that may take a positive value */
198  uint64_t negsignature; /**< bit signature of coefficients that may take a negative value */
199  SCIP_ROW* row; /**< LP row, if constraint is already stored in LP row format */
200  SCIP_VAR** vars; /**< variables of constraint entries */
201  SCIP_Real* vals; /**< coefficients of constraint entries */
202  SCIP_EVENTDATA** eventdata; /**< event data for bound change events of the variables */
203  int minactivityneginf; /**< number of coefficients contributing with neg. infinite value to minactivity */
204  int minactivityposinf; /**< number of coefficients contributing with pos. infinite value to minactivity */
205  int maxactivityneginf; /**< number of coefficients contributing with neg. infinite value to maxactivity */
206  int maxactivityposinf; /**< number of coefficients contributing with pos. infinite value to maxactivity */
207  int minactivityneghuge; /**< number of coefficients contributing with huge neg. value to minactivity */
208  int minactivityposhuge; /**< number of coefficients contributing with huge pos. value to minactivity */
209  int maxactivityneghuge; /**< number of coefficients contributing with huge neg. value to maxactivity */
210  int maxactivityposhuge; /**< number of coefficients contributing with huge pos. value to maxactivity */
211  int glbminactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbminactivity */
212  int glbminactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbminactivity */
213  int glbmaxactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbmaxactivity */
214  int glbmaxactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbmaxactivity */
215  int glbminactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbminactivity */
216  int glbminactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbminactivity */
217  int glbmaxactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbmaxactivity */
218  int glbmaxactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbmaxactivity */
219  int varssize; /**< size of the vars- and vals-arrays */
220  int nvars; /**< number of nonzeros in constraint */
221  int nbinvars; /**< the number of binary variables in the constraint, only valid after
222  * sorting in stage >= SCIP_STAGE_INITSOLVE
223  */
224  unsigned int boundstightened:2; /**< is constraint already propagated with bound tightening? */
225  unsigned int rangedrowpropagated:2; /**< did we perform ranged row propagation on this constraint?
226  * (0: no, 1: yes, 2: with potentially adding artificial constraint */
227  unsigned int validmaxabsval:1; /**< is the maximum absolute value valid? */
228  unsigned int validminabsval:1; /**< is the minimum absolute value valid? */
229  unsigned int validactivities:1; /**< are the activity bounds (local and global) valid? */
230  unsigned int validminact:1; /**< is the local minactivity valid? */
231  unsigned int validmaxact:1; /**< is the local maxactivity valid? */
232  unsigned int validglbminact:1; /**< is the global minactivity valid? */
233  unsigned int validglbmaxact:1; /**< is the global maxactivity valid? */
234  unsigned int presolved:1; /**< is constraint already presolved? */
235  unsigned int removedfixings:1; /**< are all fixed variables removed from the constraint? */
236  unsigned int validsignature:1; /**< is the bit signature valid? */
237  unsigned int changed:1; /**< was constraint changed since last aggregation round in preprocessing? */
238  unsigned int normalized:1; /**< is the constraint in normalized form? */
239  unsigned int upgradetried:1; /**< was the constraint already tried to be upgraded? */
240  unsigned int upgraded:1; /**< is the constraint upgraded and will it be removed after preprocessing? */
241  unsigned int sorted:1; /**< are the constraint's variables sorted? */
242  unsigned int merged:1; /**< are the constraint's equal variables already merged? */
243  unsigned int cliquesadded:1; /**< were the cliques of the constraint already extracted? */
244  unsigned int implsadded:1; /**< were the implications of the constraint already extracted? */
245  unsigned int binvarssorted:1; /**< are binary variables sorted w.r.t. the absolute of their coefficient? */
246  unsigned int varsdeleted:1; /**< were variables deleted after last cleanup? */
247  unsigned int hascontvar:1; /**< does the constraint contain at least one continuous variable? */
248  unsigned int hasnonbinvar:1; /**< does the constraint contain at least one non-binary variable? */
249  unsigned int hasnonbinvalid:1; /**< is the information stored in hasnonbinvar and hascontvar valid? */
250 };
251 
252 /** event data for bound change event */
253 struct SCIP_EventData
254 {
255  SCIP_CONS* cons; /**< linear constraint to process the bound change for */
256  int varpos; /**< position of variable in vars array */
257  int filterpos; /**< position of event in variable's event filter */
258 };
259 
260 /** constraint handler data */
261 struct SCIP_ConshdlrData
262 {
263  SCIP_EVENTHDLR* eventhdlr; /**< event handler for bound change events */
264  SCIP_LINCONSUPGRADE** linconsupgrades; /**< linear constraint upgrade methods for specializing linear constraints */
265  SCIP_Real maxaggrnormscale; /**< maximal allowed relative gain in maximum norm for constraint aggregation
266  * (0.0: disable constraint aggregation) */
267  SCIP_Real maxcardbounddist; /**< maximal relative distance from current node's dual bound to primal bound compared
268  * to best node's dual bound for separating knapsack cardinality cuts */
269  SCIP_Real mingainpernmincomp; /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise comparison round */
270  SCIP_Real maxeasyactivitydelta;/**< maximum activity delta to run easy propagation on linear constraint
271  * (faster, but numerically less stable) */
272  int linconsupgradessize;/**< size of linconsupgrade array */
273  int nlinconsupgrades; /**< number of linear constraint upgrade methods */
274  int tightenboundsfreq; /**< multiplier on propagation frequency, how often the bounds are tightened */
275  int maxrounds; /**< maximal number of separation rounds per node (-1: unlimited) */
276  int maxroundsroot; /**< maximal number of separation rounds in the root node (-1: unlimited) */
277  int maxsepacuts; /**< maximal number of cuts separated per separation round */
278  int maxsepacutsroot; /**< maximal number of cuts separated per separation round in root node */
279  int nmincomparisons; /**< number for minimal pairwise presolving comparisons */
280  int naddconss; /**< number of added constraints */
281  SCIP_Bool presolpairwise; /**< should pairwise constraint comparison be performed in presolving? */
282  SCIP_Bool presolusehashing; /**< should hash table be used for detecting redundant constraints in advance */
283  SCIP_Bool separateall; /**< should all constraints be subject to cardinality cut generation instead of only
284  * the ones with non-zero dual value? */
285  SCIP_Bool aggregatevariables; /**< should presolving search for redundant variables in equations */
286  SCIP_Bool simplifyinequalities;/**< should presolving try to cancel down or delete coefficients in inequalities */
287  SCIP_Bool dualpresolving; /**< should dual presolving steps be performed? */
288  SCIP_Bool singletonstuffing; /**< should stuffing of singleton continuous variables be performed? */
289  SCIP_Bool singlevarstuffing; /**< should single variable stuffing be performed, which tries to fulfill
290  * constraints using the cheapest variable? */
291  SCIP_Bool sortvars; /**< should binary variables be sorted for faster propagation? */
292  SCIP_Bool checkrelmaxabs; /**< should the violation for a constraint with side 0.0 be checked relative
293  * to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
294  SCIP_Bool detectcutoffbound; /**< should presolving try to detect constraints parallel to the objective
295  * function defining an upper bound and prevent these constraints from
296  * entering the LP */
297  SCIP_Bool detectlowerbound; /**< should presolving try to detect constraints parallel to the objective
298  * function defining a lower bound and prevent these constraints from
299  * entering the LP */
300  SCIP_Bool detectpartialobjective;/**< should presolving try to detect subsets of constraints parallel to
301  * the objective function */
302  SCIP_Bool rangedrowpropagation;/**< should presolving and propagation try to improve bounds, detect
303  * infeasibility, and extract sub-constraints from ranged rows and
304  * equations */
305  SCIP_Bool rangedrowartcons; /**< should presolving and propagation extract sub-constraints from ranged rows and equations?*/
306  int rangedrowmaxdepth; /**< maximum depth to apply ranged row propagation */
307  int rangedrowfreq; /**< frequency for applying ranged row propagation */
308  SCIP_Bool multaggrremove; /**< should multi-aggregations only be performed if the constraint can be
309  * removed afterwards? */
310 };
311 
312 /** linear constraint update method */
313 struct SCIP_LinConsUpgrade
314 {
315  SCIP_DECL_LINCONSUPGD((*linconsupgd)); /**< method to call for upgrading linear constraint */
316  int priority; /**< priority of upgrading method */
317  SCIP_Bool active; /**< is upgrading enabled */
318 };
319 
320 
321 /*
322  * Propagation rules
323  */
324 
325 enum Proprule
326 {
327  PROPRULE_1_RHS = 1, /**< activity residuals of all other variables tighten bounds of single
328  * variable due to the right hand side of the inequality */
329  PROPRULE_1_LHS = 2, /**< activity residuals of all other variables tighten bounds of single
330  * variable due to the left hand side of the inequality */
331  PROPRULE_1_RANGEDROW = 3, /**< fixed variables and gcd of all left variables tighten bounds of a
332  * single variable in this reanged row */
333  PROPRULE_INVALID = 0 /**< propagation was applied without a specific propagation rule */
334 };
335 typedef enum Proprule PROPRULE;
336 
337 /** inference information */
338 struct InferInfo
339 {
340  union
341  {
342  struct
343  {
344  unsigned int proprule:8; /**< propagation rule that was applied */
345  unsigned int pos:24; /**< variable position, the propagation rule was applied at */
346  } asbits;
347  int asint; /**< inference information as a single int value */
348  } val;
349 };
350 typedef struct InferInfo INFERINFO;
351 
352 /** converts an integer into an inference information */
353 static
355  int i /**< integer to convert */
356  )
357 {
358  INFERINFO inferinfo;
359 
360  inferinfo.val.asint = i;
361 
362  return inferinfo;
363 }
364 
365 /** converts an inference information into an int */
366 static
368  INFERINFO inferinfo /**< inference information to convert */
369  )
370 {
371  return inferinfo.val.asint;
372 }
373 
374 /** returns the propagation rule stored in the inference information */
375 static
377  INFERINFO inferinfo /**< inference information to convert */
378  )
379 {
380  return (int) inferinfo.val.asbits.proprule;
381 }
382 
383 /** returns the position stored in the inference information */
384 static
385 int inferInfoGetPos(
386  INFERINFO inferinfo /**< inference information to convert */
387  )
388 {
389  return (int) inferinfo.val.asbits.pos;
390 }
391 
392 /** constructs an inference information out of a propagation rule and a position number */
393 static
395  PROPRULE proprule, /**< propagation rule that deduced the value */
396  int pos /**< variable position, the propagation rule was applied at */
397  )
398 {
399  INFERINFO inferinfo;
400 
401  assert(pos >= 0);
402  /* in the inferinfo struct only 24 bits for 'pos' are reserved */
403  assert(pos < (1<<24));
404 
405  inferinfo.val.asbits.proprule = (unsigned int) proprule; /*lint !e641*/
406  inferinfo.val.asbits.pos = (unsigned int) pos; /*lint !e732*/
407 
408  return inferinfo;
409 }
410 
411 /** constructs an inference information out of a propagation rule and a position number, returns info as int */
412 static
413 int getInferInt(
414  PROPRULE proprule, /**< propagation rule that deduced the value */
415  int pos /**< variable position, the propagation rule was applied at */
416  )
417 {
418  return inferInfoToInt(getInferInfo(proprule, pos));
419 }
420 
421 
422 /*
423  * memory growing methods for dynamically allocated arrays
424  */
425 
426 /** ensures, that linconsupgrades array can store at least num entries */
427 static
429  SCIP* scip, /**< SCIP data structure */
430  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
431  int num /**< minimum number of entries to store */
432  )
433 {
434  assert(scip != NULL);
435  assert(conshdlrdata != NULL);
436  assert(conshdlrdata->nlinconsupgrades <= conshdlrdata->linconsupgradessize);
437 
438  if( num > conshdlrdata->linconsupgradessize )
439  {
440  int newsize;
441 
442  newsize = SCIPcalcMemGrowSize(scip, num);
443  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &conshdlrdata->linconsupgrades, conshdlrdata->linconsupgradessize, newsize) );
444  conshdlrdata->linconsupgradessize = newsize;
445  }
446  assert(num <= conshdlrdata->linconsupgradessize);
447 
448  return SCIP_OKAY;
449 }
450 
451 /** ensures, that vars and vals arrays can store at least num entries */
452 static
454  SCIP* scip, /**< SCIP data structure */
455  SCIP_CONSDATA* consdata, /**< linear constraint data */
456  int num /**< minimum number of entries to store */
457  )
458 {
459  assert(scip != NULL);
460  assert(consdata != NULL);
461  assert(consdata->nvars <= consdata->varssize);
462 
463  if( num > consdata->varssize )
464  {
465  int newsize;
466 
467  newsize = SCIPcalcMemGrowSize(scip, num);
468  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vars, consdata->varssize, newsize) );
469  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vals, consdata->varssize, newsize) );
470  if( consdata->eventdata != NULL )
471  {
472  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize, newsize) );
473  }
474  consdata->varssize = newsize;
475  }
476  assert(num <= consdata->varssize);
477 
478  return SCIP_OKAY;
479 }
480 
481 
482 /*
483  * local methods for managing linear constraint update methods
484  */
485 
486 /** creates a linear constraint upgrade data object */
487 static
489  SCIP* scip, /**< SCIP data structure */
490  SCIP_LINCONSUPGRADE** linconsupgrade, /**< pointer to store the linear constraint upgrade */
491  SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
492  int priority /**< priority of upgrading method */
493  )
494 {
495  assert(scip != NULL);
496  assert(linconsupgrade != NULL);
497  assert(linconsupgd != NULL);
498 
499  SCIP_CALL( SCIPallocBlockMemory(scip, linconsupgrade) );
500  (*linconsupgrade)->linconsupgd = linconsupgd;
501  (*linconsupgrade)->priority = priority;
502  (*linconsupgrade)->active = TRUE;
503 
504  return SCIP_OKAY;
505 }
506 
507 /** frees a linear constraint upgrade data object */
508 static
509 void linconsupgradeFree(
510  SCIP* scip, /**< SCIP data structure */
511  SCIP_LINCONSUPGRADE** linconsupgrade /**< pointer to the linear constraint upgrade */
512  )
513 {
514  assert(scip != NULL);
515  assert(linconsupgrade != NULL);
516  assert(*linconsupgrade != NULL);
517 
518  SCIPfreeBlockMemory(scip, linconsupgrade);
519 }
520 
521 /** creates constraint handler data for linear constraint handler */
522 static
524  SCIP* scip, /**< SCIP data structure */
525  SCIP_CONSHDLRDATA** conshdlrdata, /**< pointer to store the constraint handler data */
526  SCIP_EVENTHDLR* eventhdlr /**< event handler */
527  )
528 {
529  assert(scip != NULL);
530  assert(conshdlrdata != NULL);
531  assert(eventhdlr != NULL);
532 
533  SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
534  (*conshdlrdata)->linconsupgrades = NULL;
535  (*conshdlrdata)->linconsupgradessize = 0;
536  (*conshdlrdata)->nlinconsupgrades = 0;
537  (*conshdlrdata)->naddconss = 0;
538 
539  /* set event handler for updating linear constraint activity bounds */
540  (*conshdlrdata)->eventhdlr = eventhdlr;
541 
542  return SCIP_OKAY;
543 }
544 
545 /** frees constraint handler data for linear constraint handler */
546 static
547 void conshdlrdataFree(
548  SCIP* scip, /**< SCIP data structure */
549  SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to the constraint handler data */
550  )
551 {
552  int i;
553 
554  assert(scip != NULL);
555  assert(conshdlrdata != NULL);
556  assert(*conshdlrdata != NULL);
557 
558  for( i = 0; i < (*conshdlrdata)->nlinconsupgrades; ++i )
559  {
560  linconsupgradeFree(scip, &(*conshdlrdata)->linconsupgrades[i]);
561  }
562  SCIPfreeBlockMemoryArrayNull(scip, &(*conshdlrdata)->linconsupgrades, (*conshdlrdata)->linconsupgradessize);
563 
564  SCIPfreeBlockMemory(scip, conshdlrdata);
565 }
566 
567 /** creates a linear constraint upgrade data object */
568 static
570  SCIP* scip, /**< SCIP data structure */
571  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
572  SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
573  const char* conshdlrname /**< name of the constraint handler */
574  )
575 {
576  int i;
577 
578  assert(scip != NULL);
579  assert(conshdlrdata != NULL);
580  assert(linconsupgd != NULL);
581  assert(conshdlrname != NULL);
582 
583  for( i = conshdlrdata->nlinconsupgrades - 1; i >= 0; --i )
584  {
585  if( conshdlrdata->linconsupgrades[i]->linconsupgd == linconsupgd )
586  {
587 #ifdef SCIP_DEBUG
588  SCIPwarningMessage(scip, "Try to add already known upgrade message %p for constraint handler %s.\n", linconsupgd, conshdlrname);
589 #endif
590  return TRUE;
591  }
592  }
593 
594  return FALSE;
595 }
596 
597 /** adds a linear constraint update method to the constraint handler's data */
598 static
600  SCIP* scip, /**< SCIP data structure */
601  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
602  SCIP_LINCONSUPGRADE* linconsupgrade /**< linear constraint upgrade method */
603  )
604 {
605  int i;
606 
607  assert(scip != NULL);
608  assert(conshdlrdata != NULL);
609  assert(linconsupgrade != NULL);
610 
611  SCIP_CALL( conshdlrdataEnsureLinconsupgradesSize(scip, conshdlrdata, conshdlrdata->nlinconsupgrades+1) );
612 
613  for( i = conshdlrdata->nlinconsupgrades;
614  i > 0 && conshdlrdata->linconsupgrades[i-1]->priority < linconsupgrade->priority; --i )
615  {
616  conshdlrdata->linconsupgrades[i] = conshdlrdata->linconsupgrades[i-1];
617  }
618  assert(0 <= i && i <= conshdlrdata->nlinconsupgrades);
619  conshdlrdata->linconsupgrades[i] = linconsupgrade;
620  conshdlrdata->nlinconsupgrades++;
621 
622  return SCIP_OKAY;
623 }
624 
625 /*
626  * local methods
627  */
628 
629 /** installs rounding locks for the given variable associated to the given coefficient in the linear constraint */
630 static
632  SCIP* scip, /**< SCIP data structure */
633  SCIP_CONS* cons, /**< linear constraint */
634  SCIP_VAR* var, /**< variable of constraint entry */
635  SCIP_Real val /**< coefficient of constraint entry */
636  )
637 {
638  SCIP_CONSDATA* consdata;
639 
640  assert(scip != NULL);
641  assert(cons != NULL);
642  assert(var != NULL);
643 
644  consdata = SCIPconsGetData(cons);
645  assert(consdata != NULL);
646  assert(!SCIPisZero(scip, val));
647 
648  if( SCIPisPositive(scip, val) )
649  {
650  SCIP_CALL( SCIPlockVarCons(scip, var, cons,
651  !SCIPisInfinity(scip, -consdata->lhs), !SCIPisInfinity(scip, consdata->rhs)) );
652  }
653  else
654  {
655  SCIP_CALL( SCIPlockVarCons(scip, var, cons,
656  !SCIPisInfinity(scip, consdata->rhs), !SCIPisInfinity(scip, -consdata->lhs)) );
657  }
658 
659  return SCIP_OKAY;
660 }
661 
662 /** removes rounding locks for the given variable associated to the given coefficient in the linear constraint */
663 static
665  SCIP* scip, /**< SCIP data structure */
666  SCIP_CONS* cons, /**< linear constraint */
667  SCIP_VAR* var, /**< variable of constraint entry */
668  SCIP_Real val /**< coefficient of constraint entry */
669  )
670 {
671  SCIP_CONSDATA* consdata;
672 
673  assert(scip != NULL);
674  assert(cons != NULL);
675  assert(var != NULL);
676 
677  consdata = SCIPconsGetData(cons);
678  assert(consdata != NULL);
679  assert(!SCIPisZero(scip, val));
680 
681  if( SCIPisPositive(scip, val) )
682  {
683  SCIP_CALL( SCIPunlockVarCons(scip, var, cons,
684  !SCIPisInfinity(scip, -consdata->lhs), !SCIPisInfinity(scip, consdata->rhs)) );
685  }
686  else
687  {
688  SCIP_CALL( SCIPunlockVarCons(scip, var, cons,
689  !SCIPisInfinity(scip, consdata->rhs), !SCIPisInfinity(scip, -consdata->lhs)) );
690  }
691 
692  return SCIP_OKAY;
693 }
694 
695 /** creates event data for variable at given position, and catches events */
696 /**! [SnippetDebugAssertions] */
697 static
699  SCIP* scip, /**< SCIP data structure */
700  SCIP_CONS* cons, /**< linear constraint */
701  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
702  int pos /**< array position of variable to catch bound change events for */
703  )
704 {
705  SCIP_CONSDATA* consdata;
706  assert(scip != NULL);
707  assert(cons != NULL);
708  assert(eventhdlr != NULL);
709 
710  consdata = SCIPconsGetData(cons);
711  assert(consdata != NULL);
712 
713  assert(0 <= pos && pos < consdata->nvars);
714  assert(consdata->vars != NULL);
715  assert(consdata->vars[pos] != NULL);
716  assert(SCIPvarIsTransformed(consdata->vars[pos]));
717  assert(consdata->eventdata != NULL);
718  assert(consdata->eventdata[pos] == NULL);
719 
720  SCIP_CALL( SCIPallocBlockMemory(scip, &(consdata->eventdata[pos])) ); /*lint !e866*/
721  consdata->eventdata[pos]->cons = cons;
722  consdata->eventdata[pos]->varpos = pos;
723 
724  SCIP_CALL( SCIPcatchVarEvent(scip, consdata->vars[pos],
727  eventhdlr, consdata->eventdata[pos], &consdata->eventdata[pos]->filterpos) );
728 
729  return SCIP_OKAY;
730 }
731 /**! [SnippetDebugAssertions] */
732 
733 /** deletes event data for variable at given position, and drops events */
734 static
736  SCIP* scip, /**< SCIP data structure */
737  SCIP_CONS* cons, /**< linear constraint */
738  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
739  int pos /**< array position of variable to catch bound change events for */
740  )
741 {
742  SCIP_CONSDATA* consdata;
743  assert(scip != NULL);
744  assert(cons != NULL);
745  assert(eventhdlr != NULL);
746 
747  consdata = SCIPconsGetData(cons);
748  assert(consdata != NULL);
749 
750  assert(0 <= pos && pos < consdata->nvars);
751  assert(consdata->vars[pos] != NULL);
752  assert(consdata->eventdata != NULL);
753  assert(consdata->eventdata[pos] != NULL);
754  assert(consdata->eventdata[pos]->cons == cons);
755  assert(consdata->eventdata[pos]->varpos == pos);
756 
757  SCIP_CALL( SCIPdropVarEvent(scip, consdata->vars[pos],
760  eventhdlr, consdata->eventdata[pos], consdata->eventdata[pos]->filterpos) );
761 
762  SCIPfreeBlockMemory(scip, &consdata->eventdata[pos]); /*lint !e866*/
763 
764  return SCIP_OKAY;
765 }
766 
767 /** catches bound change events for all variables in transformed linear constraint */
768 static
770  SCIP* scip, /**< SCIP data structure */
771  SCIP_CONS* cons, /**< linear constraint */
772  SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
773  )
774 {
775  SCIP_CONSDATA* consdata;
776  int i;
777 
778  assert(scip != NULL);
779  assert(cons != NULL);
780 
781  consdata = SCIPconsGetData(cons);
782  assert(consdata != NULL);
783  assert(consdata->eventdata == NULL);
784 
785  /* allocate eventdata array */
786  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize) );
787  assert(consdata->eventdata != NULL);
788  BMSclearMemoryArray(consdata->eventdata, consdata->nvars);
789 
790  /* catch event for every single variable */
791  for( i = 0; i < consdata->nvars; ++i )
792  {
793  SCIP_CALL( consCatchEvent(scip, cons, eventhdlr, i) );
794  }
795 
796  return SCIP_OKAY;
797 }
798 
799 /** drops bound change events for all variables in transformed linear constraint */
800 static
802  SCIP* scip, /**< SCIP data structure */
803  SCIP_CONS* cons, /**< linear constraint */
804  SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
805  )
806 {
807  SCIP_CONSDATA* consdata;
808  int i;
809 
810  assert(scip != NULL);
811  assert(cons != NULL);
812 
813  consdata = SCIPconsGetData(cons);
814  assert(consdata != NULL);
815  assert(consdata->eventdata != NULL);
816 
817  /* drop event of every single variable */
818  for( i = consdata->nvars - 1; i >= 0; --i )
819  {
820  SCIP_CALL( consDropEvent(scip, cons, eventhdlr, i) );
821  }
822 
823  /* free eventdata array */
824  SCIPfreeBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize);
825  assert(consdata->eventdata == NULL);
826 
827  return SCIP_OKAY;
828 }
829 
830 /** returns whether we are in a stage, where the variable events should be caught */
831 static
833  SCIP* scip /**< SCIP data structure */
834  )
835 {
836  assert(scip != NULL);
837 
839 }
840 
841 /** creates a linear constraint data */
842 static
844  SCIP* scip, /**< SCIP data structure */
845  SCIP_CONSDATA** consdata, /**< pointer to linear constraint data */
846  int nvars, /**< number of nonzeros in the constraint */
847  SCIP_VAR** vars, /**< array with variables of constraint entries */
848  SCIP_Real* vals, /**< array with coefficients of constraint entries */
849  SCIP_Real lhs, /**< left hand side of row */
850  SCIP_Real rhs /**< right hand side of row */
851  )
852 {
853  int v;
854  SCIP_Real constant;
855 
856  assert(scip != NULL);
857  assert(consdata != NULL);
858  assert(nvars == 0 || vars != NULL);
859  assert(nvars == 0 || vals != NULL);
861  if( SCIPisInfinity(scip, rhs) )
862  rhs = SCIPinfinity(scip);
863  else if( SCIPisInfinity(scip, -rhs) )
864  rhs = -SCIPinfinity(scip);
865 
866  if( SCIPisInfinity(scip, -lhs) )
867  lhs = -SCIPinfinity(scip);
868  else if( SCIPisInfinity(scip, lhs) )
869  lhs = SCIPinfinity(scip);
870 
871  if( SCIPisGT(scip, lhs, rhs) )
872  {
873  SCIPwarningMessage(scip, "left hand side of linear constraint greater than right hand side\n");
874  SCIPwarningMessage(scip, " -> lhs=%g, rhs=%g\n", lhs, rhs);
875  }
876 
877  SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
878 
879  (*consdata)->varssize = 0;
880  (*consdata)->nvars = nvars;
881  (*consdata)->hascontvar = FALSE;
882  (*consdata)->hasnonbinvar = FALSE;
883  (*consdata)->hasnonbinvalid = TRUE;
884  (*consdata)->vars = NULL;
885  (*consdata)->vals = NULL;
886 
887  constant = 0.0;
888  if( nvars > 0 )
889  {
890  int k;
891 
892  SCIP_VAR** varsbuffer;
893  SCIP_Real* valsbuffer;
894 
895  /* copy variables into temporary buffer */
896  SCIP_CALL( SCIPallocBufferArray(scip, &varsbuffer, nvars) );
897  SCIP_CALL( SCIPallocBufferArray(scip, &valsbuffer, nvars) );
898  k = 0;
899 
900  /* loop over variables and sort out fixed ones */
901  for( v = 0; v < nvars; ++v )
902  {
903  SCIP_VAR* var;
904  SCIP_Real val;
905 
906  var = vars[v];
907  val = vals[v];
908 
909  assert(var != NULL);
910  if( !SCIPisZero(scip, val) )
911  {
912  /* treat fixed variable as a constant if problem compression is enabled */
914  {
915  constant += SCIPvarGetLbGlobal(var) * val;
916  }
917  else
918  {
919  varsbuffer[k] = var;
920  valsbuffer[k] = val;
921  k++;
922 
923  /* update hascontvar and hasnonbinvar flags */
924  if( !(*consdata)->hascontvar )
925  {
926  SCIP_VARTYPE vartype = SCIPvarGetType(var);
927 
928  if( vartype != SCIP_VARTYPE_BINARY )
929  {
930  (*consdata)->hasnonbinvar = TRUE;
931 
932  if( vartype == SCIP_VARTYPE_CONTINUOUS )
933  (*consdata)->hascontvar = TRUE;
934  }
935  }
936  }
937  }
938  }
939  (*consdata)->nvars = k;
940 
941  if( k > 0 )
942  {
943  /* copy the possibly reduced buffer arrays into block */
944  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, varsbuffer, k) );
945  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vals, valsbuffer, k) );
946  (*consdata)->varssize = k;
947  }
948  /* free temporary buffer */
949  SCIPfreeBufferArray(scip, &valsbuffer);
950  SCIPfreeBufferArray(scip, &varsbuffer);
951  }
952 
953  (*consdata)->eventdata = NULL;
954 
955  /* due to compressed copying, we may have fixed variables contributing to the left and right hand side */
956  if( !SCIPisZero(scip, constant) )
957  {
958  if( !SCIPisInfinity(scip, REALABS(lhs)) )
959  lhs -= constant;
960 
961  if( !SCIPisInfinity(scip, REALABS(rhs)) )
962  rhs -= constant;
963  }
964 
965  (*consdata)->row = NULL;
966  (*consdata)->lhs = lhs;
967  (*consdata)->rhs = rhs;
968  (*consdata)->maxabsval = SCIP_INVALID;
969  (*consdata)->minabsval = SCIP_INVALID;
970  (*consdata)->minactivity = SCIP_INVALID;
971  (*consdata)->maxactivity = SCIP_INVALID;
972  (*consdata)->lastminactivity = SCIP_INVALID;
973  (*consdata)->lastmaxactivity = SCIP_INVALID;
974  (*consdata)->maxactdelta = SCIP_INVALID;
975  (*consdata)->maxactdeltavar = NULL;
976  (*consdata)->minactivityneginf = -1;
977  (*consdata)->minactivityposinf = -1;
978  (*consdata)->maxactivityneginf = -1;
979  (*consdata)->maxactivityposinf = -1;
980  (*consdata)->minactivityneghuge = -1;
981  (*consdata)->minactivityposhuge = -1;
982  (*consdata)->maxactivityneghuge = -1;
983  (*consdata)->maxactivityposhuge = -1;
984  (*consdata)->glbminactivity = SCIP_INVALID;
985  (*consdata)->glbmaxactivity = SCIP_INVALID;
986  (*consdata)->lastglbminactivity = SCIP_INVALID;
987  (*consdata)->lastglbmaxactivity = SCIP_INVALID;
988  (*consdata)->glbminactivityneginf = -1;
989  (*consdata)->glbminactivityposinf = -1;
990  (*consdata)->glbmaxactivityneginf = -1;
991  (*consdata)->glbmaxactivityposinf = -1;
992  (*consdata)->glbminactivityneghuge = -1;
993  (*consdata)->glbminactivityposhuge = -1;
994  (*consdata)->glbmaxactivityneghuge = -1;
995  (*consdata)->glbmaxactivityposhuge = -1;
996  (*consdata)->possignature = 0;
997  (*consdata)->negsignature = 0;
998  (*consdata)->validmaxabsval = FALSE;
999  (*consdata)->validminabsval = FALSE;
1000  (*consdata)->validactivities = FALSE;
1001  (*consdata)->validminact = FALSE;
1002  (*consdata)->validmaxact = FALSE;
1003  (*consdata)->validglbminact = FALSE;
1004  (*consdata)->validglbmaxact = FALSE;
1005  (*consdata)->boundstightened = 0;
1006  (*consdata)->presolved = FALSE;
1007  (*consdata)->removedfixings = FALSE;
1008  (*consdata)->validsignature = FALSE;
1009  (*consdata)->changed = TRUE;
1010  (*consdata)->normalized = FALSE;
1011  (*consdata)->upgradetried = FALSE;
1012  (*consdata)->upgraded = FALSE;
1013  (*consdata)->sorted = (nvars <= 1);
1014  (*consdata)->merged = (nvars <= 1);
1015  (*consdata)->cliquesadded = FALSE;
1016  (*consdata)->implsadded = FALSE;
1017  (*consdata)->binvarssorted = FALSE;
1018  (*consdata)->nbinvars = -1;
1019  (*consdata)->varsdeleted = FALSE;
1020  (*consdata)->rangedrowpropagated = 0;
1021 
1022  if( SCIPisTransformed(scip) )
1023  {
1024  /* get transformed variables */
1025  SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
1026  }
1027 
1028  /* capture variables */
1029  for( v = 0; v < (*consdata)->nvars; v++ )
1030  {
1031  assert((*consdata)->vars[v] != NULL);
1032  assert(!SCIPisZero(scip, (*consdata)->vals[v]));
1033  SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->vars[v]) );
1034  }
1035 
1036  return SCIP_OKAY;
1037 }
1038 
1039 /** frees a linear constraint data */
1040 static
1042  SCIP* scip, /**< SCIP data structure */
1043  SCIP_CONSDATA** consdata /**< pointer to linear constraint data */
1044  )
1045 {
1046  int v;
1047 
1048  assert(scip != NULL);
1049  assert(consdata != NULL);
1050  assert(*consdata != NULL);
1051  assert((*consdata)->varssize >= 0);
1052 
1053  /* release the row */
1054  if( (*consdata)->row != NULL )
1055  {
1056  SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->row) );
1057  }
1059  /* release variables */
1060  for( v = 0; v < (*consdata)->nvars; v++ )
1061  {
1062  assert((*consdata)->vars[v] != NULL);
1063  assert(!SCIPisZero(scip, (*consdata)->vals[v]));
1064  SCIP_CALL( SCIPreleaseVar(scip, &((*consdata)->vars[v])) );
1065  }
1066 
1067  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vars, (*consdata)->varssize);
1068  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vals, (*consdata)->varssize);
1069  SCIPfreeBlockMemory(scip, consdata);
1070 
1071  return SCIP_OKAY;
1072 }
1073 
1074 /** prints linear constraint in CIP format to file stream */
1075 static
1077  SCIP* scip, /**< SCIP data structure */
1078  SCIP_CONSDATA* consdata, /**< linear constraint data */
1079  FILE* file /**< output file (or NULL for standard output) */
1080  )
1081 {
1082  assert(scip != NULL);
1083  assert(consdata != NULL);
1084 
1085  /* print left hand side for ranged rows */
1086  if( !SCIPisInfinity(scip, -consdata->lhs)
1087  && !SCIPisInfinity(scip, consdata->rhs)
1088  && !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1089  SCIPinfoMessage(scip, file, "%.15g <= ", consdata->lhs);
1090 
1091  /* print coefficients and variables */
1092  if( consdata->nvars == 0 )
1093  SCIPinfoMessage(scip, file, "0");
1094  else
1095  {
1096  /* post linear sum of the linear constraint */
1097  SCIP_CALL( SCIPwriteVarsLinearsum(scip, file, consdata->vars, consdata->vals, consdata->nvars, TRUE) );
1098  }
1099 
1100  /* print right hand side */
1101  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1102  SCIPinfoMessage(scip, file, " == %.15g", consdata->rhs);
1103  else if( !SCIPisInfinity(scip, consdata->rhs) )
1104  SCIPinfoMessage(scip, file, " <= %.15g", consdata->rhs);
1105  else if( !SCIPisInfinity(scip, -consdata->lhs) )
1106  SCIPinfoMessage(scip, file, " >= %.15g", consdata->lhs);
1107  else
1108  SCIPinfoMessage(scip, file, " [free]");
1109 
1110  return SCIP_OKAY;
1111 }
1112 
1113 /** invalidates activity bounds, such that they are recalculated in next get */
1114 static
1116  SCIP_CONSDATA* consdata /**< linear constraint */
1117  )
1118 {
1119  assert(consdata != NULL);
1120 
1121  consdata->validactivities = FALSE;
1122  consdata->validminact = FALSE;
1123  consdata->validmaxact = FALSE;
1124  consdata->validglbminact = FALSE;
1125  consdata->validglbmaxact = FALSE;
1126  consdata->validmaxabsval = FALSE;
1127  consdata->validminabsval = FALSE;
1128  consdata->hasnonbinvalid = FALSE;
1129  consdata->minactivity = SCIP_INVALID;
1130  consdata->maxactivity = SCIP_INVALID;
1131  consdata->lastminactivity = SCIP_INVALID;
1132  consdata->lastmaxactivity = SCIP_INVALID;
1133  consdata->maxabsval = SCIP_INVALID;
1134  consdata->minabsval = SCIP_INVALID;
1135  consdata->maxactdelta = SCIP_INVALID;
1136  consdata->maxactdeltavar = NULL;
1137  consdata->minactivityneginf = -1;
1138  consdata->minactivityposinf = -1;
1139  consdata->maxactivityneginf = -1;
1140  consdata->maxactivityposinf = -1;
1141  consdata->minactivityneghuge = -1;
1142  consdata->minactivityposhuge = -1;
1143  consdata->maxactivityneghuge = -1;
1144  consdata->maxactivityposhuge = -1;
1145  consdata->glbminactivity = SCIP_INVALID;
1146  consdata->glbmaxactivity = SCIP_INVALID;
1147  consdata->lastglbminactivity = SCIP_INVALID;
1148  consdata->lastglbmaxactivity = SCIP_INVALID;
1149  consdata->glbminactivityneginf = -1;
1150  consdata->glbminactivityposinf = -1;
1151  consdata->glbmaxactivityneginf = -1;
1152  consdata->glbmaxactivityposinf = -1;
1153  consdata->glbminactivityneghuge = -1;
1154  consdata->glbminactivityposhuge = -1;
1155  consdata->glbmaxactivityneghuge = -1;
1156  consdata->glbmaxactivityposhuge = -1;
1157 }
1158 
1159 /** compute the pseudo activity of a constraint */
1160 static
1162  SCIP* scip, /**< SCIP data structure */
1163  SCIP_CONSDATA* consdata /**< linear constraint data */
1164  )
1165 {
1166  int i;
1167  int pseudoactivityposinf;
1168  int pseudoactivityneginf;
1169  SCIP_Real pseudoactivity;
1170  SCIP_Real bound;
1171  SCIP_Real val;
1172 
1173  pseudoactivity = 0;
1174  pseudoactivityposinf = 0;
1175  pseudoactivityneginf = 0;
1176 
1177  for( i = consdata->nvars - 1; i >= 0; --i )
1178  {
1179  val = consdata->vals[i];
1180  bound = (SCIPvarGetBestBoundType(consdata->vars[i]) == SCIP_BOUNDTYPE_LOWER) ? SCIPvarGetLbLocal(consdata->vars[i]) : SCIPvarGetUbLocal(consdata->vars[i]);
1181  if( SCIPisInfinity(scip, bound) )
1182  {
1183  if( val > 0.0 )
1184  pseudoactivityposinf++;
1185  else
1186  pseudoactivityneginf++;
1187  }
1188  else
1189  {
1190  if( SCIPisInfinity(scip, -bound) )
1191  {
1192  if( val > 0.0 )
1193  pseudoactivityneginf++;
1194  else
1195  pseudoactivityposinf++;
1196  }
1197  else
1198  pseudoactivity += val * bound;
1199  }
1200  }
1201 
1202  if( pseudoactivityneginf > 0 && pseudoactivityposinf > 0 )
1203  return SCIP_INVALID;
1204  else if( pseudoactivityneginf > 0 )
1205  return -SCIPinfinity(scip);
1206  else if( pseudoactivityposinf > 0 )
1207  return SCIPinfinity(scip);
1208 
1209  return pseudoactivity;
1210 }
1211 
1212 /** recompute the minactivity of a constraint */
1213 static
1215  SCIP* scip, /**< SCIP data structure */
1216  SCIP_CONSDATA* consdata /**< linear constraint data */
1217  )
1218 {
1219  int i;
1220  SCIP_Real bound;
1221 
1222  consdata->minactivity = 0;
1223 
1224  for( i = consdata->nvars - 1; i >= 0; --i )
1225  {
1226  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetLbLocal(consdata->vars[i]) : SCIPvarGetUbLocal(consdata->vars[i]);
1227  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1228  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1229  consdata->minactivity += consdata->vals[i] * bound;
1230  }
1232  /* the activity was just computed from scratch and is valid now */
1233  consdata->validminact = TRUE;
1234 
1235  /* the activity was just computed from scratch, mark it to be reliable */
1236  consdata->lastminactivity = consdata->minactivity;
1237 }
1238 
1239 /** recompute the maxactivity of a constraint */
1240 static
1242  SCIP* scip, /**< SCIP data structure */
1243  SCIP_CONSDATA* consdata /**< linear constraint data */
1244  )
1245 {
1246  int i;
1247  SCIP_Real bound;
1248 
1249  consdata->maxactivity = 0;
1250 
1251  for( i = consdata->nvars - 1; i >= 0; --i )
1252  {
1253  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetUbLocal(consdata->vars[i]) : SCIPvarGetLbLocal(consdata->vars[i]);
1254  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1255  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1256  consdata->maxactivity += consdata->vals[i] * bound;
1257  }
1259  /* the activity was just computed from scratch and is valid now */
1260  consdata->validmaxact = TRUE;
1261 
1262  /* the activity was just computed from scratch, mark it to be reliable */
1263  consdata->lastmaxactivity = consdata->maxactivity;
1264 }
1265 
1266 /** recompute the global minactivity of a constraint */
1267 static
1269  SCIP* scip, /**< SCIP data structure */
1270  SCIP_CONSDATA* consdata /**< linear constraint data */
1271  )
1272 {
1273  int i;
1274  SCIP_Real bound;
1275 
1276  consdata->glbminactivity = 0;
1277 
1278  for( i = consdata->nvars - 1; i >= 0; --i )
1279  {
1280  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetLbGlobal(consdata->vars[i]) : SCIPvarGetUbGlobal(consdata->vars[i]);
1281  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound) )
1282  consdata->glbminactivity += consdata->vals[i] * bound;
1283  }
1284 
1285  /* the activity was just computed from scratch and is valid now */
1286  consdata->validglbminact = TRUE;
1287 
1288  /* the activity was just computed from scratch, mark it to be reliable */
1289  consdata->lastglbminactivity = consdata->glbminactivity;
1290 }
1291 
1292 /** recompute the global maxactivity of a constraint */
1293 static
1295  SCIP* scip, /**< SCIP data structure */
1296  SCIP_CONSDATA* consdata /**< linear constraint data */
1297  )
1298 {
1299  int i;
1300  SCIP_Real bound;
1301 
1302  consdata->glbmaxactivity = 0;
1303 
1304  for( i = consdata->nvars - 1; i >= 0; --i )
1305  {
1306  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetUbGlobal(consdata->vars[i]) : SCIPvarGetLbGlobal(consdata->vars[i]);
1307  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound) )
1308  consdata->glbmaxactivity += consdata->vals[i] * bound;
1309  }
1310 
1311  /* the activity was just computed from scratch and is valid now */
1312  consdata->validglbmaxact = TRUE;
1313 
1314  /* the activity was just computed from scratch, mark it to be reliable */
1315  consdata->lastglbmaxactivity = consdata->glbmaxactivity;
1316 }
1317 
1318 /** calculates maximum absolute value of coefficients */
1319 static
1321  SCIP_CONSDATA* consdata /**< linear constraint data */
1322  )
1323 {
1324  SCIP_Real absval;
1325  int i;
1326 
1327  assert(consdata != NULL);
1328  assert(!consdata->validmaxabsval);
1329  assert(consdata->maxabsval >= SCIP_INVALID);
1330 
1331  consdata->validmaxabsval = TRUE;
1332  consdata->maxabsval = 0.0;
1333  for( i = 0; i < consdata->nvars; ++i )
1334  {
1335  absval = consdata->vals[i];
1336  absval = REALABS(absval);
1337  if( absval > consdata->maxabsval )
1338  consdata->maxabsval = absval;
1339  }
1340 }
1341 
1342 /** calculates minimum absolute value of coefficients */
1343 static
1345  SCIP_CONSDATA* consdata /**< linear constraint data */
1346  )
1347 {
1348  SCIP_Real absval;
1349  int i;
1350 
1351  assert(consdata != NULL);
1352  assert(!consdata->validminabsval);
1353  assert(consdata->minabsval >= SCIP_INVALID);
1354 
1355  consdata->validminabsval = TRUE;
1356 
1357  if( consdata->nvars > 0 )
1358  consdata->minabsval = REALABS(consdata->vals[0]);
1359  else
1360  consdata->minabsval = 0.0;
1362  for( i = 1; i < consdata->nvars; ++i )
1363  {
1364  absval = consdata->vals[i];
1365  absval = REALABS(absval);
1366  if( absval < consdata->minabsval )
1367  consdata->minabsval = absval;
1368  }
1369 }
1370 
1371 /** checks the type of all variables of the constraint and sets hasnonbinvar and hascontvar flags accordingly */
1372 static
1374  SCIP_CONSDATA* consdata /**< linear constraint data */
1375  )
1376 {
1377  int v;
1378 
1379  assert(!consdata->hasnonbinvalid);
1380  consdata->hasnonbinvar = FALSE;
1381  consdata->hascontvar = FALSE;
1382 
1383  for( v = consdata->nvars - 1; v >= 0; --v )
1384  {
1385  SCIP_VARTYPE vartype = SCIPvarGetType(consdata->vars[v]);
1386 
1387  if( vartype != SCIP_VARTYPE_BINARY )
1388  {
1389  consdata->hasnonbinvar = TRUE;
1391  if( vartype == SCIP_VARTYPE_CONTINUOUS )
1392  {
1393  consdata->hascontvar = TRUE;
1394  break;
1395  }
1396  }
1397  }
1398  assert(consdata->hascontvar || v < 0);
1399 
1400  consdata->hasnonbinvalid = TRUE;
1401 }
1402 
1403 
1404 #ifdef CHECKMAXACTDELTA
1405 /* checks that the stored maximal activity delta (if not invalid) is correct */
1406 static
1408  SCIP* scip, /**< SCIP data structure */
1409  SCIP_CONSDATA* consdata /**< linear constraint data */
1410  )
1411 {
1412  if( consdata->maxactdelta != SCIP_INVALID )
1413  {
1414  SCIP_Real maxactdelta = 0.0;
1415  SCIP_Real domain;
1416  SCIP_Real delta;
1417  SCIP_Real lb;
1418  SCIP_Real ub;
1419  int v;
1420 
1421  for( v = consdata->nvars - 1; v >= 0; --v )
1422  {
1423  lb = SCIPvarGetLbLocal(consdata->vars[v]);
1424  ub = SCIPvarGetUbLocal(consdata->vars[v]);
1425 
1426  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
1427  {
1428  maxactdelta = SCIPinfinity(scip);
1429  break;
1430  }
1431 
1432  domain = ub - lb;
1433  delta = REALABS(consdata->vals[v]) * domain;
1434 
1435  if( delta > maxactdelta )
1436  {
1437  maxactdelta = delta;
1438  }
1439  }
1440  assert(SCIPisFeasEQ(scip, maxactdelta, consdata->maxactdelta));
1441  }
1442 }
1443 #else
1444 #define checkMaxActivityDelta(scip, consdata) /**/
1445 #endif
1446 
1447 /** recompute maximal activity contribution for a single variable */
1448 static
1450  SCIP* scip, /**< SCIP data structure */
1451  SCIP_CONSDATA* consdata /**< linear constraint data */
1452  )
1453 {
1454  SCIP_Real delta;
1455  int v;
1456 
1457  consdata->maxactdelta = 0.0;
1458 
1459  if( !consdata->hasnonbinvalid )
1460  consdataCheckNonbinvar(consdata);
1462  /* easy case, the problem consists only of binary variables */
1463  if( !consdata->hasnonbinvar )
1464  {
1465  for( v = consdata->nvars - 1; v >= 0; --v )
1466  {
1467  if( SCIPvarGetLbLocal(consdata->vars[v]) < 0.5 && SCIPvarGetUbLocal(consdata->vars[v]) > 0.5 )
1468  {
1469  delta = REALABS(consdata->vals[v]);
1470 
1471  if( delta > consdata->maxactdelta )
1472  {
1473  consdata->maxactdelta = delta;
1474  consdata->maxactdeltavar = consdata->vars[v];
1475  }
1476  }
1477  }
1478  return;
1479  }
1480 
1481  for( v = consdata->nvars - 1; v >= 0; --v )
1482  {
1483  SCIP_Real domain;
1484  SCIP_Real lb;
1485  SCIP_Real ub;
1486 
1487  lb = SCIPvarGetLbLocal(consdata->vars[v]);
1488  ub = SCIPvarGetUbLocal(consdata->vars[v]);
1489 
1490  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
1491  {
1492  consdata->maxactdelta = SCIPinfinity(scip);
1493  consdata->maxactdeltavar = consdata->vars[v];
1494  break;
1495  }
1496 
1497  domain = ub - lb;
1498  delta = REALABS(consdata->vals[v]) * domain;
1499 
1500  if( delta > consdata->maxactdelta )
1501  {
1502  consdata->maxactdelta = delta;
1503  consdata->maxactdeltavar = consdata->vars[v];
1504  }
1505  }
1506 }
1507 
1508 
1509 /** updates activities for a change in a bound */
1510 static
1512  SCIP* scip, /**< SCIP data structure */
1513  SCIP_CONSDATA* consdata, /**< linear constraint data */
1514  SCIP_VAR* var, /**< variable that has been changed; can be NULL for global bound changes */
1515  SCIP_Real oldbound, /**< old bound of variable */
1516  SCIP_Real newbound, /**< new bound of variable */
1517  SCIP_Real val, /**< coefficient of constraint entry */
1518  SCIP_BOUNDTYPE boundtype, /**< type of the bound change */
1519  SCIP_Bool global, /**< is it a global or a local bound change? */
1520  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1521  )
1522 {
1523  SCIP_Real* activity;
1524  SCIP_Real* lastactivity;
1525  int* activityposinf;
1526  int* activityneginf;
1527  int* activityposhuge;
1528  int* activityneghuge;
1529  SCIP_Real oldcontribution;
1530  SCIP_Real newcontribution;
1531  SCIP_Real delta;
1532  SCIP_Bool validact;
1533  SCIP_Bool finitenewbound;
1534  SCIP_Bool hugevalnewcont;
1535 
1536  assert(scip != NULL);
1537  assert(consdata != NULL);
1538  assert(global || (var != NULL));
1539  assert(consdata->validactivities);
1540  assert(consdata->minactivity < SCIP_INVALID);
1541  assert(consdata->maxactivity < SCIP_INVALID);
1542  assert(consdata->lastminactivity < SCIP_INVALID);
1543  assert(consdata->lastmaxactivity < SCIP_INVALID);
1544  assert(consdata->minactivityneginf >= 0);
1545  assert(consdata->minactivityposinf >= 0);
1546  assert(consdata->maxactivityneginf >= 0);
1547  assert(consdata->maxactivityposinf >= 0);
1548  assert(consdata->minactivityneghuge >= 0);
1549  assert(consdata->minactivityposhuge >= 0);
1550  assert(consdata->maxactivityneghuge >= 0);
1551  assert(consdata->maxactivityposhuge >= 0);
1552  assert(consdata->glbminactivity < SCIP_INVALID);
1553  assert(consdata->glbmaxactivity < SCIP_INVALID);
1554  assert(consdata->lastglbminactivity < SCIP_INVALID);
1555  assert(consdata->lastglbmaxactivity < SCIP_INVALID);
1556  assert(consdata->glbminactivityneginf >= 0);
1557  assert(consdata->glbminactivityposinf >= 0);
1558  assert(consdata->glbmaxactivityneginf >= 0);
1559  assert(consdata->glbmaxactivityposinf >= 0);
1560  assert(consdata->glbminactivityneghuge >= 0);
1561  assert(consdata->glbminactivityposhuge >= 0);
1562  assert(consdata->glbmaxactivityneghuge >= 0);
1563  assert(consdata->glbmaxactivityposhuge >= 0);
1564 
1565  delta = 0.0;
1566 
1567  /* we are updating global activities */
1568  if( global )
1569  {
1570  /* depending on the boundtype and the coefficient, we choose the activity to be updated:
1571  * lower bound + pos. coef: update minactivity
1572  * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
1573  * upper bound + pos. coef: update maxactivity
1574  * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
1575  */
1576  if( boundtype == SCIP_BOUNDTYPE_LOWER )
1577  {
1578  if( val > 0.0 )
1579  {
1580  activity = &(consdata->glbminactivity);
1581  lastactivity = &(consdata->lastglbminactivity);
1582  activityposinf = &(consdata->glbminactivityposinf);
1583  activityneginf = &(consdata->glbminactivityneginf);
1584  activityposhuge = &(consdata->glbminactivityposhuge);
1585  activityneghuge = &(consdata->glbminactivityneghuge);
1586  validact = consdata->validglbminact;
1587  }
1588  else
1589  {
1590  activity = &(consdata->glbmaxactivity);
1591  lastactivity = &(consdata->lastglbmaxactivity);
1592  activityposinf = &(consdata->glbmaxactivityneginf);
1593  activityneginf = &(consdata->glbmaxactivityposinf);
1594  activityposhuge = &(consdata->glbmaxactivityposhuge);
1595  activityneghuge = &(consdata->glbmaxactivityneghuge);
1596  validact = consdata->validglbmaxact;
1597  }
1598  }
1599  else
1600  {
1601  if( val > 0.0 )
1602  {
1603  activity = &(consdata->glbmaxactivity);
1604  lastactivity = &(consdata->lastglbmaxactivity);
1605  activityposinf = &(consdata->glbmaxactivityposinf);
1606  activityneginf = &(consdata->glbmaxactivityneginf);
1607  activityposhuge = &(consdata->glbmaxactivityposhuge);
1608  activityneghuge = &(consdata->glbmaxactivityneghuge);
1609  validact = consdata->validglbmaxact;
1610  }
1611  else
1612  {
1613  activity = &(consdata->glbminactivity);
1614  lastactivity = &(consdata->lastglbminactivity);
1615  activityposinf = &(consdata->glbminactivityneginf);
1616  activityneginf = &(consdata->glbminactivityposinf);
1617  activityposhuge = &(consdata->glbminactivityposhuge);
1618  activityneghuge = &(consdata->glbminactivityneghuge);
1619  validact = consdata->validglbminact;
1620  }
1621  }
1622  }
1623  /* we are updating local activities */
1624  else
1625  {
1626  /* depending on the boundtype and the coefficient, we choose the activity to be updated:
1627  * lower bound + pos. coef: update minactivity
1628  * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
1629  * upper bound + pos. coef: update maxactivity
1630  * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
1631  */
1632  if( boundtype == SCIP_BOUNDTYPE_LOWER )
1633  {
1634  if( val > 0.0 )
1635  {
1636  activity = &(consdata->minactivity);
1637  lastactivity = &(consdata->lastminactivity);
1638  activityposinf = &(consdata->minactivityposinf);
1639  activityneginf = &(consdata->minactivityneginf);
1640  activityposhuge = &(consdata->minactivityposhuge);
1641  activityneghuge = &(consdata->minactivityneghuge);
1642  validact = consdata->validminact;
1643  }
1644  else
1645  {
1646  activity = &(consdata->maxactivity);
1647  lastactivity = &(consdata->lastmaxactivity);
1648  activityposinf = &(consdata->maxactivityneginf);
1649  activityneginf = &(consdata->maxactivityposinf);
1650  activityposhuge = &(consdata->maxactivityposhuge);
1651  activityneghuge = &(consdata->maxactivityneghuge);
1652  validact = consdata->validmaxact;
1653  }
1654  }
1655  else
1656  {
1657  if( val > 0.0 )
1658  {
1659  activity = &(consdata->maxactivity);
1660  lastactivity = &(consdata->lastmaxactivity);
1661  activityposinf = &(consdata->maxactivityposinf);
1662  activityneginf = &(consdata->maxactivityneginf);
1663  activityposhuge = &(consdata->maxactivityposhuge);
1664  activityneghuge = &(consdata->maxactivityneghuge);
1665  validact = consdata->validmaxact;
1666  }
1667  else
1668  {
1669  activity = &(consdata->minactivity);
1670  lastactivity = &(consdata->lastminactivity);
1671  activityposinf = &(consdata->minactivityneginf);
1672  activityneginf = &(consdata->minactivityposinf);
1673  activityposhuge = &(consdata->minactivityposhuge);
1674  activityneghuge = &(consdata->minactivityneghuge);
1675  validact = consdata->validminact;
1676  }
1677  }
1678  }
1679 
1680  oldcontribution = val * oldbound;
1681  newcontribution = val * newbound;
1682  hugevalnewcont = SCIPisHugeValue(scip, REALABS(newcontribution));
1683  finitenewbound = !SCIPisInfinity(scip, REALABS(newbound));
1684 
1685  if( SCIPisInfinity(scip, REALABS(oldbound)) )
1686  {
1687  /* old bound was +infinity */
1688  if( oldbound > 0.0 )
1689  {
1690  assert((*activityposinf) >= 1);
1691 
1692  /* we only have to do something if the new bound is not again +infinity */
1693  if( finitenewbound || newbound < 0.0 )
1694  {
1695  /* decrease the counter for positive infinite contributions */
1696  (*activityposinf)--;
1697 
1698  /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1699  if( !finitenewbound && newbound < 0.0 )
1700  (*activityneginf)++;
1701  else if( hugevalnewcont )
1702  {
1703  /* if the contribution of this variable is too large, increase the counter for huge values */
1704  if( newcontribution > 0.0 )
1705  (*activityposhuge)++;
1706  else
1707  (*activityneghuge)++;
1708  }
1709  /* "normal case": just add the contribution to the activity */
1710  else
1711  delta = newcontribution;
1712  }
1713  }
1714  /* old bound was -infinity */
1715  else
1716  {
1717  assert(oldbound < 0.0);
1718  assert((*activityneginf) >= 1);
1719 
1720  /* we only have to do something ig the new bound is not again -infinity */
1721  if( finitenewbound || newbound > 0.0 )
1722  {
1723  /* decrease the counter for negative infinite contributions */
1724  (*activityneginf)--;
1725 
1726  /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1727  if( !finitenewbound && newbound > 0.0 )
1728  (*activityposinf)++;
1729  else if( hugevalnewcont )
1730  {
1731  /* if the contribution of this variable is too large, increase the counter for huge values */
1732  if( newcontribution > 0.0 )
1733  (*activityposhuge)++;
1734  else
1735  (*activityneghuge)++;
1736  }
1737  /* "normal case": just add the contribution to the activity */
1738  else
1739  delta = newcontribution;
1740  }
1741  }
1742  }
1743  else if( SCIPisHugeValue(scip, REALABS(oldcontribution)) )
1744  {
1745  /* old contribution was too large and positive */
1746  if( oldcontribution > 0.0 )
1747  {
1748  assert((*activityposhuge) >= 1);
1749 
1750  /* decrease the counter for huge positive contributions; it might be increased again later,
1751  * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
1752  */
1753  (*activityposhuge)--;
1754 
1755  if( !finitenewbound )
1756  {
1757  /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1758  if( newbound > 0.0 )
1759  (*activityposinf)++;
1760  /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1761  else
1762  (*activityneginf)++;
1763  }
1764  else if( hugevalnewcont )
1765  {
1766  /* if the contribution of this variable is too large and positive, increase the corresponding counter */
1767  if( newcontribution > 0.0 )
1768  (*activityposhuge)++;
1769  /* if the contribution of this variable is too large and negative, increase the corresponding counter */
1770  else
1771  (*activityneghuge)++;
1772  }
1773  /* "normal case": just add the contribution to the activity */
1774  else
1775  delta = newcontribution;
1776  }
1777  /* old contribution was too large and negative */
1778  else
1779  {
1780  assert(oldcontribution < 0.0);
1781  assert((*activityneghuge) >= 1);
1782 
1783  /* decrease the counter for huge negative contributions; it might be increased again later,
1784  * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
1785  */
1786  (*activityneghuge)--;
1787 
1788  if( !finitenewbound )
1789  {
1790  /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1791  if( newbound > 0.0 )
1792  (*activityposinf)++;
1793  /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1794  else
1795  (*activityneginf)++;
1796  }
1797  else if( hugevalnewcont )
1798  {
1799  /* if the contribution of this variable is too large and positive, increase the corresponding counter */
1800  if( newcontribution > 0.0 )
1801  (*activityposhuge)++;
1802  /* if the contribution of this variable is too large and negative, increase the corresponding counter */
1803  else
1804  (*activityneghuge)++;
1805  }
1806  /* "normal case": just add the contribution to the activity */
1807  else
1808  delta = newcontribution;
1809  }
1810  }
1811  /* old bound was finite and not too large */
1812  else
1813  {
1814  if( !finitenewbound )
1815  {
1816  /* if the new bound is +infinity, the old contribution has to be subtracted
1817  * and the counter for positive infinite contributions has to be increased
1818  */
1819  if( newbound > 0.0 )
1820  {
1821  (*activityposinf)++;
1822  delta = -oldcontribution;
1823  }
1824  /* if the new bound is -infinity, the old contribution has to be subtracted
1825  * and the counter for negative infinite contributions has to be increased
1826  */
1827  else
1828  {
1829  assert(newbound < 0.0 );
1830 
1831  (*activityneginf)++;
1832  delta = -oldcontribution;
1833  }
1834  }
1835  /* if the contribution of this variable is too large, increase the counter for huge values */
1836  else if( hugevalnewcont )
1837  {
1838  if( newcontribution > 0.0 )
1839  {
1840  (*activityposhuge)++;
1841  delta = -oldcontribution;
1842  }
1843  else
1844  {
1845  (*activityneghuge)++;
1846  delta = -oldcontribution;
1847  }
1848  }
1849  /* "normal case": just update the activity */
1850  else
1851  delta = newcontribution - oldcontribution;
1852  }
1853 
1854  /* update the activity, if the current value is valid and there was a change in the finite part */
1855  if( validact && (delta != 0.0) )
1856  {
1857  /* if the absolute value of the activity is increased, this is regarded as reliable,
1858  * otherwise, we check whether we can still trust the updated value
1859  */
1860  (*activity) = (*activity) + delta;
1861  assert(!SCIPisInfinity(scip, -(*activity)) && !SCIPisInfinity(scip, *activity));
1862 
1863  if( REALABS((*lastactivity)) < REALABS(*activity) )
1864  {
1865  (*lastactivity) = (*activity);
1866  }
1867  else
1868  {
1869  if( checkreliability && SCIPisUpdateUnreliable(scip, (*activity), (*lastactivity)) )
1870  {
1871  SCIPdebugMsg(scip, "%s activity of linear constraint unreliable after update: %16.9g\n",
1872  (global ? "global " : ""), (*activity));
1873 
1874  /* mark the activity that was just changed and is not reliable anymore to be invalid */
1875  if( global )
1876  {
1877  if( (boundtype == SCIP_BOUNDTYPE_LOWER) == (val > 0.0) )
1878  consdata->validglbminact = FALSE;
1879  else
1880  consdata->validglbmaxact = FALSE;
1881  }
1882  else
1883  {
1884  if( (boundtype == SCIP_BOUNDTYPE_LOWER) == (val > 0.0) )
1885  consdata->validminact = FALSE;
1886  else
1887  consdata->validmaxact = FALSE;
1888  }
1889  }
1890  }
1891  }
1892 }
1893 
1894 /** updates minimum and maximum activity for a change in lower bound */
1895 static
1897  SCIP* scip, /**< SCIP data structure */
1898  SCIP_CONSDATA* consdata, /**< linear constraint data */
1899  SCIP_VAR* var, /**< variable that has been changed */
1900  SCIP_Real oldlb, /**< old lower bound of variable */
1901  SCIP_Real newlb, /**< new lower bound of variable */
1902  SCIP_Real val, /**< coefficient of constraint entry */
1903  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1904  )
1905 {
1906  assert(scip != NULL);
1907  assert(consdata != NULL);
1908  assert(var != NULL);
1909 
1910  if( consdata->validactivities )
1911  {
1912  consdataUpdateActivities(scip, consdata, var, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, FALSE, checkreliability);
1914  assert(!SCIPisInfinity(scip, -consdata->minactivity) && !SCIPisInfinity(scip, consdata->minactivity));
1915  assert(!SCIPisInfinity(scip, -consdata->maxactivity) && !SCIPisInfinity(scip, consdata->maxactivity));
1916  }
1917 }
1918 
1919 /** updates minimum and maximum activity for a change in upper bound */
1920 static
1922  SCIP* scip, /**< SCIP data structure */
1923  SCIP_CONSDATA* consdata, /**< linear constraint data */
1924  SCIP_VAR* var, /**< variable that has been changed */
1925  SCIP_Real oldub, /**< old upper bound of variable */
1926  SCIP_Real newub, /**< new upper bound of variable */
1927  SCIP_Real val, /**< coefficient of constraint entry */
1928  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1929  )
1930 {
1931  assert(scip != NULL);
1932  assert(consdata != NULL);
1933  assert(var != NULL);
1934 
1935  if( consdata->validactivities )
1936  {
1937  consdataUpdateActivities(scip, consdata, var, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, FALSE, checkreliability);
1939  assert(!SCIPisInfinity(scip, -consdata->minactivity) && !SCIPisInfinity(scip, consdata->minactivity));
1940  assert(!SCIPisInfinity(scip, -consdata->maxactivity) && !SCIPisInfinity(scip, consdata->maxactivity));
1941  }
1942 }
1943 
1944 /** updates minimum and maximum global activity for a change in the global lower bound */
1945 static
1947  SCIP* scip, /**< SCIP data structure */
1948  SCIP_CONSDATA* consdata, /**< linear constraint data */
1949  SCIP_Real oldlb, /**< old lower bound of variable */
1950  SCIP_Real newlb, /**< new lower bound of variable */
1951  SCIP_Real val, /**< coefficient of constraint entry */
1952  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1953  )
1954 {
1955  assert(scip != NULL);
1956  assert(consdata != NULL);
1957 
1958  if( consdata->validactivities )
1959  {
1960  consdataUpdateActivities(scip, consdata, NULL, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, TRUE, checkreliability);
1961 
1962  assert(!SCIPisInfinity(scip, -consdata->glbminactivity) && !SCIPisInfinity(scip, consdata->glbminactivity));
1963  assert(!SCIPisInfinity(scip, -consdata->glbmaxactivity) && !SCIPisInfinity(scip, consdata->glbmaxactivity));
1964  }
1965 }
1966 
1967 /** updates minimum and maximum global activity for a change in global upper bound */
1968 static
1970  SCIP* scip, /**< SCIP data structure */
1971  SCIP_CONSDATA* consdata, /**< linear constraint data */
1972  SCIP_Real oldub, /**< old upper bound of variable */
1973  SCIP_Real newub, /**< new upper bound of variable */
1974  SCIP_Real val, /**< coefficient of constraint entry */
1975  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1976  )
1977 {
1978  assert(scip != NULL);
1979  assert(consdata != NULL);
1980 
1981  if( consdata->validactivities )
1982  {
1983  consdataUpdateActivities(scip, consdata, NULL, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, TRUE, checkreliability);
1984 
1985  assert(!SCIPisInfinity(scip, -consdata->glbminactivity) && !SCIPisInfinity(scip, consdata->glbminactivity));
1986  assert(!SCIPisInfinity(scip, -consdata->glbmaxactivity) && !SCIPisInfinity(scip, consdata->glbmaxactivity));
1987  }
1988 }
1989 
1990 /** updates minimum and maximum activity and maximum absolute value for coefficient addition */
1991 static
1993  SCIP* scip, /**< SCIP data structure */
1994  SCIP_CONSDATA* consdata, /**< linear constraint data */
1995  SCIP_VAR* var, /**< variable of constraint entry */
1996  SCIP_Real val, /**< coefficient of constraint entry */
1997  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1998  )
1999 {
2000  assert(scip != NULL);
2001  assert(consdata != NULL);
2002  assert(var != NULL);
2003 
2004  /* update maximum absolute value */
2005  if( consdata->validmaxabsval )
2006  {
2007  SCIP_Real absval;
2008 
2009  assert(consdata->maxabsval < SCIP_INVALID);
2010 
2011  absval = REALABS(val);
2012  consdata->maxabsval = MAX(consdata->maxabsval, absval);
2013  }
2014 
2015  if( consdata->validminabsval )
2016  {
2017  SCIP_Real absval;
2018 
2019  assert(consdata->minabsval < SCIP_INVALID);
2020 
2021  absval = REALABS(val);
2022  consdata->minabsval = MIN(consdata->minabsval, absval);
2023  }
2024 
2025  /* update minimal and maximal activity */
2026  if( consdata->validactivities )
2027  {
2028  assert(consdata->minactivity < SCIP_INVALID);
2029  assert(consdata->maxactivity < SCIP_INVALID);
2030  assert(consdata->glbminactivity < SCIP_INVALID);
2031  assert(consdata->glbmaxactivity < SCIP_INVALID);
2032 
2033  consdataUpdateActivitiesLb(scip, consdata, var, 0.0, SCIPvarGetLbLocal(var), val, checkreliability);
2034  consdataUpdateActivitiesUb(scip, consdata, var, 0.0, SCIPvarGetUbLocal(var), val, checkreliability);
2035  consdataUpdateActivitiesGlbLb(scip, consdata, 0.0, SCIPvarGetLbGlobal(var), val, checkreliability);
2036  consdataUpdateActivitiesGlbUb(scip, consdata, 0.0, SCIPvarGetUbGlobal(var), val, checkreliability);
2037  }
2038 }
2039 
2040 /** updates minimum and maximum activity for coefficient deletion, invalidates maximum absolute value if necessary */
2041 static
2043  SCIP* scip, /**< SCIP data structure */
2044  SCIP_CONSDATA* consdata, /**< linear constraint data */
2045  SCIP_VAR* var, /**< variable of constraint entry */
2046  SCIP_Real val, /**< coefficient of constraint entry */
2047  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2048  )
2049 {
2050  assert(scip != NULL);
2051  assert(consdata != NULL);
2052  assert(var != NULL);
2053 
2054  /* invalidate maximum absolute value, if this coefficient was the maximum */
2055  if( consdata->validmaxabsval )
2056  {
2057  SCIP_Real absval;
2058 
2059  absval = REALABS(val);
2060 
2061  if( SCIPisEQ(scip, absval, consdata->maxabsval) )
2062  {
2063  consdata->validmaxabsval = FALSE;
2064  consdata->maxabsval = SCIP_INVALID;
2065  }
2066  }
2067 
2068  /* invalidate minimum absolute value, if this coefficient was the minimum */
2069  if( consdata->validminabsval )
2070  {
2071  SCIP_Real absval;
2072 
2073  absval = REALABS(val);
2074 
2075  if( SCIPisEQ(scip, absval, consdata->minabsval) )
2076  {
2077  consdata->validminabsval = FALSE;
2078  consdata->minabsval = SCIP_INVALID;
2079  }
2080  }
2081 
2082  /* update minimal and maximal activity */
2083  if( consdata->validactivities )
2084  {
2085  assert(consdata->minactivity < SCIP_INVALID);
2086  assert(consdata->maxactivity < SCIP_INVALID);
2087  assert(consdata->glbminactivity < SCIP_INVALID);
2088  assert(consdata->glbmaxactivity < SCIP_INVALID);
2089 
2090  consdataUpdateActivitiesLb(scip, consdata, var, SCIPvarGetLbLocal(var), 0.0, val, checkreliability);
2091  consdataUpdateActivitiesUb(scip, consdata, var, SCIPvarGetUbLocal(var), 0.0, val, checkreliability);
2092  consdataUpdateActivitiesGlbLb(scip, consdata, SCIPvarGetLbGlobal(var), 0.0, val, checkreliability);
2093  consdataUpdateActivitiesGlbUb(scip, consdata, SCIPvarGetUbGlobal(var), 0.0, val, checkreliability);
2094  }
2095 }
2096 
2097 /** updates minimum and maximum activity for coefficient change, invalidates maximum absolute value if necessary */
2098 static
2100  SCIP* scip, /**< SCIP data structure */
2101  SCIP_CONSDATA* consdata, /**< linear constraint data */
2102  SCIP_VAR* var, /**< variable of constraint entry */
2103  SCIP_Real oldval, /**< old coefficient of constraint entry */
2104  SCIP_Real newval, /**< new coefficient of constraint entry */
2105  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2106  )
2107 {
2108  assert(scip != NULL);
2109  assert(consdata != NULL);
2110  assert(var != NULL);
2111 
2112  /* old zero coefficients should be handled by consdataUpdateAddCoef() */
2113  assert(!SCIPisZero(scip, oldval));
2114 
2115  /* new zero coefficients should be handled by consdataUpdateDelCoef() */
2116  assert(!SCIPisZero(scip, newval));
2117 
2118  /* update maximum absolute value */
2119  if( consdata->validmaxabsval )
2120  {
2121  SCIP_Real absval;
2122 
2123  absval = REALABS(newval);
2124 
2125  if( SCIPisGE(scip, absval, consdata->maxabsval) )
2126  {
2127  consdata->maxabsval = absval;
2128  }
2129  else
2130  {
2131  absval = REALABS(oldval);
2132 
2133  /* invalidate maximum absolute value */
2134  if( SCIPisEQ(scip, absval, consdata->maxabsval) )
2135  {
2136  consdata->validmaxabsval = FALSE;
2137  consdata->maxabsval = SCIP_INVALID;
2138  }
2139  }
2140  }
2141 
2142  /* update minimum absolute value */
2143  if( consdata->validminabsval )
2144  {
2145  SCIP_Real absval;
2146 
2147  absval = REALABS(newval);
2148 
2149  if( SCIPisLE(scip, absval, consdata->minabsval) )
2150  {
2151  consdata->minabsval = absval;
2152  }
2153  else
2154  {
2155  absval = REALABS(oldval);
2156 
2157  /* invalidate minimum absolute value */
2158  if( SCIPisEQ(scip, absval, consdata->minabsval) )
2159  {
2160  consdata->validminabsval = FALSE;
2161  consdata->minabsval = SCIP_INVALID;
2162  }
2163  }
2164  }
2165 
2166 
2167  /* update maximum activity delta */
2168  if( !SCIPisInfinity(scip, consdata->maxactdelta ) )
2169  {
2170  SCIP_Real domain;
2171  SCIP_Real delta;
2172 
2173  assert(!SCIPisInfinity(scip, SCIPvarGetLbLocal(var)));
2174  assert(!SCIPisInfinity(scip, SCIPvarGetUbLocal(var)));
2175 
2176  domain = SCIPvarGetUbLocal(var) - SCIPvarGetLbLocal(var);
2177  delta = REALABS(newval) * domain;
2178 
2179  if( delta > consdata->maxactdelta )
2180  {
2181  consdata->maxactdelta = delta;
2182  consdata->maxactdeltavar = var;
2183  }
2184  else
2185  {
2186  /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
2187  if( consdata->maxactdeltavar == var )
2188  consdata->maxactdelta = SCIP_INVALID;
2189  }
2190  }
2191 
2192  /* @todo do something more clever here, e.g. if oldval * newval >= 0, do the update directly */
2193  consdataUpdateDelCoef(scip, consdata, var, oldval, checkreliability);
2194  consdataUpdateAddCoef(scip, consdata, var, newval, checkreliability);
2195 }
2196 
2197 /** returns the maximum absolute value of all coefficients in the constraint */
2198 static
2200  SCIP_CONSDATA* consdata /**< linear constraint data */
2201  )
2202 {
2203  assert(consdata != NULL);
2204 
2205  if( !consdata->validmaxabsval )
2206  consdataCalcMaxAbsval(consdata);
2207  assert(consdata->validmaxabsval);
2208  assert(consdata->maxabsval < SCIP_INVALID);
2209 
2210  return consdata->maxabsval;
2211 }
2212 
2213 /** returns the minimum absolute value of all coefficients in the constraint */
2214 static
2216  SCIP_CONSDATA* consdata /**< linear constraint data */
2217  )
2218 {
2219  assert(consdata != NULL);
2220 
2221  if( !consdata->validminabsval )
2222  consdataCalcMinAbsval(consdata);
2223  assert(consdata->validminabsval);
2224  assert(consdata->minabsval < SCIP_INVALID);
2225 
2226  return consdata->minabsval;
2227 }
2228 
2229 /** calculates minimum and maximum local and global activity for constraint from scratch;
2230  * additionally recalculates maximum absolute value of coefficients
2231  */
2232 static
2234  SCIP* scip, /**< SCIP data structure */
2235  SCIP_CONSDATA* consdata /**< linear constraint data */
2236  )
2237 {
2238  int i;
2239 
2240  assert(scip != NULL);
2241  assert(consdata != NULL);
2242  assert(!consdata->validactivities);
2243  assert(consdata->minactivity >= SCIP_INVALID || consdata->validminact);
2244  assert(consdata->maxactivity >= SCIP_INVALID || consdata->validmaxact);
2245  assert(consdata->glbminactivity >= SCIP_INVALID || consdata->validglbminact);
2246  assert(consdata->glbmaxactivity >= SCIP_INVALID || consdata->validglbmaxact);
2247 
2248  consdata->validmaxabsval = TRUE;
2249  consdata->validminabsval = TRUE;
2250  consdata->validactivities = TRUE;
2251  consdata->validminact = TRUE;
2252  consdata->validmaxact = TRUE;
2253  consdata->validglbminact = TRUE;
2254  consdata->validglbmaxact = TRUE;
2255  consdata->maxabsval = 0.0;
2256  consdata->minabsval = (consdata->nvars == 0 ? 0.0 : REALABS(consdata->vals[0]));
2257  consdata->minactivity = 0.0;
2258  consdata->maxactivity = 0.0;
2259  consdata->lastminactivity = 0.0;
2260  consdata->lastmaxactivity = 0.0;
2261  consdata->minactivityneginf = 0;
2262  consdata->minactivityposinf = 0;
2263  consdata->maxactivityneginf = 0;
2264  consdata->maxactivityposinf = 0;
2265  consdata->minactivityneghuge = 0;
2266  consdata->minactivityposhuge = 0;
2267  consdata->maxactivityneghuge = 0;
2268  consdata->maxactivityposhuge = 0;
2269  consdata->glbminactivity = 0.0;
2270  consdata->glbmaxactivity = 0.0;
2271  consdata->lastglbminactivity = 0.0;
2272  consdata->lastglbmaxactivity = 0.0;
2273  consdata->glbminactivityneginf = 0;
2274  consdata->glbminactivityposinf = 0;
2275  consdata->glbmaxactivityneginf = 0;
2276  consdata->glbmaxactivityposinf = 0;
2277  consdata->glbminactivityneghuge = 0;
2278  consdata->glbminactivityposhuge = 0;
2279  consdata->glbmaxactivityneghuge = 0;
2280  consdata->glbmaxactivityposhuge = 0;
2281 
2282  for( i = 0; i < consdata->nvars; ++i )
2283  consdataUpdateAddCoef(scip, consdata, consdata->vars[i], consdata->vals[i], FALSE);
2284 
2285  consdata->lastminactivity = consdata->minactivity;
2286  consdata->lastmaxactivity = consdata->maxactivity;
2287  consdata->lastglbminactivity = consdata->glbminactivity;
2288  consdata->lastglbmaxactivity = consdata->glbmaxactivity;
2289 }
2290 
2291 /** gets minimal activity for constraint and given values of counters for infinite and huge contributions
2292  * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
2293  */
2294 static
2295 void getMinActivity(
2296  SCIP* scip, /**< SCIP data structure */
2297  SCIP_CONSDATA* consdata, /**< linear constraint */
2298  int posinf, /**< number of coefficients contributing pos. infinite value */
2299  int neginf, /**< number of coefficients contributing neg. infinite value */
2300  int poshuge, /**< number of coefficients contributing huge pos. value */
2301  int neghuge, /**< number of coefficients contributing huge neg. value */
2302  SCIP_Real delta, /**< value to subtract from stored minactivity
2303  * (contribution of the variable set to zero when getting residual activity) */
2304  SCIP_Bool global, /**< should the global or local minimal activity be returned? */
2305  SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
2306  SCIP_Real* minactivity, /**< pointer to store the minimal activity */
2307  SCIP_Bool* isrelax, /**< pointer to store whether the activity is a relaxation,
2308  * i.e. is <= the exact minactivity (in case of huge contributing values) */
2309  SCIP_Bool* issettoinfinity /**< pointer to store whether minactivity was set to infinity or calculated */
2310  )
2311 {
2312  assert(scip != NULL);
2313  assert(consdata != NULL);
2314  assert(posinf >= 0);
2315  assert(neginf >= 0);
2316  assert(poshuge >= 0);
2317  assert(neghuge >= 0);
2318  assert(minactivity != NULL);
2319  assert(isrelax != NULL);
2320  assert(issettoinfinity != NULL);
2321 
2322  /* if we have pos. infinite contributions, the minactivity is +infty */
2323  if( posinf > 0 )
2324  {
2325  *minactivity = SCIPinfinity(scip);
2326  *issettoinfinity = TRUE;
2327  *isrelax = FALSE;
2328  }
2329  /* if we have neg. (and no pos.) infinite contributions, the minactivity is -infty */
2330  else if( neginf > 0 )
2331  {
2332  *minactivity = -SCIPinfinity(scip);
2333  *issettoinfinity = TRUE;
2334  *isrelax = FALSE;
2335  }
2336  /* if we have neg. huge contributions, we only know that -infty is a relaxation of the minactivity */
2337  else if( neghuge > 0 )
2338  {
2339  *minactivity = -SCIPinfinity(scip);
2340  *issettoinfinity = TRUE;
2341  *isrelax = TRUE;
2342  }
2343  /* we do not need a good relaxation and we have positve huge contributions, so we just return -infty as activity */
2344  else if( !goodrelax && poshuge > 0 )
2345  {
2346  *minactivity = -SCIPinfinity(scip);
2347  *issettoinfinity = TRUE;
2348  *isrelax = TRUE;
2349  }
2350  else
2351  {
2352  SCIP_Real tmpactivity;
2353 
2354  /* recompute minactivity if it is not valid */
2355  if( global )
2356  {
2357  if( !consdata->validglbminact )
2358  consdataRecomputeGlbMinactivity(scip, consdata);
2359  assert(consdata->validglbminact);
2360 
2361  tmpactivity = consdata->glbminactivity;
2362  }
2363  else
2364  {
2365  if( !consdata->validminact )
2366  consdataRecomputeMinactivity(scip, consdata);
2367  assert(consdata->validminact);
2368 
2369  tmpactivity = consdata->minactivity;
2370  }
2371 
2372  /* we have no infinite and no neg. huge contributions, but pos. huge contributions;
2373  * a feasible relaxation of the minactivity is the number of positive huge contributions
2374  * times the minimum value counting as "huge" plus finite (and non-huge) part of minactivity - delta
2375  */
2376  if( poshuge > 0 )
2377  {
2378  *minactivity = 1.0 * poshuge * SCIPgetHugeValue(scip) + (tmpactivity - delta);
2379  *issettoinfinity = FALSE;
2380  *isrelax = TRUE;
2381  }
2382  /* all counters are zero, so the minactivity is just stored and we subtract the delta */
2383  else
2384  {
2385  *minactivity = tmpactivity - delta;
2386  *issettoinfinity = FALSE;
2387  *isrelax = FALSE;
2388  }
2389  }
2390 }
2391 
2392 /** gets maximal activity for constraint and given values of counters for infinite and huge contributions
2393  * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
2394  */
2395 static
2396 void getMaxActivity(
2397  SCIP* scip, /**< SCIP data structure */
2398  SCIP_CONSDATA* consdata, /**< linear constraint */
2399  int posinf, /**< number of coefficients contributing pos. infinite value */
2400  int neginf, /**< number of coefficients contributing neg. infinite value */
2401  int poshuge, /**< number of coefficients contributing huge pos. value */
2402  int neghuge, /**< number of coefficients contributing huge neg. value */
2403  SCIP_Real delta, /**< value to subtract from stored maxactivity
2404  * (contribution of the variable set to zero when getting residual activity) */
2405  SCIP_Bool global, /**< should the global or local maximal activity be returned? */
2406  SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
2407  SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
2408  SCIP_Bool* isrelax, /**< pointer to store whether the activity is a relaxation,
2409  * i.e. is >= the exact maxactivity (in case of huge contributing values) */
2410  SCIP_Bool* issettoinfinity /**< pointer to store whether maxactivity was set to infinity or calculated */
2411  )
2412 {
2413  assert(scip != NULL);
2414  assert(consdata != NULL);
2415  assert(posinf >= 0);
2416  assert(neginf >= 0);
2417  assert(poshuge >= 0);
2418  assert(neghuge >= 0);
2419  assert(maxactivity != NULL);
2420  assert(isrelax != NULL);
2421  assert(issettoinfinity != NULL);
2422 
2423  /* if we have neg. infinite contributions, the maxactivity is -infty */
2424  if( neginf > 0 )
2425  {
2426  *maxactivity = -SCIPinfinity(scip);
2427  *issettoinfinity = TRUE;
2428  *isrelax = FALSE;
2429  }
2430  /* if we have pos. (and no neg.) infinite contributions, the maxactivity is +infty */
2431  else if( posinf > 0 )
2432  {
2433  *maxactivity = SCIPinfinity(scip);
2434  *issettoinfinity = TRUE;
2435  *isrelax = FALSE;
2436  }
2437  /* if we have pos. huge contributions, we only know that +infty is a relaxation of the maxactivity */
2438  else if( poshuge > 0 )
2439  {
2440  *maxactivity = SCIPinfinity(scip);
2441  *issettoinfinity = TRUE;
2442  *isrelax = TRUE;
2443  }
2444  /* we do not need a good relaxation and we have positve huge contributions, so we just return +infty as activity */
2445  else if( !goodrelax && neghuge > 0 )
2446  {
2447  *maxactivity = SCIPinfinity(scip);
2448  *issettoinfinity = TRUE;
2449  *isrelax = TRUE;
2450  }
2451  else
2452  {
2453  SCIP_Real tmpactivity;
2454 
2455  /* recompute maxactivity if it is not valid */
2456  if( global )
2457  {
2458  if( !consdata->validglbmaxact )
2459  consdataRecomputeGlbMaxactivity(scip, consdata);
2460  assert(consdata->validglbmaxact);
2461 
2462  tmpactivity = consdata->glbmaxactivity;
2463  }
2464  else
2465  {
2466  if( !consdata->validmaxact )
2467  consdataRecomputeMaxactivity(scip, consdata);
2468  assert(consdata->validmaxact);
2469 
2470  tmpactivity = consdata->maxactivity;
2471  }
2472 
2473  /* we have no infinite, and no pos. huge contributions, but neg. huge contributions;
2474  * a feasible relaxation of the maxactivity is minus the number of negative huge contributions
2475  * times the minimum value counting as "huge" plus the finite (and non-huge) part of maxactivity minus delta
2476  */
2477  if( neghuge > 0 )
2478  {
2479  *maxactivity = -1.0 * neghuge * SCIPgetHugeValue(scip) + tmpactivity - delta;
2480  *issettoinfinity = FALSE;
2481  *isrelax = TRUE;
2482  }
2483  /* all counters are zero, so the maxactivity is just stored and we subtract the delta */
2484  else
2485  {
2486  *maxactivity = tmpactivity - delta;
2487  *issettoinfinity = FALSE;
2488  *isrelax = FALSE;
2489  }
2490  }
2491 }
2492 
2493 /** gets activity bounds for constraint */
2494 static
2496  SCIP* scip, /**< SCIP data structure */
2497  SCIP_CONSDATA* consdata, /**< linear constraint */
2498  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2499  * relaxed acticities ignored, anyway? */
2500  SCIP_Real* minactivity, /**< pointer to store the minimal activity */
2501  SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
2502  SCIP_Bool* minisrelax, /**< pointer to store whether the returned minactivity is just a relaxation,
2503  * i.e. <= the exact minactivity (in case of huge contributions),
2504  * or equal to the exact minimal activity */
2505  SCIP_Bool* maxisrelax /**< pointer to store whether the returned maxactivity is just a relaxation,
2506  * i.e. >= the exact maxactivity (in case of huge contributions),
2507  * or equal to the exact maximal activity */
2508  )
2509 {
2510  SCIP_Bool issettoinfinity;
2511 
2512  assert(scip != NULL);
2513  assert(consdata != NULL);
2514  assert(minactivity != NULL);
2515  assert(maxactivity != NULL);
2516 
2517  if( !consdata->validactivities )
2518  {
2519  consdataCalcActivities(scip, consdata);
2520  assert(consdata->validminact);
2521  assert(consdata->validmaxact);
2522  }
2523  assert(consdata->minactivity < SCIP_INVALID);
2524  assert(consdata->maxactivity < SCIP_INVALID);
2525  assert(consdata->minactivityneginf >= 0);
2526  assert(consdata->minactivityposinf >= 0);
2527  assert(consdata->maxactivityneginf >= 0);
2528  assert(consdata->maxactivityposinf >= 0);
2529 
2530  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2531  consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2532  minactivity, minisrelax, &issettoinfinity);
2533 
2534  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2535  consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2536  maxactivity, maxisrelax, &issettoinfinity);
2537 }
2538 
2539 /** calculates activity bounds for constraint after setting variable to zero */
2540 static
2542  SCIP* scip, /**< SCIP data structure */
2543  SCIP_CONSDATA* consdata, /**< linear constraint */
2544  SCIP_VAR* cancelvar, /**< variable to calculate activity residual for */
2545  SCIP_Real* resactivity, /**< pointer to store the residual activity */
2546  SCIP_Bool isminresact, /**< should minimal or maximal residual activity be calculated? */
2547  SCIP_Bool useglobalbounds /**< should global or local bounds be used? */
2548  )
2549 {
2550  SCIP_VAR* var;
2551  SCIP_Real val;
2552  SCIP_Real lb;
2553  SCIP_Real ub;
2554  int v;
2555 
2556  assert(scip != NULL);
2557  assert(consdata != NULL);
2558  assert(cancelvar != NULL);
2559  assert(resactivity != NULL);
2560 
2561  *resactivity = 0.0;
2562 
2563  for( v = 0; v < consdata->nvars; ++v )
2564  {
2565  var = consdata->vars[v];
2566  assert(var != NULL);
2567  if( var == cancelvar )
2568  continue;
2569 
2570  val = consdata->vals[v];
2571 
2572  if( useglobalbounds )
2573  {
2574  lb = SCIPvarGetLbGlobal(var);
2575  ub = SCIPvarGetUbGlobal(var);
2576  }
2577  else
2578  {
2579  lb = SCIPvarGetLbLocal(var);
2580  ub = SCIPvarGetUbLocal(var);
2581  }
2582 
2583  assert(!SCIPisZero(scip, val));
2584  assert(SCIPisLE(scip, lb, ub));
2585 
2586  if( val > 0.0 )
2587  {
2588  if( isminresact )
2589  {
2590  assert(!SCIPisInfinity(scip, -lb));
2591  assert(!SCIPisHugeValue(scip, REALABS(val*lb)));
2592  *resactivity += val*lb;
2593  }
2594  else
2595  {
2596  assert(!SCIPisInfinity(scip, ub));
2597  assert(!SCIPisHugeValue(scip, REALABS(val*ub)));
2598  *resactivity += val*ub;
2599  }
2600  }
2601  else
2602  {
2603  if( isminresact)
2604  {
2605  assert(!SCIPisInfinity(scip, ub));
2606  assert(!SCIPisHugeValue(scip, REALABS(val*ub)));
2607  *resactivity += val*ub;
2608  }
2609  else
2610  {
2611  assert(!SCIPisInfinity(scip, -lb));
2612  assert(!SCIPisHugeValue(scip, REALABS(val*lb)));
2613  *resactivity += val*lb;
2614  }
2615  }
2616  }
2617  assert(!SCIPisInfinity(scip, *resactivity) && !SCIPisInfinity(scip, -(*resactivity)));
2618 }
2619 
2620 /** gets activity bounds for constraint after setting variable to zero */
2621 static
2623  SCIP* scip, /**< SCIP data structure */
2624  SCIP_CONSDATA* consdata, /**< linear constraint */
2625  SCIP_VAR* var, /**< variable to calculate activity residual for */
2626  SCIP_Real val, /**< coefficient value of variable in linear constraint */
2627  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2628  * relaxed acticities ignored, anyway? */
2629  SCIP_Real* minresactivity, /**< pointer to store the minimal residual activity */
2630  SCIP_Real* maxresactivity, /**< pointer to store the maximal residual activity */
2631  SCIP_Bool* minisrelax, /**< pointer to store whether the returned residual minactivity is just a
2632  * relaxation, i.e. <= the exact residual minactivity (in case of huge
2633  * contributions), or equal to the exact residual minactivity */
2634  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned residual maxactivity is just a
2635  * relaxation, i.e. <= the exact residual maxactivity (in case of huge
2636  * contributions), or equal to the exact residual minactivity */
2637  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2638  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
2639  )
2640 {
2641  SCIP_Real minactbound;
2642  SCIP_Real maxactbound;
2643  SCIP_Real absval;
2644 
2645  assert(scip != NULL);
2646  assert(consdata != NULL);
2647  assert(var != NULL);
2648  assert(minresactivity != NULL);
2649  assert(maxresactivity != NULL);
2650  assert(minisrelax != NULL);
2651  assert(maxisrelax != NULL);
2652  assert(isminsettoinfinity != NULL);
2653  assert(ismaxsettoinfinity != NULL);
2654 
2655  /* get activity bounds of linear constraint */
2656  if( !consdata->validactivities )
2657  {
2658  consdataCalcActivities(scip, consdata);
2659  assert(consdata->validminact);
2660  assert(consdata->validmaxact);
2661  }
2662  assert(consdata->minactivity < SCIP_INVALID);
2663  assert(consdata->maxactivity < SCIP_INVALID);
2664  assert(consdata->minactivityneginf >= 0);
2665  assert(consdata->minactivityposinf >= 0);
2666  assert(consdata->maxactivityneginf >= 0);
2667  assert(consdata->maxactivityposinf >= 0);
2668  assert(consdata->minactivityneghuge >= 0);
2669  assert(consdata->minactivityposhuge >= 0);
2670  assert(consdata->maxactivityneghuge >= 0);
2671  assert(consdata->maxactivityposhuge >= 0);
2672 
2673  if( val > 0.0 )
2674  {
2675  minactbound = SCIPvarGetLbLocal(var);
2676  maxactbound = SCIPvarGetUbLocal(var);
2677  absval = val;
2678  }
2679  else
2680  {
2681  minactbound = -SCIPvarGetUbLocal(var);
2682  maxactbound = -SCIPvarGetLbLocal(var);
2683  absval = -val;
2684  }
2685 
2686  /* get/compute minactivity by calling getMinActivity() with updated counters for infinite and huge values
2687  * and contribution of variable set to zero that has to be subtracted from finite part of activity
2688  */
2689  if( SCIPisInfinity(scip, minactbound) )
2690  {
2691  assert(consdata->minactivityposinf >= 1);
2692 
2693  getMinActivity(scip, consdata, consdata->minactivityposinf - 1, consdata->minactivityneginf,
2694  consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2695  minresactivity, minisrelax, isminsettoinfinity);
2696  }
2697  else if( SCIPisInfinity(scip, -minactbound) )
2698  {
2699  assert(consdata->minactivityneginf >= 1);
2700 
2701  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf - 1,
2702  consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2703  minresactivity, minisrelax, isminsettoinfinity);
2704  }
2705  else if( SCIPisHugeValue(scip, minactbound * absval) )
2706  {
2707  assert(consdata->minactivityposhuge >= 1);
2708 
2709  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2710  consdata->minactivityposhuge - 1, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2711  minresactivity, minisrelax, isminsettoinfinity);
2712  }
2713  else if( SCIPisHugeValue(scip, -minactbound * absval) )
2714  {
2715  assert(consdata->minactivityneghuge >= 1);
2716 
2717  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2718  consdata->minactivityposhuge, consdata->minactivityneghuge - 1, 0.0, FALSE, goodrelax,
2719  minresactivity, minisrelax, isminsettoinfinity);
2720  }
2721  else
2722  {
2723  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2724  consdata->minactivityposhuge, consdata->minactivityneghuge, absval * minactbound, FALSE, goodrelax,
2725  minresactivity, minisrelax, isminsettoinfinity);
2726  }
2727 
2728  /* get/compute maxactivity by calling getMaxActivity() with updated counters for infinite and huge values
2729  * and contribution of variable set to zero that has to be subtracted from finite part of activity
2730  */
2731  if( SCIPisInfinity(scip, -maxactbound) )
2732  {
2733  assert(consdata->maxactivityneginf >= 1);
2734 
2735  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf - 1,
2736  consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2737  maxresactivity, maxisrelax, ismaxsettoinfinity);
2738  }
2739  else if( SCIPisInfinity(scip, maxactbound) )
2740  {
2741  assert(consdata->maxactivityposinf >= 1);
2742 
2743  getMaxActivity(scip, consdata, consdata->maxactivityposinf - 1, consdata->maxactivityneginf,
2744  consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2745  maxresactivity, maxisrelax, ismaxsettoinfinity);
2746  }
2747  else if( SCIPisHugeValue(scip, absval * maxactbound) )
2748  {
2749  assert(consdata->maxactivityposhuge >= 1);
2750 
2751  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2752  consdata->maxactivityposhuge - 1, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2753  maxresactivity, maxisrelax, ismaxsettoinfinity);
2754  }
2755  else if( SCIPisHugeValue(scip, -absval * maxactbound) )
2756  {
2757  assert(consdata->maxactivityneghuge >= 1);
2758 
2759  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2760  consdata->maxactivityposhuge, consdata->maxactivityneghuge - 1, 0.0, FALSE, goodrelax,
2761  maxresactivity, maxisrelax, ismaxsettoinfinity);
2762  }
2763  else
2764  {
2765  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2766  consdata->maxactivityposhuge, consdata->maxactivityneghuge, absval * maxactbound, FALSE, goodrelax,
2767  maxresactivity, maxisrelax, ismaxsettoinfinity);
2768  }
2769 }
2770 
2771 /** gets global activity bounds for constraint */
2772 static
2774  SCIP* scip, /**< SCIP data structure */
2775  SCIP_CONSDATA* consdata, /**< linear constraint */
2776  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2777  * relaxed acticities ignored, anyway? */
2778  SCIP_Real* glbminactivity, /**< pointer to store the minimal activity, or NULL, if not needed */
2779  SCIP_Real* glbmaxactivity, /**< pointer to store the maximal activity, or NULL, if not needed */
2780  SCIP_Bool* minisrelax, /**< pointer to store whether the returned minactivity is just a relaxation,
2781  * i.e. <= the exact minactivity (in case of huge contributions),
2782  * or equal to the exact minimal activity */
2783  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned maxactivity is just a relaxation,
2784  * i.e. >= the exact maxactivity (in case of huge contributions),
2785  * or equal to the exact maximal activity */
2786  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2787  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
2788  )
2789 {
2790  assert(scip != NULL);
2791  assert(consdata != NULL);
2792  assert((glbminactivity != NULL && minisrelax != NULL && isminsettoinfinity != NULL)
2793  || (glbmaxactivity != NULL && maxisrelax != NULL && ismaxsettoinfinity != NULL));
2794 
2795  if( !consdata->validactivities )
2796  {
2797  consdataCalcActivities(scip, consdata);
2798  assert(consdata->validglbminact);
2799  assert(consdata->validglbmaxact);
2800  }
2801  assert(consdata->glbminactivity < SCIP_INVALID);
2802  assert(consdata->glbmaxactivity < SCIP_INVALID);
2803  assert(consdata->glbminactivityneginf >= 0);
2804  assert(consdata->glbminactivityposinf >= 0);
2805  assert(consdata->glbmaxactivityneginf >= 0);
2806  assert(consdata->glbmaxactivityposinf >= 0);
2807  assert(consdata->glbminactivityneghuge >= 0);
2808  assert(consdata->glbminactivityposhuge >= 0);
2809  assert(consdata->glbmaxactivityneghuge >= 0);
2810  assert(consdata->glbmaxactivityposhuge >= 0);
2811 
2812  if( glbminactivity != NULL )
2813  {
2814  assert(isminsettoinfinity != NULL);
2815  assert(minisrelax != NULL);
2816 
2817  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
2818  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
2819  glbminactivity, minisrelax, isminsettoinfinity);
2820  }
2821 
2822  if( glbmaxactivity != NULL )
2823  {
2824  assert(ismaxsettoinfinity != NULL);
2825  assert(maxisrelax != NULL);
2826 
2827  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
2828  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
2829  glbmaxactivity, maxisrelax, ismaxsettoinfinity);
2830  }
2831 }
2832 
2833 /** gets global activity bounds for constraint after setting variable to zero */
2834 static
2836  SCIP* scip, /**< SCIP data structure */
2837  SCIP_CONSDATA* consdata, /**< linear constraint */
2838  SCIP_VAR* var, /**< variable to calculate activity residual for */
2839  SCIP_Real val, /**< coefficient value of variable in linear constraint */
2840  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2841  * relaxed acticities ignored, anyway? */
2842  SCIP_Real* minresactivity, /**< pointer to store the minimal residual activity, or NULL, if not needed */
2843  SCIP_Real* maxresactivity, /**< pointer to store the maximal residual activity, or NULL, if not needed */
2844  SCIP_Bool* minisrelax, /**< pointer to store whether the returned residual minactivity is just a
2845  * relaxation, i.e. <= the exact residual minactivity (in case of huge
2846  * contributions), or equal to the exact residual minactivity */
2847  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned residual maxactivity is just a
2848  * relaxation, i.e. <= the exact residual maxactivity (in case of huge
2849  * contributions), or equal to the exact residual minactivity */
2850  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2851  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
2852  )
2853 {
2854  SCIP_Real minactbound;
2855  SCIP_Real maxactbound;
2856  SCIP_Real absval;
2857 
2858  assert(scip != NULL);
2859  assert(consdata != NULL);
2860  assert(var != NULL);
2861  assert((minresactivity != NULL && minisrelax != NULL && isminsettoinfinity != NULL )
2862  || (maxresactivity != NULL && maxisrelax != NULL && ismaxsettoinfinity != NULL));
2863 
2864  /* get activity bounds of linear constraint */
2865  if( !consdata->validactivities )
2866  consdataCalcActivities(scip, consdata);
2867 
2868  assert(consdata->glbminactivity < SCIP_INVALID);
2869  assert(consdata->glbmaxactivity < SCIP_INVALID);
2870  assert(consdata->glbminactivityneginf >= 0);
2871  assert(consdata->glbminactivityposinf >= 0);
2872  assert(consdata->glbmaxactivityneginf >= 0);
2873  assert(consdata->glbmaxactivityposinf >= 0);
2874 
2875  if( val > 0.0 )
2876  {
2877  minactbound = SCIPvarGetLbGlobal(var);
2878  maxactbound = SCIPvarGetUbGlobal(var);
2879  absval = val;
2880  }
2881  else
2882  {
2883  minactbound = -SCIPvarGetUbGlobal(var);
2884  maxactbound = -SCIPvarGetLbGlobal(var);
2885  absval = -val;
2886  }
2887 
2888  if( minresactivity != NULL )
2889  {
2890  assert(isminsettoinfinity != NULL);
2891  assert(minisrelax != NULL);
2892 
2893  /* get/compute minactivity by calling getMinActivity() with updated counters for infinite and huge values
2894  * and contribution of variable set to zero that has to be subtracted from finite part of activity
2895  */
2896  if( SCIPisInfinity(scip, minactbound) )
2897  {
2898  assert(consdata->glbminactivityposinf >= 1);
2899 
2900  getMinActivity(scip, consdata, consdata->glbminactivityposinf - 1, consdata->glbminactivityneginf,
2901  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
2902  minresactivity, minisrelax, isminsettoinfinity);
2903  }
2904  else if( SCIPisInfinity(scip, -minactbound) )
2905  {
2906  assert(consdata->glbminactivityneginf >= 1);
2907 
2908  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf - 1,
2909  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
2910  minresactivity, minisrelax, isminsettoinfinity);
2911  }
2912  else if( SCIPisHugeValue(scip, minactbound * absval) )
2913  {
2914  assert(consdata->glbminactivityposhuge >= 1);
2915 
2916  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
2917  consdata->glbminactivityposhuge - 1, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
2918  minresactivity, minisrelax, isminsettoinfinity);
2919  }
2920  else if( SCIPisHugeValue(scip, -minactbound * absval) )
2921  {
2922  assert(consdata->glbminactivityneghuge >= 1);
2923 
2924  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
2925  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge - 1, 0.0, TRUE, goodrelax,
2926  minresactivity, minisrelax, isminsettoinfinity);
2927  }
2928  else
2929  {
2930  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
2931  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, absval * minactbound, TRUE,
2932  goodrelax, minresactivity, minisrelax, isminsettoinfinity);
2933  }
2934  }
2935 
2936  if( maxresactivity != NULL )
2937  {
2938  assert(ismaxsettoinfinity != NULL);
2939  assert(maxisrelax != NULL);
2940 
2941  /* get/compute maxactivity by calling getMaxActivity() with updated counters for infinite and huge values
2942  * and contribution of variable set to zero that has to be subtracted from finite part of activity
2943  */
2944  if( SCIPisInfinity(scip, -maxactbound) )
2945  {
2946  assert(consdata->glbmaxactivityneginf >= 1);
2947 
2948  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf - 1,
2949  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
2950  maxresactivity, maxisrelax, ismaxsettoinfinity);
2951  }
2952  else if( SCIPisInfinity(scip, maxactbound) )
2953  {
2954  assert(consdata->glbmaxactivityposinf >= 1);
2955 
2956  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf - 1, consdata->glbmaxactivityneginf,
2957  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
2958  maxresactivity, maxisrelax, ismaxsettoinfinity);
2959  }
2960  else if( SCIPisHugeValue(scip, absval * maxactbound) )
2961  {
2962  assert(consdata->glbmaxactivityposhuge >= 1);
2963 
2964  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
2965  consdata->glbmaxactivityposhuge - 1, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
2966  maxresactivity, maxisrelax, ismaxsettoinfinity);
2967  }
2968  else if( SCIPisHugeValue(scip, -absval * maxactbound) )
2969  {
2970  assert(consdata->glbmaxactivityneghuge >= 1);
2971 
2972  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
2973  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge - 1, 0.0, TRUE, goodrelax,
2974  maxresactivity, maxisrelax, ismaxsettoinfinity);
2975  }
2976  else
2977  {
2978  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
2979  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, absval * maxactbound, TRUE,
2980  goodrelax, maxresactivity, maxisrelax, ismaxsettoinfinity);
2981  }
2982  }
2983 }
2984 
2985 /** calculates the activity of the linear constraint for given solution */
2986 static
2988  SCIP* scip, /**< SCIP data structure */
2989  SCIP_CONSDATA* consdata, /**< linear constraint data */
2990  SCIP_SOL* sol /**< solution to get activity for, NULL to current solution */
2991  )
2992 {
2993  SCIP_Real activity;
2994 
2995  assert(scip != NULL);
2996  assert(consdata != NULL);
2997 
2998  if( sol == NULL && !SCIPhasCurrentNodeLP(scip) )
2999  activity = consdataComputePseudoActivity(scip, consdata);
3000  else
3001  {
3002  SCIP_Real solval;
3003  int nposinf;
3004  int nneginf;
3005  SCIP_Bool negsign;
3006  int v;
3007 
3008  activity = 0.0;
3009  nposinf = 0;
3010  nneginf = 0;
3011 
3012  for( v = 0; v < consdata->nvars; ++v )
3013  {
3014  solval = SCIPgetSolVal(scip, sol, consdata->vars[v]);
3015 
3016  if( consdata->vals[v] < 0 )
3017  negsign = TRUE;
3018  else
3019  negsign = FALSE;
3020 
3021  if( (SCIPisInfinity(scip, solval) && !negsign) || (SCIPisInfinity(scip, -solval) && negsign) )
3022  ++nposinf;
3023  else if( (SCIPisInfinity(scip, solval) && negsign) || (SCIPisInfinity(scip, -solval) && !negsign) )
3024  ++nneginf;
3025  else
3026  activity += consdata->vals[v] * solval;
3027  }
3028  assert(nneginf >= 0 && nposinf >= 0);
3029 
3030  SCIPdebugMsg(scip, "activity of linear constraint: %.15g, %d positive infinity values, %d negative infinity values \n", activity, nposinf, nneginf);
3031 
3032  /* check for amount of infinity values and correct the activity */
3033  if( nposinf > 0 && nneginf > 0 )
3034  activity = (consdata->rhs + consdata->lhs) / 2;
3035  else if( nposinf > 0 )
3036  activity = SCIPinfinity(scip);
3037  else if( nneginf > 0 )
3038  activity = -SCIPinfinity(scip);
3039 
3040  SCIPdebugMsg(scip, "corrected activity of linear constraint: %.15g\n", activity);
3041  }
3042 
3043  if( activity == SCIP_INVALID ) /*lint !e777*/
3044  return activity;
3045  else if( activity < 0 )
3046  activity = MAX(activity, -SCIPinfinity(scip)); /*lint !e666*/
3047  else
3048  activity = MIN(activity, SCIPinfinity(scip)); /*lint !e666*/
3049 
3050  return activity;
3051 }
3052 
3053 /** calculates the feasibility of the linear constraint for given solution */
3054 static
3056  SCIP* scip, /**< SCIP data structure */
3057  SCIP_CONSDATA* consdata, /**< linear constraint data */
3058  SCIP_SOL* sol /**< solution to get feasibility for, NULL to current solution */
3059  )
3060 {
3061  SCIP_Real activity;
3062 
3063  assert(scip != NULL);
3064  assert(consdata != NULL);
3065 
3066  activity = consdataGetActivity(scip, consdata, sol);
3067 
3068  if( activity == SCIP_INVALID ) /*lint !e777*/
3069  return -SCIPinfinity(scip);
3070 
3071  return MIN(consdata->rhs - activity, activity - consdata->lhs);
3073 
3074 /** updates bit signatures after adding a single coefficient */
3075 static
3077  SCIP_CONSDATA* consdata, /**< linear constraint data */
3078  int pos /**< position of coefficient to update signatures for */
3079  )
3080 {
3081  uint64_t varsignature;
3082  SCIP_Real lb;
3083  SCIP_Real ub;
3084  SCIP_Real val;
3085 
3086  assert(consdata != NULL);
3087  assert(consdata->validsignature);
3088 
3089  varsignature = SCIPhashSignature64(SCIPvarGetIndex(consdata->vars[pos]));
3090  lb = SCIPvarGetLbGlobal(consdata->vars[pos]);
3091  ub = SCIPvarGetUbGlobal(consdata->vars[pos]);
3092  val = consdata->vals[pos];
3093  if( (val > 0.0 && ub > 0.0) || (val < 0.0 && lb < 0.0) )
3094  consdata->possignature |= varsignature;
3095  if( (val > 0.0 && lb < 0.0) || (val < 0.0 && ub > 0.0) )
3096  consdata->negsignature |= varsignature;
3097 }
3098 
3099 /** calculates the bit signatures of the given constraint data */
3100 static
3102  SCIP_CONSDATA* consdata /**< linear constraint data */
3103  )
3104 {
3105  assert(consdata != NULL);
3106 
3107  if( !consdata->validsignature )
3108  {
3109  int i;
3110 
3111  consdata->validsignature = TRUE;
3112  consdata->possignature = 0;
3113  consdata->negsignature = 0;
3114  for( i = 0; i < consdata->nvars; ++i )
3115  consdataUpdateSignatures(consdata, i);
3116  }
3117 }
3119 /** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
3120 static
3121 SCIP_DECL_SORTINDCOMP(consdataCompVar)
3122 { /*lint --e{715}*/
3123  SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
3124 
3125  assert(consdata != NULL);
3126  assert(0 <= ind1 && ind1 < consdata->nvars);
3127  assert(0 <= ind2 && ind2 < consdata->nvars);
3128 
3129  return SCIPvarCompare(consdata->vars[ind1], consdata->vars[ind2]);
3130 }
3131 
3132 /** permutes the constraint's variables according to a given permutation. */
3133 static
3134 void permSortConsdata(
3135  SCIP_CONSDATA* consdata, /**< the constraint data */
3136  int* perm, /**< the target permutation */
3137  int nvars /**< the number of variables */
3138  )
3139 { /*lint --e{715}*/
3140  SCIP_VAR* varv;
3141  SCIP_EVENTDATA* eventdatav;
3142  SCIP_Real valv;
3143  int v;
3144  int i;
3145  int nexti;
3146 
3147  assert(perm != NULL);
3148  assert(consdata != NULL);
3149 
3150  /* permute the variables in the linear constraint according to the target permutation */
3151  eventdatav = NULL;
3152  for( v = 0; v < nvars; ++v )
3153  {
3154  if( perm[v] != v )
3155  {
3156  varv = consdata->vars[v];
3157  valv = consdata->vals[v];
3158  if( consdata->eventdata != NULL )
3159  eventdatav = consdata->eventdata[v];
3160  i = v;
3161  do
3162  {
3163  assert(0 <= perm[i] && perm[i] < nvars);
3164  assert(perm[i] != i);
3165  consdata->vars[i] = consdata->vars[perm[i]];
3166  consdata->vals[i] = consdata->vals[perm[i]];
3167  if( consdata->eventdata != NULL )
3168  {
3169  consdata->eventdata[i] = consdata->eventdata[perm[i]];
3170  consdata->eventdata[i]->varpos = i;
3171  }
3172  nexti = perm[i];
3173  perm[i] = i;
3174  i = nexti;
3175  }
3176  while( perm[i] != v );
3177  consdata->vars[i] = varv;
3178  consdata->vals[i] = valv;
3179  if( consdata->eventdata != NULL )
3180  {
3181  consdata->eventdata[i] = eventdatav;
3182  consdata->eventdata[i]->varpos = i;
3183  }
3184  perm[i] = i;
3185  }
3186  }
3187 #ifdef SCIP_DEBUG
3188  /* check sorting */
3189  for( v = 0; v < nvars; ++v )
3190  {
3191  assert(perm[v] == v);
3192  assert(consdata->eventdata == NULL || consdata->eventdata[v]->varpos == v);
3193  }
3194 #endif
3195 }
3196 
3197 /** sorts linear constraint's variables depending on the stage of the solving process:
3198  * - during PRESOLVING
3199  * sorts variables by binaries, integers, implicit integers, and continuous variables,
3200  * and the variables of the same type by non-decreasing variable index
3201  *
3202  * - during SOLVING
3203  * sorts binary variables of the remaining problem w.r.t the absolute of their coefficient.
3204  * This fastens the propagation time of the constraint handler.
3205  */
3206 static
3208  SCIP* scip, /**< SCIP data structure */
3209  SCIP_CONSDATA* consdata /**< linear constraint data */
3210  )
3211 {
3212  assert(scip != NULL);
3213  assert(consdata != NULL);
3214 
3215  /* check if there are variables for sorting */
3216  if( consdata->nvars <= 1 )
3217  {
3218  consdata->sorted = TRUE;
3219  consdata->binvarssorted = TRUE;
3220  }
3221  else if( SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE && !consdata->sorted )
3222  {
3223  int* perm;
3225  /* get temporary memory to store the sorted permutation */
3226  SCIP_CALL( SCIPallocBufferArray(scip, &perm, consdata->nvars) );
3227 
3228  /* call sorting method */
3229  SCIPsort(perm, consdataCompVar, (void*)consdata, consdata->nvars);
3230 
3231  permSortConsdata(consdata, perm, consdata->nvars);
3232 
3233  /* free temporary memory */
3234  SCIPfreeBufferArray(scip, &perm);
3235 
3236  consdata->sorted = TRUE;
3237  consdata->binvarssorted = FALSE;
3238  }
3239  else if( SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE && !consdata->binvarssorted )
3240  {
3241  SCIP_EVENTDATA** eventdata;
3242  SCIP_VAR** vars;
3243  SCIP_Real* vals;
3244  int nvars;
3245  int v;
3246  int lastbin;
3247 
3248  nvars = consdata->nvars;
3249  vars = consdata->vars;
3250  vals = consdata->vals;
3251  eventdata = consdata->eventdata;
3252  assert(vars != NULL || nvars == 0);
3253  assert(vals != NULL || nvars == 0);
3254 
3255  lastbin = 0;
3256  /* count binary variables and permute variables such that binaries appear first in the sorted vars array */
3257  for( v = 0; v < nvars; ++v )
3258  {
3259  assert( vars != NULL); /* for flexelint */
3260  assert( vals != NULL); /* for flexelint */
3261  if( SCIPvarIsBinary(vars[v]) )
3262  {
3263  /* swap variable at the end of the binary variables, if necessary */
3264  if( lastbin < v )
3265  {
3266  SCIP_VAR* tmpvar;
3267  SCIP_Real tmpval;
3268 
3269  tmpvar = vars[lastbin];
3270  tmpval = vals[lastbin];
3271 
3272  vars[lastbin] = vars[v];
3273  vals[lastbin] = vals[v];
3274 
3275  vars[v] = tmpvar;
3276  vals[v] = tmpval;
3277 
3278  if( eventdata != NULL )
3279  {
3280  SCIP_EVENTDATA* tmpeventdata;
3281 
3282  tmpeventdata = eventdata[lastbin];
3283  eventdata[lastbin] = eventdata[v];
3284  eventdata[lastbin]->varpos = lastbin;
3285  eventdata[v] = tmpeventdata;
3286  eventdata[v]->varpos = v;
3287  }
3288  assert(SCIPvarIsBinary(vars[lastbin]));
3289  }
3290 #ifndef NDEBUG
3291  else
3292  assert(lastbin == v);
3293 #endif
3294  ++lastbin;
3295  }
3296  }
3297  consdata->nbinvars = lastbin;
3298 
3299 #ifndef NDEBUG
3300  /* check sorting */
3301  for( v = 0; v < nvars; ++v )
3302  {
3303  assert(vars != NULL); /* for flexelint */
3304  assert(eventdata == NULL || eventdata[v]->varpos == v);
3305  assert((v >= consdata->nbinvars && !SCIPvarIsBinary(vars[v])) || (v < consdata->nbinvars && SCIPvarIsBinary(vars[v])));
3306  }
3307 #endif
3308 
3309  if( consdata->nbinvars > 1 )
3310  {
3311  SCIP_Real* absvals;
3312  int* perm;
3313 
3314  assert(lastbin == consdata->nbinvars);
3315  assert(lastbin <= nvars);
3316  assert(vals != NULL);
3317 
3318  /* initialize absolute coefficients and the target permutation for binary variables */
3319  SCIP_CALL( SCIPallocBufferArray(scip, &absvals, lastbin) );
3320  SCIP_CALL( SCIPallocBufferArray(scip, &perm, lastbin) );
3321 
3322  for( v = 0; v < lastbin; ++v )
3323  {
3324  absvals[v] = ABS(vals[v]);
3325  perm[v] = v;
3326  }
3327 
3328  /* execute the sorting */
3329  SCIPsortDownRealInt(absvals, perm, lastbin);
3330 
3331  permSortConsdata(consdata, perm, lastbin);
3332 
3333  /* free temporary arrays */
3334  SCIPfreeBufferArray(scip, &perm);
3335  SCIPfreeBufferArray(scip, &absvals);
3336  }
3337  consdata->binvarssorted = TRUE;
3338 
3339  /* presolve sorting cannot be guaranteed after binary sorting */
3340  consdata->sorted = (consdata->sorted && consdata->nbinvars == 0);
3341  }
3342  assert(SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE || consdata->binvarssorted);
3343  assert(SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE || consdata->sorted);
3344 
3345  return SCIP_OKAY;
3346 }
3347 
3348 
3349 /*
3350  * local linear constraint handler methods
3351  */
3352 
3353 /** sets left hand side of linear constraint */
3354 static
3356  SCIP* scip, /**< SCIP data structure */
3357  SCIP_CONS* cons, /**< linear constraint */
3358  SCIP_Real lhs /**< new left hand side */
3359  )
3360 {
3361  SCIP_CONSDATA* consdata;
3362 
3363  assert(scip != NULL);
3364  assert(cons != NULL);
3365  assert(!SCIPisInfinity(scip, lhs));
3366 
3367  /* adjust value to not be smaller than -inf */
3368  if ( SCIPisInfinity(scip, -lhs) )
3369  lhs = -SCIPinfinity(scip);
3370 
3371  consdata = SCIPconsGetData(cons);
3372  assert(consdata != NULL);
3373  assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
3374  assert(!SCIPisInfinity(scip, consdata->lhs));
3375 
3376  /* check whether the side is not changed */
3377  if( SCIPisEQ(scip, consdata->lhs, lhs) )
3378  return SCIP_OKAY;
3379 
3380  /* ensure that rhs >= lhs is satisfied without numerical tolerance */
3381  if( SCIPisEQ(scip, lhs, consdata->rhs) )
3382  {
3383  consdata->rhs = lhs;
3384  assert(consdata->row == NULL);
3385  }
3386 
3387  /* if necessary, update the rounding locks of variables */
3388  if( SCIPconsIsLocked(cons) )
3389  {
3390  if( SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, -lhs) )
3391  {
3392  SCIP_VAR** vars;
3393  SCIP_Real* vals;
3394  int v;
3395 
3396  /* the left hand side switched from -infinity to a non-infinite value -> install rounding locks */
3397  vars = consdata->vars;
3398  vals = consdata->vals;
3399 
3400  for( v = 0; v < consdata->nvars; ++v )
3401  {
3402  assert(vars[v] != NULL);
3403  assert(!SCIPisZero(scip, vals[v]));
3404 
3405  if( SCIPisPositive(scip, vals[v]) )
3406  {
3407  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3408  }
3409  else
3410  {
3411  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3412  }
3413  }
3414  }
3415  else if( !SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, -lhs) )
3416  {
3417  SCIP_VAR** vars;
3418  SCIP_Real* vals;
3419  int v;
3420 
3421  /* the left hand side switched from a non-infinite value to -infinity -> remove rounding locks */
3422  vars = consdata->vars;
3423  vals = consdata->vals;
3424 
3425  for( v = 0; v < consdata->nvars; ++v )
3426  {
3427  assert(vars[v] != NULL);
3428  assert(!SCIPisZero(scip, vals[v]));
3429 
3430  if( SCIPisPositive(scip, vals[v]) )
3431  {
3432  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3433  }
3434  else
3435  {
3436  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3437  }
3438  }
3439  }
3440  }
3441 
3442  /* 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 */
3443  if( !SCIPisInfinity(scip, -lhs) && SCIPisGT(scip, lhs, consdata->lhs) )
3444  {
3445  consdata->boundstightened = 0;
3446  consdata->presolved = FALSE;
3447  consdata->cliquesadded = FALSE;
3448  consdata->implsadded = FALSE;
3449 
3450  /* mark the constraint for propagation */
3451  if( SCIPconsIsTransformed(cons) )
3452  {
3453  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3454  }
3455  }
3456 
3457  /* set new left hand side and update constraint data */
3458  consdata->lhs = lhs;
3459  consdata->changed = TRUE;
3460  consdata->normalized = FALSE;
3461  consdata->upgradetried = FALSE;
3462  consdata->rangedrowpropagated = 0;
3463 
3464 
3465  /* update the lhs of the LP row */
3466  if( consdata->row != NULL )
3467  {
3468  SCIP_CALL( SCIPchgRowLhs(scip, consdata->row, lhs) );
3469  }
3470 
3471  return SCIP_OKAY;
3472 }
3473 
3474 /** sets right hand side of linear constraint */
3475 static
3477  SCIP* scip, /**< SCIP data structure */
3478  SCIP_CONS* cons, /**< linear constraint */
3479  SCIP_Real rhs /**< new right hand side */
3480  )
3481 {
3482  SCIP_CONSDATA* consdata;
3483 
3484  assert(scip != NULL);
3485  assert(cons != NULL);
3486  assert(!SCIPisInfinity(scip, -rhs));
3487 
3488  /* adjust value to not be larger than inf */
3489  if ( SCIPisInfinity(scip, rhs) )
3490  rhs = SCIPinfinity(scip);
3491 
3492  consdata = SCIPconsGetData(cons);
3493  assert(consdata != NULL);
3494  assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
3495  assert(!SCIPisInfinity(scip, -consdata->rhs));
3496 
3497  /* check whether the side is not changed */
3498  if( SCIPisEQ(scip, consdata->rhs, rhs) )
3499  return SCIP_OKAY;
3500 
3501  /* ensure that rhs >= lhs is satisfied without numerical tolerance */
3502  if( SCIPisEQ(scip, rhs, consdata->lhs) )
3503  {
3504  consdata->lhs = rhs;
3505  assert(consdata->row == NULL);
3506  }
3507 
3508  /* if necessary, update the rounding locks of variables */
3509  if( SCIPconsIsLocked(cons) )
3510  {
3511  assert(SCIPconsIsTransformed(cons));
3512 
3513  if( SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, rhs) )
3514  {
3515  SCIP_VAR** vars;
3516  SCIP_Real* vals;
3517  int v;
3518 
3519  /* the right hand side switched from infinity to a non-infinite value -> install rounding locks */
3520  vars = consdata->vars;
3521  vals = consdata->vals;
3522 
3523  for( v = 0; v < consdata->nvars; ++v )
3524  {
3525  assert(vars[v] != NULL);
3526  assert(!SCIPisZero(scip, vals[v]));
3527 
3528  if( SCIPisPositive(scip, vals[v]) )
3529  {
3530  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3531  }
3532  else
3533  {
3534  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3535  }
3536  }
3537  }
3538  else if( !SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, rhs) )
3539  {
3540  SCIP_VAR** vars;
3541  SCIP_Real* vals;
3542  int v;
3543 
3544  /* the right hand side switched from a non-infinite value to infinity -> remove rounding locks */
3545  vars = consdata->vars;
3546  vals = consdata->vals;
3547 
3548  for( v = 0; v < consdata->nvars; ++v )
3549  {
3550  assert(vars[v] != NULL);
3551  assert(!SCIPisZero(scip, vals[v]));
3552 
3553  if( SCIPisPositive(scip, vals[v]) )
3554  {
3555  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3556  }
3557  else
3558  {
3559  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3560  }
3561  }
3562  }
3563  }
3564 
3565  /* 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 */
3566  if( !SCIPisInfinity(scip, rhs) && SCIPisLT(scip, rhs, consdata->rhs) )
3567  {
3568  consdata->boundstightened = 0;
3569  consdata->presolved = FALSE;
3570  consdata->cliquesadded = FALSE;
3571  consdata->implsadded = FALSE;
3572 
3573  /* mark the constraint for propagation */
3574  if( SCIPconsIsTransformed(cons) )
3575  {
3576  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3577  }
3578  }
3579 
3580  /* set new right hand side and update constraint data */
3581  consdata->rhs = rhs;
3582  consdata->changed = TRUE;
3583  consdata->normalized = FALSE;
3584  consdata->upgradetried = FALSE;
3585  consdata->rangedrowpropagated = 0;
3586 
3587  /* update the rhs of the LP row */
3588  if( consdata->row != NULL )
3589  {
3590  SCIP_CALL( SCIPchgRowRhs(scip, consdata->row, rhs) );
3591  }
3592 
3593  return SCIP_OKAY;
3594 }
3595 
3596 /** adds coefficient in linear constraint */
3597 static
3599  SCIP* scip, /**< SCIP data structure */
3600  SCIP_CONS* cons, /**< linear constraint */
3601  SCIP_VAR* var, /**< variable of constraint entry */
3602  SCIP_Real val /**< coefficient of constraint entry */
3603  )
3604 {
3605  SCIP_CONSDATA* consdata;
3606  SCIP_Bool transformed;
3607 
3608  assert(scip != NULL);
3609  assert(cons != NULL);
3610  assert(var != NULL);
3611 
3612  /* ignore coefficient if it is nearly zero */
3613  if( SCIPisZero(scip, val) )
3614  return SCIP_OKAY;
3616  consdata = SCIPconsGetData(cons);
3617  assert(consdata != NULL);
3618 
3619  /* are we in the transformed problem? */
3620  transformed = SCIPconsIsTransformed(cons);
3621 
3622  /* always use transformed variables in transformed constraints */
3623  if( transformed )
3624  {
3625  SCIP_CALL( SCIPgetTransformedVar(scip, var, &var) );
3626  }
3627  assert(var != NULL);
3628  assert(transformed == SCIPvarIsTransformed(var));
3629 
3630  SCIP_CALL( consdataEnsureVarsSize(scip, consdata, consdata->nvars+1) );
3631  consdata->vars[consdata->nvars] = var;
3632  consdata->vals[consdata->nvars] = val;
3633  consdata->nvars++;
3634 
3635  /* capture variable */
3636  SCIP_CALL( SCIPcaptureVar(scip, var) );
3637 
3638  /* if we are in transformed problem, the variable needs an additional event data */
3639  if( transformed )
3640  {
3641  if( consdata->eventdata != NULL )
3642  {
3643  SCIP_CONSHDLR* conshdlr;
3644  SCIP_CONSHDLRDATA* conshdlrdata;
3645 
3646  /* check for event handler */
3647  conshdlr = SCIPconsGetHdlr(cons);
3648  conshdlrdata = SCIPconshdlrGetData(conshdlr);
3649  assert(conshdlrdata != NULL);
3650  assert(conshdlrdata->eventhdlr != NULL);
3651 
3652  /* initialize eventdata array */
3653  consdata->eventdata[consdata->nvars-1] = NULL;
3654 
3655  /* catch bound change events of variable */
3656  SCIP_CALL( consCatchEvent(scip, cons, conshdlrdata->eventhdlr, consdata->nvars-1) );
3657  }
3658 
3659  /* update minimum and maximum activities */
3660  consdataUpdateAddCoef(scip, consdata, var, val, FALSE);
3661 
3662  /* update maximum activity delta */
3663  if( !SCIPisInfinity(scip, consdata->maxactdelta ) )
3664  {
3665  SCIP_Real lb;
3666  SCIP_Real ub;
3667 
3668  lb = SCIPvarGetLbLocal(var);
3669  ub = SCIPvarGetUbLocal(var);
3670 
3671  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
3672  {
3673  consdata->maxactdelta = SCIPinfinity(scip);
3674  consdata->maxactdeltavar = var;
3675  }
3676  else
3677  {
3678  SCIP_Real domain = ub - lb;
3679  SCIP_Real delta = REALABS(val) * domain;
3680 
3681  if( delta > consdata->maxactdelta )
3682  {
3683  consdata->maxactdelta = delta;
3684  consdata->maxactdeltavar = var;
3685  }
3686  }
3687  }
3688  }
3689 
3690  /* install rounding locks for new variable */
3691  SCIP_CALL( lockRounding(scip, cons, var, val) );
3692 
3693  /* mark the constraint for propagation */
3694  if( transformed )
3695  {
3696  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3697  }
3698 
3699  consdata->boundstightened = 0;
3700  consdata->presolved = FALSE;
3701  consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(var);
3702 
3703  if( consdata->validsignature )
3704  consdataUpdateSignatures(consdata, consdata->nvars-1);
3705 
3706  consdata->changed = TRUE;
3707  consdata->normalized = FALSE;
3708  consdata->upgradetried = FALSE;
3709  consdata->cliquesadded = FALSE;
3710  consdata->implsadded = FALSE;
3711  consdata->rangedrowpropagated = 0;
3712 
3713  if( consdata->nvars == 1 )
3714  {
3715  consdata->binvarssorted = TRUE;
3716  consdata->sorted = TRUE;
3717  consdata->merged = TRUE;
3718  }
3719  else
3720  {
3721  consdata->binvarssorted = consdata->binvarssorted && !SCIPvarIsBinary(var);
3722  consdata->sorted = consdata->sorted
3723  && (SCIPvarCompare(consdata->vars[consdata->nvars-2], consdata->vars[consdata->nvars-1]) <= 0);
3724  consdata->merged = FALSE;
3725  }
3726 
3727  /* update hascontvar and hasnonbinvar flags */
3728  if( consdata->hasnonbinvalid && !consdata->hascontvar )
3729  {
3730  SCIP_VARTYPE vartype = SCIPvarGetType(var);
3731 
3732  if( vartype != SCIP_VARTYPE_BINARY )
3733  {
3734  consdata->hasnonbinvar = TRUE;
3735 
3736  if( vartype == SCIP_VARTYPE_CONTINUOUS )
3737  consdata->hascontvar = TRUE;
3738  }
3739  }
3740 
3741  /* add the new coefficient to the LP row */
3742  if( consdata->row != NULL )
3743  {
3744  SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, var, val) );
3745  }
3746 
3747  return SCIP_OKAY;
3748 }
3749 
3750 /** deletes coefficient at given position from linear constraint data */
3751 static
3753  SCIP* scip, /**< SCIP data structure */
3754  SCIP_CONS* cons, /**< linear constraint */
3755  int pos /**< position of coefficient to delete */
3756  )
3757 {
3758  SCIP_CONSDATA* consdata;
3759  SCIP_VAR* var;
3760  SCIP_Real val;
3761 
3762  assert(scip != NULL);
3763  assert(cons != NULL);
3764 
3765  consdata = SCIPconsGetData(cons);
3766  assert(consdata != NULL);
3767  assert(0 <= pos && pos < consdata->nvars);
3768 
3769  var = consdata->vars[pos];
3770  val = consdata->vals[pos];
3771  assert(var != NULL);
3772 
3773  /* remove rounding locks for deleted variable */
3774  SCIP_CALL( unlockRounding(scip, cons, var, val) );
3775 
3776  /* if we are in transformed problem, delete the event data of the variable */
3777  if( SCIPconsIsTransformed(cons) )
3778  {
3779  SCIP_CONSHDLR* conshdlr;
3780  SCIP_CONSHDLRDATA* conshdlrdata;
3781 
3782  /* check for event handler */
3783  conshdlr = SCIPconsGetHdlr(cons);
3784  conshdlrdata = SCIPconshdlrGetData(conshdlr);
3785  assert(conshdlrdata != NULL);
3786  assert(conshdlrdata->eventhdlr != NULL);
3787 
3788  /* drop bound change events of variable */
3789  if( consdata->eventdata != NULL )
3790  {
3791  SCIP_CALL( consDropEvent(scip, cons, conshdlrdata->eventhdlr, pos) );
3792  assert(consdata->eventdata[pos] == NULL);
3793  }
3794  }
3795 
3796  /* move the last variable to the free slot */
3797  if( pos != consdata->nvars-1 )
3798  {
3799  consdata->binvarssorted = consdata->binvarssorted && !SCIPvarIsBinary(consdata->vars[pos]);
3800 
3801  consdata->vars[pos] = consdata->vars[consdata->nvars-1];
3802  consdata->vals[pos] = consdata->vals[consdata->nvars-1];
3803 
3804  if( consdata->eventdata != NULL )
3805  {
3806  consdata->eventdata[pos] = consdata->eventdata[consdata->nvars-1];
3807  assert(consdata->eventdata[pos] != NULL);
3808  consdata->eventdata[pos]->varpos = pos;
3809  }
3810  consdata->sorted = consdata->sorted && (pos + 2 >= consdata->nvars || (SCIPvarCompare(consdata->vars[pos], consdata->vars[pos + 1]) <= 0));
3811  }
3812  consdata->nvars--;
3813 
3814  /* if at most one variable is left, the activities should be recalculated (to correspond exactly to the bounds
3815  * of the remaining variable, or give exactly 0.0)
3816  */
3817  if( consdata->nvars <= 1 )
3818  consdataInvalidateActivities(consdata);
3819  else
3820  {
3821  if( SCIPconsIsTransformed(cons) )
3822  {
3823  /* if we are in transformed problem, update minimum and maximum activities */
3824  consdataUpdateDelCoef(scip, consdata, var, val, TRUE);
3825 
3826  /* if the variable defining the maximal activity delta was removed from the constraint, the maximal activity
3827  * delta needs to be recalculated on the next real propagation
3828  */
3829  if( consdata->maxactdeltavar == var )
3830  {
3831  consdata->maxactdelta = SCIP_INVALID;
3832  consdata->maxactdeltavar = NULL;
3833  }
3834  }
3835  }
3836 
3837  /* mark the constraint for propagation */
3838  if( SCIPconsIsTransformed(cons) )
3839  {
3840  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3841  }
3842 
3843  consdata->boundstightened = 0;
3844  consdata->presolved = FALSE;
3845  consdata->validsignature = FALSE;
3846  consdata->changed = TRUE;
3847  consdata->normalized = FALSE;
3848  consdata->upgradetried = FALSE;
3849  consdata->cliquesadded = FALSE;
3850  consdata->implsadded = FALSE;
3851  consdata->rangedrowpropagated = 0;
3852 
3853  /* check if hasnonbinvar flag might be incorrect now */
3854  if( consdata->hasnonbinvar && SCIPvarGetType(var) != SCIP_VARTYPE_BINARY )
3855  {
3856  consdata->hasnonbinvalid = FALSE;
3857  }
3858 
3859  /* delete coefficient from the LP row */
3860  if( consdata->row != NULL )
3861  {
3862  SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, var, -val) );
3863  }
3864 
3865  /* release variable */
3866  SCIP_CALL( SCIPreleaseVar(scip, &var) );
3867 
3868  return SCIP_OKAY;
3869 }
3870 
3871 /** changes coefficient value at given position of linear constraint data */
3872 static
3874  SCIP* scip, /**< SCIP data structure */
3875  SCIP_CONS* cons, /**< linear constraint */
3876  int pos, /**< position of coefficient to delete */
3877  SCIP_Real newval /**< new value of coefficient */
3878  )
3879 {
3880  SCIP_CONSDATA* consdata;
3881  SCIP_VAR* var;
3882  SCIP_Real val;
3883 
3884  assert(scip != NULL);
3885  assert(cons != NULL);
3886  assert(!SCIPisZero(scip, newval));
3887 
3888  consdata = SCIPconsGetData(cons);
3889  assert(consdata != NULL);
3890  assert(0 <= pos && pos < consdata->nvars);
3891  assert(!SCIPisZero(scip, newval));
3892 
3893  var = consdata->vars[pos];
3894  val = consdata->vals[pos];
3895  assert(var != NULL);
3896  assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(var));
3897 
3898  /* if necessary, update the rounding locks of the variable */
3899  if( SCIPconsIsLocked(cons) && newval * val < 0.0 )
3900  {
3901  assert(SCIPconsIsTransformed(cons));
3902 
3903  /* remove rounding locks for variable with old coefficient */
3904  SCIP_CALL( unlockRounding(scip, cons, var, val) );
3905 
3906  /* install rounding locks for variable with new coefficient */
3907  SCIP_CALL( lockRounding(scip, cons, var, newval) );
3908  }
3909 
3910  /* change the value */
3911  consdata->vals[pos] = newval;
3912 
3913  consdata->binvarssorted = consdata->binvarssorted && !SCIPvarIsBinary(var);
3914 
3915  /* update minimum and maximum activities */
3916  if( SCIPconsIsTransformed(cons) )
3917  consdataUpdateChgCoef(scip, consdata, var, val, newval, TRUE);
3918 
3919  /* mark the constraint for propagation */
3920  if( SCIPconsIsTransformed(cons) )
3921  {
3922  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3923  }
3924 
3925  consdata->boundstightened = 0;
3926  consdata->presolved = FALSE;
3927  consdata->validsignature = consdata->validsignature && (newval * val > 0.0);
3928  consdata->changed = TRUE;
3929  consdata->normalized = FALSE;
3930  consdata->upgradetried = FALSE;
3931  consdata->cliquesadded = FALSE;
3932  consdata->implsadded = FALSE;
3933  consdata->rangedrowpropagated = 0;
3934 
3935  return SCIP_OKAY;
3936 }
3937 
3938 /** scales a linear constraint with a constant scalar */
3939 static
3941  SCIP* scip, /**< SCIP data structure */
3942  SCIP_CONS* cons, /**< linear constraint to scale */
3943  SCIP_Real scalar /**< value to scale constraint with */
3944  )
3945 {
3946  SCIP_CONSDATA* consdata;
3947  SCIP_Real newval;
3948  SCIP_Real absscalar;
3949  int i;
3950 
3951  assert(scip != NULL);
3952  assert(cons != NULL);
3953 
3954  consdata = SCIPconsGetData(cons);
3955  assert(consdata != NULL);
3956  assert(consdata->row == NULL);
3957  assert(!SCIPisEQ(scip, scalar, 1.0));
3958 
3959  /* scale the coefficients */
3960  for( i = consdata->nvars - 1; i >= 0; --i )
3961  {
3962  newval = scalar * consdata->vals[i];
3963 
3964  /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasFloor, we add an additional 0.5 before
3965  * flooring down our new value
3966  */
3967  if( SCIPisScalingIntegral(scip, consdata->vals[i], scalar) )
3968  newval = SCIPfeasFloor(scip, newval + 0.5);
3969 
3970  if( SCIPisZero(scip, newval) )
3971  {
3972  SCIPwarningMessage(scip, "coefficient %.15g of variable <%s> in linear constraint <%s> scaled to zero (scalar: %.15g)\n",
3973  consdata->vals[i], SCIPvarGetName(consdata->vars[i]), SCIPconsGetName(cons), scalar);
3974  SCIP_CALL( delCoefPos(scip, cons, i) );
3975  }
3976  else
3977  consdata->vals[i] = newval;
3978  }
3979 
3980  /* scale the sides */
3981  if( scalar < 0.0 )
3982  {
3983  SCIP_Real lhs;
3984 
3985  lhs = consdata->lhs;
3986  consdata->lhs = -consdata->rhs;
3987  consdata->rhs = -lhs;
3988  }
3989  absscalar = REALABS(scalar);
3990  if( !SCIPisInfinity(scip, -consdata->lhs) )
3991  {
3992  newval = absscalar * consdata->lhs;
3993 
3994  /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasFloor, we add an additional 0.5 before
3995  * flooring down our new value
3996  */
3997  if( SCIPisScalingIntegral(scip, consdata->lhs, absscalar) )
3998  consdata->lhs = SCIPfeasFloor(scip, newval + 0.5);
3999  else
4000  consdata->lhs = newval;
4001  }
4002  if( !SCIPisInfinity(scip, consdata->rhs) )
4003  {
4004  newval = absscalar * consdata->rhs;
4005 
4006  /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasCeil, we subtract 0.5 before ceiling up
4007  * our new value
4008  */
4009  if( SCIPisScalingIntegral(scip, consdata->rhs, absscalar) )
4010  consdata->rhs = SCIPfeasCeil(scip, newval - 0.5);
4011  else
4012  consdata->rhs = newval;
4013  }
4014 
4015  consdataInvalidateActivities(consdata);
4016  consdata->cliquesadded = FALSE;
4017  consdata->implsadded = FALSE;
4018 
4019  return SCIP_OKAY;
4020 }
4021 
4022 /* perform deletion of variables in all constraints of the constraint handler */
4023 static
4025  SCIP* scip, /**< SCIP data structure */
4026  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4027  SCIP_CONS** conss, /**< array of constraints */
4028  int nconss /**< number of constraints */
4029  )
4030 {
4031  SCIP_CONSDATA* consdata;
4032  int i;
4033  int v;
4034 
4035  assert(scip != NULL);
4036  assert(conshdlr != NULL);
4037  assert(conss != NULL);
4038  assert(nconss >= 0);
4039  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
4040 
4041  /* iterate over all constraints */
4042  for( i = 0; i < nconss; i++ )
4043  {
4044  consdata = SCIPconsGetData(conss[i]);
4045 
4046  /* constraint is marked, that some of its variables were deleted */
4047  if( consdata->varsdeleted )
4048  {
4049  /* iterate over all variables of the constraint and delete them from the constraint */
4050  for( v = consdata->nvars - 1; v >= 0; --v )
4051  {
4052  if( SCIPvarIsDeleted(consdata->vars[v]) )
4053  {
4054  SCIP_CALL( delCoefPos(scip, conss[i], v) );
4055  }
4056  }
4057  consdata->varsdeleted = FALSE;
4058  }
4059  }
4060 
4061  return SCIP_OKAY;
4062 }
4063 
4064 
4065 /** normalizes a linear constraint with the following rules:
4066  * - if all coefficients have them same absolute value, change them to (-)1.0
4067  * - multiplication with +1 or -1:
4068  * Apply the following rules in the given order, until the sign of the factor is determined. Later rules only apply,
4069  * if the current rule doesn't determine the sign):
4070  * 1. the right hand side must not be negative
4071  * 2. the right hand side must not be infinite
4072  * 3. the absolute value of the right hand side must be greater than that of the left hand side
4073  * 4. the number of positive coefficients must not be smaller than the number of negative coefficients
4074  * 5. multiply with +1
4075  * - rationals to integrals
4076  * Try to identify a rational representation of the fractional coefficients, and multiply all coefficients
4077  * by the smallest common multiple of all denominators to get integral coefficients.
4078  * Forbid large denominators due to numerical stability.
4079  * - division by greatest common divisor
4080  * If all coefficients are integral, divide them by the greatest common divisor.
4081  */
4082 static
4084  SCIP* scip, /**< SCIP data structure */
4085  SCIP_CONS* cons /**< linear constraint to normalize */
4086  )
4087 {
4088  SCIP_CONSDATA* consdata;
4089  SCIP_VAR** vars;
4090  SCIP_Real* vals;
4091  SCIP_Longint scm;
4092  SCIP_Longint nominator;
4093  SCIP_Longint denominator;
4094  SCIP_Longint gcd;
4095  SCIP_Longint maxmult;
4096  SCIP_Real epsilon;
4097  SCIP_Real feastol;
4098  SCIP_Real maxabsval;
4099  SCIP_Real minabsval;
4100  SCIP_Bool success;
4101  SCIP_Bool onlyintegral;
4102  int nvars;
4103  int mult;
4104  int nposcoeffs;
4105  int nnegcoeffs;
4106  int i;
4107  int v;
4108 
4109  assert(scip != NULL);
4110  assert(cons != NULL);
4111 
4112  /* we must not change a modifiable constraint in any way */
4113  if( SCIPconsIsModifiable(cons) )
4114  return SCIP_OKAY;
4115 
4116  /* get constraint data */
4117  consdata = SCIPconsGetData(cons);
4118  assert(consdata != NULL);
4119 
4120  /* check, if the constraint is already normalized */
4121  if( consdata->normalized )
4122  return SCIP_OKAY;
4123 
4124  /* get coefficient arrays */
4125  vals = consdata->vals;
4126  nvars = consdata->nvars;
4127  vars = consdata->vars;
4128  assert(nvars == 0 || vars != NULL);
4129  assert(nvars == 0 || vals != NULL);
4130 
4131  if( nvars == 0 )
4132  {
4133  consdata->normalized = TRUE;
4134  return SCIP_OKAY;
4135  }
4136 
4137  assert(vars != NULL);
4138  assert(vals != NULL);
4139 
4140  /* get maximal and minimal absolute coefficient */
4141  maxabsval = consdataGetMaxAbsval(consdata);
4142  minabsval = consdataGetMinAbsval(consdata);
4143 
4144  /* return if scaling by maxval will eliminate coefficients */
4145  if( SCIPisZero(scip, minabsval/maxabsval) )
4146  return SCIP_OKAY;
4147 
4148  /* check if all coefficients are in absolute value equal, and not 1.0 */
4149  if( !SCIPisEQ(scip, maxabsval, 1.0) )
4150  {
4151  SCIP_Bool abscoefsequ;
4152 
4153  abscoefsequ = TRUE;
4154 
4155  for( v = nvars - 1; v >= 0; --v )
4156  {
4157  if( !SCIPisEQ(scip, REALABS(vals[v]), maxabsval) )
4158  {
4159  abscoefsequ = FALSE;
4160  break;
4161  }
4162  }
4163 
4164  /* all coefficients are in absolute value equal, so change them to (-)1.0 */
4165  if( abscoefsequ )
4166  {
4167  SCIPdebugMsg(scip, "divide linear constraint with %g, because all coefficents are in absolute value the same\n", maxabsval);
4168  SCIPdebugPrintCons(scip, cons, NULL);
4169  SCIP_CALL( scaleCons(scip, cons, 1/maxabsval) );
4170 
4171  if( consdata->validmaxabsval )
4172  {
4173  if( !SCIPisEQ(scip, consdata->maxabsval, 1.0) )
4174  consdata->maxabsval = 1.0;
4175  if( !SCIPisEQ(scip, consdata->minabsval, 1.0) )
4176  consdata->minabsval = 1.0;
4177 
4178  maxabsval = 1.0;
4179  }
4180  else
4181  {
4182  /* get maximal absolute coefficient */
4183  maxabsval = consdataGetMaxAbsval(consdata);
4184  }
4185 
4186  /* get new consdata information, because scalecons() might have deleted variables */
4187  vals = consdata->vals;
4188  nvars = consdata->nvars;
4189  vars = consdata->vars;
4190 
4191  assert(nvars == 0 || vars != NULL);
4192  assert(nvars == 0 || vals != NULL);
4193  }
4194  }
4195 
4196  /* nvars might have changed */
4197  if( nvars == 0 )
4198  {
4199  consdata->normalized = TRUE;
4200  return SCIP_OKAY;
4201  }
4202 
4203  assert(vars != NULL);
4204  assert(vals != NULL);
4205 
4206  /* calculate the maximal multiplier for common divisor calculation:
4207  * |p/q - val| < epsilon and q < feastol/epsilon => |p - q*val| < feastol
4208  * which means, a value of feastol/epsilon should be used as maximal multiplier;
4209  * additionally, we don't want to scale the constraint if this would lead to too
4210  * large coefficients
4211  */
4212  epsilon = SCIPepsilon(scip) * 0.9; /* slightly decrease epsilon to be safe in rational conversion below */
4213  feastol = SCIPfeastol(scip);
4214  maxmult = (SCIP_Longint)(feastol/epsilon + feastol);
4215  maxmult = MIN(maxmult, (SCIP_Longint)( MAXSCALEDCOEF/MAX(maxabsval, 1.0)));
4216 
4217  if( !consdata->hasnonbinvalid )
4218  consdataCheckNonbinvar(consdata);
4219 
4220  /* if all variables are of integral type we will allow a greater multiplier */
4221  if( !consdata->hascontvar )
4222  {
4223  if( SCIPvarGetType(vars[nvars - 1]) != SCIP_VARTYPE_CONTINUOUS )
4224  {
4225  maxmult = (SCIP_Longint) (MAXSCALEDCOEFINTEGER/(MAX(maxabsval, 1.0)));
4226  }
4227  }
4228  else
4229  {
4230  SCIP_Bool foundcont;
4231 
4232  foundcont = FALSE;
4233 
4234  for( v = nvars - 1; v >= 0; --v )
4235  {
4236  if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
4237  {
4238  foundcont = TRUE;
4239  break;
4240  }
4241  }
4242 
4243  if( !foundcont )
4244  {
4245  maxmult = (SCIP_Longint) (MAXSCALEDCOEFINTEGER/(MAX(maxabsval, 1.0)));
4246  }
4247  }
4248 
4249  /*
4250  * multiplication with +1 or -1
4251  */
4252  mult = 0;
4253 
4254  /* 1. the right hand side must not be negative */
4255  if( SCIPisPositive(scip, consdata->lhs) )
4256  mult = +1;
4257  else if( SCIPisNegative(scip, consdata->rhs) )
4258  mult = -1;
4259 
4260  if( mult == 0 )
4261  {
4262  /* 2. the right hand side must not be infinite */
4263  if( SCIPisInfinity(scip, -consdata->lhs) )
4264  mult = +1;
4265  else if( SCIPisInfinity(scip, consdata->rhs) )
4266  mult = -1;
4267  }
4268 
4269  if( mult == 0 )
4270  {
4271  /* 3. the absolute value of the right hand side must be greater than that of the left hand side */
4272  if( SCIPisGT(scip, REALABS(consdata->rhs), REALABS(consdata->lhs)) )
4273  mult = +1;
4274  else if( SCIPisLT(scip, REALABS(consdata->rhs), REALABS(consdata->lhs)) )
4275  mult = -1;
4276  }
4277 
4278  if( mult == 0 )
4279  {
4280  /* 4. the number of positive coefficients must not be smaller than the number of negative coefficients */
4281  nposcoeffs = 0;
4282  nnegcoeffs = 0;
4283  for( i = 0; i < nvars; ++i )
4284  {
4285  if( vals[i] > 0.0 )
4286  nposcoeffs++;
4287  else
4288  nnegcoeffs++;
4289  }
4290  if( nposcoeffs > nnegcoeffs )
4291  mult = +1;
4292  else if( nposcoeffs < nnegcoeffs )
4293  mult = -1;
4294  }
4295 
4296  if( mult == 0 )
4297  {
4298  /* 5. multiply with +1 */
4299  mult = +1;
4300  }
4301 
4302  assert(mult == +1 || mult == -1);
4303  if( mult == -1 )
4304  {
4305  /* scale the constraint with -1 */
4306  SCIPdebugMsg(scip, "multiply linear constraint with -1.0\n");
4307  SCIPdebugPrintCons(scip, cons, NULL);
4308  SCIP_CALL( scaleCons(scip, cons, -1.0) );
4309 
4310  /* scalecons() can delete variables, but scaling with -1 should not do that */
4311  assert(nvars == consdata->nvars);
4312  }
4313 
4314  /*
4315  * rationals to integrals
4316  *
4317  * @todo try scaling only on behalf of non-continuous variables
4318  */
4319  success = TRUE;
4320  scm = 1;
4321  for( i = 0; i < nvars && success && scm <= maxmult; ++i )
4322  {
4323  if( !SCIPisIntegral(scip, vals[i]) )
4324  {
4325  /* epsilon has been slightly decreased above - to be on the safe side */
4326  success = SCIPrealToRational(vals[i], -epsilon, epsilon , maxmult, &nominator, &denominator);
4327  if( success )
4328  scm = SCIPcalcSmaComMul(scm, denominator);
4329  }
4330  }
4331  assert(scm >= 1);
4332 
4333  /* it might be that we have really big coefficients, but all are integral, in that case we want to divide them by
4334  * their greatest common divisor
4335  */
4336  onlyintegral = TRUE;
4337  if( scm == 1 )
4338  {
4339  for( i = nvars - 1; i >= 0; --i )
4340  {
4341  if( !SCIPisIntegral(scip, vals[i]) )
4342  {
4343  onlyintegral = FALSE;
4344  break;
4345  }
4346  }
4347  }
4348 
4349  success = success && (scm <= maxmult || (scm == 1 && onlyintegral));
4350  if( success && scm != 1 )
4351  {
4352  /* scale the constraint with the smallest common multiple of all denominators */
4353  SCIPdebugMsg(scip, "scale linear constraint with %" SCIP_LONGINT_FORMAT " to make coefficients integral\n", scm);
4354  SCIPdebugPrintCons(scip, cons, NULL);
4355  SCIP_CALL( scaleCons(scip, cons, (SCIP_Real)scm) );
4356 
4357  if( consdata->validmaxabsval )
4358  {
4359  consdata->maxabsval *= REALABS((SCIP_Real)scm);
4360  if( !SCIPisIntegral(scip, consdata->maxabsval) )
4361  {
4362  consdata->validmaxabsval = FALSE;
4363  consdata->maxabsval = SCIP_INVALID;
4364  consdataCalcMaxAbsval(consdata);
4365  }
4366  }
4367 
4368  if( consdata->validminabsval )
4369  {
4370  consdata->minabsval *= REALABS((SCIP_Real)scm);
4371  if( !SCIPisIntegral(scip, consdata->minabsval) )
4372  {
4373  consdata->validminabsval = FALSE;
4374  consdata->minabsval = SCIP_INVALID;
4375  consdataCalcMinAbsval(consdata);
4376  }
4377  }
4378 
4379  /* get new consdata information, because scalecons() might have deleted variables */
4380  vals = consdata->vals;
4381  nvars = consdata->nvars;
4382  assert(nvars == 0 || vals != NULL);
4383  }
4384 
4385  /*
4386  * division by greatest common divisor
4387  */
4388  if( success && nvars >= 1 )
4389  {
4390  /* all coefficients are integral: divide them by their greatest common divisor */
4391  assert(SCIPisIntegral(scip, vals[0]));
4392 
4393  gcd = (SCIP_Longint)(REALABS(vals[0]) + feastol);
4394  for( i = 1; i < nvars && gcd > 1; ++i )
4395  {
4396  assert(SCIPisIntegral(scip, vals[i]));
4397  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[i]) + feastol));
4398  }
4399 
4400  if( gcd > 1 )
4401  {
4402  /* divide the constraint by the greatest common divisor of the coefficients */
4403  SCIPdebugMsg(scip, "divide linear constraint by greatest common divisor %" SCIP_LONGINT_FORMAT "\n", gcd);
4404  SCIPdebugPrintCons(scip, cons, NULL);
4405  SCIP_CALL( scaleCons(scip, cons, 1.0/(SCIP_Real)gcd) );
4406 
4407  if( consdata->validmaxabsval )
4408  {
4409  consdata->maxabsval /= REALABS((SCIP_Real)gcd);
4410  }
4411  if( consdata->validminabsval )
4412  {
4413  consdata->minabsval /= REALABS((SCIP_Real)gcd);
4414  }
4415  }
4416  }
4417 
4418  /* mark constraint to be normalized */
4419  consdata->normalized = TRUE;
4420 
4421  SCIPdebugMsg(scip, "normalized constraint:\n");
4422  SCIPdebugPrintCons(scip, cons, NULL);
4423 
4424  return SCIP_OKAY;
4425 }
4426 
4427 /** replaces multiple occurrences of a variable by a single coefficient */
4428 static
4430  SCIP* scip, /**< SCIP data structure */
4431  SCIP_CONS* cons /**< linear constraint */
4432  )
4433 {
4434  SCIP_CONSDATA* consdata;
4435  SCIP_VAR* var;
4436  SCIP_Real valsum;
4437  int v;
4438 
4439  assert(scip != NULL);
4440  assert(cons != NULL);
4441 
4442  consdata = SCIPconsGetData(cons);
4443  assert(consdata != NULL);
4444 
4445  if( consdata->merged )
4446  return SCIP_OKAY;
4447 
4448  /* sort the constraint */
4449  SCIP_CALL( consdataSort(scip, consdata) );
4450 
4451  /* go backwards through the constraint looking for multiple occurrences of the same variable;
4452  * backward direction is necessary, since delCoefPos() modifies the given position and
4453  * the subsequent ones
4454  */
4455  v = consdata->nvars-1;
4456  while( v >= 1 )
4457  {
4458  var = consdata->vars[v];
4459  if( consdata->vars[v-1] == var )
4460  {
4461  valsum = consdata->vals[v];
4462  do
4463  {
4464  SCIP_CALL( delCoefPos(scip, cons, v) );
4465  --v;
4466  valsum += consdata->vals[v];
4467  }
4468  while( v >= 1 && consdata->vars[v-1] == var );
4469 
4470  /* modify the last existing occurrence of the variable */
4471  assert(consdata->vars[v] == var);
4472  if( SCIPisZero(scip, valsum) )
4473  {
4474  SCIP_CALL( delCoefPos(scip, cons, v) );
4475 
4476  /* if the variable defining the maximal activity delta was removed from the constraint, the maximal activity
4477  * delta needs to be recalculated on the next real propagation
4478  */
4479  if( consdata->maxactdeltavar == var )
4480  {
4481  consdata->maxactdelta = SCIP_INVALID;
4482  consdata->maxactdeltavar = NULL;
4483  }
4484  }
4485  else
4486  {
4487  SCIP_CALL( chgCoefPos(scip, cons, v, valsum) );
4488  }
4489  }
4490  --v;
4491  }
4492 
4493  consdata->merged = TRUE;
4494 
4495  return SCIP_OKAY;
4496 }
4497 
4498 /** replaces all fixed and aggregated variables by their non-fixed counterparts */
4499 static
4501  SCIP* scip, /**< SCIP data structure */
4502  SCIP_CONS* cons, /**< linear constraint */
4503  SCIP_Bool* infeasible /**< pointer to store if infeasibility is detected; or NULL if this
4504  * information is not needed; in this case, we apply all fixings
4505  * instead of stopping after the first infeasible one */
4506  )
4507 {
4508  SCIP_CONSDATA* consdata;
4509  SCIP_VAR* var;
4510  SCIP_VAR** aggrvars;
4511  SCIP_Real val;
4512  SCIP_Real* aggrscalars;
4513  SCIP_Real fixedval;
4514  SCIP_Real aggrconst;
4515  int v;
4516  int naggrvars;
4517  int i;
4518 
4519  assert(scip != NULL);
4520  assert(cons != NULL);
4521 
4522  if( infeasible != NULL )
4523  *infeasible = FALSE;
4524 
4525  consdata = SCIPconsGetData(cons);
4526  assert(consdata != NULL);
4527 
4528  if( !consdata->removedfixings )
4529  {
4530  SCIP_Real lhssubtrahend;
4531  SCIP_Real rhssubtrahend;
4532 
4533  lhssubtrahend = 0.0;
4534  rhssubtrahend = 0.0;
4535 
4536  SCIPdebugMsg(scip, "applying fixings:\n");
4537  SCIPdebugPrintCons(scip, cons, NULL);
4538 
4539  v = 0;
4540  while( v < consdata->nvars )
4541  {
4542  var = consdata->vars[v];
4543  val = consdata->vals[v];
4544  assert(SCIPvarIsTransformed(var));
4545 
4546  switch( SCIPvarGetStatus(var) )
4547  {
4549  SCIPerrorMessage("original variable in transformed linear constraint\n");
4550  return SCIP_INVALIDDATA;
4551 
4552  case SCIP_VARSTATUS_LOOSE:
4553  case SCIP_VARSTATUS_COLUMN:
4554  ++v;
4555  break;
4556 
4557  case SCIP_VARSTATUS_FIXED:
4558  assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)));
4559  fixedval = SCIPvarGetLbGlobal(var);
4560  if( !SCIPisInfinity(scip, -consdata->lhs) )
4561  {
4562  if( SCIPisInfinity(scip, ABS(fixedval)) )
4563  {
4564  if( val * fixedval > 0.0 )
4565  {
4566  SCIP_CALL( chgLhs(scip, cons, -SCIPinfinity(scip)) );
4567  }
4568  else
4569  {
4570  if( infeasible != NULL )
4571  {
4572  /* if lhs gets infinity it means that the problem is infeasible */
4573  *infeasible = TRUE;
4574  return SCIP_OKAY;
4575  }
4576  else
4577  {
4578  SCIP_CALL( chgLhs(scip, cons, SCIPinfinity(scip)) );
4579  }
4580  }
4581  }
4582  else
4583  lhssubtrahend += val * fixedval;
4584  }
4585  if( !SCIPisInfinity(scip, consdata->rhs) )
4586  {
4587  if( SCIPisInfinity(scip, ABS(fixedval)) )
4588  {
4589  if( val * fixedval > 0.0 )
4590  {
4591  if( infeasible != NULL )
4592  {
4593  /* if rhs gets -infinity it means that the problem is infeasible */
4594  *infeasible = TRUE;
4595  return SCIP_OKAY;
4596  }
4597  else
4598  {
4599  SCIP_CALL( chgRhs(scip, cons, -SCIPinfinity(scip)) );
4600  }
4601  }
4602  else
4603  {
4604  SCIP_CALL( chgRhs(scip, cons, SCIPinfinity(scip)) );
4605  }
4606  }
4607  else
4608  rhssubtrahend += val * fixedval;
4609  }
4610  SCIP_CALL( delCoefPos(scip, cons, v) );
4611  break;
4612 
4614  {
4615  SCIP_VAR* activevar = SCIPvarGetAggrVar(var);
4616  SCIP_Real activescalar = val * SCIPvarGetAggrScalar(var);
4617  SCIP_Real activeconstant = val * SCIPvarGetAggrConstant(var);
4618 
4619  assert(activevar != NULL);
4620  SCIP_CALL( SCIPgetProbvarSum(scip, &activevar, &activescalar, &activeconstant) );
4621  assert(activevar != NULL);
4622 
4623  if( !SCIPisZero(scip, activescalar) )
4624  {
4625  SCIP_CALL( addCoef(scip, cons, activevar, activescalar) );
4626  }
4627 
4628  if( !SCIPisZero(scip, activeconstant) )
4629  {
4630  if( !SCIPisInfinity(scip, -consdata->lhs) )
4631  lhssubtrahend += activeconstant;
4632  if( !SCIPisInfinity(scip, consdata->rhs) )
4633  rhssubtrahend += activeconstant;
4634  }
4635 
4636  SCIP_CALL( delCoefPos(scip, cons, v) );
4637  break;
4638  }
4641  naggrvars = SCIPvarGetMultaggrNVars(var);
4642  aggrvars = SCIPvarGetMultaggrVars(var);
4643  aggrscalars = SCIPvarGetMultaggrScalars(var);
4644  for( i = 0; i < naggrvars; ++i )
4645  {
4646  SCIP_CALL( addCoef(scip, cons, aggrvars[i], val * aggrscalars[i]) );
4647  }
4648  aggrconst = SCIPvarGetMultaggrConstant(var);
4649 
4650  if( !SCIPisInfinity(scip, -consdata->lhs) )
4651  lhssubtrahend += val * aggrconst;
4652  if( !SCIPisInfinity(scip, consdata->rhs) )
4653  rhssubtrahend += val * aggrconst;
4654 
4655  SCIP_CALL( delCoefPos(scip, cons, v) );
4656  break;
4657 
4659  SCIP_CALL( addCoef(scip, cons, SCIPvarGetNegationVar(var), -val) );
4660  aggrconst = SCIPvarGetNegationConstant(var);
4661 
4662  if( !SCIPisInfinity(scip, -consdata->lhs) )
4663  lhssubtrahend += val * aggrconst;
4664  if( !SCIPisInfinity(scip, consdata->rhs) )
4665  rhssubtrahend += val * aggrconst;
4666 
4667  SCIP_CALL( delCoefPos(scip, cons, v) );
4668  break;
4669 
4670  default:
4671  SCIPerrorMessage("unknown variable status\n");
4672  SCIPABORT();
4673  return SCIP_INVALIDDATA; /*lint !e527*/
4674  }
4675  }
4676 
4677  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->lhs) )
4678  {
4679  /* for large numbers that are relatively equal, substraction can lead to cancellation,
4680  * causing wrong fixings of other variables --> better use a real zero here;
4681  * for small numbers, polishing the difference might lead to wrong results -->
4682  * better use the exact difference in this case
4683  */
4684  if( SCIPisEQ(scip, lhssubtrahend, consdata->lhs) && SCIPisFeasGE(scip, REALABS(lhssubtrahend), 1.0) )
4685  {
4686  SCIP_CALL( chgLhs(scip, cons, 0.0) );
4687  }
4688  else
4689  {
4690  SCIP_CALL( chgLhs(scip, cons, consdata->lhs - lhssubtrahend) );
4691  }
4692  }
4693  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, -consdata->rhs))
4694  {
4695 
4696  /* for large numbers that are relatively equal, substraction can lead to cancellation,
4697  * causing wrong fixings of other variables --> better use a real zero here;
4698  * for small numbers, polishing the difference might lead to wrong results -->
4699  * better use the exact difference in this case
4700  */
4701  if( SCIPisEQ(scip, rhssubtrahend, consdata->rhs ) && SCIPisFeasGE(scip, REALABS(rhssubtrahend), 1.0) )
4702  {
4703  SCIP_CALL( chgRhs(scip, cons, 0.0) );
4704  }
4705  else
4706  {
4707  SCIP_CALL( chgRhs(scip, cons, consdata->rhs - rhssubtrahend) );
4708  }
4709  }
4710 
4711  consdata->removedfixings = TRUE;
4712 
4713  SCIPdebugMsg(scip, "after fixings:\n");
4714  SCIPdebugPrintCons(scip, cons, NULL);
4715 
4716  /* if aggregated variables have been replaced, multiple entries of the same variable are possible and we have
4717  * to clean up the constraint
4718  */
4719  SCIP_CALL( mergeMultiples(scip, cons) );
4720 
4721  SCIPdebugMsg(scip, "after merging:\n");
4722  SCIPdebugPrintCons(scip, cons, NULL);
4723  }
4724  assert(consdata->removedfixings);
4725 
4726 #ifndef NDEBUG
4727  /* check, if all fixings are applied */
4728  for( v = 0; v < consdata->nvars; ++v )
4729  assert(SCIPvarIsActive(consdata->vars[v]));
4730 #endif
4731 
4732  return SCIP_OKAY;
4733 }
4734 
4735 /** for each variable in the linear constraint, except the inferred variable, adds one bound to the conflict analysis'
4736  * candidate store (bound depends on sign of coefficient and whether the left or right hand side was the reason for the
4737  * inference variable's bound change); the conflict analysis can be initialized with the linear constraint being the
4738  * conflict detecting constraint by using NULL as inferred variable
4739  */
4740 static
4742  SCIP* scip, /**< SCIP data structure */
4743  SCIP_CONS* cons, /**< constraint that inferred the bound change */
4744  SCIP_VAR* infervar, /**< variable that was deduced, or NULL */
4745  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
4746  int inferpos, /**< position of the inferred variable in the vars array */
4747  SCIP_Bool reasonisrhs /**< is the right hand side responsible for the bound change? */
4748  )
4749 {
4750  SCIP_CONSDATA* consdata;
4751  SCIP_VAR** vars;
4752  SCIP_Real* vals;
4753  int nvars;
4754  int i;
4755 
4756  assert(scip != NULL);
4757  assert(cons != NULL);
4759  consdata = SCIPconsGetData(cons);
4760 
4761  assert(consdata != NULL);
4762 
4763  vars = consdata->vars;
4764  vals = consdata->vals;
4765  nvars = consdata->nvars;
4766 
4767  assert(vars != NULL || nvars == 0);
4768  assert(vals != NULL || nvars == 0);
4769 
4770  assert(-1 <= inferpos && inferpos < nvars);
4771  assert((infervar == NULL) == (inferpos == -1));
4772  assert(inferpos == -1 || vars[inferpos] == infervar); /*lint !e613*/
4773 
4774  /* for each variable, add the bound to the conflict queue, that is responsible for the minimal or maximal
4775  * residual value, depending on whether the left or right hand side is responsible for the bound change:
4776  * - if the right hand side is the reason, the minimal residual activity is responsible
4777  * - if the left hand side is the reason, the maximal residual activity is responsible
4778  */
4779 
4780  /* if the variable is integral we only need to add reason bounds until the propagation could be applied */
4781  if( infervar == NULL || SCIPvarIsIntegral(infervar) )
4782  {
4783  SCIP_Real minresactivity;
4784  SCIP_Real maxresactivity;
4785  SCIP_Bool minisrelax;
4786  SCIP_Bool maxisrelax;
4787  SCIP_Bool isminsettoinfinity;
4788  SCIP_Bool ismaxsettoinfinity;
4789 
4790  minresactivity = -SCIPinfinity(scip);
4791  maxresactivity = SCIPinfinity(scip);
4792 
4793  /* calculate the minimal and maximal global activity of all other variables involved in the constraint */
4794  if( infervar != NULL )
4795  {
4796  assert(vals != NULL); /* for flexelint */
4797  if( reasonisrhs )
4798  consdataGetGlbActivityResiduals(scip, consdata, infervar, vals[inferpos], FALSE, &minresactivity, NULL,
4799  &minisrelax, NULL, &isminsettoinfinity, NULL);
4800  else
4801  consdataGetGlbActivityResiduals(scip, consdata, infervar, vals[inferpos], FALSE, NULL, &maxresactivity,
4802  NULL, &maxisrelax, NULL, &ismaxsettoinfinity);
4803  }
4804  else
4805  {
4806  if( reasonisrhs )
4807  consdataGetGlbActivityBounds(scip, consdata, FALSE, &minresactivity, NULL,
4808  &minisrelax, NULL, &isminsettoinfinity, NULL);
4809  else
4810  consdataGetGlbActivityBounds(scip, consdata, FALSE, NULL, &maxresactivity,
4811  NULL, &maxisrelax, NULL, &ismaxsettoinfinity);
4812  }
4813 
4814  /* we can only do something clever, if the residual activity is finite and not relaxed */
4815  if( (reasonisrhs && !isminsettoinfinity && !minisrelax) || (!reasonisrhs && !ismaxsettoinfinity && !maxisrelax) ) /*lint !e644*/
4816  {
4817  SCIP_Real rescap;
4818  SCIP_Bool resactisinf;
4819 
4820  resactisinf = FALSE;
4821 
4822  /* calculate the residual capacity that would be left, if the variable would be set to one more / one less
4823  * than its inferred bound
4824  */
4825  if( infervar != NULL )
4826  {
4827  assert(vals != NULL); /* for flexelint */
4828 
4829  if( reasonisrhs )
4830  {
4831  if( SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastglbminactivity) )
4832  {
4833  consdataGetReliableResidualActivity(scip, consdata, infervar, &minresactivity, TRUE, TRUE);
4834  if( SCIPisInfinity(scip, -minresactivity) )
4835  resactisinf = TRUE;
4836  }
4837  rescap = consdata->rhs - minresactivity;
4838  }
4839  else
4840  {
4841  if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastglbmaxactivity) )
4842  {
4843  consdataGetReliableResidualActivity(scip, consdata, infervar, &maxresactivity, FALSE, TRUE);
4844  if( SCIPisInfinity(scip, maxresactivity) )
4845  resactisinf = TRUE;
4846  }
4847  rescap = consdata->lhs - maxresactivity;
4848  }
4849 
4850  if( reasonisrhs == (vals[inferpos] > 0.0) )
4851  rescap -= vals[inferpos] * (SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) + 1.0);
4852  else
4853  rescap -= vals[inferpos] * (SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) - 1.0);
4854  }
4855  else
4856  rescap = (reasonisrhs ? consdata->rhs - minresactivity : consdata->lhs - maxresactivity);
4857 
4858  if( !resactisinf )
4859  {
4860  /* now add bounds as reasons until the residual capacity is exceeded */
4861  for( i = 0; i < nvars; ++i )
4862  {
4863  assert( vars != NULL && vals != NULL ); /* for lint */
4864 
4865  /* zero coefficients and the infered variable can be ignored */
4866  if( vars[i] == infervar || SCIPisZero(scip, vals[i]) )
4867  continue;
4868 
4869  /* check if the residual capacity is exceeded */
4870  if( (reasonisrhs && SCIPisFeasNegative(scip, rescap))
4871  || (!reasonisrhs && SCIPisFeasPositive(scip, rescap)) )
4872  break;
4873 
4874  /* update the residual capacity due to the local bound of this variable */
4875  if( reasonisrhs == (vals[i] > 0.0) )
4876  {
4877  /* rhs is reason and coeff is positive, or lhs is reason and coeff is negative -> lower bound */
4878  SCIP_CALL( SCIPaddConflictLb(scip, vars[i], bdchgidx) );
4879  rescap -= vals[i] * (SCIPgetVarLbAtIndex(scip, vars[i], bdchgidx, FALSE) - SCIPvarGetLbGlobal(vars[i]));
4880  }
4881  else
4882  {
4883  /* lhs is reason and coeff is positive, or rhs is reason and coeff is negative -> upper bound */
4884  SCIP_CALL( SCIPaddConflictUb(scip, vars[i], bdchgidx) );
4885  rescap -= vals[i] * (SCIPgetVarUbAtIndex(scip, vars[i], bdchgidx, FALSE) - SCIPvarGetUbGlobal(vars[i]));
4886  }
4887  }
4888  return SCIP_OKAY;
4889  }
4890  }
4891  }
4892 
4893  /* for a bound change on a continuous variable, all locally changed bounds are responsible */
4894  for( i = 0; i < nvars; ++i )
4895  {
4896  assert(vars != NULL); /* for flexelint */
4897  assert(vals != NULL); /* for flexelint */
4898 
4899  /* zero coefficients and the infered variable can be ignored */
4900  if( vars[i] == infervar || SCIPisZero(scip, vals[i]) )
4901  continue;
4902 
4903  if( reasonisrhs == (vals[i] > 0.0) )
4904  {
4905  /* rhs is reason and coeff is positive, or lhs is reason and coeff is negative -> lower bound is responsible */
4906  SCIP_CALL( SCIPaddConflictLb(scip, vars[i], bdchgidx) );
4907  }
4908  else
4909  {
4910  /* lhs is reason and coeff is positive, or rhs is reason and coeff is negative -> upper bound is responsible */
4911  SCIP_CALL( SCIPaddConflictUb(scip, vars[i], bdchgidx) );
4912  }
4913  }
4914 
4915  return SCIP_OKAY;
4916 }
4917 
4918 /** for each variable in the linear ranged row constraint, except the inferred variable, adds the bounds of all fixed
4919  * variables to the conflict analysis' candidate store; the conflict analysis can be initialized
4920  * with the linear constraint being the conflict detecting constraint by using NULL as inferred variable
4921  */
4922 static
4924  SCIP* scip, /**< SCIP data structure */
4925  SCIP_CONS* cons, /**< constraint that inferred the bound change */
4926  SCIP_VAR* infervar, /**< variable that was deduced, or NULL */
4927  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
4928  int inferpos /**< position of the inferred variable in the vars array, or -1 */
4929  )
4930 {
4931  SCIP_CONSDATA* consdata;
4932  SCIP_VAR** vars;
4933  int nvars;
4934  int v;
4935 
4936  assert(scip != NULL);
4937  assert(cons != NULL);
4938 
4939  consdata = SCIPconsGetData(cons);
4940  assert(consdata != NULL);
4941  vars = consdata->vars;
4942  nvars = consdata->nvars;
4943  assert(vars != NULL || nvars == 0);
4944  assert(-1 <= inferpos && inferpos < nvars);
4945  assert((infervar == NULL) == (inferpos == -1));
4946  assert(inferpos == -1 || vars != NULL);
4947  assert(inferpos == -1 || vars[inferpos] == infervar); /*lint !e613*/
4948 
4949  /* collect all fixed variables */
4950  for( v = nvars - 1; v >= 0; --v )
4951  {
4952  assert(vars != NULL); /* for flexelint */
4953 
4954  /* need to add old bounds before propagation of inferrence variable */
4955  if( vars[v] == infervar )
4956  {
4957  assert(vars[v] != NULL);
4958 
4959  if( !SCIPisEQ(scip, SCIPgetVarLbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPvarGetLbGlobal(vars[v])) )
4960  {
4961  /* @todo get boundchange index before this last boundchange and correct the index */
4962  SCIP_CALL( SCIPaddConflictLb(scip, vars[v], bdchgidx) );
4963  }
4964 
4965  if( !SCIPisEQ(scip, SCIPgetVarUbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPvarGetUbGlobal(vars[v])) )
4966  {
4967  /* @todo get boundchange index before this last boundchange and correct the index */
4968  SCIP_CALL( SCIPaddConflictUb(scip, vars[v], bdchgidx) );
4969  }
4970 
4971  continue;
4972  }
4973 
4974  /* check for fixed variables */
4975  if( SCIPisEQ(scip, SCIPgetVarLbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPgetVarUbAtIndex(scip, vars[v], bdchgidx, FALSE)) )
4976  {
4977  /* add all bounds of fixed variables which lead to the boundchange of the given inference variable */
4978  SCIP_CALL( SCIPaddConflictLb(scip, vars[v], bdchgidx) );
4979  SCIP_CALL( SCIPaddConflictUb(scip, vars[v], bdchgidx) );
4980  }
4981  }
4982 
4983  return SCIP_OKAY;
4984 }
4985 
4986 /** add reasoning variables to conflict candidate queue which led to the conflict */
4987 static
4989  SCIP* scip, /**< SCIP data structure */
4990  SCIP_VAR** vars, /**< variables reasoning the infeasibility */
4991  int nvars, /**< number of variables reasoning the infeasibility */
4992  SCIP_VAR* var, /**< variable which was tried to fix/tighten, or NULL */
4993  SCIP_Real bound /**< bound of variable which was tried to apply, or SCIP_INVALID */
4994  )
4995 {
4996  int v;
4997 
4998  assert(scip != NULL);
4999 
5000  /* collect all variables for which the local bounds differ from their global bounds */
5001  for( v = nvars - 1; v >= 0; --v )
5002  {
5003  assert(vars != NULL);
5004 
5005  /* check for local bound changes variables */
5006  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(vars[v]), SCIPvarGetLbGlobal(vars[v])) )
5007  {
5008  /* add conflict bound */
5009  SCIP_CALL( SCIPaddConflictLb(scip, vars[v], 0) );
5010  }
5011 
5012  if( !SCIPisEQ(scip, SCIPvarGetUbLocal(vars[v]), SCIPvarGetUbGlobal(vars[v])) )
5013  {
5014  SCIP_CALL( SCIPaddConflictUb(scip, vars[v], 0) );
5015  }
5016  }
5017 
5018  if( var != NULL )
5019  {
5020  if( bound < SCIPvarGetLbLocal(var) )
5021  {
5022  SCIP_CALL( SCIPaddConflictLb(scip, var, 0) );
5023  }
5024 
5025  if( bound > SCIPvarGetUbLocal(var) )
5026  {
5027  SCIP_CALL( SCIPaddConflictUb(scip, var, 0) );
5028  }
5029  }
5030 
5031  return SCIP_OKAY;
5032 }
5033 
5034 /** resolves a propagation on the given variable by supplying the variables needed for applying the corresponding
5035  * propagation rule (see propagateCons()):
5036  * (1) activity residuals of all other variables tighten bounds of single variable
5037  */
5038 static
5040  SCIP* scip, /**< SCIP data structure */
5041  SCIP_CONS* cons, /**< constraint that inferred the bound change */
5042  SCIP_VAR* infervar, /**< variable that was deduced */
5043  INFERINFO inferinfo, /**< inference information */
5044  SCIP_BOUNDTYPE boundtype, /**< the type of the changed bound (lower or upper bound) */
5045  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
5046  SCIP_RESULT* result /**< pointer to store the result of the propagation conflict resolving call */
5047  )
5048 {
5049  SCIP_CONSDATA* consdata;
5050  SCIP_VAR** vars;
5051 #ifndef NDEBUG
5052  SCIP_Real* vals;
5053 #endif
5054  int nvars;
5055  int inferpos;
5057  assert(scip != NULL);
5058  assert(cons != NULL);
5059  assert(result != NULL);
5060 
5061  consdata = SCIPconsGetData(cons);
5062  assert(consdata != NULL);
5063  vars = consdata->vars;
5064  nvars = consdata->nvars;
5065 #ifndef NDEBUG
5066  vals = consdata->vals;
5067  assert(vars != NULL);
5068  assert(vals != NULL);
5069 #endif
5070 
5071  /* get the position of the inferred variable in the vars array */
5072  inferpos = inferInfoGetPos(inferinfo);
5073  if( inferpos >= nvars || vars[inferpos] != infervar )
5074  {
5075  /* find inference variable in constraint */
5076  /**@todo use a binary search here; the variables can be sorted by variable index */
5077  for( inferpos = 0; inferpos < nvars && vars[inferpos] != infervar; ++inferpos )
5078  {}
5079  }
5080  assert(inferpos < nvars);
5081  assert(vars[inferpos] == infervar);
5082  assert(!SCIPisZero(scip, vals[inferpos]));
5083 
5084  switch( inferInfoGetProprule(inferinfo) )
5085  {
5086  case PROPRULE_1_RHS:
5087  /* the bound of the variable was tightened, because the minimal or maximal residual activity of the linear
5088  * constraint (only taking the other variables into account) didn't leave enough space for a larger
5089  * domain in order to not exceed the right hand side of the inequality
5090  */
5091  assert((vals[inferpos] > 0.0) == (boundtype == SCIP_BOUNDTYPE_UPPER));
5092  SCIP_CALL( addConflictBounds(scip, cons, infervar, bdchgidx, inferpos, TRUE) );
5093  *result = SCIP_SUCCESS;
5094  break;
5095 
5096  case PROPRULE_1_LHS:
5097  /* the bound of the variable was tightened, because the minimal or maximal residual activity of the linear
5098  * constraint (only taking the other variables into account) didn't leave enough space for a larger
5099  * domain in order to not fall below the left hand side of the inequality
5100  */
5101  assert((vals[inferpos] > 0.0) == (boundtype == SCIP_BOUNDTYPE_LOWER));
5102  SCIP_CALL( addConflictBounds(scip, cons, infervar, bdchgidx, inferpos, FALSE) );
5103  *result = SCIP_SUCCESS;
5104  break;
5105 
5106  case PROPRULE_1_RANGEDROW:
5107  /* the bound of the variable was tightened, because some variables were already fixed and the leftover only allow
5108  * the given inference variable to their bounds in this given ranged row
5109  */
5110 
5111  /* check that we really have a ranged row here */
5112  assert(!SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->rhs));
5113  SCIP_CALL( addConflictFixedVars(scip, cons, infervar, bdchgidx, inferpos) );
5114  *result = SCIP_SUCCESS;
5115  break;
5116 
5117  case PROPRULE_INVALID:
5118  default:
5119  SCIPerrorMessage("invalid inference information %d in linear constraint <%s> at position %d for %s bound of variable <%s>\n",
5120  inferInfoGetProprule(inferinfo), SCIPconsGetName(cons), inferInfoGetPos(inferinfo),
5121  boundtype == SCIP_BOUNDTYPE_LOWER ? "lower" : "upper", SCIPvarGetName(infervar));
5122  SCIP_CALL( SCIPprintCons(scip, cons, NULL) );
5123  SCIPinfoMessage(scip, NULL, ";\n");
5124  return SCIP_INVALIDDATA;
5125  }
5126 
5127  return SCIP_OKAY;
5128 }
5129 
5130 /** analyzes conflicting bounds on given constraint, and adds conflict constraint to problem */
5131 static
5133  SCIP* scip, /**< SCIP data structure */
5134  SCIP_CONS* cons, /**< conflict detecting constraint */
5135  SCIP_Bool reasonisrhs /**< is the right hand side responsible for the conflict? */
5136  )
5137 {
5138  /* conflict analysis can only be applied in solving stage and if it is turned on */
5140  return SCIP_OKAY;
5141 
5142  /* initialize conflict analysis */
5144 
5145  /* add the conflicting bound for each variable of infeasible constraint to conflict candidate queue */
5146  SCIP_CALL( addConflictBounds(scip, cons, NULL, NULL, -1, reasonisrhs) );
5147 
5148  /* analyze the conflict */
5150 
5151  return SCIP_OKAY;
5152 }
5153 
5154 /** check if there is any hope of tightening some bounds */
5155 static
5157  SCIP* scip, /**< SCIP data structure */
5158  SCIP_CONS* cons /**< linear constraint */
5159  )
5160 {
5161  SCIP_CONSDATA* consdata;
5162  int infcountmin;
5163  int infcountmax;
5164 
5165  consdata = SCIPconsGetData(cons);
5166  assert(consdata != NULL);
5167 
5168  infcountmin = consdata->minactivityneginf
5169  + consdata->minactivityposinf
5170  + consdata->minactivityneghuge
5171  + consdata->minactivityposhuge;
5172  infcountmax = consdata->maxactivityneginf
5173  + consdata->maxactivityposinf
5174  + consdata->maxactivityneghuge
5175  + consdata->maxactivityposhuge;
5176 
5177  if( infcountmin > 1 && infcountmax > 1 )
5178  return FALSE;
5179 
5180  return TRUE;
5181 }
5182 
5183 /** tighten upper bound */
5184 static
5186  SCIP* scip, /**< SCIP data structure */
5187  SCIP_CONS* cons, /**< linear constraint */
5188  int pos, /**< variable position */
5189  PROPRULE proprule, /**< propagation rule that deduced the value */
5190  SCIP_Real newub, /**< new upper bound */
5191  SCIP_Real oldub, /**< old upper bound */
5192  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
5193  int* nchgbds, /**< pointer to count the total number of tightened bounds */
5194  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
5195  )
5196 {
5197  SCIP_CONSDATA* consdata;
5198  SCIP_VAR* var;
5199  SCIP_Real lb;
5200  SCIP_Bool infeasible;
5201  SCIP_Bool tightened;
5203  assert(cons != NULL);
5204  assert(!SCIPisInfinity(scip, newub));
5205 
5206  consdata = SCIPconsGetData(cons);
5207  assert(consdata != NULL);
5208  var = consdata->vars[pos];
5209  assert(var != NULL);
5210 
5211  lb = SCIPvarGetLbLocal(var);
5212  newub = SCIPadjustedVarUb(scip, var, newub);
5213 
5214  if( force || SCIPisUbBetter(scip, newub, lb, oldub) )
5215  {
5216  SCIP_VARTYPE vartype;
5217 
5218  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, activity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newub=%.15g\n",
5219  SCIPconsGetName(cons), SCIPvarGetName(var), lb, oldub, consdata->vals[pos], consdata->minactivity, consdata->maxactivity, consdata->lhs, consdata->rhs, newub);
5220 
5221  vartype = SCIPvarGetType(var);
5222 
5223  /* tighten upper bound */
5224  SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(proprule, pos), force, &infeasible, &tightened) );
5225 
5226  if( infeasible )
5227  {
5228  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5229  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5230 
5231  /* analyze conflict */
5232  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
5233 
5234  *cutoff = TRUE;
5235  }
5236  else if( tightened )
5237  {
5238  assert(SCIPisFeasLE(scip, SCIPvarGetUbLocal(var), oldub));
5239  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
5240  SCIPconsGetName(cons), SCIPvarGetName(var), lb, SCIPvarGetUbLocal(var));
5241 
5242  (*nchgbds)++;
5243 
5244  /* if variable type was changed we might be able to upgrade the constraint */
5245  if( vartype != SCIPvarGetType(var) )
5246  consdata->upgradetried = FALSE;
5247  }
5248  }
5249  return SCIP_OKAY;
5250 }
5251 
5252 /** tighten lower bound */
5253 static
5255  SCIP* scip, /**< SCIP data structure */
5256  SCIP_CONS* cons, /**< linear constraint */
5257  int pos, /**< variable position */
5258  PROPRULE proprule, /**< propagation rule that deduced the value */
5259  SCIP_Real newlb, /**< new lower bound */
5260  SCIP_Real oldlb, /**< old lower bound */
5261  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
5262  int* nchgbds, /**< pointer to count the total number of tightened bounds */
5263  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
5264  )
5265 {
5266  SCIP_CONSDATA* consdata;
5267  SCIP_VAR* var;
5268  SCIP_Real ub;
5269  SCIP_Bool infeasible;
5270  SCIP_Bool tightened;
5272  assert(cons != NULL);
5273  assert(!SCIPisInfinity(scip, newlb));
5274 
5275  consdata = SCIPconsGetData(cons);
5276  assert(consdata != NULL);
5277  var = consdata->vars[pos];
5278  assert(var != NULL);
5279 
5280  ub = SCIPvarGetUbLocal(var);
5281  newlb = SCIPadjustedVarLb(scip, var, newlb);
5282 
5283  if( force || SCIPisLbBetter(scip, newlb, oldlb, ub) )
5284  {
5285  SCIP_VARTYPE vartype;
5286 
5287  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, activity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
5288  SCIPconsGetName(cons), SCIPvarGetName(var), oldlb, ub, consdata->vals[pos], consdata->minactivity, consdata->maxactivity, consdata->lhs, consdata->rhs, newlb);
5289 
5290  vartype = SCIPvarGetType(var);
5291 
5292  /* tighten lower bound */
5293  SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(proprule, pos), force, &infeasible, &tightened) );
5294 
5295  if( infeasible )
5296  {
5297  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5298  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5299 
5300  /* analyze conflict */
5301  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
5302 
5303  *cutoff = TRUE;
5304  }
5305  else if( tightened )
5306  {
5307  assert(SCIPisFeasGE(scip, SCIPvarGetLbLocal(var), oldlb));
5308  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
5309  SCIPconsGetName(cons), SCIPvarGetName(var), SCIPvarGetLbLocal(var), ub);
5310 
5311  (*nchgbds)++;
5312 
5313  /* if variable type was changed we might be able to upgrade the constraint */
5314  if( vartype != SCIPvarGetType(var) )
5315  consdata->upgradetried = FALSE;
5316  }
5317  }
5318  return SCIP_OKAY;
5319 }
5320 
5321 /** tightens bounds of a single variable due to activity bounds (easy case) */
5322 static
5324  SCIP* scip, /**< SCIP data structure */
5325  SCIP_CONS* cons, /**< linear constraint */
5326  int pos, /**< position of the variable in the vars array */
5327  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
5328  int* nchgbds, /**< pointer to count the total number of tightened bounds */
5329  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
5330  )
5331 {
5332  SCIP_CONSDATA* consdata;
5333  SCIP_VAR* var;
5334  SCIP_Real val;
5335  SCIP_Real lb;
5336  SCIP_Real ub;
5337  SCIP_Real lhs;
5338  SCIP_Real rhs;
5339 
5340  assert(scip != NULL);
5341  assert(cons != NULL);
5342  assert(cutoff != NULL);
5343  assert(nchgbds != NULL);
5344 
5345  /* we cannot tighten variables' bounds, if the constraint may be not complete */
5346  if( SCIPconsIsModifiable(cons) )
5347  return SCIP_OKAY;
5348 
5349  consdata = SCIPconsGetData(cons);
5350  assert(consdata != NULL);
5351  assert(0 <= pos && pos < consdata->nvars);
5352 
5353  *cutoff = FALSE;
5354 
5355  var = consdata->vars[pos];
5356  assert(var != NULL);
5357 
5358  /* we cannot tighten bounds of multi-aggregated variables */
5360  return SCIP_OKAY;
5361 
5362  val = consdata->vals[pos];
5363  lhs = consdata->lhs;
5364  rhs = consdata->rhs;
5365  assert(!SCIPisZero(scip, val));
5366  assert(!SCIPisInfinity(scip, lhs));
5367  assert(!SCIPisInfinity(scip, -rhs));
5368 
5369  lb = SCIPvarGetLbLocal(var);
5370  ub = SCIPvarGetUbLocal(var);
5371  assert(SCIPisLE(scip, lb, ub));
5372 
5373  /* recompute activities if needed */
5374  if( !consdata->validactivities )
5375  consdataCalcActivities(scip, consdata);
5376  assert(consdata->validactivities);
5377  if( !consdata->validminact )
5378  consdataRecomputeMinactivity(scip, consdata);
5379  assert(consdata->validminact);
5380  if( !consdata->validmaxact )
5381  consdataRecomputeMaxactivity(scip, consdata);
5382  assert(consdata->validmaxact);
5383 
5384  if( val > 0.0 )
5385  {
5386  /* check, if we can tighten the variable's upper bound */
5387  if( !SCIPisInfinity(scip, rhs) )
5388  {
5389  SCIP_Real slack;
5390  SCIP_Real alpha;
5391 
5392  /* if the minactivity is larger than the right hand side by feasibility epsilon, the constraint is infeasible */
5393  if( SCIPisFeasLT(scip, rhs, consdata->minactivity) )
5394  {
5395  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, minactivity=%.15g > rhs=%.15g\n",
5396  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->minactivity, rhs);
5397 
5398  *cutoff = TRUE;
5399  return SCIP_OKAY;
5400  }
5401 
5402  slack = rhs - consdata->minactivity;
5403 
5404  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5405  * it to zero
5406  */
5407  if( !SCIPisPositive(scip, slack) )
5408  slack = 0.0;
5409 
5410  alpha = val * (ub - lb);
5411  assert(!SCIPisNegative(scip, alpha));
5412 
5413  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5414  {
5415  SCIP_Real newub;
5416 
5417  /* compute new upper bound */
5418  newub = lb + (slack / val);
5419 
5420  SCIP_CALL( tightenVarUb(scip, cons, pos, PROPRULE_1_RHS, newub, ub, cutoff, nchgbds, force) );
5421 
5422  if( *cutoff )
5423  {
5424  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5425  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5426 
5427  return SCIP_OKAY;
5428  }
5429 
5430  /* collect the new upper bound which is needed for the lower bound computation */
5431  ub = SCIPvarGetUbLocal(var);
5432  }
5433  }
5434 
5435  /* check, if we can tighten the variable's lower bound */
5436  if( !SCIPisInfinity(scip, -lhs) )
5437  {
5438  SCIP_Real slack;
5439  SCIP_Real alpha;
5440 
5441  /* if the maxactivity is smaller than the left hand side by feasibility epsilon, the constraint is infeasible */
5442  if( SCIPisFeasLT(scip, consdata->maxactivity, lhs) )
5443  {
5444  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, maxactivity=%.15g < lhs=%.15g\n",
5445  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->maxactivity, lhs);
5446 
5447  *cutoff = TRUE;
5448  return SCIP_OKAY;
5449  }
5450 
5451  slack = consdata->maxactivity - lhs;
5452 
5453  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5454  * it to zero
5455  */
5456  if( !SCIPisPositive(scip, slack) )
5457  slack = 0.0;
5458 
5459  alpha = val * (ub - lb);
5460  assert(!SCIPisNegative(scip, alpha));
5461 
5462  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5463  {
5464  SCIP_Real newlb;
5465 
5466  /* compute new lower bound */
5467  newlb = ub - (slack / val);
5468 
5469  SCIP_CALL( tightenVarLb(scip, cons, pos, PROPRULE_1_LHS, newlb, lb, cutoff, nchgbds, force) );
5470 
5471  if( *cutoff )
5472  {
5473  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5474  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5475 
5476  return SCIP_OKAY;
5477  }
5478  }
5479  }
5480  }
5481  else
5482  {
5483  /* check, if we can tighten the variable's lower bound */
5484  if( !SCIPisInfinity(scip, rhs) )
5485  {
5486  SCIP_Real slack;
5487  SCIP_Real alpha;
5488 
5489  /* if the minactivity is larger than the right hand side by feasibility epsilon, the constraint is infeasible */
5490  if( SCIPisFeasLT(scip, rhs, consdata->minactivity) )
5491  {
5492  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, minactivity=%.15g > rhs=%.15g\n",
5493  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->minactivity, rhs);
5494 
5495  *cutoff = TRUE;
5496  return SCIP_OKAY;
5497  }
5498 
5499  slack = rhs - consdata->minactivity;
5500 
5501  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5502  * it to zero
5503  */
5504  if( !SCIPisPositive(scip, slack) )
5505  slack = 0.0;
5506 
5507  alpha = val * (lb - ub);
5508  assert(!SCIPisNegative(scip, alpha));
5509 
5510  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5511  {
5512  SCIP_Real newlb;
5513 
5514  /* compute new lower bound */
5515  newlb = ub + slack / val;
5516 
5517  SCIP_CALL( tightenVarLb(scip, cons, pos, PROPRULE_1_RHS, newlb, lb, cutoff, nchgbds, force) );
5518 
5519  if( *cutoff )
5520  {
5521  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5522  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5523 
5524  return SCIP_OKAY;
5525  }
5526  /* collect the new lower bound which is needed for the upper bound computation */
5527  lb = SCIPvarGetLbLocal(var);
5528  }
5529  }
5530 
5531  /* check, if we can tighten the variable's upper bound */
5532  if( !SCIPisInfinity(scip, -lhs) )
5533  {
5534  SCIP_Real slack;
5535  SCIP_Real alpha;
5536 
5537  /* if the maxactivity is smaller than the left hand side by feasibility epsilon, the constraint is infeasible */
5538  if( SCIPisFeasLT(scip, consdata->maxactivity, lhs) )
5539  {
5540  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, maxactivity=%.15g < lhs=%.15g\n",
5541  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->maxactivity, lhs);
5542 
5543  *cutoff = TRUE;
5544  return SCIP_OKAY;
5545  }
5546 
5547  slack = consdata->maxactivity - lhs;
5548 
5549  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5550  * it to zero
5551  */
5552  if( !SCIPisPositive(scip, slack) )
5553  slack = 0.0;
5554 
5555  alpha = val * (lb - ub);
5556  assert(!SCIPisNegative(scip, alpha));
5557 
5558  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5559  {
5560  SCIP_Real newub;
5561 
5562  /* compute new upper bound */
5563  newub = lb - (slack / val);
5564 
5565  SCIP_CALL( tightenVarUb(scip, cons, pos, PROPRULE_1_LHS, newub, ub, cutoff, nchgbds, force) );
5566 
5567  if( *cutoff )
5568  {
5569  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5570  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5571 
5572  return SCIP_OKAY;
5573  }
5574  }
5575  }
5576  }
5577 
5578  return SCIP_OKAY;
5579 }
5580 
5581 /** analyzes conflicting bounds on given ranged row constraint, and adds conflict constraint to problem */
5582 static
5584  SCIP* scip, /**< SCIP data structure */
5585  SCIP_CONS* cons, /**< conflict detecting constraint */
5586  SCIP_VAR** vars, /**< variables reasoning the infeasibility */
5587  int nvars, /**< number of variables reasoning the infeasibility */
5588  SCIP_VAR* var, /**< variable which was tried to fix/tighten, or NULL */
5589  SCIP_Real bound /**< bound of variable which was tried to apply, or SCIP_INVALID */
5590  )
5591 {
5592 #ifndef NDEBUG
5593  SCIP_CONSDATA* consdata;
5594 
5595  assert(scip != NULL);
5596  assert(cons != NULL);
5597 
5598  consdata = SCIPconsGetData(cons);
5599  assert(consdata != NULL);
5600  assert(!SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->rhs));
5601 #endif
5602 
5603  /* conflict analysis can only be applied in solving stage and if it is turned on */
5605  return SCIP_OKAY;
5606 
5607  /* initialize conflict analysis */
5609 
5610  /* add the conflicting fixed variables of this ranged row constraint to conflict candidate queue */
5611  SCIP_CALL( addConflictFixedVars(scip, cons, NULL, NULL, -1) );
5612 
5613  /* add reasoning variables to conflict candidate queue which led to the conflict */
5614  SCIP_CALL( addConflictReasonVars(scip, vars, nvars, var, bound) );
5615 
5616  /* analyze the conflict */
5617  SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
5618 
5619  return SCIP_OKAY;
5620 }
5621 
5622 /** propagate ranged rows
5623  *
5624  * Check ranged rows for possible solutions, possibly detect infeasibility, fix variables due to having only one possible
5625  * solution, tighten bounds if having only two possible solutions or add constraints which propagate a subset of
5626  * variables better.
5627  *
5628  * Example:
5629  * c1: 12 x1 + 9 x2 - x3 = 0 with x1, x2 free and 1 <= x3 <= 2
5630  *
5631  * x3 needs to be a multiple of 3, so the instance is infeasible.
5632  *
5633  * Example:
5634  * c1: 12 x1 + 9 x2 - x3 = 1 with x1, x2 free and 1 <= x3 <= 2
5635  *
5636  * The only posible value for x3 is 2, so the variable will be fixed.
5637  *
5638  * @todo add holes if possible
5639  */
5640 static
5642  SCIP* scip, /**< SCIP data structure */
5643  SCIP_CONS* cons, /**< linear constraint */
5644  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
5645  int* nfixedvars, /**< pointer to count number of fixed variables */
5646  int* nchgbds, /**< pointer to count the number of bound changes */
5647  int* naddconss /**< pointer to count number of added constraints */
5648  )
5649 {
5650  SCIP_CONSHDLRDATA* conshdlrdata;
5651  SCIP_CONSHDLR* conshdlr;
5652  SCIP_CONSDATA* consdata;
5653  SCIP_VAR** infcheckvars;
5654  SCIP_Real* infcheckvals;
5655  SCIP_Real minactinfvars;
5656  SCIP_Real maxactinfvars;
5657  SCIP_Real lb;
5659  SCIP_Real feastol;
5660  SCIP_Real fixedact;
5661  SCIP_Real lhs;
5662  SCIP_Real rhs;
5663  SCIP_Real absminbincoef;
5664  SCIP_Longint gcd;
5665  SCIP_Longint gcdtmp;
5666  SCIP_Bool minactinfvarsinvalid;
5667  SCIP_Bool maxactinfvarsinvalid;
5668  SCIP_Bool possiblegcd;
5669  SCIP_Bool gcdisone;
5670  SCIP_Bool addartconss;
5671  int ninfcheckvars;
5672  int nunfixedvars;
5673  int nfixedconsvars;
5674  int ncontvars;
5675  int pos;
5676  int v;
5677 
5678  assert(scip != NULL);
5679  assert(cons != NULL);
5680  assert(cutoff != NULL);
5681  assert(nfixedvars != NULL);
5682  assert(nchgbds != NULL);
5683  assert(naddconss != NULL);
5684 
5685  /* modifiable constraint can be changed so we do not have all necessary information */
5686  if( SCIPconsIsModifiable(cons) )
5687  return SCIP_OKAY;
5688 
5689  consdata = SCIPconsGetData(cons);
5690  assert(consdata != NULL);
5691 
5692  /* we already did full ranged row propagation */
5693  if( consdata->rangedrowpropagated == 2 )
5694  return SCIP_OKAY;
5695 
5696  /* at least three variables are needed */
5697  if( consdata->nvars < 3 )
5698  return SCIP_OKAY;
5699 
5700  /* do nothing on normal inequalities */
5701  if( SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, consdata->rhs) )
5702  return SCIP_OKAY;
5703 
5704  /* get constraint handler data */
5705  conshdlr = SCIPconsGetHdlr(cons);
5706  assert(conshdlr != NULL);
5707  conshdlrdata = SCIPconshdlrGetData(conshdlr);
5708  assert(conshdlrdata != NULL);
5709 
5710  addartconss = conshdlrdata->rangedrowartcons && SCIPgetDepth(scip) < 1 && !SCIPinProbing(scip) && !SCIPinRepropagation(scip);
5711 
5712  /* we may add artificial constraints */
5713  if( addartconss )
5714  consdata->rangedrowpropagated = 2;
5715  /* we are not allowed to add artificial constraints during propagation; if nothing changed on this constraint since
5716  * the last rangedrowpropagation, we can stop; otherwise, we mark this constraint to be rangedrowpropagated without
5717  * artificial constraints
5718  */
5719  else
5720  {
5721  if( consdata->rangedrowpropagated > 0 )
5722  return SCIP_OKAY;
5723 
5724  consdata->rangedrowpropagated = 1;
5725  }
5726  fixedact = 0;
5727  nfixedconsvars = 0;
5728  /* calculate fixed activity and number of fixed variables */
5729  for( v = consdata->nvars - 1; v >= 0; --v )
5730  {
5731  /* all zero coefficients should be eliminated */
5732  assert(!SCIPisZero(scip, consdata->vals[v]));
5733 
5734  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5735  {
5736  fixedact += SCIPvarGetLbLocal(consdata->vars[v]) * consdata->vals[v];
5737  ++nfixedconsvars;
5738  }
5739  }
5740 
5741  /* do not work with huge fixed activities */
5742  if( SCIPisHugeValue(scip, REALABS(fixedact)) )
5743  return SCIP_OKAY;
5744 
5745  /* compute lhs and rhs for unfixed variables only and get number of unfixed variables */
5746  assert(!SCIPisInfinity(scip, -fixedact) && !SCIPisInfinity(scip, fixedact));
5747  lhs = consdata->lhs - fixedact;
5748  rhs = consdata->rhs - fixedact;
5749  nunfixedvars = consdata->nvars - nfixedconsvars;
5750 
5751  /* allocate temporary memory for variables and coefficients which may lead to infeasibility */
5752  SCIP_CALL( SCIPallocBufferArray(scip, &infcheckvars, nunfixedvars) );
5753  SCIP_CALL( SCIPallocBufferArray(scip, &infcheckvals, nunfixedvars) );
5754 
5755  absminbincoef = SCIP_REAL_MAX;
5756  ncontvars = 0;
5757  gcdisone = TRUE;
5758  possiblegcd = TRUE;
5759 
5760  /* we now partition all unfixed variables in two groups:
5761  *
5762  * the first one contains all integral variable with integral
5763  * coefficient so that all variables in this group will have a gcd greater than 1, this group will be implicitly
5764  * given
5765  *
5766  * the second group will contain all left unfixed variables and will be saved as infcheckvars with corresponding
5767  * coefficients as infcheckvals, the order of these variables should be the same as in the consdata object
5768  */
5769 
5770  /* find first integral variables with integral coefficient greater than 1, thereby collecting all other unfixed
5771  * variables
5772  */
5773  ninfcheckvars = 0;
5774  v = -1;
5775  pos = -1;
5776  do
5777  {
5778  ++v;
5779 
5780  /* partition the variables, do not change the order of collection, because it might be used later on */
5781  while( v < consdata->nvars && (SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS ||
5782  !SCIPisIntegral(scip, consdata->vals[v]) || SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0)) )
5783  {
5784  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5785  {
5786  if( SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS )
5787  {
5788  ++ncontvars;
5789  }
5790  else if( SCIPvarIsBinary(consdata->vars[v]) )
5791  {
5792  SCIP_Real absval;
5793 
5794  absval = REALABS(consdata->vals[v]);
5795 
5796  if( absminbincoef > absval )
5797  absminbincoef = absval;
5798  }
5799 
5800  gcdisone = gcdisone && SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0);
5801  possiblegcd = FALSE;
5802  infcheckvars[ninfcheckvars] = consdata->vars[v];
5803  infcheckvals[ninfcheckvars] = consdata->vals[v];
5804  ++ninfcheckvars;
5805 
5806  if( pos == -1 )
5807  pos = v;
5808  }
5809  ++v;
5810  }
5811  }
5812  while( v < consdata->nvars && SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) );
5813 
5814  /* if the first group of variables is empty, we stop */
5815  /* @todo try to propagate/split up a constraint of the form:
5816  * x_1 + ... + x_m + a_1*y_1 + ... + a_n*y_n = k + c,
5817  * 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]
5818  */
5819  if( v == consdata->nvars )
5820  goto TERMINATE;
5821 
5822  /* we need at least two non-continuous variables */
5823  if( ncontvars + 2 > nunfixedvars )
5824  goto TERMINATE;
5825 
5826  assert(!SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])));
5827  assert(SCIPisIntegral(scip, consdata->vals[v]) && SCIPvarGetType(consdata->vars[v]) != SCIP_VARTYPE_CONTINUOUS && REALABS(consdata->vals[v]) > 1.5);
5828 
5829  feastol = SCIPfeastol(scip);
5830 
5831  gcd = (SCIP_Longint)(REALABS(consdata->vals[v]) + feastol);
5832  assert(gcd >= 2);
5833 
5834  /* go on to partition the variables, do not change the order of collection, because it might be used later on;
5835  * calculate gcd over the first part of variables */
5836  for( ; v < consdata->nvars; ++v )
5837  {
5838  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5839  continue;
5840 
5841  if( SCIPvarIsBinary(consdata->vars[v]) )
5842  {
5843  SCIP_Real absval;
5844 
5845  absval = REALABS(consdata->vals[v]);
5846 
5847  if( absminbincoef > absval )
5848  absminbincoef = absval;
5849  }
5850 
5851  if( !SCIPisIntegral(scip, consdata->vals[v]) || SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS ||
5852  SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0) )
5853  {
5854  if( SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS )
5855  ++ncontvars;
5856 
5857  gcdisone = gcdisone && SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0);
5858  possiblegcd = FALSE;
5859  infcheckvars[ninfcheckvars] = consdata->vars[v];
5860  infcheckvals[ninfcheckvars] = consdata->vals[v];
5861 
5862  ++ninfcheckvars;
5863 
5864  if( pos == -1 )
5865  pos = v;
5866  }
5867  else
5868  {
5869  assert(REALABS(consdata->vals[v]) > 1.5);
5870 
5871  gcdtmp = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(consdata->vals[v]) + feastol));
5872  assert(gcdtmp >= 1);
5873 
5874  if( gcdtmp == 1 )
5875  {
5876  infcheckvars[ninfcheckvars] = consdata->vars[v];
5877  infcheckvals[ninfcheckvars] = consdata->vals[v];
5878 
5879  ++ninfcheckvars;
5880 
5881  if( pos == -1 )
5882  pos = v;
5883  }
5884  else
5885  gcd = gcdtmp;
5886  }
5887  }
5888  assert(gcd >= 2);
5889 
5890  /* it should not happen that all variables are of integral type and have a gcd >= 2, this should be done by
5891  * normalizeCons() */
5892  if( ninfcheckvars == 0 )
5893  goto TERMINATE;
5894 
5895  assert(pos >= 0);
5896 
5897  minactinfvarsinvalid = FALSE;
5898  maxactinfvarsinvalid = FALSE;
5899  maxactinfvars = 0.0;
5900  minactinfvars = 0.0;
5901 
5902  /* calculate activities over all infcheckvars */
5903  for( v = ninfcheckvars - 1; v >= 0; --v )
5904  {
5905  lb = SCIPvarGetLbLocal(infcheckvars[v]);
5906  ub = SCIPvarGetUbLocal(infcheckvars[v]);
5907 
5908  if( SCIPisInfinity(scip, -lb) )
5909  {
5910  if( infcheckvals[v] < 0.0 )
5911  maxactinfvarsinvalid = TRUE;
5912  else
5913  minactinfvarsinvalid = TRUE;
5914  }
5915  else
5916  {
5917  if( infcheckvals[v] < 0.0 )
5918  maxactinfvars += infcheckvals[v] * lb;
5919  else
5920  minactinfvars += infcheckvals[v] * lb;
5921  }
5922 
5923  if( SCIPisInfinity(scip, ub) )
5924  {
5925  if( infcheckvals[v] > 0.0 )
5926  maxactinfvarsinvalid = TRUE;
5927  else
5928  minactinfvarsinvalid = TRUE;
5929  }
5930  else
5931  {
5932  if( infcheckvals[v] > 0.0 )
5933  maxactinfvars += infcheckvals[v] * ub;
5934  else
5935  minactinfvars += infcheckvals[v] * ub;
5936  }
5937 
5938  /* better abort on to big values */
5939  if( SCIPisHugeValue(scip, -minactinfvars) )
5940  minactinfvarsinvalid = TRUE;
5941  if( SCIPisHugeValue(scip, maxactinfvars) )
5942  maxactinfvarsinvalid = TRUE;
5943 
5944  if( minactinfvarsinvalid || maxactinfvarsinvalid )
5945  goto TERMINATE;
5946  }
5947  assert(!minactinfvarsinvalid && !maxactinfvarsinvalid);
5948 
5949  SCIPdebugMsg(scip, "minactinfvarsinvalid = %u, minactinfvars = %g, maxactinfvarsinvalid = %u, maxactinfvars = %g, gcd = %lld, ninfcheckvars = %d, ncontvars = %d\n",
5950  minactinfvarsinvalid, minactinfvars, maxactinfvarsinvalid, maxactinfvars, gcd, ninfcheckvars, ncontvars);
5951 
5952  /* @todo maybe we took the wrong variables as infcheckvars we could try to exchange integer variables */
5953  /* @todo if minactinfvarsinvalid or maxactinfvarsinvalid are true, try to exchange both partitions to maybe get valid
5954  * activities */
5955  /* @todo calculate minactivity and maxactivity for all non-intcheckvars, and use this for better bounding,
5956  * !!!note!!!
5957  * that therefore the conflict variables in addConflictFixedVars() need to be extended by all variables which
5958  * are not at their global bound
5959  */
5960 
5961  /* check if between left hand side and right hand side exist a feasible point, if not the constraint leads to
5962  * infeasibility */
5963  if( !SCIPisIntegral(scip, (lhs - maxactinfvars) / gcd) &&
5964  SCIPisGT(scip, SCIPceil(scip, (lhs - maxactinfvars) / gcd) * gcd, rhs - minactinfvars) )
5965  {
5966  SCIPdebugMsg(scip, "no feasible value exist, constraint <%s> lead to infeasibility", SCIPconsGetName(cons));
5967  SCIPdebugPrintCons(scip, cons, NULL);
5968 
5969  /* start conflict analysis */
5970  /* @todo improve conflict analysis by adding relaxed bounds */
5971  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
5972 
5973  *cutoff = TRUE;
5974  }
5975  else if( ncontvars == 0 )
5976  {
5977  SCIP_Longint gcdinfvars = -1;
5978 
5979  /* check for gcd over all infcheckvars */
5980  if( possiblegcd )
5981  {
5982  v = ninfcheckvars - 1;
5983  gcdinfvars = (SCIP_Longint)(REALABS(infcheckvals[v]) + feastol);
5984  assert(gcdinfvars >= 2);
5985 
5986  for( ; v >= 0 && gcdinfvars >= 2; --v )
5987  {
5988  gcdinfvars = SCIPcalcGreComDiv(gcdinfvars, (SCIP_Longint)(REALABS(infcheckvals[v]) + feastol));
5989  }
5990  }
5991  else if( gcdisone )
5992  gcdinfvars = 1;
5993 
5994  SCIPdebugMsg(scip, "gcdinfvars =%lld, possiblegcd = %u\n", gcdinfvars, possiblegcd);
5995 
5996  /* compute solutions for this ranged row, if all variables are of integral type with integral coefficients */
5997  if( gcdinfvars >= 1 )
5998  {
5999  SCIP_Real value;
6000  SCIP_Real value2;
6001  SCIP_Real minvalue = SCIP_INVALID;
6002  SCIP_Real maxvalue = SCIP_INVALID;
6003  int nsols = 0;
6004 
6005  value = SCIPceil(scip, minactinfvars - SCIPfeastol(scip));
6006 
6007  /* check how many possible solutions exist */
6008  while( SCIPisLE(scip, value, maxactinfvars) )
6009  {
6010  value2 = value + gcd * (SCIPceil(scip, (lhs - value) / gcd));
6011 
6012  if( SCIPisGE(scip, value2, lhs) && SCIPisLE(scip, value2, rhs) )
6013  {
6014  ++nsols;
6015 
6016  /* early termination if we found more than two solutions */
6017  if( nsols == 3 )
6018  break;
6019 
6020  if( minvalue == SCIP_INVALID ) /*lint !e777*/
6021  minvalue = value;
6022 
6023  maxvalue = value;
6024  }
6025  value += gcdinfvars;
6026  }
6027  assert(nsols < 2 || minvalue <= maxvalue);
6028 
6029  /* determine last possible solution for better bounding */
6030  if( nsols == 3 )
6031  {
6032 #ifndef NDEBUG
6033  SCIP_Real secondsolval = maxvalue;
6034 #endif
6035  value = SCIPfloor(scip, maxactinfvars + SCIPfeastol(scip));
6036 
6037  /* check how many possible solutions exist */
6038  while( SCIPisGE(scip, value, minactinfvars) )
6039  {
6040  value2 = value + gcd * (SCIPfloor(scip, (rhs - value) / gcd));
6041 
6042  if( SCIPisGE(scip, value2, lhs) && SCIPisLE(scip, value2, rhs) )
6043  {
6044  maxvalue = value;
6045  assert(maxvalue > minvalue);
6046  break;
6047  }
6048  value -= gcdinfvars;
6049  }
6050  assert(maxvalue > secondsolval);
6051  }
6052 
6053  SCIPdebugMsg(scip, "here nsols %s %d, minsolvalue = %g, maxsolvalue = %g, ninfcheckvars = %d, nunfixedvars = %d\n",
6054  nsols > 2 ? ">=" : "=", nsols, minvalue, maxvalue, ninfcheckvars, nunfixedvars);
6055 
6056  /* no possible solution found */
6057  if( nsols == 0 )
6058  {
6059  SCIPdebugMsg(scip, "gcdinfvars = %lld, gcd = %lld, correctedlhs = %g, correctedrhs = %g\n",
6060  gcdinfvars, gcd, lhs, rhs);
6061  SCIPdebugMsg(scip, "no solution found; constraint <%s> lead to infeasibility\n", SCIPconsGetName(cons));
6062  SCIPdebugPrintCons(scip, cons, NULL);
6063 
6064  /* start conflict analysis */
6065  /* @todo improve conflict analysis by adding relaxed bounds */
6066  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6067 
6068  *cutoff = TRUE;
6069  }
6070  /* if only one solution exist we can extract a new constraint or fix variables */
6071  else if( nsols == 1 )
6072  {
6073  assert(minvalue == maxvalue); /*lint !e777*/
6074 
6075  /* we can fix the only variable in our second set of variables */
6076  if( ninfcheckvars == 1 )
6077  {
6078  SCIP_Bool fixed;
6079 
6080  assert(SCIPisEQ(scip, (SCIP_Real)gcdinfvars, REALABS(infcheckvals[0])));
6081 
6082  SCIPdebugMsg(scip, "fixing single variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
6083  SCIPvarGetName(infcheckvars[0]), SCIPvarGetLbLocal(infcheckvars[0]),
6084  SCIPvarGetUbLocal(infcheckvars[0]), maxvalue/infcheckvals[0]);
6085 
6086  /* fix variable to only possible value */
6087  SCIP_CALL( SCIPinferVarFixCons(scip, infcheckvars[0], maxvalue/infcheckvals[0], cons,
6088  getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &fixed) );
6089 
6090  if( *cutoff )
6091  {
6092  /* start conflict analysis */
6093  /* @todo improve conflict analysis by adding relaxed bounds */
6094  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6095  }
6096 
6097  if( fixed )
6098  ++(*nfixedvars);
6099  }
6100  else
6101  {
6102  /* check for exactly one unfixed variable which is not part of the infcheckvars */
6103  if( ninfcheckvars == nunfixedvars - 1 )
6104  {
6105  SCIP_Real bound;
6106  SCIP_Bool foundvar = FALSE;
6107  SCIP_Bool fixed;
6108  int w = 0;
6109 
6110  assert(ninfcheckvars > 0);
6111 
6112  /* find variable which is not an infcheckvar and fix it */
6113  for( v = 0; v < consdata->nvars - 1; ++v )
6114  {
6115  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6116  {
6117  if( w >= ninfcheckvars || consdata->vars[v] != infcheckvars[w] )
6118  {
6119 #ifndef NDEBUG
6120  int v2 = v + 1;
6121  int w2 = w;
6122 
6123  assert((nfixedconsvars == 0) ? (consdata->nvars - v - 1 == ninfcheckvars - w) : TRUE);
6124 
6125  for( ; v2 < consdata->nvars && w2 < ninfcheckvars; ++v2 )
6126  {
6127  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v2]), SCIPvarGetUbLocal(consdata->vars[v2])) )
6128  continue;
6129 
6130  assert(consdata->vars[v2] == infcheckvars[w2]);
6131  ++w2;
6132  }
6133  assert(w2 == ninfcheckvars);
6134 #endif
6135  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6136 
6137  foundvar = TRUE;
6138 
6139  if( consdata->vals[v] < 0 )
6140  {
6141  bound = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6142  }
6143  else
6144  {
6145  bound = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6146  }
6147 
6148  SCIPdebugMsg(scip, "fixing variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
6149  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]),
6150  SCIPvarGetUbLocal(consdata->vars[v]), bound);
6151 
6152  /* fix variable to only possible value */
6153  SCIP_CALL( SCIPinferVarFixCons(scip, consdata->vars[v], bound, cons,
6154  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &fixed) );
6155 
6156  if( *cutoff )
6157  {
6158  /* start conflict analysis */
6159  /* @todo improve conflict analysis by adding relaxed bounds */
6160  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6161  consdata->vars[v], bound) );
6162  }
6163 
6164  if( fixed )
6165  ++(*nfixedvars);
6166 
6167  break;
6168  }
6169 
6170  ++w;
6171  }
6172  }
6173 
6174  /* maybe last variable was the not infcheckvar */
6175  if( !foundvar )
6176  {
6177  assert(v == consdata->nvars - 1);
6178  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6179 
6180  if( consdata->vals[v] < 0 )
6181  {
6182  bound = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6183  }
6184  else
6185  {
6186  bound = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6187  }
6188 
6189  SCIPdebugMsg(scip, "fixing variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
6190  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]),
6191  SCIPvarGetUbLocal(consdata->vars[v]), bound);
6192 
6193  /* fix variable to only possible value */
6194  SCIP_CALL( SCIPinferVarFixCons(scip, consdata->vars[v], bound, cons,
6195  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &fixed) );
6196 
6197  if( *cutoff )
6198  {
6199  /* start conflict analysis */
6200  /* @todo improve conflict analysis by adding relaxed bounds */
6201  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6202  consdata->vars[v], bound) );
6203  }
6204 
6205  if( fixed )
6206  ++(*nfixedvars);
6207  }
6208  }
6209  else if( addartconss && (SCIPisGT(scip, minvalue, minactinfvars) || SCIPisLT(scip, maxvalue, maxactinfvars)) )
6210  {
6211  /* aggregation possible if we have two variables, but this will be done later on */
6212  SCIP_CONS* newcons;
6213  char name[SCIP_MAXSTRLEN];
6214 
6215  /* create, add, and release new artificial constraint */
6216  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6217  ++conshdlrdata->naddconss;
6218 
6219  SCIPdebugMsg(scip, "adding artificial constraint %s\n", name);
6220 
6221  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals,
6222  maxvalue, maxvalue, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6223  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6224 
6225  SCIPdebugPrintCons(scip, newcons, NULL);
6226 
6227  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6228 
6229  ++(*naddconss);
6230  }
6231  }
6232  }
6233  /* at least two solutions */
6234  else
6235  {
6236  /* @todo if we found more then one solution, we may reduced domains due to dualpresolving? */
6237 
6238  /* only one variable in the second set, so we can bound this variables */
6239  if( ninfcheckvars == 1 )
6240  {
6241  SCIP_Bool tightened;
6242  SCIP_Real newlb;
6243  SCIP_Real newub;
6244 
6245  assert(SCIPisEQ(scip, (SCIP_Real)gcdinfvars, REALABS(infcheckvals[0])));
6246 
6247  if( infcheckvals[0] < 0 )
6248  {
6249  newlb = maxvalue/infcheckvals[0];
6250  newub = minvalue/infcheckvals[0];
6251  }
6252  else
6253  {
6254  newlb = minvalue/infcheckvals[0];
6255  newub = maxvalue/infcheckvals[0];
6256  }
6257  assert(newlb < newub);
6258 
6259  if( newlb > SCIPvarGetLbLocal(infcheckvars[0]) )
6260  {
6261  /* update lower bound of variable */
6262  SCIPdebugMsg(scip, "tightening lower bound of variable <%s> from %g to %g\n",
6263  SCIPvarGetName(infcheckvars[0]), SCIPvarGetLbLocal(infcheckvars[0]), newlb);
6264 
6265  /* tighten variable lower bound to minimal possible value */
6266  SCIP_CALL( SCIPinferVarLbCons(scip, infcheckvars[0], newlb, cons,
6267  getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &tightened) );
6268 
6269  if( *cutoff )
6270  {
6271  /* start conflict analysis */
6272  /* @todo improve conflict analysis by adding relaxed bounds */
6273  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6274  }
6275 
6276  if( tightened )
6277  ++(*nchgbds);
6278  }
6279 
6280  if( newub < SCIPvarGetUbLocal(infcheckvars[0]) )
6281  {
6282  /* update upper bound of variable */
6283  SCIPdebugMsg(scip, "tightening upper bound of variable <%s> from %g to %g\n",
6284  SCIPvarGetName(infcheckvars[0]), SCIPvarGetUbLocal(infcheckvars[0]), newub);
6285 
6286  /* tighten variable upper bound to maximal possible value */
6287  SCIP_CALL( SCIPinferVarUbCons(scip, infcheckvars[0], newub, cons,
6288  getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &tightened) );
6289 
6290  if( *cutoff )
6291  {
6292  /* start conflict analysis */
6293  /* @todo improve conflict analysis by adding relaxed bounds */
6294  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6295  }
6296 
6297  if( tightened )
6298  ++(*nchgbds);
6299  }
6300  }
6301  /* check if we have only one not infcheckvars, if so we can tighten this variable */
6302  else if( ninfcheckvars == nunfixedvars - 1 )
6303  {
6304  SCIP_Bool foundvar = FALSE;
6305  SCIP_Bool tightened;
6306  SCIP_Real newlb;
6307  SCIP_Real newub;
6308  int w = 0;
6309 
6310  assert(ninfcheckvars > 0);
6311  assert(minvalue < maxvalue);
6312 
6313  /* find variable which is not an infcheckvar and fix it */
6314  for( v = 0; v < consdata->nvars - 1; ++v )
6315  {
6316  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6317  {
6318  if( w >= ninfcheckvars || consdata->vars[v] != infcheckvars[w] )
6319  {
6320 #ifndef NDEBUG
6321  int v2 = v + 1;
6322  int w2 = w;
6323 
6324  assert((nfixedconsvars == 0) ? (consdata->nvars - v - 1 == ninfcheckvars - w) : TRUE);
6325 
6326  for( ; v2 < consdata->nvars && w2 < ninfcheckvars; ++v2 )
6327  {
6328  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v2]), SCIPvarGetUbLocal(consdata->vars[v2])) )
6329  continue;
6330 
6331  assert(consdata->vars[v2] == infcheckvars[w2]);
6332  ++w2;
6333  }
6334  assert(w2 == ninfcheckvars);
6335 #endif
6336 
6337  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6338  foundvar = TRUE;
6339 
6340  if( consdata->vals[v] < 0 )
6341  {
6342  newlb = SCIPfloor(scip, (rhs - minvalue) / consdata->vals[v]);
6343  newub = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6344  }
6345  else
6346  {
6347  newlb = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6348  newub = SCIPceil(scip, (rhs - minvalue) / consdata->vals[v]);
6349  }
6350  assert(SCIPisLE(scip, newlb, newub));
6351 
6352  if( newlb > SCIPvarGetLbLocal(consdata->vars[v]) )
6353  {
6354  /* update lower bound of variable */
6355  SCIPdebugMsg(scip, "tightening lower bound of variable <%s> from %g to %g\n",
6356  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]), newlb);
6357 
6358  /* tighten variable lower bound to minimal possible value */
6359  SCIP_CALL( SCIPinferVarLbCons(scip, consdata->vars[v], newlb, cons,
6360  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6361 
6362  if( *cutoff )
6363  {
6364  /* start conflict analysis */
6365  /* @todo improve conflict analysis by adding relaxed bounds */
6366  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6367  consdata->vars[v], newlb) );
6368  }
6369 
6370  if( tightened )
6371  ++(*nchgbds);
6372  }
6373 
6374  if( newub < SCIPvarGetUbLocal(consdata->vars[v]) )
6375  {
6376  /* update upper bound of variable */
6377  SCIPdebugMsg(scip, "tightening upper bound of variable <%s> from %g to %g\n",
6378  SCIPvarGetName(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v]), newub);
6379 
6380  /* tighten variable upper bound to maximal possible value */
6381  SCIP_CALL( SCIPinferVarUbCons(scip, consdata->vars[v], newub, cons,
6382  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6383 
6384  if( *cutoff )
6385  {
6386  /* start conflict analysis */
6387  /* @todo improve conflict analysis by adding relaxed bounds */
6388  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6389  consdata->vars[v], newub) );
6390  }
6391 
6392  if( tightened )
6393  ++(*nchgbds);
6394  }
6395 
6396  break;
6397  }
6398 
6399  ++w;
6400  }
6401  }
6402 
6403  /* maybe last variable was the not infcheckvar */
6404  if( !foundvar )
6405  {
6406  assert(v == consdata->nvars - 1);
6407  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6408 
6409  if( consdata->vals[v] < 0 )
6410  {
6411  newlb = SCIPfloor(scip, (rhs - minvalue) / consdata->vals[v]);
6412  newub = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6413  }
6414  else
6415  {
6416  newlb = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6417  newub = SCIPceil(scip, (rhs - minvalue) / consdata->vals[v]);
6418  }
6419  assert(SCIPisLE(scip, newlb, newub));
6420 
6421  if( newlb > SCIPvarGetLbLocal(consdata->vars[v]) )
6422  {
6423  /* update lower bound of variable */
6424  SCIPdebugMsg(scip, "tightening lower bound of variable <%s> from %g to %g\n",
6425  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]), newlb);
6426 
6427  /* tighten variable lower bound to minimal possible value */
6428  SCIP_CALL( SCIPinferVarLbCons(scip, consdata->vars[v], newlb, cons,
6429  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6430 
6431  if( *cutoff )
6432  {
6433  /* start conflict analysis */
6434  /* @todo improve conflict analysis by adding relaxed bounds */
6435  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, consdata->vars[v], newlb) );
6436  }
6437 
6438  if( tightened )
6439  ++(*nchgbds);
6440  }
6441 
6442  if( newub < SCIPvarGetUbLocal(consdata->vars[v]) )
6443  {
6444  /* update upper bound of variable */
6445  SCIPdebugMsg(scip, "tightening upper bound of variable <%s> from %g to %g\n",
6446  SCIPvarGetName(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v]), newub);
6447 
6448  /* tighten variable upper bound to maximal possible value */
6449  SCIP_CALL( SCIPinferVarUbCons(scip, consdata->vars[v], newub, cons,
6450  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6451 
6452  if( *cutoff )
6453  {
6454  /* start conflict analysis */
6455  /* @todo improve conflict analysis by adding relaxed bounds */
6456  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, consdata->vars[v], newub) );
6457  }
6458 
6459  if( tightened )
6460  ++(*nchgbds);
6461  }
6462  }
6463  }
6464  /* at least two solutions and more than one variable, so we add a new constraint which bounds the feasible
6465  * region for our infcheckvars, if possible
6466  */
6467  else if( addartconss && (SCIPisGT(scip, minvalue, minactinfvars) || SCIPisLT(scip, maxvalue, maxactinfvars)) )
6468  {
6469  SCIP_CONS* newcons;
6470  char name[SCIP_MAXSTRLEN];
6471  SCIP_Real newlhs;
6472  SCIP_Real newrhs;
6473 
6474  assert(maxvalue > minvalue);
6475 
6476  if( SCIPisGT(scip, minvalue, minactinfvars) )
6477  newlhs = minvalue;
6478  else
6479  newlhs = -SCIPinfinity(scip);
6480 
6481  if( SCIPisLT(scip, maxvalue, maxactinfvars) )
6482  newrhs = maxvalue;
6483  else
6484  newrhs = SCIPinfinity(scip);
6485 
6486  if( !SCIPisInfinity(scip, -newlhs) || !SCIPisInfinity(scip, newrhs) )
6487  {
6488  /* create, add, and release new artificial constraint */
6489  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons1_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6490  ++conshdlrdata->naddconss;
6491 
6492  SCIPdebugMsg(scip, "adding artificial constraint %s\n", name);
6493 
6494  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals, newlhs, newrhs,
6495  TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6496  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6497 
6498  SCIPdebugPrintCons(scip, newcons, NULL);
6499  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6500 
6501  ++(*naddconss);
6502  }
6503  /* @todo maybe add constraint for all variables which are not infcheckvars, lhs should be minvalue, rhs
6504  * should be maxvalue */
6505  }
6506  }
6507  }
6508  }
6509  else if( addartconss && ncontvars < ninfcheckvars )
6510  {
6511  SCIP_Real maxact = 0.0;
6512  SCIP_Real minact = 0.0;
6513  int w = 0;
6514 
6515  /* compute activities of non-infcheckvars */
6516  for( v = 0; v < consdata->nvars; ++v )
6517  {
6518  if( w < ninfcheckvars && consdata->vars[v] == infcheckvars[w] )
6519  {
6520  ++w;
6521  continue;
6522  }
6523 
6524  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6525  {
6526  if( SCIPvarIsBinary(consdata->vars[v]) )
6527  {
6528  if( consdata->vals[v] > 0.0 )
6529  maxact += consdata->vals[v];
6530  else
6531  minact += consdata->vals[v];
6532  }
6533  else
6534  {
6535  SCIP_Real tmpval;
6536 
6537  assert(SCIPvarIsIntegral(consdata->vars[v]));
6538 
6539  if( consdata->vals[v] > 0.0 )
6540  {
6541  tmpval = consdata->vals[v] * SCIPvarGetLbLocal(consdata->vars[v]);
6542 
6543  if( SCIPisHugeValue(scip, -tmpval) )
6544  break;
6545 
6546  minact += tmpval;
6547 
6548  tmpval = consdata->vals[v] * SCIPvarGetUbLocal(consdata->vars[v]);
6549 
6550  if( SCIPisHugeValue(scip, tmpval) )
6551  break;
6552 
6553  maxact += tmpval;
6554  }
6555  else
6556  {
6557  tmpval = consdata->vals[v] * SCIPvarGetUbLocal(consdata->vars[v]);
6558 
6559  if( SCIPisHugeValue(scip, -tmpval) )
6560  break;
6561 
6562  minact += tmpval;
6563 
6564  tmpval = consdata->vals[v] * SCIPvarGetLbLocal(consdata->vars[v]);
6565 
6566  if( SCIPisHugeValue(scip, tmpval) )
6567  break;
6568 
6569  maxact += tmpval;
6570  }
6571  }
6572  }
6573  }
6574  if( v == consdata->nvars && !SCIPisHugeValue(scip, -minact) && !SCIPisHugeValue(scip, maxact) )
6575  {
6576  SCIP_CONS* newcons;
6577  char name[SCIP_MAXSTRLEN];
6578  SCIP_Real newlhs;
6579  SCIP_Real newrhs;
6580 
6581  assert(maxact > minact);
6582  assert(w == ninfcheckvars);
6583 
6584  newlhs = lhs - maxact;
6585  newrhs = rhs - minact;
6586  assert(newlhs < newrhs);
6587 
6588  /* create, add, and release new artificial constraint */
6589  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons2_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6590  ++conshdlrdata->naddconss;
6591 
6592  SCIPdebugMsg(scip, "adding artificial constraint %s\n", name);
6593 
6594  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals, newlhs, newrhs,
6595  TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6596  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6597 
6598  SCIPdebugPrintCons(scip, newcons, NULL);
6599  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6600 
6601  ++(*naddconss);
6602  }
6603  }
6604 
6605  TERMINATE:
6606  SCIPfreeBufferArray(scip, &infcheckvals);
6607  SCIPfreeBufferArray(scip, &infcheckvars);
6608 
6609  return SCIP_OKAY;
6610 }
6611 
6612 /** tightens bounds of a single variable due to activity bounds */
6613 static
6615  SCIP* scip, /**< SCIP data structure */
6616  SCIP_CONS* cons, /**< linear constraint */
6617  int pos, /**< position of the variable in the vars array */
6618  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
6619  int* nchgbds, /**< pointer to count the total number of tightened bounds */
6620  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
6621  )
6622 {
6623  SCIP_CONSDATA* consdata;
6624  SCIP_VAR* var;
6625  SCIP_Real val;
6626  SCIP_Real lb;
6627  SCIP_Real ub;
6628  SCIP_Real minresactivity;
6629  SCIP_Real maxresactivity;
6630  SCIP_Real lhs;
6632  SCIP_Bool infeasible;
6633  SCIP_Bool tightened;
6634  SCIP_Bool minisrelax;
6635  SCIP_Bool maxisrelax;
6636  SCIP_Bool isminsettoinfinity;
6637  SCIP_Bool ismaxsettoinfinity;
6638 
6639  assert(scip != NULL);
6640  assert(cons != NULL);
6641  assert(cutoff != NULL);
6642  assert(nchgbds != NULL);
6643 
6644  /* we cannot tighten variables' bounds, if the constraint may be not complete */
6645  if( SCIPconsIsModifiable(cons) )
6646  return SCIP_OKAY;
6647 
6648  consdata = SCIPconsGetData(cons);
6649  assert(consdata != NULL);
6650  assert(0 <= pos && pos < consdata->nvars);
6651 
6652  *cutoff = FALSE;
6653 
6654  var = consdata->vars[pos];
6655 
6656  /* we cannot tighten bounds of multi-aggregated variables */
6658  return SCIP_OKAY;
6659 
6660  val = consdata->vals[pos];
6661  lhs = consdata->lhs;
6662  rhs = consdata->rhs;
6663  consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
6664  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
6665  assert(var != NULL);
6666  assert(!SCIPisZero(scip, val));
6667  assert(!SCIPisInfinity(scip, lhs));
6668  assert(!SCIPisInfinity(scip, -rhs));
6669 
6670  lb = SCIPvarGetLbLocal(var);
6671  ub = SCIPvarGetUbLocal(var);
6672  assert(SCIPisLE(scip, lb, ub));
6673 
6674  if( val > 0.0 )
6675  {
6676  /* check, if we can tighten the variable's bounds */
6677  if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && !minisrelax )
6678  {
6679  SCIP_Real newub;
6680 
6681  newub = (rhs - minresactivity)/val;
6682 
6683  if( !SCIPisInfinity(scip, newub) &&
6684  ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
6685  {
6686  SCIP_Bool activityunreliable;
6687  activityunreliable = SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity);
6688 
6689  /* check minresactivities for reliability */
6690  if( activityunreliable )
6691  {
6692  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
6693  newub = (rhs - minresactivity)/val;
6694  activityunreliable = SCIPisInfinity(scip, -minresactivity) ||
6695  (!SCIPisUbBetter(scip, newub, lb, ub) && (!SCIPisFeasLT(scip, newub, ub) || !SCIPvarIsIntegral(var))
6696  && (!force || !SCIPisLT(scip, newub, ub)));
6697  }
6698 
6699  if( !activityunreliable )
6700  {
6701  /* tighten upper bound */
6702  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newub=%.15g\n",
6703  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newub);
6704  SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_RHS, pos), force,
6705  &infeasible, &tightened) );
6706  if( infeasible )
6707  {
6708  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
6709  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
6710 
6711  /* analyze conflict */
6712  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
6713 
6714  *cutoff = TRUE;
6715  return SCIP_OKAY;
6716  }
6717  if( tightened )
6718  {
6719  ub = SCIPvarGetUbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6720  assert(SCIPisFeasLE(scip, ub, newub));
6721  (*nchgbds)++;
6722 
6723  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6724  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6725  }
6726  }
6727  }
6728  }
6729 
6730  if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && !maxisrelax )
6731  {
6732  SCIP_Real newlb;
6733 
6734  newlb = (lhs - maxresactivity)/val;
6735  if( !SCIPisInfinity(scip, -newlb) &&
6736  ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
6737  {
6738  /* check maxresactivities for reliability */
6739  if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
6740  {
6741  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
6742  newlb = (lhs - maxresactivity)/val;
6743 
6744  if( SCIPisInfinity(scip, maxresactivity) || (!SCIPisLbBetter(scip, newlb, lb, ub)
6745  && (!SCIPisFeasGT(scip, newlb, lb) || !SCIPvarIsIntegral(var))
6746  && (!force || !SCIPisGT(scip, newlb, lb))) )
6747  return SCIP_OKAY;
6748  }
6749 
6750  /* tighten lower bound */
6751  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
6752  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newlb);
6753  SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_LHS, pos), force,
6754  &infeasible, &tightened) );
6755  if( infeasible )
6756  {
6757  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
6758  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
6759 
6760  /* analyze conflict */
6761  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
6762 
6763  *cutoff = TRUE;
6764  return SCIP_OKAY;
6765  }
6766  if( tightened )
6767  {
6768  lb = SCIPvarGetLbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6769  assert(SCIPisFeasGE(scip, lb, newlb));
6770  (*nchgbds)++;
6771  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6772  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6773  }
6774  }
6775  }
6776  }
6777  else
6778  {
6779  /* check, if we can tighten the variable's bounds */
6780  if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && !minisrelax )
6781  {
6782  SCIP_Real newlb;
6783 
6784  newlb = (rhs - minresactivity)/val;
6785  if( !SCIPisInfinity(scip, -newlb) &&
6786  ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
6787  {
6788  SCIP_Bool activityunreliable;
6789  activityunreliable = SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity);
6790  /* check minresactivities for reliability */
6791  if( activityunreliable )
6792  {
6793  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
6794  newlb = (rhs - minresactivity)/val;
6795 
6796  activityunreliable = SCIPisInfinity(scip, -minresactivity)
6797  || (!SCIPisLbBetter(scip, newlb, lb, ub) && (!SCIPisFeasGT(scip, newlb, lb) || !SCIPvarIsIntegral(var))
6798  && (!force || !SCIPisGT(scip, newlb, lb)));
6799  }
6800 
6801  if( !activityunreliable )
6802  {
6803  /* tighten lower bound */
6804  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
6805  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newlb);
6806  SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_RHS, pos), force,
6807  &infeasible, &tightened) );
6808  if( infeasible )
6809  {
6810  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
6811  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
6812 
6813  /* analyze conflict */
6814  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
6815 
6816  *cutoff = TRUE;
6817  return SCIP_OKAY;
6818  }
6819  if( tightened )
6820  {
6821  lb = SCIPvarGetLbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6822  assert(SCIPisFeasGE(scip, lb, newlb));
6823  (*nchgbds)++;
6824  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6825  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6826  }
6827  }
6828  }
6829  }
6830 
6831  if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && !maxisrelax )
6832  {
6833  SCIP_Real newub;
6834 
6835  newub = (lhs - maxresactivity)/val;
6836  if( !SCIPisInfinity(scip, newub) &&
6837  ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
6838  {
6839  /* check maxresactivities for reliability */
6840  if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
6841  {
6842  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
6843  newub = (lhs - maxresactivity)/val;
6844 
6845  if( SCIPisInfinity(scip, maxresactivity) || (!SCIPisUbBetter(scip, newub, lb, ub)
6846  && (!SCIPisFeasLT(scip, newub, ub) && !SCIPvarIsIntegral(var))
6847  && (!force || !SCIPisLT(scip, newub, ub))) )
6848  return SCIP_OKAY;
6849  }
6850 
6851  /* tighten upper bound */
6852  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g], newub=%.15g\n",
6853  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newub);
6854  SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_LHS, pos), force,
6855  &infeasible, &tightened) );
6856  if( infeasible )
6857  {
6858  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
6859  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
6860 
6861  /* analyze conflict */
6862  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
6863 
6864  *cutoff = TRUE;
6865  return SCIP_OKAY;
6866  }
6867  if( tightened )
6868  {
6869  ub = SCIPvarGetUbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6870  assert(SCIPisFeasLE(scip, ub, newub));
6871  (*nchgbds)++;
6872  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6873  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6874  }
6875  }
6876  }
6877  }
6878 
6879  return SCIP_OKAY;
6880 }
6881 
6882 #define MAXTIGHTENROUNDS 10
6883 
6884 /** tightens bounds of variables in constraint due to activity bounds */
6885 static
6887  SCIP* scip, /**< SCIP data structure */
6888  SCIP_CONS* cons, /**< linear constraint */
6889  SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
6890  SCIP_Bool sortvars, /**< should variables be used in sorted order? */
6891  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
6892  int* nchgbds /**< pointer to count the total number of tightened bounds */
6893  )
6894 {
6895  SCIP_CONSDATA* consdata;
6896  unsigned int tightenmode;
6897  int nvars;
6898  int nrounds;
6899  int lastchange;
6900  int oldnchgbds;
6901 #ifndef SCIP_DEBUG
6902  int oldnchgbdstotal;
6903 #endif
6904  int v;
6905  SCIP_Bool force;
6906  SCIP_Bool easycase;
6907 
6908  assert(scip != NULL);
6909  assert(cons != NULL);
6910  assert(nchgbds != NULL);
6911  assert(cutoff != NULL);
6912 
6913  *cutoff = FALSE;
6914 
6915  /* we cannot tighten variables' bounds, if the constraint may be not complete */
6916  if( SCIPconsIsModifiable(cons) )
6917  return SCIP_OKAY;
6918 
6919  /* if a constraint was created after presolve, then it may hold fixed variables
6920  * if there are even multi-aggregated variables, then we cannot do bound tightening on these
6921  * thus, ensure here again that variable fixings have been applied
6922  */
6923  SCIP_CALL( applyFixings(scip, cons, cutoff) );
6924  if( *cutoff )
6925  return SCIP_OKAY;
6926 
6927  /* check if constraint has any chances of tightening bounds */
6928  if( !canTightenBounds(scip, cons) )
6929  return SCIP_OKAY;
6930 
6931  consdata = SCIPconsGetData(cons);
6932  assert(consdata != NULL);
6933 
6934  nvars = consdata->nvars;
6935  force = (nvars == 1) && !SCIPconsIsModifiable(cons);
6936 
6937  /* we are at the root node or during presolving */
6938  if( SCIPgetDepth(scip) < 1 )
6939  tightenmode = 2;
6940  else
6941  tightenmode = 1;
6942 
6943  /* stop if we already tightened the constraint and the tightening is not forced */
6944  if( !force && (consdata->boundstightened >= tightenmode) ) /*lint !e574*/
6945  return SCIP_OKAY;
6946 
6947  /* ensure that the variables are properly sorted */
6948  if( sortvars && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE && !consdata->binvarssorted )
6949  {
6950  SCIP_CALL( consdataSort(scip, consdata) );
6951  assert(consdata->binvarssorted);
6952  }
6953 
6954  /* update maximal activity delta if necessary */
6955  if( consdata->maxactdelta == SCIP_INVALID ) /*lint !e777*/
6956  consdataRecomputeMaxActivityDelta(scip, consdata);
6957 
6958  assert(consdata->maxactdelta != SCIP_INVALID); /*lint !e777*/
6959  assert(!SCIPisFeasNegative(scip, consdata->maxactdelta));
6960  checkMaxActivityDelta(scip, consdata);
6961 
6962  /* this may happen if all variables are fixed */
6963  if( SCIPisFeasZero(scip, consdata->maxactdelta) )
6964  return SCIP_OKAY;
6965 
6966  if( !SCIPisInfinity(scip, consdata->maxactdelta) )
6967  {
6968  SCIP_Real slack;
6969  SCIP_Real surplus;
6970  SCIP_Real minactivity;
6971  SCIP_Real maxactivity;
6972  SCIP_Bool minisrelax;
6973  SCIP_Bool maxisrelax;
6974 
6975  /* use maximal activity delta to skip propagation (cannot deduce anything) */
6976  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minisrelax, &maxisrelax);
6977  assert(!SCIPisInfinity(scip, minactivity));
6978  assert(!SCIPisInfinity(scip, -maxactivity));
6979 
6980  slack = (SCIPisInfinity(scip, consdata->rhs) || SCIPisInfinity(scip, -minactivity)) ? SCIPinfinity(scip) : (consdata->rhs - minactivity);
6981  surplus = (SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, maxactivity)) ? SCIPinfinity(scip) : (maxactivity - consdata->lhs);
6982 
6983  /* check if the constraint will propagate */
6984  if( SCIPisLE(scip, consdata->maxactdelta, MIN(slack, surplus)) )
6985  return SCIP_OKAY;
6986  }
6987 
6988  /* check if we can use fast implementation for easy and numerically well behaved cases */
6989  easycase = SCIPisLT(scip, consdata->maxactdelta, maxeasyactivitydelta);
6990 
6991  /* as long as the bounds might be tightened again, try to tighten them; abort after a maximal number of rounds */
6992  lastchange = -1;
6993  oldnchgbds = 0;
6994 
6995 #ifndef SCIP_DEBUG
6996  oldnchgbdstotal = *nchgbds;
6997 #endif
6998 
6999  for( nrounds = 0; (force || consdata->boundstightened < tightenmode) && nrounds < MAXTIGHTENROUNDS; ++nrounds ) /*lint !e574*/
7000  {
7001  /* mark the constraint to have the variables' bounds tightened */
7002  consdata->boundstightened = (unsigned int)tightenmode;
7003 
7004  /* try to tighten the bounds of each variable in the constraint. During solving process, the binary variable
7005  * sorting enables skipping variables
7006  */
7007  v = 0;
7008  while( v < nvars && v != lastchange && !(*cutoff) )
7009  {
7010  oldnchgbds = *nchgbds;
7011 
7012  assert(!sortvars || SCIPgetStage(scip) < SCIP_STAGE_SOLVING || consdata->binvarssorted);
7013 
7014  if( easycase )
7015  {
7016  SCIP_CALL( tightenVarBoundsEasy(scip, cons, v, cutoff, nchgbds, force) );
7017  }
7018  else
7019  {
7020  SCIP_CALL( tightenVarBounds(scip, cons, v, cutoff, nchgbds, force) );
7021  }
7022 
7023  /* if there was no progress, skip the rest of the binary variables */
7024  if( *nchgbds > oldnchgbds )
7025  {
7026  lastchange = v;
7027  ++v;
7028  }
7029  else if( consdata->binvarssorted && v < consdata->nbinvars - 1
7030  && !SCIPisFeasEQ(scip, SCIPvarGetUbLocal(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v])) )
7031  v = consdata->nbinvars;
7032  else
7033  ++v;
7034  }
7035 
7036 #ifndef SCIP_DEBUG
7037  SCIPdebugMessage("linear constraint <%s> found %d bound changes in round %d\n", SCIPconsGetName(cons),
7038  *nchgbds - oldnchgbdstotal, nrounds);
7039  oldnchgbdstotal += oldnchgbds;
7040 #endif
7041  }
7042 
7043 #ifndef NDEBUG
7044  if( force && SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
7045  assert(*cutoff || SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->vars[0]), SCIPvarGetUbLocal(consdata->vars[0])));
7046 #endif
7047 
7048  return SCIP_OKAY;
7049 }
7050 
7051 /** checks linear constraint for feasibility of given solution or current solution */
7052 static
7054  SCIP* scip, /**< SCIP data structure */
7055  SCIP_CONS* cons, /**< linear constraint */
7056  SCIP_SOL* sol, /**< solution to be checked, or NULL for current solution */
7057  SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
7058  SCIP_Bool checkrelmaxabs, /**< Should the violation for a constraint with side 0.0 be checked relative
7059  * to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
7060  SCIP_Bool* violated /**< pointer to store whether the constraint is violated */
7061  )
7062 {
7063  SCIP_CONSDATA* consdata;
7064  SCIP_Real activity;
7065 
7066  assert(scip != NULL);
7067  assert(cons != NULL);
7068  assert(violated != NULL);
7069 
7070  SCIPdebugMsg(scip, "checking linear constraint <%s>\n", SCIPconsGetName(cons));
7071  SCIPdebugPrintCons(scip, cons, NULL);
7072 
7073  consdata = SCIPconsGetData(cons);
7074  assert(consdata != NULL);
7075 
7076  *violated = FALSE;
7077 
7078  if( consdata->row != NULL )
7079  {
7080  if( !checklprows && SCIProwIsInLP(consdata->row) )
7081  return SCIP_OKAY;
7082  else if( sol == NULL && !SCIPhasCurrentNodeLP(scip) )
7083  activity = consdataComputePseudoActivity(scip, consdata);
7084  else
7085  activity = SCIPgetRowSolActivity(scip, consdata->row, sol);
7086  }
7087  else
7088  activity = consdataGetActivity(scip, consdata, sol);
7089 
7090  SCIPdebugMsg(scip, " consdata activity=%.15g (lhs=%.15g, rhs=%.15g, row=%p, checklprows=%u, rowinlp=%u, sol=%p, hascurrentnodelp=%u)\n",
7091  activity, consdata->lhs, consdata->rhs, (void*)consdata->row, checklprows,
7092  consdata->row == NULL ? 0 : SCIProwIsInLP(consdata->row), (void*)sol,
7093  consdata->row == NULL ? FALSE : SCIPhasCurrentNodeLP(scip));
7094 
7095  /* the activity of pseudo solutions may be invalid if it comprises positive and negative infinity contributions; we
7096  * return infeasible for safety
7097  */
7098  if( activity == SCIP_INVALID ) /*lint !e777*/
7099  {
7100  assert(sol == NULL);
7101  *violated = TRUE;
7102 
7103  /* reset constraint age since we are in enforcement */
7104  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7105  }
7106  else if( SCIPisFeasLT(scip, activity, consdata->lhs) || SCIPisFeasGT(scip, activity, consdata->rhs) )
7107  {
7108  /* the "normal" check: one of the two sides is violated */
7109  if( !checkrelmaxabs )
7110  {
7111  *violated = TRUE;
7112 
7113  /* only reset constraint age if we are in enforcement */
7114  if( sol == NULL )
7115  {
7116  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7117  }
7118  }
7119  /* the (much) more complicated check: we try to disregard random noise and violations of a 0.0 side which are
7120  * small compared to the absolute values occuring in the activity
7121  */
7122  else
7123  {
7124  SCIP_Real maxabs;
7125  SCIP_Real coef;
7126  SCIP_Real absval;
7127  SCIP_Real solval;
7128  int v;
7129 
7130  maxabs = 1.0;
7131 
7132  /* compute maximum absolute value */
7133  for( v = 0; v < consdata->nvars; ++v )
7134  {
7135  if( consdata->vals != NULL )
7136  {
7137  coef = consdata->vals[v];
7138  }
7139  else
7140  coef = 1.0;
7141 
7142  solval = SCIPgetSolVal(scip, sol, consdata->vars[v]);
7143  absval = REALABS( coef * solval );
7144  maxabs = MAX( maxabs, absval );
7145  }
7146 
7147  /* regard left hand side, first */
7148  if( SCIPisFeasLT(scip, activity, consdata->lhs) )
7149  {
7150  /* check whether violation is random noise */
7151  if( (consdata->lhs - activity) <= (1e-15 * maxabs) )
7152  {
7153  SCIPdebugMsg(scip, " lhs violated due to random noise: violation=%16.9g, maxabs=%16.9g\n",
7154  consdata->lhs - activity, maxabs);
7155  SCIPdebug( SCIP_CALL( SCIPprintCons(scip, cons, NULL) ) );
7156 
7157  /* only increase constraint age if we are in enforcement */
7158  if( sol == NULL )
7159  {
7160  SCIP_CALL( SCIPincConsAge(scip, cons) );
7161  }
7162  }
7163  /* lhs is violated and lhs is 0.0: use relative tolerance w.r.t. largest absolute value */
7164  else if( SCIPisZero(scip, consdata->lhs) )
7165  {
7166  if( (consdata->lhs - activity) <= (SCIPfeastol(scip) * maxabs) )
7167  {
7168  SCIPdebugMsg(scip, " lhs violated absolutely (violation=%16.9g), but feasible when using relative tolerance w.r.t. maximum absolute value (%16.9g)\n",
7169  consdata->lhs - activity, maxabs);
7170  SCIPdebug( SCIP_CALL( SCIPprintCons(scip, cons, NULL) ) );
7171 
7172  /* only increase constraint age if we are in enforcement */
7173  if( sol == NULL )
7174  {
7175  SCIP_CALL( SCIPincConsAge(scip, cons) );
7176  }
7177  }
7178  else
7179  {
7180  *violated = TRUE;
7181 
7182  /* only reset constraint age if we are in enforcement */
7183  if( sol == NULL )
7184  {
7185  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7186  }
7187  }
7188  }
7189  else
7190  {
7191  *violated = TRUE;
7192 
7193  /* only reset constraint age if we are in enforcement */
7194  if( sol == NULL )
7195  {
7196  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7197  }
7198  }
7199  }
7200 
7201  /* now regard right hand side */
7202  if( SCIPisFeasGT(scip, activity, consdata->rhs) )
7203  {
7204  /* check whether violation is random noise */
7205  if( (activity - consdata->rhs) <= (1e-15 * maxabs) )
7206  {
7207  SCIPdebugMsg(scip, " rhs violated due to random noise: violation=%16.9g, maxabs=%16.9g\n",
7208  activity - consdata->rhs, maxabs);
7209  SCIPdebug( SCIP_CALL( SCIPprintCons(scip, cons, NULL) ) );
7210 
7211  /* only increase constraint age if we are in enforcement */
7212  if( sol == NULL )
7213  {
7214  SCIP_CALL( SCIPincConsAge(scip, cons) );
7215  }
7216  }
7217  /* rhs is violated and rhs is 0.0, use relative tolerance w.r.t. largest absolute value */
7218  else if( SCIPisZero(scip, consdata->rhs) )
7219  {
7220  if( (activity - consdata->rhs) <= (SCIPfeastol(scip) * maxabs) )
7221  {
7222  SCIPdebugMsg(scip, " rhs violated absolutely (violation=%16.9g), but feasible when using relative tolerance w.r.t. maximum absolute value (%16.9g)\n",
7223  activity - consdata->rhs, maxabs);
7224  SCIPdebug( SCIP_CALL( SCIPprintCons(scip, cons, NULL) ) );
7225 
7226  /* only increase constraint age if we are in enforcement */
7227  if( sol == NULL )
7228  {
7229  SCIP_CALL( SCIPincConsAge(scip, cons) );
7230  }
7231  }
7232  else
7233  {
7234  *violated = TRUE;
7235 
7236  /* only reset constraint age if we are in enforcement */
7237  if( sol == NULL )
7238  {
7239  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7240  }
7241  }
7242  }
7243  else
7244  {
7245  *violated = TRUE;
7246 
7247  /* only reset constraint age if we are in enforcement */
7248  if( sol == NULL )
7249  {
7250  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7251  }
7252  }
7253  }
7254  }
7255  }
7256  else
7257  {
7258  /* only increase constraint age if we are in enforcement */
7259  if( sol == NULL )
7260  {
7261  SCIP_CALL( SCIPincConsAge(scip, cons) );
7262  }
7263  }
7264 
7265  return SCIP_OKAY;
7266 }
7267 
7268 /** creates an LP row in a linear constraint data */
7269 static
7271  SCIP* scip, /**< SCIP data structure */
7272  SCIP_CONS* cons /**< linear constraint */
7273  )
7274 {
7275  SCIP_CONSDATA* consdata;
7276 
7277  assert(scip != NULL);
7278  assert(cons != NULL);
7279 
7280  consdata = SCIPconsGetData(cons);
7281  assert(consdata != NULL);
7282  assert(consdata->row == NULL);
7283 
7284  SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row, SCIPconsGetHdlr(cons), SCIPconsGetName(cons), consdata->lhs, consdata->rhs,
7286 
7287  SCIP_CALL( SCIPaddVarsToRow(scip, consdata->row, consdata->nvars, consdata->vars, consdata->vals) );
7288 
7289  return SCIP_OKAY;
7290 }
7291 
7292 /** adds linear constraint as cut to the LP */
7293 static
7295  SCIP* scip, /**< SCIP data structure */
7296  SCIP_CONS* cons, /**< linear constraint */
7297  SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
7298  SCIP_Bool* cutoff /**< pointer to store whether a cutoff was found */
7299  )
7300 {
7301  SCIP_CONSDATA* consdata;
7302 
7303  assert(scip != NULL);
7304  assert(cons != NULL);
7305 
7306  consdata = SCIPconsGetData(cons);
7307  assert(consdata != NULL);
7308 
7309  if( consdata->row == NULL )
7310  {
7311  /* convert consdata object into LP row */
7312  SCIP_CALL( createRow(scip, cons) );
7313  }
7314  assert(consdata->row != NULL);
7315 
7316  /* insert LP row as cut */
7317  if( !SCIProwIsInLP(consdata->row) )
7318  {
7319  SCIPdebugMsg(scip, "adding relaxation of linear constraint <%s>: ", SCIPconsGetName(cons));
7320  SCIPdebug( SCIP_CALL( SCIPprintRow(scip, consdata->row, NULL)) );
7321  /* if presolving is turned off, the row might be trivial */
7322  if ( ! SCIPisInfinity(scip, -consdata->lhs) || ! SCIPisInfinity(scip, consdata->rhs) )
7323  {
7324  SCIP_CALL( SCIPaddCut(scip, sol, consdata->row, FALSE, cutoff) );
7325  }
7326 #ifndef NDEBUG
7327  else
7328  {
7329  int pr;
7330  int cr;
7331  SCIP_CALL( SCIPgetIntParam(scip, "presolving/maxrounds", &pr) );
7332  SCIP_CALL( SCIPgetIntParam(scip, "constraints/linear/maxprerounds", &cr) );
7333  assert( pr == 0 || cr == 0 );
7334  }
7335 #endif
7336  }
7337 
7338  return SCIP_OKAY;
7339 }
7340 
7341 /** separates linear constraint: adds linear constraint as cut, if violated by given solution */
7342 static
7344  SCIP* scip, /**< SCIP data structure */
7345  SCIP_CONS* cons, /**< linear constraint */
7346  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
7347  SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
7348  SCIP_Bool separatecards, /**< should knapsack cardinality cuts be generated? */
7349  SCIP_Bool separateall, /**< should all constraints be subject to cardinality cut generation instead of only
7350  * the ones with non-zero dual value? */
7351  int* ncuts, /**< pointer to add up the number of found cuts */
7352  SCIP_Bool* cutoff /**< pointer to store whether a cutoff was found */
7353  )
7354 {
7355  SCIP_CONSDATA* consdata;
7356  SCIP_Bool violated;
7357  int oldncuts;
7358 
7359  assert(scip != NULL);
7360  assert(conshdlrdata != NULL);
7361  assert(cons != NULL);
7362  assert(cutoff != NULL);
7363 
7364  consdata = SCIPconsGetData(cons);
7365  assert(ncuts != NULL);
7366  assert(consdata != NULL);
7367 
7368  oldncuts = *ncuts;
7369  *cutoff = FALSE;
7370 
7371  SCIP_CALL( checkCons(scip, cons, sol, (sol != NULL), conshdlrdata->checkrelmaxabs, &violated) );
7372 
7373  if( violated )
7374  {
7375  /* insert LP row as cut */
7376  SCIP_CALL( addRelaxation(scip, cons, sol, cutoff) );
7377  (*ncuts)++;
7378  }
7379  else if( !SCIPconsIsModifiable(cons) && separatecards )
7380  {
7381  /* relax linear constraint into knapsack constraint and separate lifted cardinality cuts */
7382  if( !separateall && sol == NULL )
7383  {
7384  /* we only want to call the knapsack cardinality cut separator for rows that have a non-zero dual solution */
7385  if( consdata->row != NULL && SCIProwIsInLP(consdata->row) )
7386  {
7387  SCIP_Real dualsol;
7388 
7389  dualsol = SCIProwGetDualsol(consdata->row);
7390  if( SCIPisFeasNegative(scip, dualsol) )
7391  {
7392  if( !SCIPisInfinity(scip, consdata->rhs) )
7393  {
7394  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7395  consdata->vals, +1.0, consdata->rhs, sol, cutoff, ncuts) );
7396  }
7397  }
7398  else if( SCIPisFeasPositive(scip, dualsol) )
7399  {
7400  if( !SCIPisInfinity(scip, -consdata->lhs) )
7401  {
7402  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7403  consdata->vals, -1.0, -consdata->lhs, sol, cutoff, ncuts) );
7404  }
7405  }
7406  }
7407  }
7408  else
7409  {
7410  if( !SCIPisInfinity(scip, consdata->rhs) )
7411  {
7412  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7413  consdata->vals, +1.0, consdata->rhs, sol, cutoff, ncuts) );
7414  }
7415  if( !SCIPisInfinity(scip, -consdata->lhs) )
7416  {
7417  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7418  consdata->vals, -1.0, -consdata->lhs, sol, cutoff, ncuts) );
7419  }
7420  }
7421  }
7422 
7423  if( *ncuts > oldncuts )
7424  {
7425  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7426  }
7427 
7428  return SCIP_OKAY;
7429 }
7430 
7431 /** propagation method for linear constraints */
7432 static
7434  SCIP* scip, /**< SCIP data structure */
7435  SCIP_CONS* cons, /**< linear constraint */
7436  SCIP_Bool tightenbounds, /**< should the variable's bounds be tightened? */
7437  SCIP_Bool rangedrowpropagation,/**< should ranged row propagation be performed? */
7438  SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
7439  SCIP_Bool sortvars, /**< should variable sorting for faster propagation be used? */
7440  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
7441  int* nchgbds /**< pointer to count the total number of tightened bounds */
7442  )
7443 {
7444  SCIP_CONSDATA* consdata;
7445  SCIP_Real minactivity;
7446  SCIP_Real maxactivity;
7447  SCIP_Bool minactisrelax;
7448  SCIP_Bool maxactisrelax;
7449 
7450  assert(scip != NULL);
7451  assert(cons != NULL);
7452  assert(cutoff != NULL);
7453  assert(nchgbds != NULL);
7454 
7455  /*SCIPdebugMsg(scip, "propagating linear constraint <%s>\n", SCIPconsGetName(cons));*/
7456 
7457  consdata = SCIPconsGetData(cons);
7458  assert(consdata != NULL);
7459 
7460  *cutoff = FALSE;
7461 
7462  /* we can only infer activity bounds of the linear constraint, if it is not modifiable */
7463  if( !SCIPconsIsModifiable(cons) )
7464  {
7465  /* increase age of constraint; age is reset to zero, if a conflict or a propagation was found */
7466  if( !SCIPinRepropagation(scip) )
7467  {
7468  SCIP_CALL( SCIPincConsAge(scip, cons) );
7469  }
7470 
7471  /* tighten the variable's bounds */
7472  if( tightenbounds )
7473  {
7474  int oldnchgbds;
7475 
7476  oldnchgbds = *nchgbds;
7477 
7478  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
7479 
7480  if( *nchgbds > oldnchgbds )
7481  {
7482  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7483  }
7484  }
7485 
7486  /* propagate ranged rows */
7487  if( rangedrowpropagation && tightenbounds && !(*cutoff) )
7488  {
7489  int nfixedvars;
7490  int naddconss;
7491  /* cppcheck-suppress unassignedVariable */
7492  int oldnchgbds;
7493 
7494  nfixedvars = 0;
7495  naddconss = 0;
7496  SCIPdebug( oldnchgbds = *nchgbds; )
7497 
7498  SCIP_CALL( rangedRowPropagation(scip, cons, cutoff, &nfixedvars, nchgbds, &naddconss) );
7499 
7500  if( *cutoff )
7501  {
7502  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible\n", SCIPconsGetName(cons));
7503  }
7504  else
7505  {
7506  SCIPdebugMsg(scip, "linear constraint <%s> found %d bound changes and %d fixings\n", SCIPconsGetName(cons), *nchgbds - oldnchgbds, nfixedvars);
7507  }
7508 
7509  if( nfixedvars > 0 )
7510  *nchgbds += 2*nfixedvars;
7511  }
7512 
7513  /* check constraint for infeasibility and redundancy */
7514  if( !(*cutoff) )
7515  {
7516  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
7517 
7518  if( SCIPisFeasGT(scip, minactivity, consdata->rhs) )
7519  {
7520  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible (rhs): activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7521  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7522 
7523  /* analyze conflict */
7524  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
7525 
7526  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7527  *cutoff = TRUE;
7528  }
7529  else if( SCIPisFeasLT(scip, maxactivity, consdata->lhs) )
7530  {
7531  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible (lhs): activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7532  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7533 
7534  /* analyze conflict */
7535  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
7536 
7537  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7538  *cutoff = TRUE;
7539  }
7540  else if( SCIPisGE(scip, minactivity, consdata->lhs) && SCIPisLE(scip, maxactivity, consdata->rhs) )
7541  {
7542  SCIPdebugMsg(scip, "linear constraint <%s> is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7543  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7544  SCIP_CALL( SCIPdelConsLocal(scip, cons) );
7545  }
7546  }
7547  }
7548 
7549  return SCIP_OKAY;
7550 }
7551 
7552 
7553 /*
7554  * Presolving methods
7555  */
7556 
7557 /** converts all variables with fixed domain into FIXED variables */
7558 static
7560  SCIP* scip, /**< SCIP data structure */
7561  SCIP_CONS* cons, /**< linear constraint */
7562  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
7563  int* nfixedvars /**< pointer to count the total number of fixed variables */
7564  )
7565 {
7566  SCIP_CONSDATA* consdata;
7567  SCIP_VAR* var;
7568  SCIP_VARSTATUS varstatus;
7569  SCIP_Real lb;
7570  SCIP_Real ub;
7571  SCIP_Bool fixed;
7572  SCIP_Bool infeasible;
7573  int v;
7574 
7575  assert(scip != NULL);
7576  assert(cons != NULL);
7577  assert(cutoff != NULL);
7578  assert(nfixedvars != NULL);
7579 
7580  consdata = SCIPconsGetData(cons);
7581  assert(consdata != NULL);
7582 
7583  for( v = 0; v < consdata->nvars; ++v )
7584  {
7585  assert(consdata->vars != NULL);
7586  var = consdata->vars[v];
7587  varstatus = SCIPvarGetStatus(var);
7588 
7589  if( varstatus != SCIP_VARSTATUS_FIXED )
7590  {
7591  lb = SCIPvarGetLbGlobal(var);
7592  ub = SCIPvarGetUbGlobal(var);
7593  if( SCIPisEQ(scip, lb, ub) )
7594  {
7595  SCIP_Real fixval;
7596 
7597  fixval = SCIPselectSimpleValue(lb, ub, MAXDNOM);
7598  SCIPdebugMsg(scip, "converting variable <%s> with fixed bounds [%.15g,%.15g] into fixed variable fixed at %.15g\n",
7599  SCIPvarGetName(var), lb, ub, fixval);
7600  SCIP_CALL( SCIPfixVar(scip, var, fixval, &infeasible, &fixed) );
7601  if( infeasible )
7602  {
7603  SCIPdebugMsg(scip, " -> infeasible fixing\n");
7604  *cutoff = TRUE;
7605  return SCIP_OKAY;
7606  }
7607  if( fixed )
7608  (*nfixedvars)++;
7609  }
7610  }
7611  }
7612 
7613  SCIP_CALL( applyFixings(scip, cons, &infeasible) );
7614 
7615  if( infeasible )
7616  {
7617  SCIPdebugMsg(scip, " -> infeasible fixing\n");
7618  *cutoff = TRUE;
7619  return SCIP_OKAY;
7620  }
7621 
7622  assert(consdata->removedfixings);
7623 
7624  return SCIP_OKAY;
7625 }
7626 
7627 #define MAX_CLIQUE_NONZEROS_PER_CONS 1000000
7628 
7629 /** extracts cliques of the constraint and adds them to SCIP
7630  *
7631  * The following clique extraction mechanism are implemeneted
7632  *
7633  * 1. collect binary variables and sort them in non increasing order, then
7634  *
7635  * a) if the constraint has a finite right hand side and the negative infinity counters for the minactivity are zero
7636  * then add the variables as a clique for which all successive pairs of coefficients fullfill the following
7637  * condition
7638  *
7639  * minactivity + vals[i] + vals[i+1] > rhs
7640  *
7641  * and also add the binary to binary implication also for non-successive variables for which the same argument
7642  * holds
7643  *
7644  * minactivity + vals[i] + vals[j] > rhs
7645  *
7646  * 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
7647  * binary to binary implications x1 = 1 => x4 = 0 and x2 = 1 => x4 = 0
7648  *
7649  * b) if the constraint has a finite left hand side and the positive infinity counters for the maxactivity are zero
7650  * then add the variables as a clique for which all successive pairs of coefficients fullfill the follwoing
7651  * condition
7652  *
7653  * maxactivity + vals[i] + vals[i-1] < lhs
7654  *
7655  * and also add the binary to binary implication also for non-successive variables for which the same argument
7656  * holds
7657  *
7658  * maxactivity + vals[i] + vals[j] < lhs
7659  *
7660  * e.g. you could multiply the above example by -1
7661  *
7662  * c) the constraint has a finite right hand side and a finite minactivity then add the variables as a negated
7663  * clique(clique on the negated variables) for which all successive pairs of coefficients fullfill the following
7664  * condition
7665  *
7666  * minactivity - vals[i] - vals[i-1] > rhs
7667  *
7668  * and also add the binary to binary implication also for non-successive variables for which the
7669  * same argument holds
7670  *
7671  * minactivity - vals[i] - vals[j] > rhs
7672  *
7673  * e.g. -4 x1 -3 x2 - 2 x3 + 2 x4 <= -4 would lead to the (negated) clique (~x1, ~x2) and the binary to binary
7674  * implication x1 = 0 => x3 = 1
7675  *
7676  * d) the constraint has a finite left hand side and a finite maxactivity then add the variables as a negated
7677  * clique(clique on the negated variables) for which all successive pairs of coefficients fullfill the following
7678  * condition
7679  *
7680  * maxactivity - vals[i] - vals[i+1] < lhs
7681  *
7682  * and also add the binary to binary implication also for non-successive variables for which the same argument
7683  * holds
7684  *
7685  * maxactivity - vals[i] - vals[j] < lhs
7686  *
7687  * e.g. you could multiply the above example by -1
7688  *
7689  * 2. if the linear constraint represents a set-packing or set-partitioning constraint, the whole constraint is added
7690  * as clique, (this part is done at the end of the method)
7691  *
7692  */
7693 static
7695  SCIP* scip, /**< SCIP data structure */
7696  SCIP_CONS* cons, /**< linear constraint */
7697  SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
7698  SCIP_Bool sortvars, /**< should variables be used in sorted order? */
7699  int* nfixedvars, /**< pointer to count number of fixed variables */
7700  int* nchgbds, /**< pointer to count the total number of tightened bounds */
7701  SCIP_Bool* cutoff /**< pointer to store TRUE, if a cutoff was found */
7702  )
7703 {
7704  SCIP_VAR** vars;
7705  SCIP_Real* vals;
7706  SCIP_CONSDATA* consdata;
7707  SCIP_Bool lhsclique;
7708  SCIP_Bool rhsclique;
7709  SCIP_Bool finitelhs;
7710  SCIP_Bool finiterhs;
7711  SCIP_Bool finiteminact;
7712  SCIP_Bool finitemaxact;
7713  SCIP_Bool finitenegminact;
7714  SCIP_Bool finitenegmaxact;
7715  SCIP_Bool finiteposminact;
7716  SCIP_Bool finiteposmaxact;
7717  SCIP_Bool infeasible;
7718  SCIP_Bool stopped;
7719  int cliquenonzerosadded;
7720  int v;
7721  int i;
7722  int nposcoefs;
7723  int nnegcoefs;
7724  int nvars;
7725 
7726  assert(scip != NULL);
7727  assert(cons != NULL);
7728  assert(nfixedvars != NULL);
7729  assert(nchgbds != NULL);
7730  assert(cutoff != NULL);
7731  assert(!SCIPconsIsDeleted(cons));
7732 
7733  consdata = SCIPconsGetData(cons);
7734  assert(consdata != NULL);
7735 
7736  if( consdata->nvars < 2 )
7737  return SCIP_OKAY;
7738 
7739  /* add implications if posibble
7740  *
7741  * for now we only add binary to non-binary implications, and this is only done for the binary variable with the
7742  * maximal absolute contribution and also only if this variable would force all other variables to their bound
7743  * corresponding to the global minimal activity of the constraint
7744  */
7745  if( !consdata->implsadded )
7746  {
7747  /* sort variables by variable type */
7748  SCIP_CALL( consdataSort(scip, consdata) );
7749 
7750  /* @todo we might extract implications/cliques if SCIPvarIsBinary() variables exist and we have integer variables
7751  * up front, might change sorting correspondingly
7752  */
7753  /* fast abort if no binaries exist */
7754  if( !SCIPvarIsBinary(consdata->vars[0]) )
7755  return SCIP_OKAY;
7756 
7757  nvars = consdata->nvars;
7758  vars = consdata->vars;
7759  vals = consdata->vals;
7760 
7761  /* recompute activities if needed */
7762  if( !consdata->validactivities )
7763  consdataCalcActivities(scip, consdata);
7764  assert(consdata->validactivities);
7765 
7766  finitelhs = !SCIPisInfinity(scip, -consdata->lhs);
7767  finiterhs = !SCIPisInfinity(scip, consdata->rhs);
7768  finitenegminact = (consdata->glbminactivityneginf == 0 && consdata->glbminactivityneghuge == 0);
7769  finitenegmaxact = (consdata->glbmaxactivityneginf == 0 && consdata->maxactivityneghuge == 0);
7770  finiteposminact = (consdata->glbminactivityposinf == 0 && consdata->glbminactivityposhuge == 0);
7771  finiteposmaxact = (consdata->glbmaxactivityposinf == 0 && consdata->glbmaxactivityposhuge == 0);
7772  finiteminact = (finitenegminact && finiteposminact);
7773  finitemaxact = (finitenegmaxact && finiteposmaxact);
7774 
7775  if( (finiterhs || finitelhs) && (finitenegminact || finiteposminact || finitenegmaxact || finiteposmaxact) )
7776  {
7777  SCIP_Real maxabscontrib = -1.0;
7778  SCIP_Bool posval = FALSE;
7779  SCIP_Bool allbinary = TRUE;
7780  int oldnchgbds = *nchgbds;
7781  int nbdchgs = 0;
7782  int nimpls = 0;
7783  int position = -1;
7784 
7785  /* we need a valid minimal/maximal activity to add cliques */
7786  if( (finitenegminact || finiteposminact) && !consdata->validglbminact )
7787  {
7788  consdataRecomputeGlbMinactivity(scip, consdata);
7789  assert(consdata->validglbminact);
7790  }
7791 
7792  if( (finitenegmaxact || finiteposmaxact) && !consdata->validglbmaxact )
7793  {
7794  consdataRecomputeGlbMaxactivity(scip, consdata);
7795  assert(consdata->validglbmaxact);
7796  }
7797  assert(consdata->validglbminact || consdata->validglbmaxact);
7798 
7799  /* @todo extend this to local/constraint probing */
7800 
7801  /* determine maximal contribution to the activity */
7802  for( v = nvars - 1; v >= 0; --v )
7803  {
7804  if( SCIPvarIsBinary(vars[v]) )
7805  {
7806  if( vals[v] > 0 )
7807  {
7808  SCIP_Real value = vals[v] * SCIPvarGetUbGlobal(vars[v]);
7809 
7810  if( value > maxabscontrib )
7811  {
7812  maxabscontrib = value;
7813  position = v;
7814  posval = TRUE;
7815  }
7816  }
7817  else
7818  {
7819  SCIP_Real value = vals[v] * SCIPvarGetLbGlobal(vars[v]);
7820 
7821  value = REALABS(value);
7822 
7823  if( value > maxabscontrib )
7824  {
7825  maxabscontrib = value;
7826  position = v;
7827  posval = FALSE;
7828  }
7829  }
7830  }
7831  else
7832  allbinary = FALSE;
7833  }
7834  assert(0 <= position && position < nvars);
7835 
7836  if( !SCIPisEQ(scip, maxabscontrib, 1.0) && !allbinary )
7837  {
7838  /* if the right hand side and the minimal activity are finite and changing the variable with the biggest
7839  * influence to their bound forces all other variables to be at their minimal contribution, we can add these
7840  * implications
7841  */
7842  if( finiterhs && finiteminact && SCIPisEQ(scip, consdata->glbminactivity, consdata->rhs - maxabscontrib) )
7843  {
7844  for( v = nvars - 1; v >= 0; --v )
7845  {
7846  /* binary to binary implications will be collected when extrating cliques */
7847  if( !SCIPvarIsBinary(vars[v]) )
7848  {
7849  if( v != position )
7850  {
7851  if( vals[v] > 0 )
7852  {
7853  /* add implications */
7854  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_UPPER, SCIPvarGetLbGlobal(vars[v]), &infeasible, &nbdchgs) );
7855  ++nimpls;
7856  *nchgbds += nbdchgs;
7857  }
7858  else
7859  {
7860  /* add implications */
7861  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_LOWER, SCIPvarGetUbGlobal(vars[v]), &infeasible, &nbdchgs) );
7862  ++nimpls;
7863  *nchgbds += nbdchgs;
7864  }
7865 
7866  if( infeasible )
7867  {
7868  *cutoff = TRUE;
7869  break;
7870  }
7871  }
7872  }
7873  /* stop when reaching a 'real' binary variable because the variables are sorted after their type */
7874  else if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_BINARY )
7875  break;
7876  }
7877  }
7878 
7879  /* if the left hand side and the maximal activity are finite and changing the variable with the biggest
7880  * influence to their bound forces all other variables to be at their minimal contribution, we can add these
7881  * implications
7882  */
7883  if( finitelhs && finitemaxact && SCIPisEQ(scip, consdata->glbmaxactivity, consdata->lhs - maxabscontrib) )
7884  {
7885  for( v = nvars - 1; v >= 0; --v )
7886  {
7887  /* binary to binary implications will be collected when extrating cliques */
7888  if( !SCIPvarIsBinary(vars[v]) )
7889  {
7890  if( v != position )
7891  {
7892  if( vals[v] > 0 )
7893  {
7894  /* add implications */
7895  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_LOWER, SCIPvarGetUbGlobal(vars[v]), &infeasible, &nbdchgs) );
7896  ++nimpls;
7897  *nchgbds += nbdchgs;
7898  }
7899  else
7900  {
7901  /* add implications */
7902  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_UPPER, SCIPvarGetLbGlobal(vars[v]), &infeasible, &nbdchgs) );
7903  ++nimpls;
7904  *nchgbds += nbdchgs;
7905  }
7906 
7907  if( infeasible )
7908  {
7909  *cutoff = TRUE;
7910  break;
7911  }
7912  }
7913  }
7914  /* stop when reaching a 'real' binary variable because the variables are sorted after their type */
7915  else if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_BINARY )
7916  break;
7917  }
7918  }
7919 
7920  /* did we find some implications */
7921  if( nimpls > 0 )
7922  {
7923  SCIPdebugMsg(scip, "extracted %d implications from constraint %s which led to %d bound changes, %scutoff detetcted\n", nimpls, SCIPconsGetName(cons), *nchgbds - oldnchgbds, *cutoff ? "" : "no ");
7924 
7925  if( *cutoff )
7926  return SCIP_OKAY;
7927 
7928  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
7929  if( *nchgbds - oldnchgbds > 0 )
7930  {
7931  /* check for fixed variables */
7932  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
7933  if( *cutoff )
7934  return SCIP_OKAY;
7935 
7936  /* tighten variable's bounds */
7937  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
7938  if( *cutoff )
7939  return SCIP_OKAY;
7940 
7941  /* check for fixed variables */
7942  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
7943  if( *cutoff )
7944  return SCIP_OKAY;
7945  }
7946  }
7947  }
7948  }
7949 
7950  consdata->implsadded = TRUE;
7951  }
7952 
7953  /* check if we already added the cliques of this constraint */
7954  if( consdata->cliquesadded )
7955  return SCIP_OKAY;
7956 
7957  consdata->cliquesadded = TRUE;
7958  cliquenonzerosadded = 0;
7959  stopped = FALSE;
7960 
7961  /* sort variables by variable type */
7962  SCIP_CALL( consdataSort(scip, consdata) );
7963 
7964  nvars = consdata->nvars;
7965  vars = consdata->vars;
7966  vals = consdata->vals;
7967 
7968  /**@todo extract more cliques, implications and variable bounds from linear constraints */
7969 
7970  /* recompute activities if needed */
7971  if( !consdata->validactivities )
7972  consdataCalcActivities(scip, consdata);
7973  assert(consdata->validactivities);
7974 
7975  finitelhs = !SCIPisInfinity(scip, -consdata->lhs);
7976  finiterhs = !SCIPisInfinity(scip, consdata->rhs);
7977  finitenegminact = (consdata->glbminactivityneginf == 0 && consdata->glbminactivityneghuge == 0);
7978  finitenegmaxact = (consdata->glbmaxactivityneginf == 0 && consdata->maxactivityneghuge == 0);
7979  finiteposminact = (consdata->glbminactivityposinf == 0 && consdata->glbminactivityposhuge == 0);
7980  finiteposmaxact = (consdata->glbmaxactivityposinf == 0 && consdata->glbmaxactivityposhuge == 0);
7981  finiteminact = (finitenegminact && finiteposminact);
7982  finitemaxact = (finitenegmaxact && finiteposmaxact);
7983 
7984  /* 1. we wheck whether some variables do not fit together into this constraint and add the corresponding clique
7985  * information
7986  */
7987  if( (finiterhs || finitelhs) && (finitenegminact || finiteposminact || finitenegmaxact || finiteposmaxact) )
7988  {
7989  SCIP_VAR** binvars;
7990  SCIP_Real* binvarvals;
7991  int nposbinvars = 0;
7992  int nnegbinvars = 0;
7993  int allonebinary = 0;
7994 
7995  SCIP_CALL( SCIPallocBufferArray(scip, &binvars, nvars) );
7996  SCIP_CALL( SCIPallocBufferArray(scip, &binvarvals, nvars) );
7997 
7998  /* collect binary variables */
7999  for( i = 0; i < nvars; ++i )
8000  {
8001  if( SCIPvarIsBinary(vars[i]) )
8002  {
8003  assert(!SCIPisZero(scip, vals[i]));
8004 
8005  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8006  ++allonebinary;
8007 
8008  binvars[nposbinvars + nnegbinvars] = vars[i];
8009  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8010 
8011  if( SCIPisPositive(scip, vals[i]) )
8012  ++nposbinvars;
8013  else
8014  ++nnegbinvars;
8015 
8016  assert(nposbinvars + nnegbinvars <= nvars);
8017  }
8018  /* stop searching for binary variables, because the constraint data is sorted */
8019  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8020  break;
8021  }
8022  assert(nposbinvars + nnegbinvars <= nvars);
8023 
8024  /* setppc constraints will be handled later; we need at least two binary variables with same sign to extract
8025  * cliques
8026  */
8027  if( allonebinary < nvars && (nposbinvars >= 2 || nnegbinvars >= 2) )
8028  {
8029  SCIP_Real threshold;
8030  int oldnchgbds = *nchgbds;
8031  int nbdchgs;
8032  int jstart;
8033  int j;
8034 
8035  /* we need a valid minimal/maximal activity to add cliques */
8036  if( (finitenegminact || finiteposminact) && !consdata->validglbminact )
8037  {
8038  consdataRecomputeGlbMinactivity(scip, consdata);
8039  assert(consdata->validglbminact);
8040  }
8041 
8042  if( (finitenegmaxact || finiteposmaxact) && !consdata->validglbmaxact )
8043  {
8044  consdataRecomputeGlbMaxactivity(scip, consdata);
8045  assert(consdata->validglbmaxact);
8046  }
8047  assert(consdata->validglbminact || consdata->validglbmaxact);
8048 
8049  /* sort coefficients non-increasing to be faster in the clique search */
8050  SCIPsortDownRealPtr(binvarvals, (void**) binvars, nposbinvars + nnegbinvars);
8051 
8052  /* case a) */
8053  if( finiterhs && finitenegminact && nposbinvars >= 2 )
8054  {
8055  /* compute value that needs to be exceeded */
8056  threshold = consdata->rhs - consdata->glbminactivity;
8057 
8058  i = 0;
8059  j = i + 1;
8060 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8061  /* check that it is possible to choose binvar[i], otherwise it should have been fixed to zero */
8062  assert(SCIPisFeasLE(scip, binvarvals[i], threshold));
8063 #endif
8064  /* check if at least two variables are in a clique */
8065  if( SCIPisFeasGT(scip, binvarvals[i] + binvarvals[j], threshold) )
8066  {
8067  ++j;
8068  /* check for extending the clique */
8069  while( j < nposbinvars )
8070  {
8071  if( !SCIPisFeasGT(scip, binvarvals[j-1] + binvarvals[j], threshold) )
8072  break;
8073  ++j;
8074  }
8075  assert(j >= 2);
8076 
8077  /* add clique with at least two variables */
8078  SCIP_CALL( SCIPaddClique(scip, &(binvars[i]), NULL, j - i, FALSE, &infeasible, &nbdchgs) );
8079 
8080  if( infeasible )
8081  *cutoff = TRUE;
8082 
8083  *nchgbds += nbdchgs;
8084 
8085  cliquenonzerosadded += j;
8086  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8087  stopped = TRUE;
8088 
8089  /* exchange the last variable in the clique if possible and add all new ones */
8090  if( !stopped && !(*cutoff) && j < nposbinvars )
8091  {
8092  SCIP_VAR** clqvars;
8093  int lastfit = j - 2;
8094  assert(lastfit >= i);
8095 
8096  /* copy all 'main'-clique variables */
8097  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[i]), j - i) );
8098 
8099  /* iterate up to the end with j and up to the front with lastfit, and check for different cliques */
8100  while( lastfit >= i && j < nposbinvars )
8101  {
8102  /* check if two variables are in a clique */
8103  if( SCIPisFeasGT(scip, binvarvals[lastfit] + binvarvals[j], threshold) )
8104  {
8105  clqvars[lastfit + 1] = binvars[j];
8106 
8107  /* add clique with at least two variables */
8108  SCIP_CALL( SCIPaddClique(scip, clqvars, NULL, lastfit - i + 2, FALSE, &infeasible, &nbdchgs) );
8109 
8110  if( infeasible )
8111  {
8112  *cutoff = TRUE;
8113  break;
8114  }
8115 
8116  *nchgbds += nbdchgs;
8117 
8118  cliquenonzerosadded += (lastfit - i + 2);
8119  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8120  {
8121  stopped = TRUE;
8122  break;
8123  }
8124 
8125  ++j;
8126  }
8127  else
8128  --lastfit;
8129  }
8130 
8131  SCIPfreeBufferArray(scip, &clqvars);
8132  }
8133  }
8134  }
8135 
8136  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8137  if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8138  {
8139  /* check for fixed variables */
8140  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8141 
8142  if( !*cutoff )
8143  {
8144  /* tighten variable's bounds */
8145  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8146 
8147  if( !*cutoff )
8148  {
8149  /* check for fixed variables */
8150  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8151 
8152  if( !*cutoff )
8153  {
8154  /* sort variables by variable type */
8155  SCIP_CALL( consdataSort(scip, consdata) );
8156 
8157  /* recompute activities if needed */
8158  if( !consdata->validactivities )
8159  consdataCalcActivities(scip, consdata);
8160  assert(consdata->validactivities);
8161 
8162  nvars = consdata->nvars;
8163  vars = consdata->vars;
8164  vals = consdata->vals;
8165  nposbinvars = 0;
8166  nnegbinvars = 0;
8167  allonebinary = 0;
8168 
8169  /* update binary variables */
8170  for( i = 0; i < nvars; ++i )
8171  {
8172  if( SCIPvarIsBinary(vars[i]) )
8173  {
8174  assert(!SCIPisZero(scip, vals[i]));
8175 
8176  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8177  ++allonebinary;
8178 
8179  binvars[nposbinvars + nnegbinvars] = vars[i];
8180  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8181 
8182  if( SCIPisPositive(scip, vals[i]) )
8183  ++nposbinvars;
8184  else
8185  ++nnegbinvars;
8186 
8187  assert(nposbinvars + nnegbinvars <= nvars);
8188  }
8189  /* stop searching for binary variables, because the constraint data is sorted */
8190  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8191  break;
8192  }
8193  assert(nposbinvars + nnegbinvars <= nvars);
8194  }
8195  }
8196  }
8197 
8198  oldnchgbds = *nchgbds;
8199  }
8200 
8201  /* case b) */
8202  if( !stopped && !(*cutoff) && finitelhs && finiteposmaxact && nnegbinvars >= 2 )
8203  {
8204  /* compute value that needs to be deceeded */
8205  threshold = consdata->lhs - consdata->glbmaxactivity;
8206 
8207  i = nposbinvars + nnegbinvars - 1;
8208  j = i - 1;
8209 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8210  /* check that it is possible to choose binvar[i], otherwise it should have been fixed to zero */
8211  assert(SCIPisFeasGE(scip, binvarvals[i], threshold));
8212 #endif
8213  /* check if two variables are in a clique */
8214  if( SCIPisFeasLT(scip, binvarvals[i] + binvarvals[j], threshold) )
8215  {
8216  --j;
8217  /* check for extending the clique */
8218  while( j >= nposbinvars )
8219  {
8220  if( !SCIPisFeasLT(scip, binvarvals[j+1] + binvarvals[j], threshold) )
8221  break;
8222  --j;
8223  }
8224  jstart = j;
8225 
8226  assert(i - j >= 2);
8227  /* add clique with at least two variables */
8228  SCIP_CALL( SCIPaddClique(scip, &(binvars[j+1]), NULL, i - j, FALSE, &infeasible, &nbdchgs) );
8229 
8230  if( infeasible )
8231  *cutoff = TRUE;
8232 
8233  *nchgbds += nbdchgs;
8234 
8235  cliquenonzerosadded += (i - j);
8236  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8237  stopped = TRUE;
8238 
8239  /* exchange the last variable in the clique if possible and add all new ones */
8240  if( !stopped && !(*cutoff) && jstart >= nposbinvars )
8241  {
8242  SCIP_VAR** clqvars;
8243  int lastfit = jstart + 1;
8244  assert(lastfit < i);
8245 
8246  /* copy all 'main'-clique variables */
8247  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[lastfit]), i - j) );
8248  ++lastfit;
8249 
8250  /* iterate up to the front with j and up to the end with lastfit, and check for different cliques */
8251  while( lastfit <= i && j >= nposbinvars )
8252  {
8253  /* check if two variables are in a clique */
8254  if( SCIPisFeasLT(scip, binvarvals[lastfit] + binvarvals[j], threshold) )
8255  {
8256  assert(lastfit - jstart - 2 >= 0 && lastfit - jstart - 2 < i);
8257  clqvars[lastfit - jstart - 2] = binvars[j];
8258 
8259  assert(i - lastfit + 2 >= 2);
8260  /* add clique with at least two variables */
8261  SCIP_CALL( SCIPaddClique(scip, &(clqvars[lastfit - jstart - 2]), NULL, i - lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8262 
8263  if( infeasible )
8264  {
8265  *cutoff = TRUE;
8266  break;
8267  }
8268 
8269  *nchgbds += nbdchgs;
8270 
8271  cliquenonzerosadded += (i - lastfit + 2);
8272  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8273  {
8274  stopped = TRUE;
8275  break;
8276  }
8277 
8278  --j;
8279  }
8280  else
8281  ++lastfit;
8282  }
8283 
8284  SCIPfreeBufferArray(scip, &clqvars);
8285  }
8286  }
8287  }
8288 
8289  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8290  if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8291  {
8292  /* check for fixed variables */
8293  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8294 
8295  if( !*cutoff )
8296  {
8297  /* tighten variable's bounds */
8298  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8299 
8300  if( !*cutoff )
8301  {
8302  /* check for fixed variables */
8303  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8304 
8305  if( !*cutoff )
8306  {
8307  /* sort variables by variable type */
8308  SCIP_CALL( consdataSort(scip, consdata) );
8309 
8310  /* recompute activities if needed */
8311  if( !consdata->validactivities )
8312  consdataCalcActivities(scip, consdata);
8313  assert(consdata->validactivities);
8314 
8315  nvars = consdata->nvars;
8316  vars = consdata->vars;
8317  vals = consdata->vals;
8318  nposbinvars = 0;
8319  nnegbinvars = 0;
8320  allonebinary = 0;
8321 
8322  /* update binary variables */
8323  for( i = 0; i < nvars; ++i )
8324  {
8325  if( SCIPvarIsBinary(vars[i]) )
8326  {
8327  assert(!SCIPisZero(scip, vals[i]));
8328 
8329  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8330  ++allonebinary;
8331 
8332  binvars[nposbinvars + nnegbinvars] = vars[i];
8333  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8334 
8335  if( SCIPisPositive(scip, vals[i]) )
8336  ++nposbinvars;
8337  else
8338  ++nnegbinvars;
8339 
8340  assert(nposbinvars + nnegbinvars <= nvars);
8341  }
8342  /* stop searching for binary variables, because the constraint data is sorted */
8343  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8344  break;
8345  }
8346  assert(nposbinvars + nnegbinvars <= nvars);
8347  }
8348  }
8349  }
8350 
8351  oldnchgbds = *nchgbds;
8352  }
8353 
8354  /* case c) */
8355  if( !(*cutoff) && finiterhs && finiteminact && nnegbinvars >= 2 )
8356  {
8357  SCIP_Bool* values;
8358 
8359  /* initialize clique values array for adding a negated clique */
8360  SCIP_CALL( SCIPallocBufferArray(scip, &values, nnegbinvars) );
8361  BMSclearMemoryArray(values, nnegbinvars);
8362 
8363  /* compute value that needs to be exceeded */
8364  threshold = consdata->rhs - consdata->glbminactivity;
8365 
8366  i = nposbinvars + nnegbinvars - 1;
8367  j = i - 1;
8368 
8369 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8370  /* check if the variable should not have already been fixed to one */
8371  assert(!SCIPisFeasGT(scip, binvarvals[i], threshold));
8372 #endif
8373 
8374  if( SCIPisFeasGT(scip, -binvarvals[i] - binvarvals[j], threshold) )
8375  {
8376  --j;
8377  /* check for extending the clique */
8378  while( j >= nposbinvars )
8379  {
8380  if( !SCIPisFeasGT(scip, -binvarvals[j+1] - binvarvals[j], threshold) )
8381  break;
8382  --j;
8383  }
8384  jstart = j;
8385 
8386  assert(i - j >= 2);
8387  /* add negated clique with at least two variables */
8388  SCIP_CALL( SCIPaddClique(scip, &(binvars[j+1]), values, i - j, FALSE, &infeasible, &nbdchgs) );
8389 
8390  if( infeasible )
8391  *cutoff = TRUE;
8392 
8393  *nchgbds += nbdchgs;
8394 
8395  cliquenonzerosadded += (i - j);
8396  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8397  stopped = TRUE;
8398 
8399  /* exchange the last variable in the clique if possible and add all new ones */
8400  if( !stopped && !(*cutoff) && jstart >= nposbinvars )
8401  {
8402  SCIP_VAR** clqvars;
8403  int lastfit = j + 1;
8404  assert(lastfit < i);
8405 
8406  /* copy all 'main'-clique variables */
8407  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[lastfit]), i - j) );
8408  ++lastfit;
8409 
8410  /* iterate up to the front with j and up to the end with lastfit, and check for different cliques */
8411  while( lastfit <= i && j >= nposbinvars )
8412  {
8413  /* check if two variables are in a negated clique */
8414  if( SCIPisFeasGT(scip, -binvarvals[lastfit] - binvarvals[j], threshold) )
8415  {
8416  assert(lastfit - jstart - 2 >= 0 && lastfit - jstart - 2 < i);
8417  clqvars[lastfit - jstart - 2] = binvars[j];
8418 
8419  assert(i - lastfit + 2 >= 2);
8420  /* add clique with at least two variables */
8421  SCIP_CALL( SCIPaddClique(scip, &(clqvars[lastfit - jstart - 2]), values, i - lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8422 
8423  if( infeasible )
8424  {
8425  *cutoff = TRUE;
8426  break;
8427  }
8428 
8429  *nchgbds += nbdchgs;
8430 
8431  cliquenonzerosadded += (i - lastfit + 2);
8432  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8433  {
8434  stopped = TRUE;
8435  break;
8436  }
8437 
8438  --j;
8439  }
8440  else
8441  ++lastfit;
8442  }
8443 
8444  SCIPfreeBufferArray(scip, &clqvars);
8445  }
8446  }
8447 
8448  SCIPfreeBufferArray(scip, &values);
8449  }
8450 
8451  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8452  if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8453  {
8454  /* check for fixed variables */
8455  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8456 
8457  if( !*cutoff )
8458  {
8459  /* tighten variable's bounds */
8460  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8461 
8462  if( !*cutoff )
8463  {
8464  /* check for fixed variables */
8465  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8466 
8467  if( !*cutoff )
8468  {
8469  /* sort variables by variable type */
8470  SCIP_CALL( consdataSort(scip, consdata) );
8471 
8472  /* recompute activities if needed */
8473  if( !consdata->validactivities )
8474  consdataCalcActivities(scip, consdata);
8475  assert(consdata->validactivities);
8476 
8477  nvars = consdata->nvars;
8478  vars = consdata->vars;
8479  vals = consdata->vals;
8480  nposbinvars = 0;
8481  nnegbinvars = 0;
8482  allonebinary = 0;
8483 
8484  /* update binary variables */
8485  for( i = 0; i < nvars; ++i )
8486  {
8487  if( SCIPvarIsBinary(vars[i]) )
8488  {
8489  assert(!SCIPisZero(scip, vals[i]));
8490 
8491  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8492  ++allonebinary;
8493 
8494  binvars[nposbinvars + nnegbinvars] = vars[i];
8495  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8496 
8497  if( SCIPisPositive(scip, vals[i]) )
8498  ++nposbinvars;
8499  else
8500  ++nnegbinvars;
8501 
8502  assert(nposbinvars + nnegbinvars <= nvars);
8503  }
8504  /* stop searching for binary variables, because the constraint data is sorted */
8505  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8506  break;
8507  }
8508  assert(nposbinvars + nnegbinvars <= nvars);
8509  }
8510  }
8511  }
8512  }
8513 
8514  /* case d) */
8515  if( !stopped && !(*cutoff) && finitelhs && finitemaxact && nposbinvars >= 2 )
8516  {
8517  SCIP_Bool* values;
8518 
8519  /* initialize clique values array for adding a negated clique */
8520  SCIP_CALL( SCIPallocBufferArray(scip, &values, nposbinvars) );
8521  BMSclearMemoryArray(values, nposbinvars);
8522 
8523  /* compute value that needs to be exceeded */
8524  threshold = consdata->lhs - consdata->glbmaxactivity;
8525 
8526  i = 0;
8527  j = i + 1;
8528 
8529 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8530  /* check if the variable should not have already been fixed to one */
8531  assert(!SCIPisFeasLT(scip, -binvarvals[i], threshold));
8532 #endif
8533 
8534  if( SCIPisFeasLT(scip, -binvarvals[i] - binvarvals[j], threshold) )
8535  {
8536  ++j;
8537  /* check for extending the clique */
8538  while( j < nposbinvars )
8539  {
8540  if( !SCIPisFeasLT(scip, -binvarvals[j-1] - binvarvals[j], threshold) )
8541  break;
8542  ++j;
8543  }
8544  assert(j >= 2);
8545 
8546  /* add negated clique with at least two variables */
8547  SCIP_CALL( SCIPaddClique(scip, &(binvars[i]), values, j - i, FALSE, &infeasible, &nbdchgs) );
8548 
8549  if( infeasible )
8550  *cutoff = TRUE;
8551 
8552  *nchgbds += nbdchgs;
8553 
8554  cliquenonzerosadded += j;
8555  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8556  stopped = TRUE;
8557 
8558  /* exchange the last variable in the clique if possible and add all new ones */
8559  if( !stopped && !(*cutoff) && j < nposbinvars )
8560  {
8561  SCIP_VAR** clqvars;
8562  int lastfit = j - 2;
8563  assert(lastfit >= i);
8564 
8565  /* copy all 'main'-clique variables */
8566  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[i]), j - i) );
8567 
8568  /* iterate up to the end with j and up to the front with lastfit, and check for different cliques */
8569  while( lastfit >= i && j < nposbinvars )
8570  {
8571  /* check if two variables are in a negated clique */
8572  if( SCIPisFeasLT(scip, -binvarvals[lastfit] - binvarvals[j], threshold) )
8573  {
8574  clqvars[lastfit + 1] = binvars[j];
8575 
8576  /* add clique with at least two variables */
8577  SCIP_CALL( SCIPaddClique(scip, clqvars, values, lastfit - i + 2, FALSE, &infeasible, &nbdchgs) );
8578 
8579  if( infeasible )
8580  {
8581  *cutoff = TRUE;
8582  break;
8583  }
8584 
8585  *nchgbds += nbdchgs;
8586 
8587  cliquenonzerosadded += (lastfit - i + 2);
8588  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8589  break;
8590 
8591  ++j;
8592  }
8593  else
8594  --lastfit;
8595  }
8596 
8597  SCIPfreeBufferArray(scip, &clqvars);
8598  }
8599  }
8600 
8601  SCIPfreeBufferArray(scip, &values);
8602  }
8603  }
8604 
8605  SCIPfreeBufferArray(scip, &binvarvals);
8606  SCIPfreeBufferArray(scip, &binvars);
8607 
8608  if( *cutoff )
8609  return SCIP_OKAY;
8610  }
8611 
8612  /* 2. we only check if the constraint is a set packing / partitioning constraint */
8613 
8614  /* check if all variables are binary, if the coefficients are +1 or -1, and if the right hand side is equal
8615  * to 1 - number of negative coefficients, or if the left hand side is equal to number of positive coefficients - 1
8616  */
8617  nposcoefs = 0;
8618  nnegcoefs = 0;
8619  for( i = 0; i < nvars; ++i )
8620  {
8621  if( !SCIPvarIsBinary(vars[i]) )
8622  return SCIP_OKAY;
8623  else if( SCIPisEQ(scip, vals[i], +1.0) )
8624  nposcoefs++;
8625  else if( SCIPisEQ(scip, vals[i], -1.0) )
8626  nnegcoefs++;
8627  else
8628  return SCIP_OKAY;
8629  }
8630 
8631  lhsclique = SCIPisEQ(scip, consdata->lhs, (SCIP_Real)nposcoefs - 1.0);
8632  rhsclique = SCIPisEQ(scip, consdata->rhs, 1.0 - (SCIP_Real)nnegcoefs);
8633 
8634  if( lhsclique || rhsclique )
8635  {
8636  SCIP_Bool* values;
8637  int nbdchgs;
8638 
8639  SCIPdebugMsg(scip, "linear constraint <%s>: adding clique with %d vars (%d pos, %d neg)\n",
8640  SCIPconsGetName(cons), nvars, nposcoefs, nnegcoefs);
8641  SCIP_CALL( SCIPallocBufferArray(scip, &values, nvars) );
8642 
8643  for( i = 0; i < nvars; ++i )
8644  values[i] = (rhsclique == (vals[i] > 0.0));
8645 
8646  SCIP_CALL( SCIPaddClique(scip, vars, values, nvars, SCIPisEQ(scip, consdata->lhs, consdata->rhs), &infeasible, &nbdchgs) );
8647 
8648  if( infeasible )
8649  *cutoff = TRUE;
8650 
8651  *nchgbds += nbdchgs;
8652  SCIPfreeBufferArray(scip, &values);
8653  }
8654 
8655  return SCIP_OKAY;
8656 }
8657 
8658 /** tightens left and right hand side of constraint due to integrality */
8659 static
8661  SCIP* scip, /**< SCIP data structure */
8662  SCIP_CONS* cons, /**< linear constraint */
8663  int* nchgsides /**< pointer to count number of side changes */
8664  )
8665 {
8666  SCIP_CONSDATA* consdata;
8667  SCIP_Bool integral;
8668  int i;
8669 
8670  assert(scip != NULL);
8671  assert(cons != NULL);
8672  assert(nchgsides != NULL);
8673 
8674  consdata = SCIPconsGetData(cons);
8675  assert(consdata != NULL);
8676 
8677  if( !SCIPisIntegral(scip, consdata->lhs) || !SCIPisIntegral(scip, consdata->rhs) )
8678  {
8679  integral = TRUE;
8680  for( i = 0; i < consdata->nvars && integral; ++i )
8681  {
8682  integral = SCIPisIntegral(scip, consdata->vals[i])
8683  && (SCIPvarGetType(consdata->vars[i]) != SCIP_VARTYPE_CONTINUOUS);
8684  }
8685  if( integral )
8686  {
8687  SCIPdebugMsg(scip, "linear constraint <%s>: make sides integral: sides=[%.15g,%.15g]\n",
8688  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
8689  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisIntegral(scip, consdata->lhs) )
8690  {
8691  SCIP_CALL( chgLhs(scip, cons, SCIPfeasCeil(scip, consdata->lhs)) );
8692  if( !consdata->upgraded )
8693  (*nchgsides)++;
8694  }
8695  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisIntegral(scip, consdata->rhs) )
8696  {
8697  SCIP_CALL( chgRhs(scip, cons, SCIPfeasFloor(scip, consdata->rhs)) );
8698  if( !consdata->upgraded )
8699  (*nchgsides)++;
8700  }
8701  SCIPdebugMsg(scip, "linear constraint <%s>: new integral sides: sides=[%.15g,%.15g]\n",
8702  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
8703  }
8704  }
8705 
8706  return SCIP_OKAY;
8707 }
8708 
8709 /** tightens coefficients of binary, integer, and implicit integer variables due to activity bounds in presolving:
8710  * given an inequality lhs <= a*x + ai*xi <= rhs, with a non-continuous variable li <= xi <= ui
8711  * let minact := min{a*x + ai*xi}, maxact := max{a*x + ai*xi}
8712  * (i) ai >= 0:
8713  * if minact + ai >= lhs and maxact - ai <= rhs: (**)
8714  * - a deviation from the lower/upper bound of xi would make the left/right hand side redundant
8715  * - ai, lhs and rhs can be changed to have the same redundancy effect and the same results for
8716  * xi fixed to its bounds, but with a reduced ai and tightened sides to tighten the LP relaxation
8717  * - change coefficients:
8718  * ai' := max(lhs - minact, maxact - rhs)
8719  * lhs' := lhs - (ai - ai')*li
8720  * rhs' := rhs - (ai - ai')*ui
8721  * (ii) ai < 0:
8722  * if minact - ai >= lhs and maxact + ai <= rhs: (***)
8723  * - a deviation from the upper/lower bound of xi would make the left/right hand side redundant
8724  * - ai, lhs and rhs can be changed to have the same redundancy effect and the same results for
8725  * xi fixed to its bounds, but with a reduced ai and tightened sides to tighten the LP relaxation
8726  * - change coefficients:
8727  * ai' := min(rhs - maxact, minact - lhs)
8728  * lhs' := lhs - (ai - ai')*ui
8729  * rhs' := rhs - (ai - ai')*li
8730  *
8731  * We further try to remove redundant variable from the constraint;
8732  * Variables which fulfill conditions (**) or (***) are called surely non-redundant variables.
8733  * A deviation of only one from their bound makes the lhs/rhs feasible (i.e., redundant), even if all other
8734  * variables are set to their "worst" bound. If all variables which are not surely non-redundant cannot make
8735  * the lhs/rhs redundant, even if they are set to their "best" bound, they can be removed from the constraint.
8736  * 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
8737  * suffices to fulfill the inequality, whereas the x_i do not contribute to feasibility and can be removed.
8738  *
8739  * @todo use also some tightening procedures for (knapsack) constraints with non-integer coefficients, see
8740  * cons_knapsack.c the following methods detectRedundantVars() and tightenWeights()
8741  */
8742 static
8744  SCIP* scip, /**< SCIP data structure */
8745  SCIP_CONS* cons, /**< linear constraint */
8746  int* nchgcoefs, /**< pointer to count total number of changed coefficients */
8747  int* nchgsides /**< pointer to count number of side changes */
8748  )
8749 {
8750  SCIP_CONSDATA* consdata;
8751  SCIP_VAR* var;
8752  SCIP_Real minactivity; /* minimal value w.r.t. the variable's local bounds for the constraint's
8753  * activity, ignoring the coefficients contributing with infinite value */
8754  SCIP_Real maxactivity; /* maximal value w.r.t. the variable's local bounds for the constraint's
8755  * activity, ignoring the coefficients contributing with infinite value */
8756  SCIP_Bool minactisrelax; /* do huge finite values contribute to the minactivity? */
8757  SCIP_Bool maxactisrelax; /* do huge finite values contribute to the maxactivity? */
8758  SCIP_Real minleftactivity; /* minimal activity without surely non-redundant variables. */
8759  SCIP_Real maxleftactivity; /* maximal activity without surely non-redundant variables. */
8760  SCIP_Real aggrlhs; /* lhs without minimal activity of surely non-redundant variables. */
8761  SCIP_Real aggrrhs; /* rhs without maximal activity of surely non-redundant variables. */
8762  SCIP_Real lval; /* candidate for new value arising from considering the left hand side */
8763  SCIP_Real rval; /* candidate for new value arising from considering the left hand side */
8764  SCIP_Real val;
8765  SCIP_Real newval;
8766  SCIP_Real newlhs;
8767  SCIP_Real newrhs;
8768  SCIP_Real lb;
8769  SCIP_Real ub;
8770  int i;
8771 
8772  assert(scip != NULL);
8773  assert(cons != NULL);
8774  assert(nchgcoefs != NULL);
8775  assert(nchgsides != NULL);
8776 
8777  consdata = SCIPconsGetData(cons);
8778  assert(consdata != NULL);
8779 
8780  /* @todo Is this still needed with automatic recomputation of activities? */
8781  /* if the maximal coefficient is too large, recompute the activities */
8782  if( (consdata->validmaxabsval && consdata->maxabsval > MAXVALRECOMP)
8783  || (consdata->validminabsval && consdata->minabsval < MINVALRECOMP) )
8784  {
8785  consdataRecomputeMinactivity(scip, consdata);
8786  consdataRecomputeMaxactivity(scip, consdata);
8787  }
8788 
8789  /* get the minimal and maximal activity of the constraint */
8790  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
8791 
8792  minleftactivity = 0.0;
8793  maxleftactivity = 0.0;
8794 
8795  /* try to tighten each coefficient */
8796  i = 0;
8797  while( i < consdata->nvars )
8798  {
8799  var = consdata->vars[i];
8800 
8801  /* get coefficient and variable's bounds */
8802  lb = SCIPvarGetLbLocal(var);
8803  ub = SCIPvarGetUbLocal(var);
8804  val = consdata->vals[i];
8805  assert(!SCIPisZero(scip, val));
8806 
8807  /* check sign of coefficient */
8808  if( val >= 0.0 )
8809  {
8810  /* check, if a deviation from lower/upper bound would make lhs/rhs redundant */
8812  SCIPisGE(scip, minactivity + val, consdata->lhs) && SCIPisLE(scip, maxactivity - val, consdata->rhs) )
8813  {
8814  /* change coefficients:
8815  * ai' := max(lhs - minact, maxact - rhs)
8816  * lhs' := lhs - (ai - ai')*li
8817  * rhs' := rhs - (ai - ai')*ui
8818  */
8819 
8820  lval = consdata->lhs - minactivity;
8821  rval = maxactivity - consdata->rhs;
8822 
8823  /* Try to avoid cancellation, if there are only two variables */
8824  if( consdata->nvars == 2 )
8825  {
8826  SCIP_Real otherval;
8827  otherval = consdata->vals[1-i];
8828 
8829  if( !SCIPisInfinity(scip, -consdata->lhs) && consdata->minactivityneginf + consdata->minactivityneginf == 0 )
8830  {
8831  lval = consdata->lhs - val*lb;
8832  lval -= otherval > 0.0 ? otherval * SCIPvarGetLbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetUbLocal(consdata->vars[1-i]);
8833  }
8834 
8835  if( !SCIPisInfinity(scip,consdata->rhs) && consdata->maxactivityneginf + consdata->maxactivityneginf == 0 )
8836  {
8837  rval = val*ub - consdata->rhs;
8838  rval += otherval > 0.0 ? otherval * SCIPvarGetUbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetLbLocal(consdata->vars[1-i]);
8839  }
8840  }
8841 
8842  newval = MAX(lval, rval);
8843  assert(SCIPisSumRelLE(scip, newval, val));
8844 
8845  /* Try to avoid cancellation in computation of lhs/rhs */
8846  newlhs = consdata->lhs - val * lb;
8847  newlhs += newval * lb;
8848  newrhs = consdata->rhs - val * ub;
8849  newrhs += newval * ub;
8850 
8851  if( !SCIPisSumRelEQ(scip, newval, val) )
8852  {
8853  SCIPdebugMsg(scip, "linear constraint <%s>: change coefficient %+.15g<%s> to %+.15g<%s>, act=[%.15g,%.15g], side=[%.15g,%.15g]\n",
8854  SCIPconsGetName(cons), val, SCIPvarGetName(var), newval, SCIPvarGetName(var),
8855  minactivity, maxactivity, consdata->lhs, consdata->rhs);
8856 
8857  /* update the coefficient and the activity bounds */
8858  if( SCIPisZero(scip, newval) )
8859  {
8860  SCIP_CALL( delCoefPos(scip, cons, i) );
8861  i--;
8862  }
8863  else
8864  {
8865  SCIP_CALL( chgCoefPos(scip, cons, i, newval) );
8866  }
8867  (*nchgcoefs)++;
8868 
8869  /* get the new minimal and maximal activity of the constraint */
8870  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
8871 
8872  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisEQ(scip, newlhs, consdata->lhs) )
8873  {
8874  SCIPdebugMsg(scip, "linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
8875 
8876  SCIP_CALL( chgLhs(scip, cons, newlhs) );
8877  (*nchgsides)++;
8878  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
8879  }
8880 
8881  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisEQ(scip, newrhs, consdata->rhs) )
8882  {
8883  SCIPdebugMsg(scip, "linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
8884 
8885  SCIP_CALL( chgRhs(scip, cons, newrhs) );
8886  (*nchgsides)++;
8887  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
8888  }
8889  }
8890  }
8891  else
8892  {
8893  if( !SCIPisInfinity(scip, -minleftactivity) )
8894  {
8895  assert(!SCIPisInfinity(scip, val));
8896  assert(!SCIPisInfinity(scip, lb));
8897  if( SCIPisInfinity(scip, -lb) )
8898  minleftactivity = -SCIPinfinity(scip);
8899  else
8900  minleftactivity += val * lb;
8901  }
8902 
8903  if( !SCIPisInfinity(scip, maxleftactivity) )
8904  {
8905  assert(!SCIPisInfinity(scip, val));
8906  assert(!SCIPisInfinity(scip, -ub));
8907  if( SCIPisInfinity(scip,ub) )
8908  maxleftactivity = SCIPinfinity(scip);
8909  else
8910  maxleftactivity += val * ub;
8911  }
8912  }
8913  }
8914  else
8915  {
8916  /* check, if a deviation from lower/upper bound would make lhs/rhs redundant */
8918  SCIPisGE(scip, minactivity - val, consdata->lhs) && SCIPisLE(scip, maxactivity + val, consdata->rhs) )
8919  {
8920  /* change coefficients:
8921  * ai' := min(rhs - maxact, minact - lhs)
8922  * lhs' := lhs - (ai - ai')*ui
8923  * rhs' := rhs - (ai - ai')*li
8924  */
8925 
8926  lval = minactivity - consdata->lhs;
8927  rval = consdata->rhs - maxactivity;
8928 
8929  /* Try to avoid cancellation, if there are only two variables */
8930  if( consdata->nvars == 2 )
8931  {
8932  SCIP_Real otherval;
8933  otherval = consdata->vals[1-i];
8934 
8935  if( !SCIPisInfinity(scip,-consdata->lhs) && consdata->minactivityneginf + consdata->minactivityneginf == 0 )
8936  {
8937  lval = val*ub - consdata->lhs;
8938  lval += otherval > 0.0 ? otherval * SCIPvarGetLbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetUbLocal(consdata->vars[1-i]);
8939  }
8940 
8941  if( !SCIPisInfinity(scip,consdata->rhs) && consdata->maxactivityneginf + consdata->maxactivityneginf == 0 )
8942  {
8943  rval = consdata->rhs - val*lb;
8944  rval -= otherval > 0.0 ? otherval * SCIPvarGetUbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetLbLocal(consdata->vars[1-i]);
8945  }
8946  }
8947 
8948  newval = MIN(lval, rval);
8949  assert(SCIPisSumRelGE(scip, newval, val));
8950 
8951  /* Try to avoid cancellation in computation of lhs/rhs */
8952  newlhs = consdata->lhs - val * ub;
8953  newlhs += newval * ub;
8954  newrhs = consdata->rhs - val * lb;
8955  newrhs += newval * lb;
8956 
8957  if( !SCIPisSumRelEQ(scip, newval, val) )
8958  {
8959  SCIPdebugMsg(scip, "linear constraint <%s>: change coefficient %+.15g<%s> to %+.15g<%s>, act=[%.15g,%.15g], side=[%.15g,%.15g]\n",
8960  SCIPconsGetName(cons), val, SCIPvarGetName(var), newval, SCIPvarGetName(var),
8961  minactivity, maxactivity, consdata->lhs, consdata->rhs);
8962 
8963  /* update the coefficient and the activity bounds */
8964  if( SCIPisZero(scip, newval) )
8965  {
8966  SCIP_CALL( delCoefPos(scip, cons, i) );
8967  i--;
8968  }
8969  else
8970  {
8971  SCIP_CALL( chgCoefPos(scip, cons, i, newval) );
8972  }
8973  (*nchgcoefs)++;
8974 
8975  /* get the new minimal and maximal activity of the constraint */
8976  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
8977 
8978  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisEQ(scip, newlhs, consdata->lhs) )
8979  {
8980  SCIPdebugMsg(scip, "linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
8981 
8982  SCIP_CALL( chgLhs(scip, cons, newlhs) );
8983  (*nchgsides)++;
8984  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
8985  }
8986 
8987  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisEQ(scip, newrhs, consdata->rhs) )
8988  {
8989  SCIPdebugMsg(scip, "linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
8990 
8991  SCIP_CALL( chgRhs(scip, cons, newrhs) );
8992  (*nchgsides)++;
8993  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
8994  }
8995  }
8996  }
8997  else
8998  {
8999  if( !SCIPisInfinity(scip, -minleftactivity) )
9000  {
9001  assert(!SCIPisInfinity(scip, -val));
9002  assert(!SCIPisInfinity(scip, -ub));
9003  if( SCIPisInfinity(scip, ub) )
9004  minleftactivity = -SCIPinfinity(scip);
9005  else
9006  minleftactivity += val * ub;
9007  }
9008 
9009  if( !SCIPisInfinity(scip, maxleftactivity) )
9010  {
9011  assert(!SCIPisInfinity(scip, -val));
9012  assert(!SCIPisInfinity(scip, lb));
9013  if( SCIPisInfinity(scip, -lb) )
9014  maxleftactivity = SCIPinfinity(scip);
9015  else
9016  maxleftactivity += val * lb;
9017  }
9018  }
9019  }
9020  ++i;
9021  }
9022 
9023  SCIPdebugMsg(scip, "minleftactivity = %.15g, rhs = %.15g\n",
9024  minleftactivity, consdata->rhs);
9025  SCIPdebugMsg(scip, "maxleftactivity = %.15g, lhs = %.15g\n",
9026  maxleftactivity, consdata->lhs);
9027 
9028  /* minleft == \infty ==> minactivity == \infty */
9029  assert(!SCIPisInfinity(scip, -minleftactivity) || SCIPisInfinity(scip, -minactivity));
9030  assert(!SCIPisInfinity(scip, maxleftactivity) || SCIPisInfinity(scip, maxactivity));
9031 
9032  /* if the lhs is finite, we will check in the following whether the not non-redundant variables can make lhs feasible;
9033  * this is not valid, if the minactivity is -\infty (aggrlhs would be minus infinity in the following computation)
9034  * or if huge values contributed to the minactivity, because the minactivity is then just a relaxation
9035  * (<= the exact minactivity), and we might falsely claim variables to be redundant in the following
9036  */
9037  assert(!SCIPisInfinity(scip, minactivity));
9038  if( !SCIPisInfinity(scip, -consdata->lhs) && (SCIPisInfinity(scip, -minactivity) || minactisrelax) )
9039  return SCIP_OKAY;
9040 
9041  /* if the rhs is finite, we will check in the following whether the not non-redundant variables can make rhs feasible;
9042  * this is not valid, if the maxactivity is \infty (aggrrhs would be infinity in the following computation)
9043  * or if huge values contributed to the maxactivity, because the maxactivity is then just a relaxation
9044  * (>= the exact maxactivity), and we might falsely claim variables to be redundant in the following
9045  */
9046  assert(!SCIPisInfinity(scip, -maxactivity));
9047  if( !SCIPisInfinity(scip, consdata->rhs) && (SCIPisInfinity(scip, maxactivity) || maxactisrelax) )
9048  return SCIP_OKAY;
9049 
9050  /* correct lhs and rhs by min/max activity of surely non-redundant variables
9051  * surely non-redundant variables are all those where a deviation from the bound makes the lhs/rhs redundant
9052  */
9053  aggrlhs = consdata->lhs - minactivity + minleftactivity;
9054  aggrrhs = consdata->rhs - maxactivity + maxleftactivity;
9055 
9056  /* check if the constraint contains variables which are redundant. The reasoning is the following:
9057  * Each non-redundant variable can make the lhs/rhs feasible with a deviation of only one in the bound.
9058  * If _all_ variables which are not non-redundant together cannot make lhs/rhs feasible,
9059  * they can be removed from the constraint.
9060  * aggrrhs may contain some near-infinity value, but only if rhs is infinity.
9061  */
9062  if( (SCIPisInfinity(scip, -consdata->lhs) || SCIPisFeasLT(scip, maxleftactivity, aggrlhs))
9063  && (SCIPisInfinity(scip, consdata->rhs) || SCIPisFeasGT(scip, minleftactivity, aggrrhs)) )
9064  {
9065  SCIP_Real minleftactivitypart;
9066  SCIP_Real maxleftactivitypart;
9067 
9068  assert(!SCIPisInfinity(scip, -consdata->lhs) || !SCIPisInfinity(scip, consdata->rhs));
9069 
9070  /* try to remove redundant variables from constraint */
9071  i = 0;
9072  while( i < consdata->nvars )
9073  {
9074  var = consdata->vars[i];
9075  minleftactivitypart = 0.0;
9076  maxleftactivitypart = 0.0;
9077  lb = SCIPvarGetLbLocal(var);
9078  ub = SCIPvarGetUbLocal(var);
9079 
9080  /* get coefficient and variable's bounds */
9081  val = consdata->vals[i];
9082  assert(!SCIPisZero(scip, val));
9083 
9084  /* check sign of coefficient */
9085  if( val >= 0.0 )
9086  {
9087  /* negation of condition above in case of positive val */
9088  if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS ||
9089  SCIPisLT(scip, minactivity + val, consdata->lhs) || SCIPisGT(scip, maxactivity - val, consdata->rhs) )
9090  {
9091  SCIPdebugMsg(scip, "minactivity = %g\tval = %g\tlhs = %g\n", minactivity, val, consdata->lhs);
9092  SCIPdebugMsg(scip, "maxactivity = %g\tval = %g\trhs = %g\n", maxactivity, val, consdata->rhs);
9093  SCIPdebugMsg(scip, "linear constraint <%s>: remove variable <%s> with coefficient <%g> from constraint since it is redundant\n",
9094  SCIPconsGetName(cons), SCIPvarGetName(consdata->vars[i]), val);
9095 
9096  minleftactivitypart = val * lb;
9097  maxleftactivitypart = val * ub;
9098 
9099  SCIP_CALL( delCoefPos(scip, cons, i) );
9100  i--;
9101 
9102  /* get the new minimal and maximal activity of the constraint */
9103  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
9104 
9105  /* we return above if the condition does not hold and deleting a variable cannot increase the number of
9106  * huge contributions
9107  */
9108  assert(!minactisrelax || SCIPisInfinity(scip, -consdata->lhs));
9109  assert(!maxactisrelax || SCIPisInfinity(scip, consdata->rhs));
9110  }
9111  }
9112  else
9113  {
9114  /* negation of condition above in case of negative val */
9115  if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS ||
9116  SCIPisLT(scip, minactivity - val, consdata->lhs) || SCIPisGT(scip, maxactivity + val, consdata->rhs) )
9117  {
9118  SCIPdebugMsg(scip, "linear constraint <%s>: remove variable <%s> with coefficient <%g> from constraint since it is redundant\n",
9119  SCIPconsGetName(cons), SCIPvarGetName(consdata->vars[i]), val);
9120 
9121  minleftactivitypart = val * ub;
9122  maxleftactivitypart = val * lb;
9123 
9124  SCIP_CALL( delCoefPos(scip, cons, i) );
9125  i--;
9126 
9127  /* get the new minimal and maximal activity of the constraint */
9128  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
9129 
9130  /* we return above if the condition does not hold and deleting a variable cannot increase the number of
9131  * huge contributions
9132  */
9133  assert(!minactisrelax || SCIPisInfinity(scip, -consdata->lhs));
9134  assert(!maxactisrelax || SCIPisInfinity(scip, consdata->rhs));
9135  }
9136  }
9137 
9138  /* the following update step is needed in every iteration cause otherwise it is possible that the surely none-
9139  * redundant variables could get deleted,
9140  * e.g. y_1 + 16y_2 >= 25, y1 with bounds [9,12], y2 with bounds [0,2], minactivity would be 9, it follows that
9141  * y_2 is surely not redundant and y_1 is redundant so we would first delete y1 and without updating the sides
9142  * we would also delete y2 and as a result we would have gotten infeasibility */
9143  /* adjust lhs and right hand side */
9144  newlhs = consdata->lhs - minleftactivitypart;
9145  newrhs = consdata->rhs - maxleftactivitypart;
9146 
9147  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisFeasEQ(scip, newlhs, consdata->lhs) )
9148  {
9149  SCIPdebugMsg(scip, "linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
9150  SCIP_CALL( chgLhs(scip, cons, newlhs) );
9151  ++(*nchgsides);
9152  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
9153  }
9154  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisFeasEQ(scip, newrhs, consdata->rhs) )
9155  {
9156  SCIPdebugMsg(scip, "linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
9157  SCIP_CALL( chgRhs(scip, cons, newrhs) );
9158  ++(*nchgsides);
9159  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
9160  }
9161  ++i;
9162  }
9163  }
9164 
9165  return SCIP_OKAY;
9166 }
9167 
9168 /* processes equality with only one variable by fixing the variable and deleting the constraint */
9169 static
9171  SCIP* scip, /**< SCIP data structure */
9172  SCIP_CONS* cons, /**< linear constraint */
9173  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
9174  int* nfixedvars, /**< pointer to count number of fixed variables */
9175  int* ndelconss /**< pointer to count number of deleted constraints */
9176  )
9177 {
9178  SCIP_CONSDATA* consdata;
9179  SCIP_VAR* var;
9180  SCIP_Real val;
9181  SCIP_Real fixval;
9182  SCIP_Bool infeasible;
9183  SCIP_Bool fixed;
9184 
9185  assert(scip != NULL);
9186  assert(cons != NULL);
9187  assert(cutoff != NULL);
9188  assert(nfixedvars != NULL);
9189  assert(ndelconss != NULL);
9190 
9191  consdata = SCIPconsGetData(cons);
9192  assert(consdata != NULL);
9193  assert(consdata->nvars == 1);
9194  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9195 
9196  /* calculate the value to fix the variable to */
9197  var = consdata->vars[0];
9198  val = consdata->vals[0];
9199  assert(!SCIPisZero(scip, val));
9200  fixval = SCIPselectSimpleValue(consdata->lhs/val - 0.9 * SCIPepsilon(scip),
9201  consdata->rhs/val + 0.9 * SCIPepsilon(scip), MAXDNOM);
9202  SCIPdebugMsg(scip, "linear equality <%s>: fix <%s> == %.15g\n",
9203  SCIPconsGetName(cons), SCIPvarGetName(var), fixval);
9204 
9205  /* fix variable */
9206  SCIP_CALL( SCIPfixVar(scip, var, fixval, &infeasible, &fixed) );
9207  if( infeasible )
9208  {
9209  SCIPdebugMsg(scip, " -> infeasible fixing\n");
9210  *cutoff = TRUE;
9211  return SCIP_OKAY;
9212  }
9213  if( fixed )
9214  (*nfixedvars)++;
9215 
9216  /* disable constraint */
9217  SCIP_CALL( SCIPdelCons(scip, cons) );
9218  if( !consdata->upgraded )
9219  (*ndelconss)++;
9220 
9221  return SCIP_OKAY;
9222 }
9223 
9224 /* processes equality with exactly two variables by aggregating one of the variables and deleting the constraint */
9225 static
9227  SCIP* scip, /**< SCIP data structure */
9228  SCIP_CONS* cons, /**< linear constraint */
9229  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
9230  int* naggrvars, /**< pointer to count number of aggregated variables */
9231  int* ndelconss /**< pointer to count number of deleted constraints */
9232  )
9233 {
9234  SCIP_CONSDATA* consdata;
9235  SCIP_Bool infeasible;
9236  SCIP_Bool redundant;
9237  SCIP_Bool aggregated;
9238 
9239  assert(scip != NULL);
9240  assert(cons != NULL);
9241  assert(cutoff != NULL);
9242  assert(naggrvars != NULL);
9243  assert(ndelconss != NULL);
9244 
9245  consdata = SCIPconsGetData(cons);
9246  assert(consdata != NULL);
9247  assert(consdata->nvars == 2);
9248  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9249 
9250  SCIPdebugMsg(scip, "linear constraint <%s>: aggregate %.15g<%s> + %.15g<%s> == %.15g\n",
9251  SCIPconsGetName(cons), consdata->vals[0], SCIPvarGetName(consdata->vars[0]),
9252  consdata->vals[1], SCIPvarGetName(consdata->vars[1]), consdata->rhs);
9253 
9254  /* aggregate the equality */
9255  SCIP_CALL( SCIPaggregateVars(scip, consdata->vars[0], consdata->vars[1], consdata->vals[0], consdata->vals[1],
9256  consdata->rhs, &infeasible, &redundant, &aggregated) );
9257 
9258  /* check for infeasibility of aggregation */
9259  if( infeasible )
9260  {
9261  SCIPdebugMsg(scip, " -> infeasible aggregation\n");
9262  *cutoff = TRUE;
9263  return SCIP_OKAY;
9264  }
9265 
9266  /* count the aggregation */
9267  if( aggregated )
9268  (*naggrvars)++;
9269 
9270  /* delete the constraint, if it is redundant */
9271  if( redundant )
9272  {
9273  SCIP_CALL( SCIPdelCons(scip, cons) );
9274 
9275  if( !consdata->upgraded )
9276  (*ndelconss)++;
9277  }
9278 
9279  return SCIP_OKAY;
9280 }
9281 
9282 /** calculates the new lhs and rhs of the constraint after the given variable is aggregated out */
9283 static
9285  SCIP* scip, /**< SCIP data structure */
9286  SCIP_CONSDATA* consdata, /**< linear constraint data */
9287  SCIP_VAR* slackvar, /**< variable to be aggregated out */
9288  SCIP_Real slackcoef, /**< coefficient of variable in constraint */
9289  SCIP_Real* newlhs, /**< pointer to store new lhs of constraint */
9290  SCIP_Real* newrhs /**< pointer to store new rhs of constraint */
9291  )
9292 {
9293  SCIP_Real slackvarlb;
9294  SCIP_Real slackvarub;
9295 
9296  assert(scip != NULL);
9297  assert(consdata != NULL);
9298  assert(newlhs != NULL);
9299  assert(newrhs != NULL);
9300  assert(!SCIPisInfinity(scip, -consdata->lhs));
9301  assert(!SCIPisInfinity(scip, consdata->rhs));
9302 
9303  slackvarlb = SCIPvarGetLbGlobal(slackvar);
9304  slackvarub = SCIPvarGetUbGlobal(slackvar);
9305  if( slackcoef > 0.0 )
9306  {
9307  if( SCIPisInfinity(scip, -slackvarlb) )
9308  *newrhs = SCIPinfinity(scip);
9309  else
9310  *newrhs = consdata->rhs - slackcoef * slackvarlb;
9311  if( SCIPisInfinity(scip, slackvarub) )
9312  *newlhs = -SCIPinfinity(scip);
9313  else
9314  *newlhs = consdata->lhs - slackcoef * slackvarub;
9315  }
9316  else
9317  {
9318  if( SCIPisInfinity(scip, -slackvarlb) )
9319  *newlhs = -SCIPinfinity(scip);
9320  else
9321  *newlhs = consdata->rhs - slackcoef * slackvarlb;
9322  if( SCIPisInfinity(scip, slackvarub) )
9323  *newrhs = SCIPinfinity(scip);
9324  else
9325  *newrhs = consdata->lhs - slackcoef * slackvarub;
9326  }
9327  assert(SCIPisLE(scip, *newlhs, *newrhs));
9328 }
9329 
9330 #define MAXMULTIAGGRQUOTIENT 1e+03
9331 
9332 /* processes equality with more than two variables by multi-aggregating one of the variables and converting the equality
9333  * into an inequality; if multi-aggregation is not possible, tries to identify one continuous or integer variable that
9334  * is implicitly integral by this constraint
9335  *
9336  * @todo Check whether a more clever way of avoiding aggregation of variables containing implicitly integer variables
9337  * can help.
9338  */
9339 static
9341  SCIP* scip, /**< SCIP data structure */
9342  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
9343  SCIP_CONS* cons, /**< linear constraint */
9344  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
9345  int* naggrvars, /**< pointer to count number of aggregated variables */
9346  int* ndelconss /**< pointer to count number of deleted constraints */
9347  )
9348 {
9349  SCIP_CONSDATA* consdata;
9350  SCIP_VAR** vars;
9351  SCIP_Real* vals;
9352  SCIP_VARTYPE bestslacktype;
9353  SCIP_VARTYPE slacktype;
9354  SCIP_Real lhs;
9355  SCIP_Real rhs;
9356  SCIP_Real bestslackdomrng;
9357  SCIP_Real minabsval;
9358  SCIP_Real maxabsval;
9359  SCIP_Bool bestremovescons;
9360  SCIP_Bool coefszeroone;
9361  SCIP_Bool coefsintegral;
9362  SCIP_Bool varsintegral;
9363  SCIP_Bool infeasible;
9364  SCIP_Bool samevar;
9365  int supinf; /* counter for infinite contributions to the supremum of a possible
9366  * multi-aggregation
9367  */
9368  int infinf; /* counter for infinite contributions to the infimum of a possible
9369  * multi-aggregation
9370  */
9371  int maxnlocksstay;
9372  int maxnlocksremove;
9373  int bestslackpos;
9374  int bestnlocks;
9375  int ncontvars;
9376  int contvarpos;
9377  int nintvars;
9378  int nimplvars;
9379  int intvarpos;
9380  int v;
9381 
9382  assert(scip != NULL);
9383  assert(cons != NULL);
9384  assert(cutoff != NULL);
9385  assert(naggrvars != NULL);
9386 
9387  consdata = SCIPconsGetData(cons);
9388  assert(consdata != NULL);
9389  assert(consdata->nvars > 2);
9390  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9391 
9392  SCIPdebugMsg(scip, "linear constraint <%s>: try to multi-aggregate equality\n", SCIPconsGetName(cons));
9393 
9394  /* We do not want to increase the total number of non-zeros due to the multi-aggregation.
9395  * Therefore, we have to restrict the number of locks of a variable that is aggregated out.
9396  * maxnlocksstay: maximal sum of lock numbers if the constraint does not become redundant after the aggregation
9397  * maxnlocksremove: maximal sum of lock numbers if the constraint can be deleted after the aggregation
9398  */
9399  lhs = consdata->lhs;
9400  rhs = consdata->rhs;
9401  maxnlocksstay = 0;
9402  if( consdata->nvars == 3 )
9403  {
9404  /* If the constraint becomes redundant, 3 non-zeros are removed, and we get 1 additional non-zero for each
9405  * constraint the variable appears in. Thus, the variable must appear in at most 3 other constraints.
9406  */
9407  maxnlocksremove = 3;
9408  }
9409  else if( consdata->nvars == 4 )
9410  {
9411  /* If the constraint becomes redundant, 4 non-zeros are removed, and we get 2 additional non-zeros for each
9412  * constraint the variable appears in. Thus, the variable must appear in at most 2 other constraints.
9413  */
9414  maxnlocksremove = 2;
9415  }
9416  else
9417  {
9418  /* If the constraint is redundant but has more than 4 variables, we can only accept one other constraint. */
9419  maxnlocksremove = 1;
9420  }
9421 
9422  /* the locks on this constraint can be ignored */
9423  if( SCIPconsIsChecked(cons) )
9424  {
9425  if( !SCIPisInfinity(scip, -lhs) )
9426  {
9427  maxnlocksstay++;
9428  maxnlocksremove++;
9429  }
9430  if( !SCIPisInfinity(scip, rhs) )
9431  {
9432  maxnlocksstay++;
9433  maxnlocksremove++;
9434  }
9435  }
9436 
9437  /* look for a slack variable s to convert a*x + s == b into lhs <= a*x <= rhs */
9438  vars = consdata->vars;
9439  vals = consdata->vals;
9440  bestslackpos = -1;
9441  bestslacktype = SCIP_VARTYPE_BINARY;
9442  bestnlocks = INT_MAX;
9443  bestremovescons = FALSE;
9444  bestslackdomrng = 0.0;
9445  coefszeroone = TRUE;
9446  coefsintegral = TRUE;
9447  varsintegral = TRUE;
9448  ncontvars = 0;
9449  contvarpos = -1;
9450  nintvars = 0;
9451  nimplvars = 0;
9452  intvarpos = -1;
9453  minabsval = SCIPinfinity(scip);
9454  maxabsval = -1.0;
9455  for( v = 0; v < consdata->nvars; ++v )
9456  {
9457  SCIP_VAR* var;
9458  SCIP_Real val;
9459  SCIP_Real absval;
9460  SCIP_Real varlb;
9461  SCIP_Real varub;
9462  SCIP_Bool iscont;
9463  int nlocks;
9464 
9465  assert(vars != NULL);
9466  assert(vals != NULL);
9467 
9468  var = vars[v];
9469  assert(!SCIPconsIsChecked(cons) || SCIPvarGetNLocksDown(var) >= 1); /* because variable is locked in this equality */
9470  assert(!SCIPconsIsChecked(cons) || SCIPvarGetNLocksUp(var) >= 1);
9471  varlb = SCIPvarGetLbGlobal(var);
9472  varub = SCIPvarGetUbGlobal(var);
9473 
9474  val = vals[v];
9475  absval = REALABS(val);
9476  assert(SCIPisPositive(scip, absval));
9477 
9478  /* calculate minimal and maximal absolute value */
9479  if( absval < minabsval )
9480  minabsval = absval;
9481  if( absval > maxabsval )
9482  maxabsval = absval;
9483 
9484  /* do not try to multi aggregate, when numerical bad */
9485  if( maxabsval / minabsval > MAXMULTIAGGRQUOTIENT )
9486  return SCIP_OKAY;
9487 
9488  slacktype = SCIPvarGetType(var);
9489  coefszeroone = coefszeroone && SCIPisEQ(scip, absval, 1.0);
9490  coefsintegral = coefsintegral && SCIPisIntegral(scip, val);
9491  varsintegral = varsintegral && (slacktype != SCIP_VARTYPE_CONTINUOUS);
9492  iscont = (slacktype == SCIP_VARTYPE_CONTINUOUS || slacktype == SCIP_VARTYPE_IMPLINT);
9493 
9494  /* update candidates for continuous -> implint and integer -> implint conversion */
9495  if( slacktype == SCIP_VARTYPE_CONTINUOUS )
9496  {
9497  ncontvars++;
9498  contvarpos = v;
9499  }
9500  else if( slacktype == SCIP_VARTYPE_IMPLINT )
9501  {
9502  ++nimplvars;
9503  }
9504  else if( slacktype == SCIP_VARTYPE_INTEGER )
9505  {
9506  nintvars++;
9507  intvarpos = v;
9508  }
9509 
9510  /* check, if variable is already fixed or aggregated */
9511  if( !SCIPvarIsActive(var) )
9512  continue;
9513 
9514  /* check, if variable is used in too many other constraints, even if this constraint could be deleted */
9515  nlocks = SCIPvarGetNLocksDown(var) + SCIPvarGetNLocksUp(var);
9516 
9517  if( nlocks > maxnlocksremove )
9518  continue;
9519 
9520  /* check, if variable can be used as a slack variable */
9521  if( (iscont || (coefsintegral && varsintegral && SCIPisEQ(scip, absval, 1.0))) &&
9522  !SCIPdoNotMultaggrVar(scip, var) )
9523  {
9524  SCIP_Bool better;
9525  SCIP_Bool equal;
9526  SCIP_Real slackdomrng;
9527 
9528  if( SCIPisInfinity(scip, varub) || SCIPisInfinity(scip, -varlb) )
9529  slackdomrng = SCIPinfinity(scip);
9530  /* we do not want to perform multi-aggregation due to numerics, if the bounds are huge */
9531  else if( SCIPisHugeValue(scip, varub) || SCIPisHugeValue(scip, -varlb) )
9532  return SCIP_OKAY;
9533  else
9534  {
9535  slackdomrng = (varub - varlb)*absval;
9536  assert(!SCIPisInfinity(scip, slackdomrng));
9537  }
9538  equal = FALSE;
9539  better = (slacktype > bestslacktype) || (bestslackpos == -1);
9540  if( !better && slacktype == bestslacktype )
9541  {
9542  better = (nlocks < bestnlocks);
9543  if( nlocks == bestnlocks && !bestremovescons )
9544  {
9545  better = SCIPisGT(scip, slackdomrng, bestslackdomrng);
9546  equal = !better && SCIPisGE(scip, slackdomrng, bestslackdomrng);
9547  }
9548  }
9549 
9550  if( better || equal )
9551  {
9552  SCIP_Real minresactivity;
9553  SCIP_Real maxresactivity;
9554  SCIP_Real newlhs;
9555  SCIP_Real newrhs;
9556  SCIP_Bool removescons;
9557  SCIP_Bool minisrelax;
9558  SCIP_Bool maxisrelax;
9559  SCIP_Bool isminsettoinfinity;
9560  SCIP_Bool ismaxsettoinfinity;
9561 
9562  /* check if the constraint becomes redundant after multi-aggregation */
9563  consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
9564  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
9565 
9566  /* do not perform the multi-aggregation due to numerics, if we have huge contributions in the residual
9567  * activity
9568  */
9569  if( minisrelax || maxisrelax )
9570  continue;
9571 
9572  getNewSidesAfterAggregation(scip, consdata, var, val, &newlhs, &newrhs);
9573  removescons = (SCIPisFeasLE(scip, newlhs, minresactivity) && SCIPisFeasLE(scip, maxresactivity, newrhs));
9574 
9575  /* check resactivities for reliability */
9576  if( removescons )
9577  {
9578  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
9579  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
9580 
9581  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity)
9582  && SCIPisFeasLE(scip, newlhs, minresactivity))
9583  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
9584 
9585  removescons = (SCIPisFeasLE(scip, newlhs, minresactivity) && SCIPisFeasLE(scip, maxresactivity, newrhs));
9586  }
9587 
9588  /* if parameter multaggrremove is set to TRUE, only aggregate when this removes constraint */
9589  if( conshdlrdata->multaggrremove && !removescons )
9590  continue;
9591 
9592  /* prefer variables that make the constraints redundant */
9593  if( bestremovescons && !removescons )
9594  continue;
9595 
9596  /* if the constraint does not become redundant, only accept the variable if it does not appear in
9597  * other constraints
9598  */
9599  if( !removescons && nlocks > maxnlocksstay )
9600  continue;
9601 
9602  better = better || (!bestremovescons && removescons);
9603  if( better )
9604  {
9605  bestslackpos = v;
9606  bestslacktype = slacktype;
9607  bestnlocks = nlocks;
9608  bestslackdomrng = slackdomrng;
9609  bestremovescons = removescons;
9610  }
9611  }
9612  }
9613  }
9614 
9615  /* if all coefficients and variables are integral, the right hand side must also be integral */
9616  if( coefsintegral && varsintegral && !SCIPisFeasIntegral(scip, consdata->rhs) )
9617  {
9618  SCIPdebugMsg(scip, "linear equality <%s> is integer infeasible\n", SCIPconsGetName(cons));
9619  SCIPdebugPrintCons(scip, cons, NULL);
9620  *cutoff = TRUE;
9621  return SCIP_OKAY;
9622  }
9623 
9624  supinf = 0;
9625  infinf = 0;
9626  samevar = FALSE;
9627 
9628  /* check whether the the infimum and the supremum of the multi-aggregation can be get infinite */
9629  for( v = 0; v < consdata->nvars; ++v )
9630  {
9631  if( v != bestslackpos )
9632  {
9633  if( SCIPisPositive(scip, consdata->vals[v]) )
9634  {
9635  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
9636  {
9637  ++supinf;
9638  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
9639  {
9640  ++infinf;
9641  samevar = TRUE;
9642  }
9643  }
9644  else if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
9645  ++infinf;
9646 
9647  }
9648  else if( SCIPisNegative(scip, consdata->vals[v]) )
9649  {
9650  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
9651  {
9652  ++supinf;
9653  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
9654  {
9655  ++infinf;
9656  samevar = TRUE;
9657  }
9658  }
9659  else if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
9660  ++infinf;
9661  }
9662  }
9663  }
9664  assert(!samevar || (supinf > 0 && infinf > 0));
9665 
9666  /* If the infimum and the supremum of a multi-aggregation are both infinite, then the multi-aggregation might not be resolvable.
9667  * E.g., consider the equality z = x-y. If x and y are both fixed to +infinity, the value for z is not determined */
9668  if( (samevar && (supinf > 1 || infinf > 1)) || (!samevar && supinf > 0 && infinf > 0) )
9669  {
9670  SCIPdebugMsg(scip, "do not perform multi-aggregation: infimum and supremum are both infinite\n");
9671  return SCIP_OKAY;
9672  }
9673 
9674  /* if the slack variable is of integer type, and the constraint itself may take fractional values,
9675  * we cannot aggregate the variable, because the integrality condition would get lost
9676  * Similarly, if there are implicitly integral variables we cannot aggregate, since we might
9677  * loose the integrality condition for this variable.
9678  */
9679  if( bestslackpos >= 0
9680  && (bestslacktype == SCIP_VARTYPE_CONTINUOUS || bestslacktype == SCIP_VARTYPE_IMPLINT
9681  || (coefsintegral && varsintegral && nimplvars == 0)) )
9682  {
9683  SCIP_VAR* slackvar;
9684  SCIP_Real* scalars;
9685  SCIP_Real slackcoef;
9686  SCIP_Real aggrconst;
9687  SCIP_Real newlhs;
9688  SCIP_Real newrhs;
9689  SCIP_Bool aggregated;
9690 
9691  /* we found a slack variable that only occurs in at most one other constraint:
9692  * a_1*x_1 + ... + a_k*x_k + a'*s == rhs -> s == rhs - a_1/a'*x_1 - ... - a_k/a'*x_k
9693  */
9694  assert(bestslackpos < consdata->nvars);
9695 
9696  /* do not multi aggregate binary variables */
9697  if( SCIPvarIsBinary(vars[bestslackpos]) )
9698  return SCIP_OKAY;
9699 
9700  /* convert equality into inequality by deleting the slack variable:
9701  * x + a*s == b, l <= s <= u -> b - a*u <= x <= b - a*l
9702  */
9703  slackvar = vars[bestslackpos];
9704  slackcoef = vals[bestslackpos];
9705  assert(!SCIPisZero(scip, slackcoef));
9706  aggrconst = consdata->rhs/slackcoef;
9707 
9708  getNewSidesAfterAggregation(scip, consdata, slackvar, slackcoef, &newlhs, &newrhs);
9709  assert(SCIPisLE(scip, newlhs, newrhs));
9710  SCIP_CALL( chgLhs(scip, cons, newlhs) );
9711  SCIP_CALL( chgRhs(scip, cons, newrhs) );
9712  SCIP_CALL( delCoefPos(scip, cons, bestslackpos) );
9713 
9714  /* allocate temporary memory */
9715  SCIP_CALL( SCIPallocBufferArray(scip, &scalars, consdata->nvars) );
9716 
9717  /* set up the multi-aggregation */
9718  SCIPdebugMsg(scip, "linear constraint <%s>: multi-aggregate <%s> ==", SCIPconsGetName(cons), SCIPvarGetName(slackvar));
9719  for( v = 0; v < consdata->nvars; ++v )
9720  {
9721  scalars[v] = -consdata->vals[v]/slackcoef;
9722  SCIPdebugMsgPrint(scip, " %+.15g<%s>", scalars[v], SCIPvarGetName(vars[v]));
9723  }
9724  SCIPdebugMsgPrint(scip, " %+.15g, bounds of <%s>: [%.15g,%.15g], nlocks=%d, maxnlocks=%d, removescons=%u\n",
9725  aggrconst, SCIPvarGetName(slackvar), SCIPvarGetLbGlobal(slackvar), SCIPvarGetUbGlobal(slackvar),
9726  bestnlocks, bestremovescons ? maxnlocksremove : maxnlocksstay, bestremovescons);
9727 
9728  /* perform the multi-aggregation */
9729  SCIP_CALL( SCIPmultiaggregateVar(scip, slackvar, consdata->nvars, vars, scalars, aggrconst,
9730  &infeasible, &aggregated) );
9731  assert(aggregated);
9732 
9733  /* free temporary memory */
9734  SCIPfreeBufferArray(scip, &scalars);
9735 
9736  /* check for infeasible aggregation */
9737  if( infeasible )
9738  {
9739  SCIPdebugMsg(scip, "linear constraint <%s>: infeasible multi-aggregation\n", SCIPconsGetName(cons));
9740  *cutoff = TRUE;
9741  return SCIP_OKAY;
9742  }
9743 
9744  (*naggrvars)++;
9745 
9746  /* delete the constraint if it became redundant */
9747  if( bestremovescons )
9748  {
9749  SCIPdebugMsg(scip, "linear constraint <%s>: redundant after multi-aggregation\n", SCIPconsGetName(cons));
9750  SCIP_CALL( SCIPdelCons(scip, cons) );
9751 
9752  if( !consdata->upgraded )
9753  (*ndelconss)++;
9754  }
9755  }
9756  else if( ncontvars == 1 )
9757  {
9758  SCIP_VAR* var;
9759 
9760  assert(0 <= contvarpos && contvarpos < consdata->nvars);
9761  var = vars[contvarpos];
9762  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
9763 
9764  if( coefsintegral && SCIPisFeasIntegral(scip, consdata->rhs) )
9765  {
9766  /* upgrade continuous variable to an implicit one, if the absolute value of the coefficient is one */
9767  if( SCIPisEQ(scip, REALABS(vals[contvarpos]), 1.0) )
9768  {
9769  /* convert the continuous variable with coefficient 1.0 into an implicit integer variable */
9770  SCIPdebugMsg(scip, "linear constraint <%s>: converting continuous variable <%s> to implicit integer variable\n",
9771  SCIPconsGetName(cons), SCIPvarGetName(var));
9772  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
9773  if( infeasible )
9774  {
9775  SCIPdebugMsg(scip, "infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
9776  *cutoff = TRUE;
9777 
9778  return SCIP_OKAY;
9779  }
9780  }
9781  /* aggregate continuous variable to an implicit one, if the absolute value of the coefficient is unequal to one */
9782  /* @todo check if the aggregation coefficient should be in some range(, which is not too big) */
9783  else if( !SCIPdoNotAggr(scip) )
9784  {
9785  SCIP_VAR* newvar;
9786  SCIP_Real absval;
9787  char newvarname[SCIP_MAXSTRLEN];
9788  SCIP_Bool redundant;
9789  SCIP_Bool aggregated;
9790 
9791  absval = REALABS(vals[contvarpos]);
9792 
9793  (void) SCIPsnprintf(newvarname, SCIP_MAXSTRLEN, "%s_impl", SCIPvarGetName(var));
9794 
9795  /* create new implicit variable for aggregation */
9796  SCIP_CALL( SCIPcreateVar(scip, &newvar, newvarname, -SCIPinfinity(scip), SCIPinfinity(scip), 0.0,
9798 
9799  /* add new variable to problem */
9800  SCIP_CALL( SCIPaddVar(scip, newvar) );
9801 
9802 #ifdef SCIP_DEBUG_SOLUTION
9803  if( SCIPdebugIsMainscip(scip) )
9804  {
9805  SCIP_Real varval;
9806  SCIP_CALL( SCIPdebugGetSolVal(scip, var, &varval) );
9807  SCIP_CALL( SCIPdebugAddSolVal(scip, newvar, absval * varval) );
9808  }
9809 #endif
9810 
9811  /* convert the continuous variable with coefficient 1.0 into an implicit integer variable */
9812  SCIPdebugMsg(scip, "linear constraint <%s>: aggregating continuous variable <%s> to newly created implicit integer variable <%s>, aggregation factor = %g\n",
9813  SCIPconsGetName(cons), SCIPvarGetName(var), SCIPvarGetName(newvar), absval);
9814 
9815  /* aggregate continuous and implicit variable */
9816  SCIP_CALL( SCIPaggregateVars(scip, var, newvar, absval, -1.0, 0.0, &infeasible, &redundant, &aggregated) );
9817 
9818  if( infeasible )
9819  {
9820  SCIPdebugMsg(scip, "infeasible aggregation of variable <%s> to implicit variable <%s>, domain is empty\n",
9821  SCIPvarGetName(var), SCIPvarGetName(newvar));
9822  *cutoff = TRUE;
9823 
9824  /* release implicit variable */
9825  SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
9826 
9827  return SCIP_OKAY;
9828  }
9829 
9830  /* release implicit variable */
9831  SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
9832 
9833  if( aggregated )
9834  (*naggrvars)++;
9835  else
9836  return SCIP_OKAY;
9837  }
9838 
9839  /* we do not have any event on vartype changes, so we need to manually force this constraint to be presolved
9840  * again
9841  */
9842  consdata->boundstightened = 0;
9843  consdata->rangedrowpropagated = 0;
9844  consdata->presolved = FALSE;
9845  }
9846  }
9847  else if( ncontvars == 0 && nimplvars == 0 && nintvars == 1 && !coefszeroone )
9848  {
9849  SCIP_VAR* var;
9850 
9851  /* this seems to help for rococo instances, but does not for rout (where all coefficients are +/- 1.0)
9852  * -> we don't convert integers into implints if the row is a 0/1-row
9853  */
9854  assert(varsintegral);
9855  assert(0 <= intvarpos && intvarpos < consdata->nvars);
9856  var = vars[intvarpos];
9857  assert(SCIPvarGetType(var) == SCIP_VARTYPE_INTEGER);
9858 
9859  if( coefsintegral
9860  && SCIPisEQ(scip, REALABS(vals[intvarpos]), 1.0)
9861  && SCIPisFeasIntegral(scip, consdata->rhs) )
9862  {
9863  /* convert the integer variable with coefficient 1.0 into an implicit integer variable */
9864  SCIPdebugMsg(scip, "linear constraint <%s>: converting integer variable <%s> to implicit integer variable\n",
9865  SCIPconsGetName(cons), SCIPvarGetName(var));
9866  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
9867  if( infeasible )
9868  {
9869  SCIPdebugMsg(scip, "infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
9870  *cutoff = TRUE;
9871 
9872  return SCIP_OKAY;
9873  }
9874  }
9875  }
9876 
9877  return SCIP_OKAY;
9878 }
9879 
9880 /** checks if the given variables and their coefficient are equal (w.r.t. scaling factor) to the objective function */
9881 static
9883  SCIP* scip, /**< SCIP data structure */
9884  SCIP_CONSDATA* consdata, /**< linear constraint data */
9885  SCIP_Real* scale, /**< pointer to store the scaling factor between the constraint and the
9886  * objective function */
9887  SCIP_Real* offset /**< pointer to store the offset of the objective function resulting by
9888  * this constraint */
9889  )
9890 {
9891  SCIP_VAR** vars;
9892  SCIP_VAR* var;
9893  SCIP_Real objval;
9894  SCIP_Bool negated;
9895  int nvars;
9896  int v;
9897 
9898  vars = consdata->vars;
9899  nvars = consdata->nvars;
9900 
9901  assert(vars != NULL);
9902 
9903  for( v = 0; v < nvars; ++v )
9904  {
9905  negated = FALSE;
9906  var = vars[v];
9907  assert(var != NULL);
9908 
9909  if( SCIPvarIsNegated(var) )
9910  {
9911  negated = TRUE;
9912  var = SCIPvarGetNegatedVar(var);
9913  assert(var != NULL);
9914  }
9915 
9916  objval = SCIPvarGetObj(var);
9917 
9918  /* if a variable has a zero objective coefficient the linear constraint is not a subset of the objective
9919  * function
9920  */
9921  if( SCIPisZero(scip, objval) )
9922  return FALSE;
9923  else
9924  {
9925  SCIP_Real val;
9926 
9927  val = consdata->vals[v];
9928 
9929  if( negated )
9930  {
9931  if( v == 0 )
9932  {
9933  /* the first variable defines the scale */
9934  (*scale) = val / -objval;
9935 
9936  (*offset) += val;
9937  }
9938  else if( SCIPisEQ(scip, -objval * (*scale), val) )
9939  (*offset) += val;
9940  else
9941  return FALSE;
9942  }
9943  else if( v == 0 )
9944  {
9945  /* the first variable defines the scale */
9946  (*scale) = val / objval;
9947  }
9948  else if( !SCIPisEQ(scip, objval * (*scale), val) )
9949  return FALSE;
9950  }
9951  }
9952 
9953  return TRUE;
9954 }
9955 
9956 /** check if the linear equality constraint is equal to a subset of the objective function; if so we can remove the
9957  * objective coefficients and add an objective offset
9958  */
9959 static
9961  SCIP* scip, /**< SCIP data structure */
9962  SCIP_CONS* cons, /**< linear equation constraint */
9963  SCIP_CONSHDLRDATA* conshdlrdata /**< linear constraint handler data */
9964  )
9965 {
9966  SCIP_CONSDATA* consdata;
9967  SCIP_Real offset;
9968  SCIP_Real scale;
9969  SCIP_Bool applicable;
9970  int nobjvars;
9971  int nvars;
9972  int v;
9973 
9974  assert(scip != NULL);
9975  assert(cons != NULL);
9976  assert(conshdlrdata != NULL);
9978  consdata = SCIPconsGetData(cons);
9979  assert(consdata != NULL);
9980  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9981 
9982  nvars = consdata->nvars;
9983  nobjvars = SCIPgetNObjVars(scip);
9984 
9985  /* check if the linear equality constraints does not have more variables than the objective function */
9986  if( nvars > nobjvars || nvars == 0 )
9987  return SCIP_OKAY;
9988 
9989  /* check for allowance of algorithm */
9990  if( (nvars < nobjvars && !conshdlrdata->detectpartialobjective) ||
9991  (nvars == nobjvars && (!conshdlrdata->detectcutoffbound || !conshdlrdata->detectlowerbound)) )
9992  return SCIP_OKAY;
9993 
9994  offset = consdata->rhs;
9995  scale = 1.0;
9996 
9997  /* checks if the variables and their coefficients are equal (w.r.t. scaling factor) to the objective function */
9998  applicable = checkEqualObjective(scip, consdata, &scale, &offset);
9999 
10000  if( applicable )
10001  {
10002  SCIP_VAR** vars;
10003 
10004  vars = consdata->vars;
10005  assert(vars != NULL);
10006 
10007  offset /= scale;
10008 
10009  SCIPdebugMsg(scip, "linear equality constraint <%s> == %g (offset %g) is a subset of the objective function\n",
10010  SCIPconsGetName(cons), consdata->rhs, offset);
10011 
10012  /* set all objective coefficient to zero */
10013  for( v = 0; v < nvars; ++v )
10014  {
10015  SCIP_CALL( SCIPchgVarObj(scip, vars[v], 0.0) );
10016  }
10017 
10018  /* add an objective offset */
10019  SCIP_CALL( SCIPaddObjoffset(scip, offset) );
10020  }
10021 
10022  return SCIP_OKAY;
10023 }
10024 
10025 /** updates the cutoff if the given primal bound (which is implied by the given constraint) is better */
10026 static
10028  SCIP* scip, /**< SCIP data structure */
10029  SCIP_CONS* cons, /**< constraint */
10030  SCIP_Real primalbound /**< feasible primal bound */
10031  )
10032 {
10033  SCIP_Real cutoffbound;
10034 
10035  /* increase the cutoff bound value by an epsilon to ensue that solution with the value of the cutoff bound are still
10036  * accepted
10037  */
10038  cutoffbound = primalbound + SCIPcutoffbounddelta(scip);
10039 
10040  if( cutoffbound < SCIPgetCutoffbound(scip) )
10041  {
10042  SCIPdebugMsg(scip, "update cutoff bound <%g>\n", cutoffbound);
10043 
10044  SCIP_CALL( SCIPupdateCutoffbound(scip, cutoffbound) );
10045  }
10046  else
10047  {
10048  SCIP_CONSDATA* consdata;
10049 
10050  consdata = SCIPconsGetData(cons);
10051  assert(consdata != NULL);
10052 
10053  /* we cannot disable the enforcement and propagation on ranged rows, because the cutoffbound could only have
10054  * resulted from one side
10055  */
10056  if( SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, consdata->rhs) )
10057  {
10058  /* in case the cutoff bound is worse then the currently known one, we additionally avoid enforcement and
10059  * propagation
10060  */
10061  SCIP_CALL( SCIPsetConsEnforced(scip, cons, FALSE) );
10062  SCIP_CALL( SCIPsetConsPropagated(scip, cons, FALSE) );
10063  }
10064  }
10065 
10066  return SCIP_OKAY;
10067 }
10068 
10069 /** check if the linear constraint is parallel to objective function; if so update the cutoff bound and avoid that the
10070  * constraint enters the LP by setting the initial and separated flag to FALSE
10071  */
10072 static
10074  SCIP* scip, /**< SCIP data structure */
10075  SCIP_CONS* cons, /**< linear constraint */
10076  SCIP_CONSHDLRDATA* conshdlrdata /**< linear constraint handler data */
10077  )
10078 {
10079  SCIP_CONSDATA* consdata;
10080  SCIP_Real offset;
10081  SCIP_Real scale;
10082  SCIP_Bool applicable;
10083  int nobjvars;
10084  int nvars;
10085 
10086  assert(scip != NULL);
10087  assert(cons != NULL);
10088  assert(conshdlrdata != NULL);
10089 
10090  consdata = SCIPconsGetData(cons);
10091  assert(consdata != NULL);
10092 
10093  /* ignore equalities since these are covered by the method checkPartialObjective() */
10094  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
10095  return SCIP_OKAY;
10096 
10097  nvars = consdata->nvars;
10098  nobjvars = SCIPgetNObjVars(scip);
10099 
10100  /* check if the linear inequality constraints has the same number of variables as the objective function and if the
10101  * initial and/or separated flag is set to FALSE
10102  */
10103  if( nvars != nobjvars || (!SCIPconsIsInitial(cons) && !SCIPconsIsSeparated(cons)) )
10104  return SCIP_OKAY;
10105 
10106  offset = 0.0;
10107  scale = 1.0;
10108 
10109  /* There are no variables in the ojective function and in the constraint. Thus, the constraint is redundant or proves
10110  * infeasibility. Since we have a pure feasibility problem, we do not want to set a cutoff or lower bound.
10111  */
10112  if( nobjvars == 0 )
10113  return SCIP_OKAY;
10114 
10115  /* checks if the variables and their coefficients are equal (w.r.t. scaling factor) to the objective function */
10116  applicable = checkEqualObjective(scip, consdata, &scale, &offset);
10117 
10118  if( applicable )
10119  {
10120  SCIP_Bool rhsfinite = !SCIPisInfinity(scip, consdata->rhs);
10121  SCIP_Bool lhsfinite = !SCIPisInfinity(scip, -consdata->lhs);
10122 
10123  if( SCIPisPositive(scip, scale) )
10124  {
10125  if( conshdlrdata->detectcutoffbound && rhsfinite )
10126  {
10127  SCIP_Real primalbound;
10128 
10129  primalbound = (consdata->rhs - offset) / scale;
10130 
10131  SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a cutoff bound <%g>\n",
10132  SCIPconsGetName(cons), primalbound);
10133 
10134  SCIP_CALL( updateCutoffbound(scip, cons, primalbound) );
10135  }
10136 
10137  if( conshdlrdata->detectlowerbound && lhsfinite )
10138  {
10139  SCIP_Real lowerbound;
10140 
10141  lowerbound = (consdata->lhs - offset) / scale;
10142 
10143  SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a lower bound <%g>\n",
10144  SCIPconsGetName(cons), lowerbound);
10145 
10146  SCIP_CALL( SCIPupdateLocalLowerbound(scip, lowerbound) );
10147  }
10148 
10149  if( (conshdlrdata->detectcutoffbound && (conshdlrdata->detectlowerbound || !lhsfinite)) ||
10150  (conshdlrdata->detectlowerbound && !rhsfinite) )
10151  {
10152  /* avoid that the linear constraint enters the LP since it is parallel to the objective function */
10153  SCIP_CALL( SCIPsetConsInitial(scip, cons, FALSE) );
10154  SCIP_CALL( SCIPsetConsSeparated(scip, cons, FALSE) );
10155  }
10156  }
10157  else
10158  {
10159  if( conshdlrdata->detectlowerbound && rhsfinite )
10160  {
10161  SCIP_Real lowerbound;
10162 
10163  lowerbound = (consdata->rhs - offset) / scale;
10164 
10165  SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a lower bound <%g>\n",
10166  SCIPconsGetName(cons), lowerbound);
10167 
10168  SCIP_CALL( SCIPupdateLocalLowerbound(scip, lowerbound) );
10169  }
10170 
10171  if( conshdlrdata->detectcutoffbound && lhsfinite )
10172  {
10173  SCIP_Real primalbound;
10174 
10175  primalbound = (consdata->lhs - offset) / scale;
10176 
10177  SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a cutoff bound <%g>\n",
10178  SCIPconsGetName(cons), primalbound);
10179 
10180  SCIP_CALL( updateCutoffbound(scip, cons, primalbound) );
10181  }
10182 
10183  if( (conshdlrdata->detectcutoffbound && (conshdlrdata->detectlowerbound || !rhsfinite)) ||
10184  (conshdlrdata->detectlowerbound && !lhsfinite) )
10185  {
10186  /* avoid that the linear constraint enters the LP since it is parallel to the objective function */
10187  SCIP_CALL( SCIPsetConsInitial(scip, cons, FALSE) );
10188  SCIP_CALL( SCIPsetConsSeparated(scip, cons, FALSE) );
10189  }
10190  }
10191  }
10192 
10193  return SCIP_OKAY;
10194 }
10195 
10196 /** converts special equalities */
10197 static
10199  SCIP* scip, /**< SCIP data structure */
10200  SCIP_CONS* cons, /**< linear constraint */
10201  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
10202  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
10203  int* nfixedvars, /**< pointer to count number of fixed variables */
10204  int* naggrvars, /**< pointer to count number of aggregated variables */
10205  int* ndelconss /**< pointer to count number of deleted constraints */
10206  )
10207 {
10208  SCIP_CONSDATA* consdata;
10209 
10210  assert(scip != NULL);
10211  assert(cons != NULL);
10212  assert(conshdlrdata != NULL);
10213  assert(cutoff != NULL);
10214  assert(nfixedvars != NULL);
10215  assert(naggrvars != NULL);
10216  assert(ndelconss != NULL);
10217 
10218  consdata = SCIPconsGetData(cons);
10219  assert(consdata != NULL);
10220  assert(consdata->removedfixings);
10221 
10222  /* do nothing on inequalities */
10223  if( !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
10224  return SCIP_OKAY;
10225 
10226  /* depending on the number of variables, call a special conversion method */
10227  if( consdata->nvars == 1 )
10228  {
10229  /* fix variable */
10230  SCIP_CALL( convertUnaryEquality(scip, cons, cutoff, nfixedvars, ndelconss) );
10231  }
10232  else if( consdata->nvars == 2 )
10233  {
10234  /* aggregate one of the variables */
10235  SCIP_CALL( convertBinaryEquality(scip, cons, cutoff, naggrvars, ndelconss) );
10236  }
10237  else
10238  {
10239  /* check if the equality is part of the objective function */
10240  SCIP_CALL( checkPartialObjective(scip, cons, conshdlrdata) );
10241 
10242  /* try to multi-aggregate one of the variables */
10243  SCIP_CALL( convertLongEquality(scip, conshdlrdata, cons, cutoff, naggrvars, ndelconss) );
10244  }
10245 
10246  return SCIP_OKAY;
10247 }
10248 
10249 /** returns whether the linear sum of all variables/coefficients except the given one divided by the given value is always
10250  * integral
10251  */
10252 static
10254  SCIP* scip, /**< SCIP data structure */
10255  SCIP_CONSDATA* consdata, /**< linear constraint */
10256  int pos, /**< position of variable to be left out */
10257  SCIP_Real val /**< value to divide the coefficients by */
10258  )
10259 {
10260  int v;
10261 
10262  assert(scip != NULL);
10263  assert(consdata != NULL);
10264  assert(0 <= pos && pos < consdata->nvars);
10265 
10266  for( v = 0; v < consdata->nvars; ++v )
10267  {
10268  if( v != pos && (!SCIPvarIsIntegral(consdata->vars[v]) || !SCIPisIntegral(scip, consdata->vals[v]/val)) )
10269  return FALSE;
10270  }
10271 
10272  return TRUE;
10273 }
10274 
10275 /* check if lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i
10276  * check if rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i
10277  */
10278 static
10280  SCIP* scip, /**< SCIP data structure */
10281  SCIP_Real side, /**< lhs or rhs */
10282  SCIP_Real val, /**< coefficient */
10283  SCIP_Real minresactivity, /**< minimal residual activity */
10284  SCIP_Real maxresactivity, /**< maximal residual activity */
10285  SCIP_Real* minval, /**< pointer to store calculated minval */
10286  SCIP_Real* maxval /**< pointer to store calculated maxval */
10287  )
10288 {
10289  assert(scip != NULL);
10290  assert(minval != NULL);
10291  assert(maxval != NULL);
10292 
10293  if( val > 0.0 )
10294  {
10295  if( SCIPisInfinity(scip, ABS(maxresactivity)) )
10296  *minval = -maxresactivity;
10297  else
10298  *minval = (side - maxresactivity)/val;
10299 
10300  if( SCIPisInfinity(scip, ABS(minresactivity)) )
10301  *maxval = -minresactivity;
10302  else
10303  *maxval = (side - minresactivity)/val;
10304  }
10305  else
10306  {
10307  if( SCIPisInfinity(scip, ABS(minresactivity)) )
10308  *minval = minresactivity;
10309  else
10310  *minval = (side - minresactivity)/val;
10311 
10312  if( SCIPisInfinity(scip, ABS(maxresactivity)) )
10313  *maxval = maxresactivity;
10314  else
10315  *maxval = (side - maxresactivity)/val;
10316  }
10317 }
10318 
10319 
10320 /* applies dual presolving for variables that are locked only once in a direction, and this locking is due to a
10321  * linear inequality
10322  */
10323 static
10325  SCIP* scip, /**< SCIP data structure */
10326  SCIP_CONS* cons, /**< linear constraint */
10327  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
10328  int* nfixedvars, /**< pointer to count number of fixed variables */
10329  int* naggrvars, /**< pointer to count number of aggregated variables */
10330  int* ndelconss /**< pointer to count number of deleted constraints */
10331  )
10332 {
10333  SCIP_CONSDATA* consdata;
10334  SCIP_Bool lhsexists;
10335  SCIP_Bool rhsexists;
10336  SCIP_Bool bestisint;
10337  SCIP_Bool bestislhs;
10338  int bestpos;
10339  int i;
10340  int maxotherlocks;
10342  assert(scip != NULL);
10343  assert(cons != NULL);
10344  assert(cutoff != NULL);
10345  assert(nfixedvars != NULL);
10346  assert(naggrvars != NULL);
10347  assert(ndelconss != NULL);
10348 
10349  /* only process checked constraints (for which the locks are increased);
10350  * otherwise we would have to check for variables with nlocks == 0, and these are already processed by the
10351  * dualfix presolver
10352  */
10353  if( !SCIPconsIsChecked(cons) )
10354  return SCIP_OKAY;
10355 
10356  consdata = SCIPconsGetData(cons);
10357  assert(consdata != NULL);
10358 
10359  lhsexists = !SCIPisInfinity(scip, -consdata->lhs);
10360  rhsexists = !SCIPisInfinity(scip, consdata->rhs);
10361 
10362  /* search for a single-locked variable which can be multi-aggregated; if a valid continuous variable was found, we
10363  * can use it safely for aggregation and break the search loop
10364  */
10365  bestpos = -1;
10366  bestisint = TRUE;
10367  bestislhs = FALSE;
10368 
10369  /* We only want to multi-aggregate variables, if they appear in maximal one additional constraint,
10370  * everything else would produce fill-in. Exceptions:
10371  * - If there are only two variables in the constraint from which the multi-aggregation arises, no fill-in will be
10372  * produced.
10373  * - If there are three variables in the constraint, multi-aggregation in three additional constraints will remove
10374  * six nonzeros (three from the constraint and the three entries of the multi-aggregated variable) and add
10375  * six nonzeros (two variables per substitution).
10376  * - If there at most four variables in the constraint, multi-aggregation in two additional constraints will remove
10377  * six nonzeros (four from the constraint and the two entries of the multi-aggregated variable) and add
10378  * six nonzeros (three variables per substitution). God exists!
10379  */
10380  if( consdata->nvars <= 2 )
10381  maxotherlocks = INT_MAX;
10382  else if( consdata->nvars == 3 )
10383  maxotherlocks = 3;
10384  else if( consdata->nvars == 4 )
10385  maxotherlocks = 2;
10386  else
10387  maxotherlocks = 1;
10388 
10389  /* if this constraint has both sides, it also provides a lock for the other side and thus we can allow one more lock */
10390  if( lhsexists && rhsexists && maxotherlocks < INT_MAX )
10391  maxotherlocks++;
10392 
10393  for( i = 0; i < consdata->nvars && bestisint; ++i )
10394  {
10395  SCIP_VAR* var;
10396  SCIP_Bool isint;
10397  SCIP_Real val;
10398  SCIP_Real obj;
10399  SCIP_Real lb;
10400  SCIP_Real ub;
10401  SCIP_Bool agglhs;
10402  SCIP_Bool aggrhs;
10403 
10404  var = consdata->vars[i];
10406 
10407  /* if we already found a candidate, skip integers */
10408  if( bestpos >= 0 && isint )
10409  continue;
10410 
10411  /* better do not multi-aggregate binary variables, since most plugins rely on their binary variables to be either
10412  * active, fixed, or single-aggregated with another binary variable
10413  */
10414  if( SCIPvarIsBinary(var) && consdata->nvars > 2 )
10415  continue;
10416 
10417  if ( SCIPdoNotMultaggrVar(scip, var) )
10418  continue;
10419 
10420  val = consdata->vals[i];
10421  obj = SCIPvarGetObj(var);
10422  lb = SCIPvarGetLbGlobal(var);
10423  ub = SCIPvarGetUbGlobal(var);
10424 
10425  /* lhs <= a_0 * x_0 + a_1 * x_1 + ... + a_{n-1} * x_{n-1} <= rhs
10426  *
10427  * a_i >= 0, c_i >= 0, lhs exists, nlocksdown(x_i) == 1:
10428  * - constraint is the only one that forbids fixing the variable to its lower bound
10429  * - 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
10430  *
10431  * a_i <= 0, c_i <= 0, lhs exists, nlocksup(x_i) == 1:
10432  * - constraint is the only one that forbids fixing the variable to its upper bound
10433  * - 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
10434  *
10435  * a_i >= 0, c_i <= 0, rhs exists, nlocksup(x_i) == 1:
10436  * - constraint is the only one that forbids fixing the variable to its upper bound
10437  * - 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
10438  *
10439  * a_i <= 0, c_i >= 0, rhs exists, nlocksdown(x_i) == 1:
10440  * - constraint is the only one that forbids fixing the variable to its lower bound
10441  * - 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
10442  *
10443  * but: all this is only applicable, if the aggregated value is inside x_i's bounds for all possible values
10444  * of all x_j
10445  * furthermore: we only want to apply this, if no fill-in will be produced
10446  */
10447  agglhs = lhsexists
10448  && ((val > 0.0 && !SCIPisNegative(scip, obj) && SCIPvarGetNLocksDown(var) == 1
10449  && SCIPvarGetNLocksUp(var) <= maxotherlocks)
10450  || (val < 0.0 && !SCIPisPositive(scip, obj) && SCIPvarGetNLocksUp(var) == 1
10451  && SCIPvarGetNLocksDown(var) <= maxotherlocks));
10452  aggrhs = rhsexists
10453  && ((val > 0.0 && !SCIPisPositive(scip, obj) && SCIPvarGetNLocksUp(var) == 1
10454  && SCIPvarGetNLocksDown(var) <= maxotherlocks)
10455  || (val < 0.0 && !SCIPisNegative(scip, obj) && SCIPvarGetNLocksDown(var) == 1
10456  && SCIPvarGetNLocksUp(var) <= maxotherlocks));
10457  if( agglhs || aggrhs )
10458  {
10459  SCIP_Real minresactivity;
10460  SCIP_Real maxresactivity;
10461  SCIP_Real minval;
10462  SCIP_Real maxval;
10463  SCIP_Bool minisrelax;
10464  SCIP_Bool maxisrelax;
10465  SCIP_Bool isminsettoinfinity;
10466  SCIP_Bool ismaxsettoinfinity;
10467 
10468  /* calculate bounds for \sum_{j \neq i} a_j * x_j */
10469  consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
10470  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
10471  assert(SCIPisLE(scip, minresactivity, maxresactivity));
10472 
10473  /* We called consdataGetActivityResiduals() saying that we do not need a good relaxation,
10474  * so whenever we have a relaxed activity, it should be relaxed to +/- infinity.
10475  * This is needed, because we do not want to rely on relaxed finite resactivities.
10476  */
10477  assert((!minisrelax || isminsettoinfinity) && (!maxisrelax || ismaxsettoinfinity));
10478 
10479  if( agglhs )
10480  {
10481  /* check if lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10482  calculateMinvalAndMaxval(scip, consdata->lhs, val, minresactivity, maxresactivity, &minval, &maxval);
10483 
10484  assert(SCIPisLE(scip, minval, maxval));
10485  if( (!SCIPisInfinity(scip, -minval) && SCIPisFeasGE(scip, minval, lb)) &&
10486  (!SCIPisInfinity(scip, maxval) && SCIPisFeasLE(scip, maxval, ub)) )
10487  {
10488  SCIP_Real oldmaxresactivity;
10489  SCIP_Real oldminresactivity;
10490  SCIP_Bool recalculated;
10491 
10492  recalculated = FALSE;
10493  oldmaxresactivity = maxresactivity;
10494  oldminresactivity = minresactivity;
10495 
10496  /* check minresactivity for reliability */
10497  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
10498  {
10499  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
10500  recalculated = !SCIPisEQ(scip, oldminresactivity, minresactivity);
10501  isminsettoinfinity = TRUE; /* here it means only that it was even calculated */
10502  }
10503 
10504  /* check maxresactivity for reliability */
10505  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
10506  {
10507  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
10508  recalculated = recalculated || !SCIPisEQ(scip, oldmaxresactivity, maxresactivity);
10509  ismaxsettoinfinity = TRUE; /* here it means only that it was even calculated */
10510  }
10511 
10512  /* minresactivity or maxresactivity wasn't reliable so recalculate min- and maxval*/
10513  if( recalculated )
10514  {
10515  assert(SCIPisLE(scip, minresactivity, maxresactivity));
10516 
10517  /* check again if lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10518  calculateMinvalAndMaxval(scip, consdata->lhs, val, minresactivity, maxresactivity, &minval, &maxval);
10519 
10520  assert(SCIPisLE(scip, minval, maxval));
10521  }
10522 
10523  if( !recalculated || (SCIPisFeasGE(scip, minval, lb) && SCIPisFeasLE(scip, maxval, ub)) )
10524  {
10525  /* if the variable is integer, we have to check whether the integrality condition would always be satisfied
10526  * in the multi-aggregation
10527  */
10528  if( !isint || (SCIPisIntegral(scip, consdata->lhs/val) && consdataIsResidualIntegral(scip, consdata, i, val)) )
10529  {
10530  bestpos = i;
10531  bestisint = isint;
10532  bestislhs = TRUE;
10533  continue; /* no need to also look at the right hand side */
10534  }
10535  }
10536  }
10537  }
10538 
10539  if( aggrhs )
10540  {
10541  /* check if rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10542  calculateMinvalAndMaxval(scip, consdata->rhs, val, minresactivity, maxresactivity, &minval, &maxval);
10543 
10544  assert(SCIPisLE(scip,minval,maxval));
10545  if( (!SCIPisInfinity(scip, -minval) && SCIPisFeasGE(scip, minval, lb)) &&
10546  (!SCIPisInfinity(scip, maxval) && SCIPisFeasLE(scip, maxval, ub)) )
10547  {
10548  SCIP_Real oldmaxresactivity;
10549  SCIP_Real oldminresactivity;
10550  SCIP_Bool recalculated;
10551 
10552  recalculated = FALSE;
10553  oldmaxresactivity = maxresactivity;
10554  oldminresactivity = minresactivity;
10555 
10556  /* check minresactivity for reliability */
10557  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
10558  {
10559  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
10560  recalculated = !SCIPisEQ(scip, oldminresactivity, minresactivity);
10561  }
10562 
10563  /* check maxresactivity for reliability */
10564  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
10565  {
10566  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
10567  recalculated = recalculated || !SCIPisEQ(scip, oldmaxresactivity, maxresactivity);
10568  }
10569 
10570  /* minresactivity or maxresactivity wasn't reliable so recalculate min- and maxval*/
10571  if( recalculated )
10572  {
10573  /* check again if rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10574  calculateMinvalAndMaxval(scip, consdata->rhs, val, minresactivity, maxresactivity, &minval, &maxval);
10575  assert(SCIPisLE(scip,minval,maxval));
10576  }
10577 
10578  if( !recalculated || (SCIPisFeasGE(scip, minval, lb) && SCIPisFeasLE(scip, maxval, ub)) )
10579  {
10580  /* if the variable is integer, we have to check whether the integrality condition would always be satisfied
10581  * in the multi-aggregation
10582  */
10583  if( !isint || (SCIPisIntegral(scip, consdata->rhs/val) && consdataIsResidualIntegral(scip, consdata, i, val)) )
10584  {
10585  bestpos = i;
10586  bestisint = isint;
10587  bestislhs = FALSE;
10588  }
10589  }
10590  }
10591  }
10592  }
10593  }
10594 
10595  if( bestpos >= 0 )
10596  {
10597  SCIP_VAR** aggrvars;
10598  SCIP_Real* aggrcoefs;
10599  SCIP_Real aggrconst;
10600  SCIP_VAR* bestvar;
10601  SCIP_Real bestval;
10602  SCIP_Real epsilon;
10603  int naggrs;
10604  int j;
10605  SCIP_Bool infeasible;
10606  SCIP_Bool aggregated;
10607  SCIP_Bool samevar;
10608  int supinf; /* counter for infinite contributions to the supremum of a possible
10609  * multi-aggregation
10610  */
10611  int infinf; /* counter for infinite contributions to the infimum of a possible
10612  * multi-aggregation
10613  */
10614 
10615  assert(!bestislhs || lhsexists);
10616  assert(bestislhs || rhsexists);
10617 
10618  bestvar = consdata->vars[bestpos];
10619  bestval = consdata->vals[bestpos];
10620  assert(bestisint ==
10622 
10623  /* allocate temporary memory */
10624  SCIP_CALL( SCIPallocBufferArray(scip, &aggrvars, consdata->nvars-1) );
10625  SCIP_CALL( SCIPallocBufferArray(scip, &aggrcoefs, consdata->nvars-1) );
10626 
10627  /* set up the multi-aggregation */
10628  SCIPdebugPrintCons(scip, cons, NULL);
10629  SCIPdebugMsg(scip, "linear constraint <%s> (dual): multi-aggregate <%s> ==", SCIPconsGetName(cons), SCIPvarGetName(bestvar));
10630  naggrs = 0;
10631  supinf = 0;
10632  infinf = 0;
10633  samevar = FALSE;
10634  epsilon = SCIPepsilon(scip);
10635 
10636  for( j = 0; j < consdata->nvars; ++j )
10637  {
10638  if( j != bestpos )
10639  {
10640  SCIP_Real absaggrcoef;
10641 
10642  aggrvars[naggrs] = consdata->vars[j];
10643  aggrcoefs[naggrs] = -consdata->vals[j]/consdata->vals[bestpos];
10644  SCIPdebugMsgPrint(scip, " %+.15g<%s>", aggrcoefs[naggrs], SCIPvarGetName(aggrvars[naggrs]));
10645 
10646  absaggrcoef = REALABS(aggrcoefs[naggrs]);
10647 
10648  /* do not try to multi aggregate, when numerical bad */
10649  if( absaggrcoef < epsilon )
10650  {
10651  SCIPdebugMsg(scip, "do not perform multi-aggregation: too large aggregation coefficients\n");
10652 
10653  /* free temporary memory */
10654  SCIPfreeBufferArray(scip, &aggrcoefs);
10655  SCIPfreeBufferArray(scip, &aggrvars);
10656 
10657  return SCIP_OKAY;
10658  }
10659 
10660  if( bestisint )
10661  {
10662  /* coefficient must be integral: round it to exact integral value */
10663  assert(SCIPisIntegral(scip, aggrcoefs[naggrs]));
10664  aggrcoefs[naggrs] = SCIPfloor(scip, aggrcoefs[naggrs]+0.5);
10665  }
10666 
10667  if( SCIPisPositive(scip, aggrcoefs[naggrs]) )
10668  {
10669  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
10670  {
10671  ++supinf;
10672  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
10673  {
10674  ++infinf;
10675  samevar = TRUE;
10676  }
10677  }
10678  else if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
10679  ++infinf;
10680  }
10681  else if( SCIPisNegative(scip, aggrcoefs[naggrs]) )
10682  {
10683  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
10684  {
10685  ++supinf;
10686  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
10687  {
10688  ++infinf;
10689  samevar = TRUE;
10690  }
10691  }
10692  else if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
10693  ++infinf;
10694  }
10695 
10696  naggrs++;
10697  }
10698  }
10699  assert(!samevar || (supinf > 0 && infinf > 0));
10700 
10701  aggrconst = (bestislhs ? consdata->lhs/bestval : consdata->rhs/bestval);
10702  SCIPdebugMsgPrint(scip, " %+.15g, bounds of <%s>: [%.15g,%.15g]\n", aggrconst, SCIPvarGetName(bestvar),
10703  SCIPvarGetLbGlobal(bestvar), SCIPvarGetUbGlobal(bestvar));
10704  assert(naggrs == consdata->nvars-1);
10705 
10706  /* right hand side must be integral: round it to exact integral value */
10707  if( bestisint )
10708  {
10709  assert(SCIPisIntegral(scip, aggrconst));
10710  aggrconst = SCIPfloor(scip, aggrconst+0.5);
10711  }
10712 
10713  aggregated = FALSE;
10714  infeasible = FALSE;
10715 
10716  /* perform the multi-aggregation */
10717  if( (samevar && supinf == 1 && infinf == 1) || (!samevar && (supinf == 0 || infinf == 0)) )
10718  {
10719  /* @todo if multi-aggregate makes them numerical trouble, avoid them if the coefficients differ to much, see
10720  * also convertLongEquality() early termination due to coefficients
10721  */
10722  SCIP_CALL( SCIPmultiaggregateVar(scip, bestvar, naggrs, aggrvars, aggrcoefs, aggrconst, &infeasible, &aggregated) );
10723  }
10724  else
10725  {
10726  /* If the infimum and the supremum of a multi-aggregation are both infinite, then the multi-aggregation might not be resolvable.
10727  * E.g., consider the equality z = x-y. If x and y are both fixed to +infinity, the value for z is not determined */
10728  SCIPdebugMsg(scip, "do not perform multi-aggregation: infimum and supremum are both infinite\n");
10729  }
10730  /* free temporary memory */
10731  SCIPfreeBufferArray(scip, &aggrcoefs);
10732  SCIPfreeBufferArray(scip, &aggrvars);
10733 
10734  /* check for infeasible aggregation */
10735  if( infeasible )
10736  {
10737  SCIPdebugMsg(scip, "linear constraint <%s>: infeasible multi-aggregation\n", SCIPconsGetName(cons));
10738  *cutoff = TRUE;
10739  return SCIP_OKAY;
10740  }
10741 
10742  /* delete the constraint, if the aggregation was successful */
10743  if( aggregated )
10744  {
10745  SCIP_CALL( SCIPdelCons(scip, cons) );
10746 
10747  if( !consdata->upgraded )
10748  (*ndelconss)++;
10749  (*naggrvars)++;
10750  }
10751  else
10752  {
10753  SCIPdebugMsg(scip, "aggregation non successful!\n");
10754  }
10755  }
10756 
10757  return SCIP_OKAY;
10758 }
10759 
10760 #define BINWEIGHT 1
10761 #define INTWEIGHT 4
10762 #define CONTWEIGHT 8
10763 
10764 /** gets weight for variable in a "weighted number of variables" sum */
10765 static
10766 int getVarWeight(
10767  SCIP_VAR* var /**< variable to get weight for */
10768  )
10769 {
10770  switch( SCIPvarGetType(var) )
10771  {
10772  case SCIP_VARTYPE_BINARY:
10773  return BINWEIGHT;
10774  case SCIP_VARTYPE_INTEGER:
10775  case SCIP_VARTYPE_IMPLINT:
10776  return INTWEIGHT;
10778  return CONTWEIGHT;
10779  default:
10780  SCIPerrorMessage("invalid variable type\n");
10781  SCIPABORT();
10782  return 0; /*lint !e527*/
10783  }
10784 }
10785 
10786 /** tries to aggregate variables in equations a^Tx = lhs
10787  * in case there are at most two binary variables with an odd coefficient and all other
10788  * variables are not continuous and have an even coefficient then:
10789  * - exactly one odd binary variables
10790  * this binary variables y can be fixed to 0 if the lhs is even and to 1 if the lhs is odd
10791  * - lhs is odd -> y = 1
10792  * - lhs is even -> y = 0
10793  * - exactly two odd binary variables
10794  * aggregate the two binary variables with odd coefficient
10795  * - lhs is odd -> exactly one of the variable has to be 1 -> var1 + var2 = 1
10796  * - lhs is even -> both have to take the same value -> var1 - var2 = 0
10797  */
10798 static
10800  SCIP* scip, /**< SCIP data structure */
10801  SCIP_CONS* cons, /**< linear constraint */
10802  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
10803  int* nfixedvars, /**< pointer to count number of fixed variables */
10804  int* naggrvars, /**< pointer to count number of aggregated variables */
10805  int* ndelconss /**< pointer to count number of deleted constraints */
10806  )
10807 { /*lint --e{715}*/
10808  SCIP_CONSDATA* consdata;
10809  SCIP_Bool success;
10810 
10811  assert( scip != NULL );
10812  assert( cons != NULL );
10813 
10814  consdata = SCIPconsGetData(cons);
10815  assert( consdata != NULL );
10817  /* check if the linear constraint is an equation with integral right hand side */
10818  if( !SCIPisEQ(scip, consdata->lhs, consdata->rhs) || !SCIPisIntegral(scip, consdata->lhs) )
10819  return SCIP_OKAY;
10820 
10821  /* try to fix and aggregated variables until nothing is possible anymore */
10822  do
10823  {
10824  int v;
10825  int nvars;
10826  SCIP_VAR** vars;
10827  SCIP_Real* vals;
10828  SCIP_Real lhs;
10829  SCIP_Bool lhsodd;
10830 
10831  SCIP_Bool infeasible;
10832  SCIP_Bool fixed;
10833  SCIP_Bool aggregated;
10834  SCIP_Bool redundant;
10835 
10836  SCIP_VAR* var1;
10837  SCIP_VAR* var2;
10838  int noddvars;
10839 
10840  success = FALSE;
10841 
10842  lhs = consdata->lhs;
10843  vars = consdata->vars;
10844  vals = consdata->vals;
10845  nvars = consdata->nvars;
10846 
10847  assert( !SCIPisInfinity(scip, ABS(lhs)) );
10848 
10849  var1 = NULL;
10850  var2 = NULL;
10851  noddvars = 0;
10852 
10853  /* search for binary variables with an odd coefficient */
10854  for( v = 0; v < nvars && noddvars < 3; ++v )
10855  {
10856  SCIP_Longint val;
10857 
10858  /* all coefficients and variables have to be integral */
10859  if( !SCIPisIntegral(scip, vals[v]) || SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
10860  return SCIP_OKAY;
10861 
10862  val = (SCIP_Longint)SCIPfeasFloor(scip, vals[v]);
10863  if( val % 2 != 0 )
10864  {
10865  /* the odd values have to belong to binary variables */
10866  if( !SCIPvarIsBinary(vars[v]) )
10867  return SCIP_OKAY;
10868 
10869  if( noddvars == 0 )
10870  var1 = vars[v];
10871  else
10872  var2 = vars[v];
10873 
10874  noddvars++;
10875  }
10876  }
10877 
10878  /* check lhs is odd or even */
10879  lhsodd = (((SCIP_Longint)SCIPfeasFloor(scip, lhs)) % 2 != 0);
10880 
10881  if( noddvars == 1 )
10882  {
10883  assert( var1 != NULL );
10884 
10885  SCIPdebugMsg(scip, "linear constraint <%s>: try fixing variable <%s> to <%g>\n",
10886  SCIPconsGetName(cons), SCIPvarGetName(var1), lhsodd ? 1.0 : 0.0);
10887 
10888  SCIP_CALL( SCIPfixVar(scip, var1, lhsodd? 1.0 : 0.0, &infeasible, &fixed) );
10889 
10890  /* check for infeasibility of fixing */
10891  if( infeasible )
10892  {
10893  SCIPdebugMsg(scip, " -> infeasible fixing\n");
10894  *cutoff = TRUE;
10895  return SCIP_OKAY;
10896  }
10897 
10898  if( fixed )
10899  {
10900  SCIPdebugMsg(scip, " -> feasible fixing\n");
10901  (*nfixedvars)++;
10902  success = TRUE;
10903  }
10904  }
10905  else if( noddvars == 2 )
10906  {
10907  assert( var1 != NULL );
10908  assert( var2 != NULL );
10909 
10910  /* aggregate the two variables with odd coefficient
10911  * - lhs is odd -> exactly one of the variable has to be 1 -> var1 + var2 = 1
10912  * - lhs is even -> both have to take the same value -> var1 - var2 = 0
10913  */
10914  SCIPdebugMsg(scip, "linear constraint <%s>: try aggregation of variables <%s> and <%s>\n",
10915  SCIPconsGetName(cons), SCIPvarGetName(var1), SCIPvarGetName(var2));
10916 
10917  SCIP_CALL( SCIPaggregateVars(scip, var1, var2, 1.0, lhsodd ? 1.0 : -1.0,
10918  lhsodd ? 1.0 : 0.0, &infeasible, &redundant, &aggregated) );
10919 
10920  /* check for infeasibility of aggregation */
10921  if( infeasible )
10922  {
10923  SCIPdebugMsg(scip, " -> infeasible aggregation\n");
10924  *cutoff = TRUE;
10925  return SCIP_OKAY;
10926  }
10927 
10928  /* count the aggregation */
10929  if( aggregated )
10930  {
10931  SCIPdebugMsg(scip, " -> feasible aggregation\n");
10932  (*naggrvars)++;
10933  success = TRUE;
10934  }
10935  }
10936 
10937  if( success )
10938  {
10939  /* apply fixings and aggregation to successfully rerun this presolving step */
10940  SCIP_CALL( applyFixings(scip, cons, &infeasible) );
10941 
10942  if( infeasible )
10943  {
10944  SCIPdebugMsg(scip, " -> infeasible fixing\n");
10945  *cutoff = TRUE;
10946  return SCIP_OKAY;
10947  }
10948 
10949  /* normalize constraint */
10950  SCIP_CALL( normalizeCons(scip, cons) );
10951  }
10952  }
10953  while( success );
10954 
10955  return SCIP_OKAY;
10956 }
10957 
10958 
10959 
10960 /** sorting method for constraint data, compares two variables on given indices, continuous variables will be sorted to
10961  * the end and for all other variables the sortation will be in non-increasing order of their absolute value of the
10962  * coefficients
10963  */
10964 static
10965 SCIP_DECL_SORTINDCOMP(consdataCompSim)
10966 { /*lint --e{715}*/
10967  SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
10968  SCIP_VARTYPE vartype1;
10969  SCIP_VARTYPE vartype2;
10970  SCIP_Real value;
10971 
10972  assert(consdata != NULL);
10973  assert(0 <= ind1 && ind1 < consdata->nvars);
10974  assert(0 <= ind2 && ind2 < consdata->nvars);
10975 
10976  vartype1 = SCIPvarGetType(consdata->vars[ind1]);
10977  vartype2 = SCIPvarGetType(consdata->vars[ind2]);
10978 
10979  if( vartype1 == SCIP_VARTYPE_CONTINUOUS )
10980  {
10981  /* continuous varibles will be sorted to the back */
10982  if( vartype2 != vartype1 )
10983  return +1;
10984  /* both variables are continuous */
10985  else
10986  return 0;
10987  }
10988  /* continuous variables will be sorted to the back */
10989  else if( vartype2 == SCIP_VARTYPE_CONTINUOUS )
10990  return -1;
10991 
10992  value = REALABS(consdata->vals[ind2]) - REALABS(consdata->vals[ind1]);
10993 
10994  /* for all non-continuous variables, the variables are sorted after decreasing absolute coefficients */
10995  return (value > 0 ? +1 : (value < 0 ? -1 : 0));
10996 }
10997 
10998 /** tries to simplify coefficients and delete variables in ranged row of the form lhs <= a^Tx <= rhs, e.g. using the greatest
10999  * common divisor
11000  *
11001  * 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
11002  * constraint to 1^Tx = 1
11003  */
11004 static
11006  SCIP* scip, /**< SCIP data structure */
11007  SCIP_CONS* cons, /**< linear constraint */
11008  int* nchgcoefs, /**< pointer to store the amount of changed coefficients */
11009  int* nchgsides /**< pointer to store the amount of changed sides */
11010  )
11011 {
11012  SCIP_CONSDATA* consdata;
11013  SCIP_VAR** vars;
11014  SCIP_Real* vals;
11015  SCIP_Real minval;
11016  SCIP_Real secondminval;
11017  SCIP_Real maxval;
11018  SCIP_Real lhs;
11019  SCIP_Real rhs;
11020  int nvars;
11021  int v;
11023  /* we must not change a modifiable constraint in any way */
11024  if( SCIPconsIsModifiable(cons) )
11025  return SCIP_OKAY;
11026 
11027  if( SCIPconsIsDeleted(cons) )
11028  return SCIP_OKAY;
11029 
11030  consdata = SCIPconsGetData(cons);
11031  assert(consdata != NULL);
11032 
11033  nvars = consdata->nvars;
11034 
11035  /* do not check empty or bound-constraints */
11036  if( nvars < 2 )
11037  return SCIP_OKAY;
11038 
11039  vals = consdata->vals;
11040  vars = consdata->vars;
11041  assert(vars != NULL);
11042  assert(vals != NULL);
11043 
11044  lhs = consdata->lhs;
11045  rhs = consdata->rhs;
11046  assert(!SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs));
11047  assert(!SCIPisNegative(scip, rhs));
11048 
11049  minval = SCIP_INVALID;
11050  secondminval = SCIP_INVALID;
11051  maxval = -SCIP_INVALID;
11052 
11053  for( v = nvars - 1; v >= 0; --v )
11054  {
11055  if( SCIPvarIsBinary(vars[v]) )
11056  {
11057  if( minval > vals[v] || minval == SCIP_INVALID ) /*lint !e777*/
11058  {
11059  secondminval = minval;
11060  minval = vals[v];
11061  }
11062  else if( secondminval > vals[v] || secondminval == SCIP_INVALID ) /*lint !e777*/
11063  secondminval = vals[v];
11064 
11065  if( maxval < vals[v] || maxval == -SCIP_INVALID ) /*lint !e777*/
11066  maxval = vals[v];
11067  }
11068  else
11069  break;
11070  }
11071 
11072  /* check if all variables are binary */
11073  if( v == -1 )
11074  {
11075  if( SCIPisEQ(scip, minval, maxval) && SCIPisEQ(scip, lhs, rhs) )
11076  return SCIP_OKAY;
11077 
11078  /* check if we can and need to choose exactly one binary variable */
11079  if( SCIPisGE(scip, minval, lhs) && SCIPisLE(scip, maxval, rhs) && SCIPisGT(scip, minval + secondminval, rhs) )
11080  {
11081  /* change all coefficients to 1.0 */
11082  for( v = nvars - 1; v >= 0; --v )
11083  {
11084  SCIP_CALL( chgCoefPos(scip, cons, v, 1.0) );
11085  }
11086  (*nchgcoefs) += nvars;
11087 
11088  /* replace old right and left hand side with 1.0 */
11089  SCIP_CALL( chgRhs(scip, cons, 1.0) );
11090  SCIP_CALL( chgLhs(scip, cons, 1.0) );
11091  (*nchgsides) += 2;
11092  }
11093  }
11094 
11095  return SCIP_OKAY;
11096 }
11097 
11098 /** tries to simplify coefficients and delete variables in constraints of the form lhs <= a^Tx <= rhs
11099  * for equations @see rangedRowSimplify() will be called
11100  *
11101  * there are several different coefficient reduction steps which will be applied
11102  *
11103  * 1. We try to determine parts of the constraint which will not change anything on (in-)feasibility of the constraint
11104  *
11105  * e.g. 5x1 + 5x2 + 3z1 <= 8 => 3z1 is redundant if all x are binary and -2 < 3z1 <= 3
11106  *
11107  * 2. We try to remove redundant fractional parts in a constraint
11108  *
11109  * e.g. 5.2x1 + 5.1x2 + 3x3 <= 8.3 => will be changed to 5x1 + 5x2 + 3x3 <= 8 if all x are binary
11110  *
11111  * 3. We are using the greatest common divisor for further reductions
11112  *
11113  * e.g. 10x1 + 5y2 + 5x3 + 3x4 <= 15 => will be changed to 2x1 + y2 + x3 + x4 <= 3 if all xi are binary and y2 is
11114  * integral
11115  */
11116 static
11118  SCIP* scip, /**< SCIP data structure */
11119  SCIP_CONS* cons, /**< linear constraint */
11120  int* nchgcoefs, /**< pointer to store the amount of changed coefficients */
11121  int* nchgsides /**< pointer to store the amount of changed sides */
11122  )
11123 {
11124  SCIP_CONSDATA* consdata;
11125  SCIP_VAR** vars;
11126  SCIP_Real* vals;
11127  int* perm;
11128  SCIP_Real minactsub;
11129  SCIP_Real maxactsub;
11130  SCIP_Real siderest;
11131  SCIP_Real feastol;
11132  SCIP_Real newcoef;
11133  SCIP_Real absval;
11135  SCIP_Real lhs;
11136  SCIP_Real rhs;
11137  SCIP_Real lb;
11138  SCIP_Real ub;
11139  SCIP_Longint restcoef;
11140  SCIP_Longint oldgcd;
11141  SCIP_Longint rest;
11142  SCIP_Longint gcd;
11143  SCIP_Bool isminsettoinfinity;
11144  SCIP_Bool ismaxsettoinfinity;
11145  SCIP_Bool isminrelax;
11146  SCIP_Bool ismaxrelax;
11147  SCIP_Bool allcoefintegral;
11148  SCIP_Bool onlybin;
11149  SCIP_Bool hasrhs;
11150  SCIP_Bool haslhs;
11151  int oldnchgcoefs;
11152  int oldnchgsides;
11153  int foundbin;
11154  int candpos;
11155  int candpos2;
11156  int offsetv;
11157  int nvars;
11158  int v;
11159  int w;
11160 
11161  assert(scip != NULL);
11162  assert(cons != NULL);
11163  assert(nchgcoefs != NULL);
11164  assert(nchgsides != NULL);
11165 
11166  /* we must not change a modifiable constraint in any way */
11167  if( SCIPconsIsModifiable(cons) )
11168  return SCIP_OKAY;
11169 
11170  if( SCIPconsIsDeleted(cons) )
11171  return SCIP_OKAY;
11172 
11173  consdata = SCIPconsGetData(cons);
11174  assert(consdata != NULL);
11175 
11176  nvars = consdata->nvars;
11177 
11178  /* do not check empty or bound-constraints */
11179  if( nvars <= 2 )
11180  return SCIP_OKAY;
11181 
11182  /* update maximal activity delta if necessary */
11183  if( consdata->maxactdelta == SCIP_INVALID ) /*lint !e777*/
11184  consdataRecomputeMaxActivityDelta(scip, consdata);
11185 
11186  assert(consdata->maxactdelta != SCIP_INVALID); /*lint !e777*/
11187  assert(!SCIPisFeasNegative(scip, consdata->maxactdelta));
11188  checkMaxActivityDelta(scip, consdata);
11189 
11190  /* @todo the following might be too hard, check which steps can be applied and what code must be corrected
11191  * accordingly
11192  */
11193  /* can only work with valid non-infinity activities per variable */
11194  if( SCIPisInfinity(scip, consdata->maxactdelta) )
11195  return SCIP_OKAY;
11196 
11197  /* @todo: change the following: due to vartype changes, the status of the normalization can be wrong, need an event
11198  * but the eventsystem seems to be full
11199  */
11200  consdata->normalized = FALSE;
11201 
11202  /* normalize constraint */
11203  SCIP_CALL( normalizeCons(scip, cons) );
11204  assert(nvars == consdata->nvars);
11205 
11206  if( !consdata->normalized )
11207  return SCIP_OKAY;
11208 
11209  lhs = consdata->lhs;
11210  rhs = consdata->rhs;
11211  assert(!SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs));
11212  assert(!SCIPisNegative(scip, rhs));
11213 
11214  if( !SCIPisInfinity(scip, -lhs) )
11215  haslhs = TRUE;
11216  else
11217  haslhs = FALSE;
11218 
11219  if( !SCIPisInfinity(scip, rhs) )
11220  hasrhs = TRUE;
11221  else
11222  hasrhs = FALSE;
11223 
11224  SCIPdebug( oldnchgcoefs = *nchgcoefs; )
11225  SCIPdebug( oldnchgsides = *nchgsides; )
11226 
11227  /* @todo also work on ranged rows */
11228  if( haslhs && hasrhs )
11229  {
11230  SCIP_CALL( rangedRowSimplify(scip, cons, nchgcoefs, nchgsides ) );
11231 
11232  return SCIP_OKAY;
11233  }
11234  assert(haslhs != hasrhs);
11235 
11236  /* if we have a normalized inequality (not ranged) the one side should be positive, @see normalizeCons() */
11237  assert(!hasrhs || !SCIPisNegative(scip, rhs));
11238  assert(!haslhs || !SCIPisNegative(scip, lhs));
11239 
11240  /* get temporary memory to store the sorted permutation */
11241  SCIP_CALL( SCIPallocBufferArray(scip, &perm, nvars) );
11242 
11243  /* call sorting method, order continuous variables to the end and all other variables after non-increasing absolute
11244  * value of their coefficients
11245  */
11246  SCIPsort(perm, consdataCompSim, (void*)consdata, nvars);
11247 
11248  /* perform sorting after permutation array */
11249  permSortConsdata(consdata, perm, nvars);
11250  consdata->sorted = FALSE;
11251  consdata->binvarssorted = FALSE;
11252 
11253  vars = consdata->vars;
11254  vals = consdata->vals;
11255  assert(vars != NULL);
11256  assert(vals != NULL);
11257  assert(consdata->validmaxabsval ? (SCIPisFeasEQ(scip, consdata->maxabsval, REALABS(vals[0])) || SCIPvarGetType(vars[nvars - 1]) == SCIP_VARTYPE_CONTINUOUS) : TRUE);
11258 
11259  /* free temporary memory */
11260  SCIPfreeBufferArray(scip, &perm);
11261 
11262  /* only check constraints with at least two non continuous variables */
11263  if( SCIPvarGetType(vars[1]) == SCIP_VARTYPE_CONTINUOUS )
11264  return SCIP_OKAY;
11265 
11266  /* do not process constraints when all coefficients are 1.0 */
11267  if( SCIPisEQ(scip, REALABS(vals[0]), 1.0) && ((hasrhs && SCIPisIntegral(scip, rhs)) || (haslhs && SCIPisIntegral(scip, lhs))) )
11268  return SCIP_OKAY;
11269 
11270  feastol = SCIPfeastol(scip);
11271 
11272  SCIPdebugMsg(scip, "starting simplification of coefficients\n");
11273  SCIPdebugPrintCons(scip, cons, NULL);
11274 
11275  /* get global activities */
11276  consdataGetGlbActivityBounds(scip, consdata, FALSE, &minactsub, &maxactsub,
11277  &isminrelax, &ismaxrelax, &isminsettoinfinity, &ismaxsettoinfinity);
11278 
11279  /* cannot work with infinite activities */
11280  if( isminsettoinfinity || ismaxsettoinfinity )
11281  return SCIP_OKAY;
11282 
11283  assert(!isminrelax);
11284  assert(!ismaxrelax);
11285  assert(maxactsub > minactsub);
11286  assert(!SCIPisInfinity(scip, -minactsub));
11287  assert(!SCIPisInfinity(scip, maxactsub));
11288 
11289  v = 0;
11290  offsetv = -1;
11291  side = haslhs ? lhs : rhs;
11292 
11293  /* we now determine coefficients as large as the side of the constraint to retrieve a better reduction where we
11294  * do not need to look at the large coefficients
11295  *
11296  * e.g. all x are binary, z are positive integer
11297  * c1: +5x1 + 5x2 + 3x3 + 3x4 + x5 >= 5 (x5 is redundant and does not change (in-)feasibility of this constraint)
11298  * c2: +4x1 + 4x2 + 3x3 + 3x4 + x5 >= 4 (gcd (without the coefficient of x5) after the large coefficients is 3
11299  * c3: +30x1 + 29x2 + 14x3 + 14z1 + 7x5 + 7x6 <= 30 (gcd (without the coefficient of x2) after the large coefficients is 7
11300  *
11301  * can be changed to
11302  *
11303  * c1: +6x1 + 6x2 + 3x3 + 3x4 >= 6 (will be changed to c1: +2x1 + 2x2 + x3 + x4 >= 2)
11304  * c2: +6x1 + 6x2 + 3x3 + 3x4 + 3x5 >= 6 (will be changed to c2: +2x1 + 2x2 + x3 + x4 + x5 >= 2)
11305  * c3: +28x1 + 28x2 + 14x3 + 14z1 + 7x5 + 7x6 <= 28 (will be changed to c3: +4x1 + 4x2 + 2x3 + 2z1 + x5 + x6 <= 4)
11306  */
11307 
11308  /* if the minimal activity is negative and we found more than one variable with a coefficient bigger than the left
11309  * hand side, we cannot apply the extra reduction step and need to reset v
11310  *
11311  * e.g. 7x1 + 7x2 - 4x3 - 4x4 >= 7 => xi = 1 for all i is not a solution, but if we would do a change on the
11312  * coefficients due to the gcd on the "small" coefficients we would get 8x1 + 8x2 - 4x3 - 4x4 >= 8 were xi = 1
11313  * for all i is a solution
11314  *
11315  * also redundancy of variables would not be correctly determined in such a case
11316  */
11317  if( nvars > 2 && SCIPisEQ(scip, vals[0], side) && !SCIPisNegative(scip, minactsub) )
11318  {
11319  v = 1;
11320 
11321  while( v < nvars && SCIPisEQ(scip, side, vals[v]) )
11322  {
11323  /* if we have integer variable with "side"-coefficients but also with a lower bound greater than 0 we stop this
11324  * extra step, which might have worked
11325  */
11326  if( SCIPvarGetLbGlobal(vars[v]) > 0.5 )
11327  {
11328  v = 0;
11329  break;
11330  }
11331 
11332  ++v;
11333  }
11334 
11335  /* easy and quick fix: if all coefficients were equal to the side, we cannot apply further simplifications */
11336  /* todo find numerically stable normalization conditions to scale this cons to have coefficients almost equal to 1 */
11337  if( v == nvars )
11338  return SCIP_OKAY;
11339 
11340  /* cannot work with continuous variables which have a big coefficient */
11341  if( v > 0 && SCIPvarGetType(vars[v - 1]) == SCIP_VARTYPE_CONTINUOUS )
11342  return SCIP_OKAY;
11343 
11344  /* big negative coefficient, do not try to use the extra coefficient reduction step */
11345  if( SCIPisEQ(scip, side, -vals[v]) )
11346  v = 0;
11347 
11348  /* all but one variable are processed or the next variable is continuous we cannot perform the extra coefficient
11349  * reduction
11350  */
11351  if( v == nvars - 1 || SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11352  v = 0;
11353 
11354  if( v > 0 )
11355  {
11356  assert(v < nvars);
11357 
11358  offsetv = v - 1;
11359 
11360  for( w = 0; w < v; ++w )
11361  {
11362  lb = SCIPvarGetLbGlobal(vars[w]);
11363  ub = SCIPvarGetUbGlobal(vars[w]);
11364 
11365  assert(vals[w] > 0);
11366 
11367  /* update residual activities */
11368  maxactsub -= ub * vals[w];
11369  minactsub -= lb * vals[w];
11370  assert(maxactsub > minactsub);
11371  }
11372  }
11373  }
11374 
11375  /* find and remove redundant variables which do not interact with the (in-)feasibility of this constraint
11376  *
11377  * e.g. let all x are binary and y1 is continuous with bounds [-3,1] then we can reduce
11378  *
11379  * 15x1 + 15x2 + 7x3 + 3x4 + y1 <= 26
11380  * to
11381  * 15x1 + 15x2 <= 26 <=> x1 + x2 <= 1
11382  */
11383  if( nvars > 2 && SCIPisIntegral(scip, vals[v]) )
11384  {
11385  SCIP_Bool redundant = FALSE;
11386 
11387  gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
11388  assert(gcd >= 1);
11389 
11390  if( v == 0 )
11391  {
11392  lb = SCIPvarGetLbGlobal(vars[0]);
11393  ub = SCIPvarGetUbGlobal(vars[0]);
11394 
11395  /* update residual activities */
11396  if( vals[0] > 0 )
11397  {
11398  maxactsub -= ub * vals[0];
11399  minactsub -= lb * vals[0];
11400  }
11401  else
11402  {
11403  maxactsub -= lb * vals[0];
11404  minactsub -= ub * vals[0];
11405  }
11406  assert(maxactsub > minactsub);
11407  ++v;
11408  }
11409 
11410  siderest = -SCIP_INVALID;
11411  allcoefintegral = TRUE;
11412 
11413  /* check if some variables always fit into the given constraint */
11414  for( ; v < nvars - 1; ++v )
11415  {
11416  if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11417  break;
11418 
11419  if( !SCIPisIntegral(scip, vals[v]) )
11420  {
11421  allcoefintegral = FALSE;
11422  break;
11423  }
11424 
11425  /* calculate greatest common divisor for all general and binary variables */
11426  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
11427 
11428  if( gcd == 1 )
11429  break;
11430 
11431  lb = SCIPvarGetLbGlobal(vars[v]);
11432  ub = SCIPvarGetUbGlobal(vars[v]);
11433 
11434  assert(!SCIPisInfinity(scip, -lb));
11435  assert(!SCIPisInfinity(scip, ub));
11436 
11437  /* update residual activities */
11438  if( vals[v] > 0 )
11439  {
11440  maxactsub -= ub * vals[v];
11441  minactsub -= lb * vals[v];
11442  }
11443  else
11444  {
11445  maxactsub -= lb * vals[v];
11446  minactsub -= ub * vals[v];
11447  }
11448  assert(SCIPisGE(scip, maxactsub, minactsub));
11449 
11450  if( hasrhs )
11451  {
11452  /* determine the remainder of the right hand side and the gcd */
11453  siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11454  }
11455  else
11456  {
11457  /* determine the remainder of the left hand side and the gcd */
11458  siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11459  if( SCIPisZero(scip, siderest) )
11460  siderest = gcd;
11461  }
11462 
11463  /* early termination if the activities deceed the gcd */
11464  if( (offsetv == -1 && hasrhs && maxactsub <= siderest && SCIPisFeasGT(scip, minactsub, siderest - gcd)) || (haslhs && SCIPisFeasLT(scip, maxactsub, siderest) && minactsub >= siderest - gcd) )
11465  {
11466  redundant = TRUE;
11467  break;
11468  }
11469  }
11470  assert(v < nvars || (offsetv >= 0 && gcd > 1));
11471 
11472  if( !redundant )
11473  {
11474  if( hasrhs )
11475  {
11476  /* determine the remainder of the right hand side and the gcd */
11477  siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11478  }
11479  else
11480  {
11481  /* determine the remainder of the left hand side and the gcd */
11482  siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11483  if( SCIPisZero(scip, siderest) )
11484  siderest = gcd;
11485  }
11486  }
11487  else
11488  ++v;
11489 
11490  SCIPdebugMsg(scip, "stopped at pos %d (of %d), subactivities [%g, %g], redundant = %u, hasrhs = %u, siderest = %g, gcd = %" SCIP_LONGINT_FORMAT ", offset position for 'side' coefficients = %d\n",
11491  v, nvars, minactsub, maxactsub, redundant, hasrhs, siderest, gcd, offsetv);
11492 
11493  /* check if we can remove redundant variables */
11494  if( v < nvars && (redundant ||
11495  (offsetv == -1 && hasrhs && maxactsub <= siderest && SCIPisFeasGT(scip, minactsub, siderest - gcd)) ||
11496  (haslhs && SCIPisFeasLT(scip, maxactsub, siderest) && minactsub >= siderest - gcd)) )
11497  {
11498  SCIP_Real oldcoef;
11499 
11500  /* double check the redundancy */
11501 #ifndef NDEBUG
11502  SCIP_Real tmpminactsub = 0.0;
11503  SCIP_Real tmpmaxactsub = 0.0;
11504 
11505  /* recompute residual activities */
11506  for( w = v; w < nvars; ++w )
11507  {
11508  lb = SCIPvarGetLbGlobal(vars[w]);
11509  ub = SCIPvarGetUbGlobal(vars[w]);
11510 
11511  assert(!SCIPisInfinity(scip, -lb));
11512  assert(!SCIPisInfinity(scip, ub));
11513 
11514  /* update residual activities */
11515  if( vals[w] > 0 )
11516  {
11517  tmpmaxactsub += ub * vals[w];
11518  tmpminactsub += lb * vals[w];
11519  }
11520  else
11521  {
11522  tmpmaxactsub += lb * vals[w];
11523  tmpminactsub += ub * vals[w];
11524  }
11525  assert(tmpmaxactsub >= tmpminactsub);
11526  }
11527 
11528  if( hasrhs )
11529  {
11530  assert(offsetv == -1);
11531 
11532  /* determine the remainder of the right hand side and the gcd */
11533  siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11534  }
11535  else
11536  {
11537  /* determine the remainder of the left hand side and the gcd */
11538  siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11539  if( SCIPisZero(scip, siderest) )
11540  siderest = gcd;
11541  }
11542 
11543  /* does the redundancy really is fulfilled */
11544  assert((hasrhs && SCIPisLE(scip, tmpmaxactsub, siderest) && tmpminactsub > siderest - gcd) || (haslhs && tmpmaxactsub < siderest && SCIPisGE(scip, tmpminactsub, siderest - gcd)));
11545 #endif
11546 
11547  SCIPdebugMsg(scip, "removing %d last variables from constraint <%s>, because they never change anything on the feasibility of this constraint\n",
11548  nvars - v, SCIPconsGetName(cons));
11549 
11550  /* remove redundant variables */
11551  for( w = nvars - 1; w >= v; --w )
11552  {
11553  SCIP_CALL( delCoefPos(scip, cons, w) );
11554  }
11555  (*nchgcoefs) += (nvars - v);
11556 
11557  assert(w >= 0);
11558 
11559  oldcoef = vals[w];
11560 
11561  /* normalize constraint */
11562  SCIP_CALL( normalizeCons(scip, cons) );
11563  assert(vars == consdata->vars);
11564  assert(vals == consdata->vals);
11565  assert(w < consdata->nvars);
11566 
11567  /* compute new greatest common divisor due to normalization */
11568  gcd = (SCIP_Longint)(gcd / (oldcoef/vals[w]) + feastol);
11569  assert(gcd >= 1);
11570 
11571  /* update side */
11572  if( hasrhs )
11573  {
11574  /* replace old with new right hand side */
11575  SCIP_CALL( chgRhs(scip, cons, SCIPfeasFloor(scip, consdata->rhs)) );
11576  rhs = consdata->rhs;
11577  }
11578  else
11579  {
11580  if( SCIPisFeasGT(scip, oldcoef/vals[w], 1.0) )
11581  {
11582  SCIP_CALL( chgLhs(scip, cons, SCIPfeasCeil(scip, consdata->lhs)) );
11583  lhs = consdata->lhs;
11584  }
11585  else
11586  assert(offsetv == -1 || SCIPisEQ(scip, vals[offsetv], consdata->lhs));
11587  }
11588  ++(*nchgsides);
11589 
11590  assert(!hasrhs || !SCIPisNegative(scip, rhs));
11591  assert(!haslhs || !SCIPisNegative(scip, lhs));
11592 
11593  /* get new constraint data */
11594  nvars = consdata->nvars;
11595  assert(nvars >= 2);
11596 
11597  allcoefintegral = TRUE;
11598 
11599 #ifndef NDEBUG
11600  /* check integrality */
11601  for( w = offsetv + 1; w < nvars; ++w )
11602  {
11603  assert(SCIPisIntegral(scip, vals[w]));
11604  }
11605 #endif
11606  SCIPdebugPrintCons(scip, cons, NULL);
11607  }
11608 
11609  /* try to find a better gcd, when having large coefficients */
11610  if( offsetv >= 0 && gcd == 1 )
11611  {
11612  /* calculate greatest common divisor for all general variables */
11613  gcd = (SCIP_Longint)(REALABS(vals[nvars - 1]) + feastol);
11614 
11615  if( gcd > 1 )
11616  {
11617  gcd = -1;
11618  candpos = -1;
11619 
11620  for( v = nvars - 1; v > offsetv; --v )
11621  {
11622  assert(!SCIPisZero(scip, vals[v]));
11623  if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11624  break;
11625 
11626  if( !SCIPisIntegral(scip, vals[v]) )
11627  {
11628  allcoefintegral = FALSE;
11629  break;
11630  }
11631 
11632  oldgcd = gcd;
11633 
11634  if( gcd == -1 )
11635  {
11636  gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
11637  assert(gcd >= 1);
11638  }
11639  else
11640  {
11641  /* calculate greatest common divisor for all general and binary variables */
11642  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
11643  }
11644 
11645  /* if the greatest commmon divisor has become 1, we might have found the possible coefficient to change or we
11646  * can stop searching
11647  */
11648  if( gcd == 1 )
11649  {
11650  if( !SCIPvarIsBinary(vars[v]) )
11651  break;
11652 
11653  /* found candidate */
11654  if( candpos == -1 )
11655  {
11656  gcd = oldgcd;
11657  candpos = v;
11658  }
11659  /* two different binary variables lead to a gcd of one, so we cannot change a coefficient */
11660  else
11661  break;
11662  }
11663  }
11664  assert(v > offsetv || candpos > offsetv);
11665  }
11666  else
11667  candpos = -1;
11668  }
11669  else
11670  candpos = nvars - 1;
11671 
11672  /* check last coefficient for integrality */
11673  if( gcd > 1 && allcoefintegral && !redundant )
11674  {
11675  if( !SCIPisIntegral(scip, vals[nvars - 1]) )
11676  allcoefintegral = FALSE;
11677  }
11678 
11679  /* check for further necessary coefficient adjustments */
11680  if( offsetv >= 0 && gcd > 1 && allcoefintegral )
11681  {
11682  assert(offsetv + 1 < nvars);
11683  assert(0 <= candpos && candpos < nvars);
11684 
11685  if( SCIPvarGetType(vars[candpos]) != SCIP_VARTYPE_CONTINUOUS )
11686  {
11687  SCIP_Bool notchangable = FALSE;
11688 
11689 #ifndef NDEBUG
11690  /* check integrality */
11691  for( w = offsetv + 1; w < nvars; ++w )
11692  {
11693  assert(SCIPisIntegral(scip, vals[w]));
11694  }
11695 #endif
11696 
11697  if( vals[candpos] > 0 && SCIPvarIsBinary(vars[candpos]) &&
11698  SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) < gcd )
11699  {
11700  /* determine the remainder of the side and the gcd */
11701  if( hasrhs )
11702  rest = ((SCIP_Longint)(rhs + feastol)) % gcd;
11703  else
11704  rest = ((SCIP_Longint)(lhs + feastol)) % gcd;
11705  assert(rest >= 0);
11706  assert(rest < gcd);
11707 
11708  /* determine the remainder of the coefficient candidate and the gcd */
11709  restcoef = ((SCIP_Longint)(vals[candpos] + feastol)) % gcd;
11710  assert(restcoef >= 1);
11711  assert(restcoef < gcd);
11712 
11713  if( hasrhs )
11714  {
11715  /* calculate new coefficient */
11716  if( restcoef > rest )
11717  newcoef = vals[candpos] - restcoef + gcd;
11718  else
11719  newcoef = vals[candpos] - restcoef;
11720  }
11721  else
11722  {
11723  /* calculate new coefficient */
11724  if( rest == 0 || restcoef < rest )
11725  newcoef = vals[candpos] - restcoef;
11726  else
11727  newcoef = vals[candpos] - restcoef + gcd;
11728  }
11729 
11730 
11731  /* done */
11732 
11733  /* new coeffcient must not be zero if we would loose the implication that a variable needs to be 0 if
11734  * another with the big coefficient was set to 1
11735  */
11736  if( hasrhs && SCIPisZero(scip, newcoef) )
11737  {
11738  notchangable = TRUE;
11739  }
11740  else if( SCIPisZero(scip, newcoef) )
11741  {
11742  /* delete old redundant coefficient */
11743  SCIP_CALL( delCoefPos(scip, cons, candpos) );
11744  ++(*nchgcoefs);
11745  }
11746  else
11747  {
11748  /* replace old with new coefficient */
11749  SCIP_CALL( chgCoefPos(scip, cons, candpos, newcoef) );
11750  ++(*nchgcoefs);
11751  }
11752  }
11753  else if( vals[candpos] < 0 || !SCIPvarIsBinary(vars[candpos]) )
11754  {
11755  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol));
11756  }
11757 
11758  /* correct side and big coefficients */
11759  if( (!notchangable && hasrhs && ((!SCIPisFeasIntegral(scip, rhs) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(rhs + feastol)) < gcd) && (SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) == gcd))) ||
11760  ( haslhs && (!SCIPisFeasIntegral(scip, lhs) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(lhs + feastol)) < gcd) && (SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) == gcd)) )
11761  {
11762  if( haslhs )
11763  {
11764  newcoef = (SCIP_Real)((SCIP_Longint)(SCIPfeasCeil(scip, lhs/gcd) * gcd + feastol));
11765 
11766  SCIP_CALL( chgLhs(scip, cons, newcoef) );
11767  ++(*nchgsides);
11768  }
11769  else
11770  {
11771  assert(hasrhs);
11772  newcoef = (SCIP_Real)((SCIP_Longint)(SCIPfeasFloor(scip, rhs/gcd) * gcd + feastol));
11773 
11774  SCIP_CALL( chgRhs(scip, cons, newcoef) );
11775  ++(*nchgsides);
11776  }
11777 
11778  /* correct coefficients up front */
11779  for( w = offsetv; w >= 0; --w )
11780  {
11781  assert(vals[w] > 0);
11782 
11783  SCIP_CALL( chgCoefPos(scip, cons, w, newcoef) );
11784  }
11785  (*nchgcoefs) += (offsetv + 1);
11786  }
11787 
11788  if( !notchangable )
11789  {
11790  /* normalize constraint */
11791  SCIP_CALL( normalizeCons(scip, cons) );
11792  assert(vars == consdata->vars);
11793  assert(vals == consdata->vals);
11794 
11795  /* get new constraint data */
11796  nvars = consdata->nvars;
11797  assert(nvars >= 2);
11798 
11799  SCIPdebugPrintCons(scip, cons, NULL);
11800 
11801  lhs = consdata->lhs;
11802  rhs = consdata->rhs;
11803  assert(!hasrhs || !SCIPisNegative(scip, rhs));
11804  assert(!haslhs || !SCIPisNegative(scip, lhs));
11805  }
11806  }
11807  }
11808  }
11809 
11810  /* @todo we still can remove continuous variables if they are redundant due to the non-integrality argument */
11811  /* no continuous variables are left over */
11812  if( SCIPvarGetType(vars[nvars - 1]) == SCIP_VARTYPE_CONTINUOUS )
11813  return SCIP_OKAY;
11814 
11815  onlybin = TRUE;
11816  allcoefintegral = TRUE;
11817  /* check if all variables are of binary type */
11818  for( v = nvars - 1; v >= 0; --v )
11819  {
11820  if( !SCIPvarIsBinary(vars[v]) )
11821  onlybin = FALSE;
11822  if( !SCIPisIntegral(scip, vals[v]) )
11823  allcoefintegral = FALSE;
11824  }
11825 
11826  /* check if the non-integrality part of all integral variables is smaller than the non-inegrality part of the right
11827  * hand side or bigger than the left hand side respectively, so we can make all of them integral
11828  *
11829  * @todo there are some steps missing ....
11830  */
11831  if( (hasrhs && !SCIPisFeasIntegral(scip, rhs)) || (haslhs && !SCIPisFeasIntegral(scip, lhs)) )
11832  {
11833  SCIP_Real val;
11834  SCIP_Real newval;
11835  SCIP_Real frac = 0.0;
11836  SCIP_Bool found = FALSE;
11837 
11838  if( hasrhs )
11839  {
11840  if( allcoefintegral )
11841  {
11842  /* replace old with new right hand side */
11843  SCIP_CALL( chgRhs(scip, cons, SCIPfloor(scip, rhs)) );
11844  ++(*nchgsides);
11845  }
11846  else
11847  {
11848  siderest = rhs - SCIPfloor(scip, rhs);
11849 
11850  /* try to round down all non-integral coefficients */
11851  for( v = nvars - 1; v >= 0; --v )
11852  {
11853  val = vals[v];
11854 
11855  /* add up all possible fractional parts */
11856  if( !SCIPisIntegral(scip, val) )
11857  {
11858  lb = SCIPvarGetLbGlobal(vars[v]);
11859  ub = SCIPvarGetUbGlobal(vars[v]);
11860 
11861  /* at least one bound need to be at zero */
11862  if( !onlybin && !SCIPisFeasZero(scip, lb) && !SCIPisFeasZero(scip, ub) )
11863  return SCIP_OKAY;
11864 
11865  /* swap bounds for 'standard' form */
11866  if( !SCIPisFeasZero(scip, lb) )
11867  {
11868  ub = lb;
11869  val *= -1;
11870  }
11871 
11872  found = TRUE;
11873 
11874  frac += (val - SCIPfloor(scip, val)) * ub;
11875 
11876  /* if we exceed the fractional part of the right hand side, we cannot tighten the coefficients
11877  *
11878  * e.g. 1.1x1 + 1.1x2 + 1.4x3 + 1.02x4 <= 2.4, here we cannot floor all fractionals because
11879  * x3, x4 set to 1 would be infeasible but feasible after flooring
11880  */
11881  if( SCIPisGT(scip, frac, siderest) )
11882  return SCIP_OKAY;
11883  }
11884  }
11885  assert(v == -1);
11886 
11887  SCIPdebugMsg(scip, "rounding all non-integral coefficients and the right hand side down\n");
11888 
11889  /* round rhs and coefficients to integral values */
11890  if( found )
11891  {
11892  for( v = nvars - 1; v >= 0; --v )
11893  {
11894  val = vals[v];
11895 
11896  /* add the whole fractional part */
11897  if( !SCIPisIntegral(scip, val) )
11898  {
11899  lb = SCIPvarGetLbGlobal(vars[v]);
11900 
11901  if( SCIPisFeasZero(scip, lb) )
11902  newval = SCIPfloor(scip, val);
11903  else
11904  newval = SCIPceil(scip, val);
11905 
11906  if( SCIPisZero(scip, newval) )
11907  {
11908  /* delete old redundant coefficient */
11909  SCIP_CALL( delCoefPos(scip, cons, v) );
11910  ++(*nchgcoefs);
11911  }
11912  else
11913  {
11914  /* replace old with new coefficient */
11915  SCIP_CALL( chgCoefPos(scip, cons, v, newval) );
11916  ++(*nchgcoefs);
11917  }
11918  }
11919  }
11920  }
11921 
11922  /* replace old with new right hand side */
11923  SCIP_CALL( chgRhs(scip, cons, SCIPfloor(scip, rhs)) );
11924  ++(*nchgsides);
11925  }
11926  }
11927  else
11928  {
11929  if( allcoefintegral )
11930  {
11931  /* replace old with new left hand side */
11932  SCIP_CALL( chgLhs(scip, cons, SCIPceil(scip, lhs)) );
11933  ++(*nchgsides);
11934  }
11935  else
11936  {
11937  /* cannot floor left hand side to zero */
11938  if( SCIPisLT(scip, lhs, 1.0) )
11939  return SCIP_OKAY;
11940 
11941  siderest = lhs - SCIPfloor(scip, lhs);
11942 
11943  /* try to round down all non-integral coefficients */
11944  for( v = nvars - 1; v >= 0; --v )
11945  {
11946  val = vals[v];
11947 
11948  /* add up all possible fractional parts */
11949  if( !SCIPisIntegral(scip, val) )
11950  {
11951  lb = SCIPvarGetLbGlobal(vars[v]);
11952  ub = SCIPvarGetUbGlobal(vars[v]);
11953 
11954  /* at least one bound need to be at zero */
11955  if( !SCIPisFeasZero(scip, lb) && !SCIPisFeasZero(scip, ub) )
11956  return SCIP_OKAY;
11957 
11958  /* swap bounds for 'standard' form */
11959  if( !SCIPisFeasZero(scip, lb) )
11960  {
11961  ub = lb;
11962  val *= -1;
11963  }
11964 
11965  /* cannot floor to zero */
11966  if( SCIPisLT(scip, val, 1.0) )
11967  return SCIP_OKAY;
11968 
11969  /* the fractional part on each variable need to exceed the fractional part on the left hand side */
11970  if( SCIPisLT(scip, val - SCIPfloor(scip, val), siderest) )
11971  return SCIP_OKAY;
11972 
11973  found = TRUE;
11974 
11975  frac += (val - SCIPfloor(scip, val)) * ub;
11976 
11977  /* if we exceed the fractional part of the left hand side plus one by summing up all maximal
11978  * fractional parts of the variables, we cannot tighten the coefficients
11979  *
11980  * e.g. 4.3x1 + 1.3x2 + 1.3x3 + 1.6x4 >= 4.2, here we cannot floor all fractionals because
11981  * x2-x4 set to 1 would be feasible but not after flooring
11982  */
11983  if( SCIPisGE(scip, frac, 1 + siderest) )
11984  return SCIP_OKAY;
11985  }
11986  /* all coefficients need to be integral, otherwise we might do an invalid reduction */
11987  else
11988  return SCIP_OKAY;
11989  }
11990  assert(v == -1);
11991 
11992  SCIPdebugMsg(scip, "rounding all non-integral coefficients and the left hand side down\n");
11993 
11994  /* round lhs and coefficients to integral values */
11995  if( found )
11996  {
11997  for( v = nvars - 1; v >= 0; --v )
11998  {
11999  val = vals[v];
12000 
12001  /* add the whole fractional part */
12002  if( !SCIPisIntegral(scip, val) )
12003  {
12004  lb = SCIPvarGetLbGlobal(vars[v]);
12005 
12006  if( SCIPisFeasZero(scip, lb) )
12007  newval = SCIPfloor(scip, val);
12008  else
12009  newval = SCIPceil(scip, val);
12010 
12011  if( SCIPisZero(scip, newval) )
12012  {
12013  /* delete old redundant coefficient */
12014  SCIP_CALL( delCoefPos(scip, cons, v) );
12015  ++(*nchgcoefs);
12016  }
12017  else
12018  {
12019  /* replace old with new coefficient */
12020  SCIP_CALL( chgCoefPos(scip, cons, v, newval) );
12021  ++(*nchgcoefs);
12022  }
12023  }
12024  }
12025  }
12026 
12027  /* replace old with new left hand side */
12028  SCIP_CALL( chgLhs(scip, cons, SCIPfloor(scip, lhs)) );
12029  ++(*nchgsides);
12030  }
12031  }
12032 
12033  /* normalize constraint */
12034  SCIP_CALL( normalizeCons(scip, cons) );
12035  assert(vars == consdata->vars);
12036  assert(vals == consdata->vals);
12037 
12038  rhs = consdata->rhs;
12039  lhs = consdata->lhs;
12040 
12041  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12042  assert(!haslhs || !SCIPisNegative(scip, lhs));
12043 
12044  SCIPdebugPrintCons(scip, cons, NULL);
12045 
12046  nvars = consdata->nvars;
12047  if( nvars < 2 )
12048  return SCIP_OKAY;
12049 
12050  allcoefintegral = TRUE;
12051 #ifndef NDEBUG
12052  /* debug check if all coefficients are really integral */
12053  for( v = nvars - 1; v >= 0; --v )
12054  assert(SCIPisIntegral(scip, vals[v]));
12055 #endif
12056  }
12057 
12058  /* @todo following can also work on non integral coefficients, need more investigation */
12059  /* only check constraints with integral coefficients on all integral variables */
12060  if( !allcoefintegral )
12061  return SCIP_OKAY;
12062 
12063  /* we want to avoid numerical troubles, therefore we do not change non-integral sides */
12064  if( (hasrhs && !SCIPisIntegral(scip, rhs)) || (haslhs && !SCIPisIntegral(scip, lhs)) )
12065  return SCIP_OKAY;
12066 
12067  /* maximal absolute value of coefficients in constraint is one, so we cannot tighten it further */
12068  if( SCIPisEQ(scip, REALABS(vals[0]), 1.0) )
12069  return SCIP_OKAY;
12070 
12071  /* stop if the last coeffcients is one in absolute value and the variable is not binary */
12072  if( !SCIPvarIsBinary(vars[nvars - 1]) && SCIPisEQ(scip, REALABS(vals[nvars - 1]), 1.0) )
12073  return SCIP_OKAY;
12074 
12075  assert(nvars >= 2);
12076 
12077  /* start gcd procedure for all variables */
12078  do
12079  {
12080  SCIPdebug( oldnchgcoefs = *nchgcoefs; )
12081  SCIPdebug( oldnchgsides = *nchgsides; )
12082 
12083  /* stop if we have two coeffcients which are one in absolute value */
12084  if( SCIPisEQ(scip, REALABS(vals[nvars - 1]), 1.0) && SCIPisEQ(scip, REALABS(vals[nvars - 2]), 1.0) )
12085  return SCIP_OKAY;
12086 
12087  gcd = -1;
12088 
12089  /* calculate greatest common divisor over all integer variables */
12090  if( !onlybin )
12091  {
12092  foundbin = -1;
12093 
12094  for( v = nvars - 1; v >= 0; --v )
12095  {
12096  assert(!SCIPisZero(scip, vals[v]));
12097  assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_CONTINUOUS);
12098 
12099  if( SCIPvarIsBinary(vars[v]) )
12100  {
12101  if( foundbin == -1 )
12102  foundbin = v;
12103  continue;
12104  }
12105 
12106  absval = REALABS(vals[v]);
12107  assert(SCIPisIntegral(scip, absval));
12108 
12109  if( gcd == -1 )
12110  {
12111  gcd = (SCIP_Longint)(absval + feastol);
12112  assert(gcd >= 1);
12113  }
12114  else
12115  {
12116  /* calculate greatest common divisor for all general variables */
12117  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(absval + feastol));
12118  }
12119  if( gcd == 1 )
12120  break;
12121  }
12122  }
12123  else
12124  foundbin = nvars - 1;
12125 
12126  /* we need at least one binary variable and a gcd greater than 1 to try to perform further coefficient changes */
12127  if( gcd == 1 || foundbin == -1)
12128  return SCIP_OKAY;
12129 
12130  assert((onlybin && gcd == -1) || (!onlybin && gcd > 1));
12131 
12132  candpos = -1;
12133  candpos2 = -1;
12134 
12135  /* calculate greatest common divisor over all integer and binary variables and determine the candidate where we might
12136  * change the coefficient
12137  */
12138  for( v = foundbin; v >= 0; --v )
12139  {
12140  if( onlybin || SCIPvarIsBinary(vars[v]) )
12141  {
12142  absval = REALABS(vals[v]);
12143  assert(SCIPisIntegral(scip, absval));
12144 
12145  oldgcd = gcd;
12146 
12147  if( gcd == -1 )
12148  {
12149  gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
12150  assert(gcd >= 1);
12151  }
12152  else
12153  {
12154  /* calculate greatest common divisor for all general and binary variables */
12155  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
12156  }
12157 
12158  /* if the greatest commmon divisor has become 1, we might have found the possible coefficient to change or we
12159  * can terminate
12160  */
12161  if( gcd == 1 )
12162  {
12163  /* found candidate */
12164  if( candpos == -1 )
12165  {
12166  gcd = oldgcd;
12167  candpos = v;
12168 
12169  /* if we have only binary variables and both first coefficients have a gcd of 1, both are candidates for
12170  * the coefficient change
12171  */
12172  if( onlybin && v == foundbin - 1 )
12173  candpos2 = foundbin;
12174  }
12175  /* two different binary variables lead to a gcd of one, so we cannot change a coefficient */
12176  else
12177  {
12178  if( onlybin && candpos == v + 1 && candpos2 == v + 2 )
12179  {
12180  assert(candpos2 == nvars - 1);
12181 
12182  /* take new candidates */
12183  candpos = candpos2;
12184 
12185  /* recalculate gcd from scratch */
12186  gcd = (SCIP_Longint)(REALABS(vals[v+1]) + feastol);
12187  assert(gcd >= 1);
12188 
12189  /* calculate greatest common divisor for all general and binary variables */
12190  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
12191  if( gcd == 1 )
12192  return SCIP_OKAY;
12193  }
12194  else
12195  /* cannot determine a possible coefficient for reduction */
12196  return SCIP_OKAY;
12197  }
12198  }
12199  }
12200  }
12201  assert(gcd >= 2);
12202 
12203  /* we should have found one coefficient, that led to a gcd of 1, otherwise we could normalize the constraint
12204  * further
12205  */
12206  assert(candpos >= 0 && candpos < nvars);
12207 
12208  /* all variables and all coefficients are integral, so the side should be too */
12209  assert((hasrhs && SCIPisIntegral(scip, rhs)) || (haslhs && SCIPisIntegral(scip, lhs)));
12210 
12211  /* check again, if we have a normalized inequality (not ranged) the one side should be positive,
12212  * @see normalizeCons()
12213  */
12214  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12215  assert(!haslhs || !SCIPisNegative(scip, lhs));
12216 
12217  /* determine the remainder of the side and the gcd */
12218  if( hasrhs )
12219  rest = ((SCIP_Longint)(rhs + feastol)) % gcd;
12220  else
12221  rest = ((SCIP_Longint)(lhs + feastol)) % gcd;
12222  assert(rest >= 0);
12223  assert(rest < gcd);
12224 
12225  /* determine the remainder of the coefficient candidate and the gcd */
12226  if( vals[candpos] < 0 )
12227  {
12228  restcoef = ((SCIP_Longint)(vals[candpos] - feastol)) % gcd;
12229  assert(restcoef <= -1);
12230  restcoef += gcd;
12231  }
12232  else
12233  restcoef = ((SCIP_Longint)(vals[candpos] + feastol)) % gcd;
12234  assert(restcoef >= 1);
12235  assert(restcoef < gcd);
12236 
12237  if( hasrhs )
12238  {
12239  if( rest > 0 )
12240  {
12241  /* replace old with new right hand side */
12242  SCIP_CALL( chgRhs(scip, cons, rhs - rest) );
12243  ++(*nchgsides);
12244  }
12245 
12246  /* calculate new coefficient */
12247  if( restcoef > rest )
12248  newcoef = vals[candpos] - restcoef + gcd;
12249  else
12250  newcoef = vals[candpos] - restcoef;
12251  }
12252  else
12253  {
12254  if( rest > 0 )
12255  {
12256  /* replace old with new left hand side */
12257  SCIP_CALL( chgLhs(scip, cons, lhs - rest + gcd) );
12258  ++(*nchgsides);
12259  }
12260 
12261  /* calculate new coefficient */
12262  if( rest == 0 || restcoef < rest )
12263  newcoef = vals[candpos] - restcoef;
12264  else
12265  newcoef = vals[candpos] - restcoef + gcd;
12266  }
12267  assert(SCIPisZero(scip, newcoef) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(newcoef) + feastol)) == gcd);
12268 
12269  SCIPdebugMsg(scip, "gcd = %" SCIP_LONGINT_FORMAT ", rest = %" SCIP_LONGINT_FORMAT ", restcoef = %" SCIP_LONGINT_FORMAT "; changing coef of variable <%s> to %g and %s by %" SCIP_LONGINT_FORMAT "\n", gcd, rest, restcoef, SCIPvarGetName(vars[candpos]), newcoef, hasrhs ? "reduced rhs" : "increased lhs", hasrhs ? rest : (rest > 0 ? gcd - rest : 0));
12270 
12271  if( SCIPisZero(scip, newcoef) )
12272  {
12273  /* delete redundant coefficient */
12274  SCIP_CALL( delCoefPos(scip, cons, candpos) );
12275  }
12276  else
12277  {
12278  /* replace old with new coefficient */
12279  SCIP_CALL( chgCoefPos(scip, cons, candpos, newcoef) );
12280  }
12281  ++(*nchgcoefs);
12282 
12283  /* now constraint can be normalized, might be directly done by dividing it by the gcd */
12284  SCIP_CALL( normalizeCons(scip, cons) );
12285  assert(vars == consdata->vars);
12286  assert(vals == consdata->vals);
12287 
12288  SCIPdebugPrintCons(scip, cons, NULL);
12289 
12290  rhs = consdata->rhs;
12291  lhs = consdata->lhs;
12292  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12293  assert(!haslhs || !SCIPisNegative(scip, lhs));
12294 
12295  nvars = consdata->nvars;
12296 
12297  SCIPdebugMsg(scip, "we did %d coefficient changes and %d side changes on constraint %s when applying one round of the gcd algorithm\n", *nchgcoefs - oldnchgcoefs, *nchgsides - oldnchgsides, SCIPconsGetName(cons));
12298  }
12299  while( nvars >= 2 );
12300 
12301  return SCIP_OKAY;
12302 }
12303 
12304 
12305 /* tries to aggregate an (in)equality and an equality in order to decrease the number of variables in the (in)equality:
12306  * cons0 := a * cons0 + b * cons1,
12307  * where a = val1[v] and b = -val0[v] for common variable v which removes most variable weight;
12308  * for numerical stability, we will only accept integral a and b;
12309  * the variable weight is a weighted sum over all included variables, where each binary variable weighs BINWEIGHT,
12310  * each integer or implicit integer variable weighs INTWEIGHT and each continuous variable weighs CONTWEIGHT
12311  */
12312 static
12314  SCIP* scip, /**< SCIP data structure */
12315  SCIP_CONS* cons0, /**< (in)equality to modify */
12316  SCIP_CONS* cons1, /**< equality to use for aggregation of cons0 */
12317  int* commonidx0, /**< array with indices of variables in cons0, that appear also in cons1 */
12318  int* commonidx1, /**< array with indices of variables in cons1, that appear also in cons0 */
12319  int* diffidx0minus1, /**< array with indices of variables in cons0, that don't appear in cons1 */
12320  int* diffidx1minus0, /**< array with indices of variables in cons1, that don't appear in cons0 */
12321  int nvarscommon, /**< number of variables, that appear in both constraints */
12322  int commonidxweight, /**< variable weight sum of common variables */
12323  int diffidx0minus1weight, /**< variable weight sum of variables in cons0, that don't appear in cons1 */
12324  int diffidx1minus0weight, /**< variable weight sum of variables in cons1, that don't appear in cons0 */
12325  SCIP_Real maxaggrnormscale, /**< maximal allowed relative gain in maximum norm for constraint aggregation */
12326  int* nchgcoefs, /**< pointer to count the number of changed coefficients */
12327  SCIP_Bool* aggregated /**< pointer to store whether an aggregation was made */
12328  )
12329 {
12330  SCIP_CONSDATA* consdata0;
12331  SCIP_CONSDATA* consdata1;
12332  SCIP_Real a;
12333  SCIP_Real b;
12334  SCIP_Real aggrcoef;
12335  SCIP_Real scalarsum;
12336  SCIP_Real bestscalarsum;
12337  SCIP_Bool betterscalarsum;
12338  SCIP_Bool commonvarlindependent; /* indicates whether coefficient vector of common variables in linearly dependent */
12339  int varweight;
12340  int nvars;
12341  int bestvarweight;
12342  int bestnvars;
12343  int bestv;
12344  int v;
12345  int i;
12346 
12347  assert(scip != NULL);
12348  assert(cons0 != NULL);
12349  assert(cons1 != NULL);
12350  assert(commonidx0 != NULL);
12351  assert(commonidx1 != NULL);
12352  assert(diffidx0minus1 != NULL);
12353  assert(diffidx1minus0 != NULL);
12354  assert(nvarscommon >= 1);
12355  assert(commonidxweight >= nvarscommon);
12356  assert(nchgcoefs != NULL);
12357  assert(aggregated != NULL);
12358 
12359  assert(SCIPconsIsActive(cons0));
12360  assert(SCIPconsIsActive(cons1));
12361 
12362  SCIPdebugMsg(scip, "try aggregation of <%s> and <%s>\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
12363 
12364  /* cons0 is an (in)equality */
12365  consdata0 = SCIPconsGetData(cons0);
12366  assert(consdata0 != NULL);
12367  assert(consdata0->nvars >= 1);
12368  assert(SCIPisLE(scip, consdata0->lhs, consdata0->rhs));
12369  assert(diffidx0minus1weight >= consdata0->nvars - nvarscommon);
12370 
12371  /* cons1 is an equality */
12372  consdata1 = SCIPconsGetData(cons1);
12373  assert(consdata1 != NULL);
12374  assert(consdata1->nvars >= 1);
12375  assert(SCIPisEQ(scip, consdata1->lhs, consdata1->rhs));
12376  assert(diffidx1minus0weight >= consdata1->nvars - nvarscommon);
12377 
12378  *aggregated = FALSE;
12379 
12380  /* search for the best common variable such that
12381  * val1[var] * consdata0 - val0[var] * consdata1
12382  * has least weighted number of variables
12383  */
12384  bestvarweight = commonidxweight + diffidx0minus1weight;
12385  bestnvars = consdata0->nvars;
12386  bestv = -1;
12387  bestscalarsum = 0.0;
12388  commonvarlindependent = TRUE;
12389  for( v = 0; v < nvarscommon; ++v )
12390  {
12391  assert(consdata0->vars[commonidx0[v]] == consdata1->vars[commonidx1[v]]);
12392  a = consdata1->vals[commonidx1[v]];
12393  b = -consdata0->vals[commonidx0[v]];
12394 
12395  /* only try aggregation, if coefficients are integral (numerical stability) */
12396  if( SCIPisIntegral(scip, a) && SCIPisIntegral(scip, b) )
12397  {
12398  /* count the number of variables in the potential new constraint a * consdata0 + b * consdata1 */
12399  varweight = diffidx0minus1weight + diffidx1minus0weight;
12400  nvars = consdata0->nvars + consdata1->nvars - 2*nvarscommon;
12401  scalarsum = REALABS(a) + REALABS(b);
12402  betterscalarsum = (scalarsum < bestscalarsum);
12403  for( i = 0; i < nvarscommon
12404  && (varweight < bestvarweight || (varweight == bestvarweight && betterscalarsum)); ++i )
12405  {
12406  aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
12407  if( !SCIPisZero(scip, aggrcoef) )
12408  {
12409  varweight += getVarWeight(consdata0->vars[commonidx0[i]]);
12410  nvars++;
12411  }
12412  }
12413  if( varweight < bestvarweight || (varweight == bestvarweight && betterscalarsum) )
12414  {
12415  bestv = v;
12416  bestvarweight = varweight;
12417  bestnvars = nvars;
12418  bestscalarsum = scalarsum;
12419  }
12420  }
12421 
12422  /* update commonvarlindependent flag, if still TRUE:
12423  * 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
12424  */
12425  if( commonvarlindependent && v > 0 )
12426  commonvarlindependent = SCIPisEQ(scip,
12427  consdata1->vals[commonidx1[v]] * consdata0->vals[commonidx0[0]],
12428  consdata1->vals[commonidx1[0]] * consdata0->vals[commonidx0[v]]);
12429  }
12430 
12431  /* if better aggregation was found, create new constraint and delete old one */
12432  if( (bestv != -1 || commonvarlindependent) && SCIPconsGetNUpgradeLocks(cons0) == 0 )
12433  {
12434  SCIP_CONS* newcons;
12435  SCIP_CONSDATA* newconsdata;
12436  SCIP_VAR** newvars;
12437  SCIP_Real* newvals;
12438  SCIP_Real newlhs;
12439  SCIP_Real newrhs;
12440  int newnvars;
12441 
12442  if( bestv != -1 )
12443  {
12444  /* choose multipliers such that the multiplier for the (in)equality cons0 is positive */
12445  if( consdata1->vals[commonidx1[bestv]] > 0.0 )
12446  {
12447  a = consdata1->vals[commonidx1[bestv]];
12448  b = -consdata0->vals[commonidx0[bestv]];
12449  }
12450  else
12451  {
12452  a = -consdata1->vals[commonidx1[bestv]];
12453  b = consdata0->vals[commonidx0[bestv]];
12454  }
12455  assert(SCIPisIntegral(scip, a));
12456  assert(SCIPisPositive(scip, a));
12457  assert(SCIPisIntegral(scip, b));
12458  assert(!SCIPisZero(scip, b));
12459  }
12460  else
12461  {
12462  assert(commonvarlindependent);
12463  if( consdata1->vals[commonidx1[0]] > 0.0 )
12464  {
12465  a = consdata1->vals[commonidx1[0]];
12466  b = -consdata0->vals[commonidx0[0]];
12467  }
12468  else
12469  {
12470  a = -consdata1->vals[commonidx1[0]];
12471  b = consdata0->vals[commonidx0[0]];
12472  }
12473  assert(SCIPisPositive(scip, a));
12474  assert(!SCIPisZero(scip, b));
12475 
12476  /* if a/b is integral, then we can easily choose integer multipliers */
12477  if( SCIPisIntegral(scip, a/b) )
12478  {
12479  if( a/b > 0 )
12480  {
12481  a /= b;
12482  b = 1.0;
12483  }
12484  else
12485  {
12486  a /= -b;
12487  b = -1.0;
12488  }
12489  }
12490 
12491  /* setup best* variables that were not setup above because we are in the commonvarlindependent case */
12492  SCIPdebug( bestvarweight = diffidx0minus1weight + diffidx1minus0weight; )
12493  bestnvars = consdata0->nvars + consdata1->nvars - 2*nvarscommon;
12494  }
12495 
12496  SCIPdebugMsg(scip, "aggregate linear constraints <%s> := %.15g*<%s> + %.15g*<%s> -> nvars: %d -> %d, weight: %d -> %d\n",
12497  SCIPconsGetName(cons0), a, SCIPconsGetName(cons0), b, SCIPconsGetName(cons1),
12498  consdata0->nvars, bestnvars, commonidxweight + diffidx0minus1weight, bestvarweight);
12499  SCIPdebugPrintCons(scip, cons0, NULL);
12500  SCIPdebugPrintCons(scip, cons1, NULL);
12501 
12502  /* get temporary memory for creating the new linear constraint */
12503  SCIP_CALL( SCIPallocBufferArray(scip, &newvars, bestnvars) );
12504  SCIP_CALL( SCIPallocBufferArray(scip, &newvals, bestnvars) );
12505 
12506  /* calculate the common coefficients, if we have not recognized linear dependency */
12507  newnvars = 0;
12508  if( !commonvarlindependent )
12509  {
12510  for( i = 0; i < nvarscommon; ++i )
12511  {
12512  assert(0 <= commonidx0[i] && commonidx0[i] < consdata0->nvars);
12513  assert(0 <= commonidx1[i] && commonidx1[i] < consdata1->nvars);
12514 
12515  aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
12516  if( !SCIPisZero(scip, aggrcoef) )
12517  {
12518  assert(newnvars < bestnvars);
12519  newvars[newnvars] = consdata0->vars[commonidx0[i]];
12520  newvals[newnvars] = aggrcoef;
12521  newnvars++;
12522  }
12523  }
12524  }
12525  else
12526  {
12527  /* if we recognized linear dependency of the common coefficients, then the aggregation coefficient should be 0.0 for every common variable */
12528 #ifndef NDEBUG
12529  for( i = 0; i < nvarscommon; ++i )
12530  {
12531  assert(0 <= commonidx0[i] && commonidx0[i] < consdata0->nvars);
12532  assert(0 <= commonidx1[i] && commonidx1[i] < consdata1->nvars);
12533 
12534  aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
12535  assert(SCIPisZero(scip, aggrcoef));
12536  }
12537 #endif
12538  }
12539 
12540  /* calculate the coefficients appearing in cons0 but not in cons1 */
12541  for( i = 0; i < consdata0->nvars - nvarscommon; ++i )
12542  {
12543  assert(0 <= diffidx0minus1[i] && diffidx0minus1[i] < consdata0->nvars);
12544 
12545  aggrcoef = a * consdata0->vals[diffidx0minus1[i]];
12546  assert(!SCIPisZero(scip, aggrcoef));
12547  assert(newnvars < bestnvars);
12548  newvars[newnvars] = consdata0->vars[diffidx0minus1[i]];
12549  newvals[newnvars] = aggrcoef;
12550  newnvars++;
12551  }
12552 
12553  /* calculate the coefficients appearing in cons1 but not in cons0 */
12554  for( i = 0; i < consdata1->nvars - nvarscommon; ++i )
12555  {
12556  assert(0 <= diffidx1minus0[i] && diffidx1minus0[i] < consdata1->nvars);
12557 
12558  aggrcoef = b * consdata1->vals[diffidx1minus0[i]];
12559  assert(!SCIPisZero(scip, aggrcoef));
12560  assert(newnvars < bestnvars);
12561  newvars[newnvars] = consdata1->vars[diffidx1minus0[i]];
12562  newvals[newnvars] = aggrcoef;
12563  newnvars++;
12564  }
12565  assert(newnvars == bestnvars);
12566 
12567  /* calculate the new left and right hand side of the (in)equality */
12568  assert(!SCIPisInfinity(scip, -consdata1->lhs));
12569  assert(!SCIPisInfinity(scip, consdata1->rhs));
12570  if( SCIPisInfinity(scip, -consdata0->lhs) )
12571  newlhs = -SCIPinfinity(scip);
12572  else
12573  newlhs = a * consdata0->lhs + b * consdata1->lhs;
12574  if( SCIPisInfinity(scip, consdata0->rhs) )
12575  newrhs = SCIPinfinity(scip);
12576  else
12577  newrhs = a * consdata0->rhs + b * consdata1->rhs;
12578 
12579  /* create the new linear constraint */
12580  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, SCIPconsGetName(cons0), newnvars, newvars, newvals, newlhs, newrhs,
12582  SCIPconsIsChecked(cons0), SCIPconsIsPropagated(cons0),
12583  SCIPconsIsLocal(cons0), SCIPconsIsModifiable(cons0),
12585 
12586  newconsdata = SCIPconsGetData(newcons);
12587  assert(newconsdata != NULL);
12588 
12589  /* copy the upgraded flag from the old cons0 to the new constraint */
12590  newconsdata->upgraded = consdata0->upgraded;
12591 
12592  /* normalize the new constraint */
12593  SCIP_CALL( normalizeCons(scip, newcons) );
12594 
12595  /* check, if we really want to use the new constraint instead of the old one:
12596  * use the new one, if the maximum norm doesn't grow too much
12597  */
12598  if( consdataGetMaxAbsval(SCIPconsGetData(newcons)) <= maxaggrnormscale * consdataGetMaxAbsval(consdata0) )
12599  {
12600  SCIPdebugMsg(scip, " -> aggregated to <%s>\n", SCIPconsGetName(newcons));
12601  SCIPdebugPrintCons(scip, newcons, NULL);
12602 
12603  /* update the statistics: we changed all coefficients */
12604  if( !consdata0->upgraded )
12605  (*nchgcoefs) += consdata0->nvars + consdata1->nvars - nvarscommon;
12606  *aggregated = TRUE;
12607 
12608  /* delete the old constraint, and add the new linear constraint to the problem */
12609  SCIP_CALL( SCIPdelCons(scip, cons0) );
12610  SCIP_CALL( SCIPaddCons(scip, newcons) );
12611  }
12612 
12613  /* release the new constraint */
12614  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
12615 
12616  /* free temporary memory */
12617  SCIPfreeBufferArray(scip, &newvals);
12618  SCIPfreeBufferArray(scip, &newvars);
12619  }
12620 
12621  return SCIP_OKAY;
12622 }
12623 
12624 /** gets the key of the given element */
12625 static
12626 SCIP_DECL_HASHGETKEY(hashGetKeyLinearcons)
12627 { /*lint --e{715}*/
12628  /* the key is the element itself */
12629  return elem;
12630 }
12631 
12632 /** returns TRUE iff both keys are equal; two constraints are equal if they have the same variables and the
12633  * coefficients are either equal or negated
12634  */
12635 static
12636 SCIP_DECL_HASHKEYEQ(hashKeyEqLinearcons)
12637 {
12638  SCIP* scip;
12639  SCIP_CONSDATA* consdata1;
12640  SCIP_CONSDATA* consdata2;
12641  SCIP_Real cons2scale;
12642  int i;
12644  assert(key1 != NULL);
12645  assert(key2 != NULL);
12646  consdata1 = SCIPconsGetData((SCIP_CONS*)key1);
12647  consdata2 = SCIPconsGetData((SCIP_CONS*)key2);
12648  assert(consdata1->sorted);
12649  assert(consdata2->sorted);
12650 
12651  scip = (SCIP*)userptr;
12652  assert(scip != NULL);
12654  /* checks trivial case */
12655  if( consdata1->nvars != consdata2->nvars )
12656  return FALSE;
12657 
12658  /* tests if variables are equal */
12659  for( i = 0; i < consdata1->nvars; ++i )
12660  {
12661  if( consdata1->vars[i] != consdata2->vars[i] )
12662  {
12663  assert(SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == 1 ||
12664  SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == -1);
12665  return FALSE;
12666  }
12667  assert(SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == 0);
12668  }
12669 
12670  cons2scale = consdata1->vals[0] / consdata2->vals[0];
12671 
12672  /* tests if coefficients are equal with the computed scale */
12673  for( i = 1; i < consdata1->nvars; ++i )
12674  {
12675  SCIP_Real val1;
12676  SCIP_Real val2;
12677 
12678  val1 = consdata1->vals[i];
12679  val2 = consdata2->vals[i] * cons2scale;
12680 
12681  if( !SCIPisEQ(scip, val1, val2) )
12682  return FALSE;
12683  }
12684 
12685  return TRUE;
12686 }
12687 
12688 /** returns the hash value of the key */
12689 static
12690 SCIP_DECL_HASHKEYVAL(hashKeyValLinearcons)
12691 {
12692  SCIP_CONSDATA* consdata;
12693  int minidx;
12694  int mididx;
12695  int maxidx;
12696  SCIP_Real scale;
12697 #ifndef NDEBUG
12698  SCIP* scip;
12699 
12700  scip = (SCIP*)userptr;
12701  assert(scip != NULL);
12702 #endif
12703 
12704  assert(key != NULL);
12705  consdata = SCIPconsGetData((SCIP_CONS*)key);
12706  assert(consdata != NULL);
12707  assert(consdata->nvars > 0);
12708 
12709  assert(consdata->sorted);
12710 
12711  minidx = SCIPvarGetIndex(consdata->vars[0]);
12712  mididx = SCIPvarGetIndex(consdata->vars[consdata->nvars / 2]);
12713  maxidx = SCIPvarGetIndex(consdata->vars[consdata->nvars - 1]);
12714  assert(minidx >= 0 && minidx <= maxidx);
12715  scale = COPYSIGN(1.0/consdata->maxabsval, consdata->vals[0]);
12716 
12717  /* using only the variable indices as hash, since the values are compared by epsilon */
12718  return SCIPhashFour(consdata->nvars,
12719  SCIPcombineTwoInt(minidx, SCIPrealHashCode(consdata->vals[0] * scale)),
12720  SCIPcombineTwoInt(mididx, SCIPrealHashCode(consdata->vals[consdata->nvars / 2] * scale)),
12721  SCIPcombineTwoInt(maxidx, SCIPrealHashCode(consdata->vals[consdata->nvars - 1] * scale))); /*lint !e571*/
12722 }
12723 
12724 /** compares each constraint with all other constraints for possible redundancy and removes or changes constraint
12725  * accordingly; in contrast to preprocessConstraintPairs(), it uses a hash table
12726  */
12727 static
12729  SCIP* scip, /**< SCIP data structure */
12730  BMS_BLKMEM* blkmem, /**< block memory */
12731  SCIP_CONS** conss, /**< constraint set */
12732  int nconss, /**< number of constraints in constraint set */
12733  int* firstchange, /**< pointer to store first changed constraint */
12734  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
12735  int* ndelconss, /**< pointer to count number of deleted constraints */
12736  int* nchgsides /**< pointer to count number of changed left/right hand sides */
12737  )
12738 {
12739  SCIP_HASHTABLE* hashtable;
12740  int hashtablesize;
12741  int c;
12742 
12743  assert(scip != NULL);
12744  assert(blkmem != NULL);
12745  assert(conss != NULL);
12746  assert(firstchange != NULL);
12747  assert(cutoff != NULL);
12748  assert(ndelconss != NULL);
12749  assert(nchgsides != NULL);
12750 
12751  /* create a hash table for the constraint set */
12752  hashtablesize = nconss;
12753  hashtablesize = MAX(hashtablesize, HASHSIZE_LINEARCONS);
12754  SCIP_CALL( SCIPhashtableCreate(&hashtable, blkmem, hashtablesize,
12755  hashGetKeyLinearcons, hashKeyEqLinearcons, hashKeyValLinearcons, (void*) scip) );
12756 
12757  /* check all constraints in the given set for redundancy */
12758  for( c = 0; c < nconss; ++c )
12759  {
12760  SCIP_CONS* cons0;
12761  SCIP_CONS* cons1;
12762  SCIP_CONSDATA* consdata0;
12763 
12764  cons0 = conss[c];
12765 
12766  if( !SCIPconsIsActive(cons0) || SCIPconsIsModifiable(cons0) )
12767  continue;
12768 
12769  /* check for interuption */
12770  if( c % 1000 == 0 && SCIPisStopped(scip) )
12771  break;
12772 
12773  /* sorts the constraint */
12774  consdata0 = SCIPconsGetData(cons0);
12775  assert(consdata0 != NULL);
12776  SCIP_CALL( consdataSort(scip, consdata0) );
12777  assert(consdata0->sorted);
12778 
12779  /* get constraint from current hash table with same variables as cons0 and with coefficients either equal or negated
12780  * to the ones of cons0 */
12781  cons1 = (SCIP_CONS*)(SCIPhashtableRetrieve(hashtable, (void*)cons0));
12782 
12783  if( cons1 != NULL )
12784  {
12785  SCIP_CONS* consstay;
12786  SCIP_CONS* consdel;
12787  SCIP_CONSDATA* consdatastay;
12788  SCIP_CONSDATA* consdatadel;
12789  SCIP_CONSDATA* consdata1;
12790 
12791  SCIP_Real scale;
12792  SCIP_Real lhs;
12793  SCIP_Real rhs;
12794 
12795  assert(SCIPconsIsActive(cons1));
12796  assert(!SCIPconsIsModifiable(cons1));
12797 
12798  /* constraint found: create a new constraint with same coefficients and best left and right hand side;
12799  * delete old constraints afterwards
12800  */
12801  consdata1 = SCIPconsGetData(cons1);
12802 
12803  assert(consdata1 != NULL);
12804  assert(consdata0->nvars >= 1 && consdata0->nvars == consdata1->nvars);
12805 
12806  assert(consdata1->sorted);
12807  assert(consdata0->vars[0] == consdata1->vars[0]);
12808 
12809  /* check which constraint has to stay;
12810  * changes applied to an upgraded constraint will not be considered in the instance */
12811  if( consdata1->upgraded && !consdata0->upgraded )
12812  {
12813  consstay = cons0;
12814  consdatastay = consdata0;
12815  consdel = cons1;
12816  consdatadel = consdata1;
12817 
12818  /* exchange consdel with consstay in hashtable */
12819  SCIP_CALL( SCIPhashtableRemove(hashtable, (void*) consdel) );
12820  SCIP_CALL( SCIPhashtableInsert(hashtable, (void*) consstay) );
12821  }
12822  else
12823  {
12824  consstay = cons1;
12825  consdatastay = consdata1;
12826  consdel = cons0;
12827  consdatadel = consdata0;
12828  }
12829 
12830  scale = consdatastay->vals[0] / consdatadel->vals[0];
12831  assert(scale != 0.0);
12832 
12833  assert(consdatastay->nvars < 2 || SCIPisEQ(scip, consdatastay->vals[1], scale * consdatadel->vals[1]));
12834 
12835  if( scale > 0.0 )
12836  {
12837  /* the coefficients of both constraints are parallel with a positive scale */
12838  SCIPdebugMsg(scip, "aggregate linear constraints <%s> and <%s> with equal coefficients into single ranged row\n",
12839  SCIPconsGetName(cons0), SCIPconsGetName(cons1));
12840  SCIPdebugPrintCons(scip, cons0, NULL);
12841  SCIPdebugPrintCons(scip, cons1, NULL);
12842 
12843  lhs = MAX(scale * consdatadel->lhs, consdatastay->lhs);
12844  rhs = MIN(scale * consdatadel->rhs, consdatastay->rhs);
12845  }
12846  else
12847  {
12848  /* the coefficients of both rows are negations */
12849  SCIPdebugMsg(scip, "aggregate linear constraints <%s> and <%s> with negated coefficients into single ranged row\n",
12850  SCIPconsGetName(cons0), SCIPconsGetName(cons1));
12851  SCIPdebugPrintCons(scip, cons0, NULL);
12852  SCIPdebugPrintCons(scip, cons1, NULL);
12853 
12854  lhs = MAX(scale * consdatadel->rhs, consdatastay->lhs);
12855  rhs = MIN(scale * consdatadel->lhs, consdatastay->rhs);
12856  }
12857 
12858  if( SCIPisFeasLT(scip, rhs, lhs) )
12859  {
12860  SCIPdebugMsg(scip, "aggregated linear constraint <%s> is infeasible\n", SCIPconsGetName(cons1));
12861  *cutoff = TRUE;
12862  break;
12863  }
12864 
12865  /* ensure that lhs <= rhs holds without tolerances as we only allow such rows to enter the LP */
12866  if( lhs > rhs )
12867  {
12868  rhs = (lhs + rhs)/2;
12869  lhs = rhs;
12870  }
12871 
12872  /* update lhs and rhs of consstay */
12873  SCIP_CALL( chgLhs(scip, consstay, lhs) );
12874  SCIP_CALL( chgRhs(scip, consstay, rhs) );
12875 
12876  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
12877  SCIP_CALL( SCIPupdateConsFlags(scip, consstay, consdel) );
12878 
12879  /* delete consdel */
12880  assert( ! consdatastay->upgraded || consdatadel->upgraded );
12881  SCIP_CALL( SCIPdelCons(scip, consdel) );
12882  if( !consdatadel->upgraded )
12883  (*ndelconss)++;
12884 
12885  /* update the first changed constraint to begin the next aggregation round with */
12886  if( consdatastay->changed && SCIPconsGetPos(consstay) < *firstchange )
12887  *firstchange = SCIPconsGetPos(consstay);
12888 
12889  assert(SCIPconsIsActive(consstay));
12890  }
12891  else
12892  {
12893  /* no such constraint in current hash table: insert cons0 into hash table */
12894  SCIP_CALL( SCIPhashtableInsert(hashtable, (void*) cons0) );
12895  }
12896  }
12897 #ifdef SCIP_MORE_DEBUG
12898  SCIPinfoMessage(scip, NULL, "linear pairwise comparison hashtable statistics:\n");
12900 #endif
12901 
12902  /* free hash table */
12903  SCIPhashtableFree(&hashtable);
12904 
12905  return SCIP_OKAY;
12906 }
12907 
12908 /** compares constraint with all prior constraints for possible redundancy or aggregation,
12909  * and removes or changes constraint accordingly
12910  */
12911 static
12913  SCIP* scip, /**< SCIP data structure */
12914  SCIP_CONS** conss, /**< constraint set */
12915  int firstchange, /**< first constraint that changed since last pair preprocessing round */
12916  int chkind, /**< index of constraint to check against all prior indices upto startind */
12917  SCIP_Real maxaggrnormscale, /**< maximal allowed relative gain in maximum norm for constraint aggregation */
12918  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
12919  int* ndelconss, /**< pointer to count number of deleted constraints */
12920  int* nchgsides, /**< pointer to count number of changed left/right hand sides */
12921  int* nchgcoefs /**< pointer to count number of changed coefficients */
12922  )
12923 {
12924  SCIP_CONS* cons0;
12925  SCIP_CONSDATA* consdata0;
12926  int* commonidx0;
12927  int* commonidx1;
12928  int* diffidx0minus1;
12929  int* diffidx1minus0;
12930  uint64_t possignature0;
12931  uint64_t negsignature0;
12932  SCIP_Bool cons0changed;
12933  SCIP_Bool cons0isequality;
12934  int diffidx1minus0size;
12935  int c;
12936  SCIP_Real cons0lhs;
12937  SCIP_Real cons0rhs;
12938  SCIP_Bool cons0upgraded;
12939 
12940  assert(scip != NULL);
12941  assert(conss != NULL);
12942  assert(firstchange <= chkind);
12943  assert(cutoff != NULL);
12944  assert(ndelconss != NULL);
12945  assert(nchgsides != NULL);
12946  assert(nchgcoefs != NULL);
12947 
12948  /* get the constraint to be checked against all prior constraints */
12949  cons0 = conss[chkind];
12950  assert(cons0 != NULL);
12951  assert(SCIPconsIsActive(cons0));
12952  assert(!SCIPconsIsModifiable(cons0));
12953 
12954  consdata0 = SCIPconsGetData(cons0);
12955  assert(consdata0 != NULL);
12956  assert(consdata0->nvars >= 1);
12957  cons0isequality = SCIPisEQ(scip, consdata0->lhs, consdata0->rhs);
12958 
12959  /* sort the constraint */
12960  SCIP_CALL( consdataSort(scip, consdata0) );
12961 
12962  /* calculate bit signatures of cons0 for potentially positive and negative coefficients */
12963  consdataCalcSignatures(consdata0);
12964  possignature0 = consdata0->possignature;
12965  negsignature0 = consdata0->negsignature;
12966 
12967  /* get temporary memory for indices of common variables */
12968  SCIP_CALL( SCIPallocBufferArray(scip, &commonidx0, consdata0->nvars) );
12969  SCIP_CALL( SCIPallocBufferArray(scip, &commonidx1, consdata0->nvars) );
12970  SCIP_CALL( SCIPallocBufferArray(scip, &diffidx0minus1, consdata0->nvars) );
12971  SCIP_CALL( SCIPallocBufferArray(scip, &diffidx1minus0, consdata0->nvars) );
12972  diffidx1minus0size = consdata0->nvars;
12973 
12974  cons0lhs = consdata0->lhs;
12975  cons0rhs = consdata0->rhs;
12976  cons0upgraded = consdata0->upgraded;
12977 
12978  /* check constraint against all prior constraints */
12979  cons0changed = consdata0->changed;
12980  consdata0->changed = FALSE;
12981  for( c = (cons0changed ? 0 : firstchange); c < chkind && !(*cutoff) && conss[chkind] != NULL; ++c )
12982  {
12983  SCIP_CONS* cons1;
12984  SCIP_CONSDATA* consdata1;
12985  uint64_t possignature1;
12986  uint64_t negsignature1;
12987  SCIP_Bool cons0dominateslhs;
12988  SCIP_Bool cons1dominateslhs;
12989  SCIP_Bool cons0dominatesrhs;
12990  SCIP_Bool cons1dominatesrhs;
12991  SCIP_Bool cons1isequality;
12992  SCIP_Bool coefsequal;
12993  SCIP_Bool coefsnegated;
12994  SCIP_Bool tryaggregation;
12995  int nvarscommon;
12996  int nvars0minus1;
12997  int nvars1minus0;
12998  int commonidxweight;
12999  int diffidx0minus1weight;
13000  int diffidx1minus0weight;
13001  int v0;
13002  int v1;
13003 
13004  assert(cons0lhs == consdata0->lhs); /*lint !e777*/
13005  assert(cons0rhs == consdata0->rhs); /*lint !e777*/
13006  assert(cons0upgraded == consdata0->upgraded);
13007 
13008  cons1 = conss[c];
13009 
13010  /* cons1 has become inactive during presolving of constraint pairs */
13011  if( cons1 == NULL )
13012  continue;
13013 
13014  assert(SCIPconsIsActive(cons0) && !SCIPconsIsModifiable(cons0));
13015  assert(SCIPconsIsActive(cons1) && !SCIPconsIsModifiable(cons1));
13016 
13017  consdata1 = SCIPconsGetData(cons1);
13018  assert(consdata1 != NULL);
13019 
13020  /* SCIPdebugMsg(scip, "preprocess linear constraint pair <%s>[chgd:%d, upgd:%d] and <%s>[chgd:%d, upgd:%d]\n",
13021  SCIPconsGetName(cons0), cons0changed, cons0upgraded,
13022  SCIPconsGetName(cons1), consdata1->changed, consdata1->upgraded); */
13023 
13024  /* if both constraints didn't change since last pair processing, we can ignore the pair */
13025  if( !cons0changed && !consdata1->changed )
13026  continue;
13027 
13028  /* if both constraints are already upgraded, skip the pair;
13029  * because changes on these constraints cannot be applied to the instance anymore */
13030  if( cons0upgraded && consdata1->upgraded )
13031  continue;
13032 
13033  assert(consdata1->nvars >= 1);
13034 
13035  /* sort the constraint */
13036  SCIP_CALL( consdataSort(scip, consdata1) );
13037 
13038  /* calculate bit signatures of cons1 for potentially positive and negative coefficients */
13039  consdataCalcSignatures(consdata1);
13040  possignature1 = consdata1->possignature;
13041  negsignature1 = consdata1->negsignature;
13042 
13043  /* the signatures give a quick test to check for domination and equality of coefficients */
13044  coefsequal = (possignature0 == possignature1) && (negsignature0 == negsignature1);
13045  coefsnegated = (possignature0 == negsignature1) && (negsignature0 == possignature1);
13046  cons0dominateslhs = SCIPisGE(scip, cons0lhs, consdata1->lhs)
13047  && ((possignature0 | possignature1) == possignature1) /* possignature0 <= possignature1 (as bit vector) */
13048  && ((negsignature0 | negsignature1) == negsignature0); /* negsignature0 >= negsignature1 (as bit vector) */
13049  cons1dominateslhs = SCIPisGE(scip, consdata1->lhs, cons0lhs)
13050  && ((possignature0 | possignature1) == possignature0) /* possignature0 >= possignature1 (as bit vector) */
13051  && ((negsignature0 | negsignature1) == negsignature1); /* negsignature0 <= negsignature1 (as bit vector) */
13052  cons0dominatesrhs = SCIPisLE(scip, cons0rhs, consdata1->rhs)
13053  && ((possignature0 | possignature1) == possignature0) /* possignature0 >= possignature1 (as bit vector) */
13054  && ((negsignature0 | negsignature1) == negsignature1); /* negsignature0 <= negsignature1 (as bit vector) */
13055  cons1dominatesrhs = SCIPisLE(scip, consdata1->rhs, cons0rhs)
13056  && ((possignature0 | possignature1) == possignature1) /* possignature0 <= possignature1 (as bit vector) */
13057  && ((negsignature0 | negsignature1) == negsignature0); /* negsignature0 >= negsignature1 (as bit vector) */
13058  cons1isequality = SCIPisEQ(scip, consdata1->lhs, consdata1->rhs);
13059  tryaggregation = (cons0isequality || cons1isequality) && (maxaggrnormscale > 0.0);
13060  if( !cons0dominateslhs && !cons1dominateslhs && !cons0dominatesrhs && !cons1dominatesrhs
13061  && !coefsequal && !coefsnegated && !tryaggregation )
13062  continue;
13063 
13064  /* make sure, we have enough memory for the index set of V_1 \ V_0 */
13065  if( tryaggregation && consdata1->nvars > diffidx1minus0size )
13066  {
13067  SCIP_CALL( SCIPreallocBufferArray(scip, &diffidx1minus0, consdata1->nvars) );
13068  diffidx1minus0size = consdata1->nvars;
13069  }
13070 
13071  /* check consdata0 against consdata1:
13072  * - if lhs0 >= lhs1 and for each variable v and each solution value x_v val0[v]*x_v <= val1[v]*x_v,
13073  * consdata0 dominates consdata1 w.r.t. left hand side
13074  * - if rhs0 <= rhs1 and for each variable v and each solution value x_v val0[v]*x_v >= val1[v]*x_v,
13075  * consdata0 dominates consdata1 w.r.t. right hand side
13076  * - if val0[v] == -val1[v] for all variables v, the two inequalities can be replaced by a single
13077  * ranged row (or equality)
13078  * - if at least one constraint is an equality, count the weighted number of common variables W_c
13079  * and the weighted number of variable in the difference sets W_0 = w(V_0 \ V_1), W_1 = w(V_1 \ V_0),
13080  * where the weight of each variable depends on its type, such that aggregations in order to remove the
13081  * number of continuous and integer variables are preferred:
13082  * - if W_c > W_1, try to aggregate consdata0 := a * consdata0 + b * consdata1 in order to decrease the
13083  * variable weight in consdata0, where a = +/- val1[v] and b = -/+ val0[v] for common v which leads to
13084  * the smallest weight; for numerical stability, we will only accept integral a and b; the sign of a has
13085  * to be positive to not switch the sense of the (in)equality cons0
13086  * - if W_c > W_0, try to aggregate consdata1 := a * consdata1 + b * consdata0 in order to decrease the
13087  * variable weight in consdata1, where a = +/- val0[v] and b = -/+ val1[v] for common v which leads to
13088  * the smallest weight; for numerical stability, we will only accept integral a and b; the sign of a has
13089  * to be positive to not switch the sense of the (in)equality cons1
13090  */
13091 
13092  /* check consdata0 against consdata1 for redundancy, or ranged row accumulation */
13093  nvarscommon = 0;
13094  commonidxweight = 0;
13095  nvars0minus1 = 0;
13096  diffidx0minus1weight = 0;
13097  nvars1minus0 = 0;
13098  diffidx1minus0weight = 0;
13099  v0 = 0;
13100  v1 = 0;
13101  while( (v0 < consdata0->nvars || v1 < consdata1->nvars)
13102  && (cons0dominateslhs || cons1dominateslhs || cons0dominatesrhs || cons1dominatesrhs
13103  || coefsequal || coefsnegated || tryaggregation) )
13104  {
13105  SCIP_VAR* var;
13106  SCIP_Real val0;
13107  SCIP_Real val1;
13108  int varcmp;
13109 
13110  /* test, if variable appears in only one or in both constraints */
13111  if( v0 < consdata0->nvars && v1 < consdata1->nvars )
13112  varcmp = SCIPvarCompare(consdata0->vars[v0], consdata1->vars[v1]);
13113  else if( v0 < consdata0->nvars )
13114  varcmp = -1;
13115  else
13116  varcmp = +1;
13117 
13118  switch( varcmp )
13119  {
13120  case -1:
13121  /* variable doesn't appear in consdata1 */
13122  var = consdata0->vars[v0];
13123  val0 = consdata0->vals[v0];
13124  val1 = 0.0;
13125  if( tryaggregation )
13126  {
13127  diffidx0minus1[nvars0minus1] = v0;
13128  nvars0minus1++;
13129  diffidx0minus1weight += getVarWeight(var);
13130  }
13131  v0++;
13132  coefsequal = FALSE;
13133  coefsnegated = FALSE;
13134  break;
13135 
13136  case +1:
13137  /* variable doesn't appear in consdata0 */
13138  var = consdata1->vars[v1];
13139  val0 = 0.0;
13140  val1 = consdata1->vals[v1];
13141  if( tryaggregation )
13142  {
13143  diffidx1minus0[nvars1minus0] = v1;
13144  nvars1minus0++;
13145  diffidx1minus0weight += getVarWeight(var);
13146  }
13147  v1++;
13148  coefsequal = FALSE;
13149  coefsnegated = FALSE;
13150  break;
13151 
13152  case 0:
13153  /* variable appears in both constraints */
13154  assert(consdata0->vars[v0] == consdata1->vars[v1]);
13155  var = consdata0->vars[v0];
13156  val0 = consdata0->vals[v0];
13157  val1 = consdata1->vals[v1];
13158  if( tryaggregation )
13159  {
13160  commonidx0[nvarscommon] = v0;
13161  commonidx1[nvarscommon] = v1;
13162  nvarscommon++;
13163  commonidxweight += getVarWeight(var);
13164  }
13165  v0++;
13166  v1++;
13167  coefsequal = coefsequal && (SCIPisEQ(scip, val0, val1));
13168  coefsnegated = coefsnegated && (SCIPisEQ(scip, val0, -val1));
13169  break;
13170 
13171  default:
13172  SCIPerrorMessage("invalid comparison result\n");
13173  SCIPABORT();
13174  var = NULL;
13175  val0 = 0.0;
13176  val1 = 0.0;
13177  }
13178  assert(var != NULL);
13179 
13180  /* update domination criteria w.r.t. the coefficient and the variable's bounds */
13181  if( SCIPisGT(scip, val0, val1) )
13182  {
13183  if( SCIPisNegative(scip, SCIPvarGetLbGlobal(var)) )
13184  {
13185  cons0dominatesrhs = FALSE;
13186  cons1dominateslhs = FALSE;
13187  }
13188  if( SCIPisPositive(scip, SCIPvarGetUbGlobal(var)) )
13189  {
13190  cons0dominateslhs = FALSE;
13191  cons1dominatesrhs = FALSE;
13192  }
13193  }
13194  else if( SCIPisLT(scip, val0, val1) )
13195  {
13196  if( SCIPisNegative(scip, SCIPvarGetLbGlobal(var)) )
13197  {
13198  cons0dominateslhs = FALSE;
13199  cons1dominatesrhs = FALSE;
13200  }
13201  if( SCIPisPositive(scip, SCIPvarGetUbGlobal(var)) )
13202  {
13203  cons0dominatesrhs = FALSE;
13204  cons1dominateslhs = FALSE;
13205  }
13206  }
13207  }
13208 
13209  /* check for disaggregated ranged rows */
13210  if( coefsequal || coefsnegated )
13211  {
13212  SCIP_CONS* consstay;
13213  SCIP_CONS* consdel;
13214 #ifndef NDEBUG
13215  SCIP_CONSDATA* consdatastay;
13216 #endif
13217  SCIP_CONSDATA* consdatadel;
13218  SCIP_Real lhs;
13219  SCIP_Real rhs;
13220  int consinddel;
13221 
13222  /* the coefficients in both rows are either equal or negated: create a new constraint with same coefficients and
13223  * best left and right hand sides; delete the old constraints afterwards
13224  */
13225  SCIPdebugMsg(scip, "aggregate linear constraints <%s> and <%s> with %s coefficients into single ranged row\n",
13226  SCIPconsGetName(cons0), SCIPconsGetName(cons1), coefsequal ? "equal" : "negated");
13227  SCIPdebugPrintCons(scip, cons0, NULL);
13228  SCIPdebugPrintCons(scip, cons1, NULL);
13229 
13230  if( coefsequal )
13231  {
13232  /* the coefficients of both rows are equal */
13233  lhs = MAX(consdata0->lhs, consdata1->lhs);
13234  rhs = MIN(consdata0->rhs, consdata1->rhs);
13235  }
13236  else
13237  {
13238  /* the coefficients of both rows are negations */
13239  lhs = MAX(consdata0->lhs, -consdata1->rhs);
13240  rhs = MIN(consdata0->rhs, -consdata1->lhs);
13241  }
13242  if( SCIPisFeasLT(scip, rhs, lhs) )
13243  {
13244  SCIPdebugMsg(scip, "aggregated linear constraint <%s> is infeasible\n", SCIPconsGetName(cons0));
13245  *cutoff = TRUE;
13246  break;
13247  }
13248 
13249  /* check which constraint has to stay;
13250  * changes applied to an upgraded constraint will not be considered in the instance */
13251  if( consdata0->upgraded )
13252  {
13253  assert(!consdata1->upgraded);
13254  consstay = cons1;
13255 #ifndef NDEBUG
13256  consdatastay = consdata1;
13257 #endif
13258 
13259  consdel = cons0;
13260  consdatadel = consdata0;
13261  consinddel = chkind;
13262  }
13263  else
13264  {
13265  consstay = cons0;
13266 #ifndef NDEBUG
13267  consdatastay = consdata0;
13268 #endif
13269 
13270  consdel = cons1;
13271  consdatadel = consdata1;
13272  consinddel = c;
13273  }
13274 
13275  /* update the sides of consstay */
13276  SCIP_CALL( chgLhs(scip, consstay, lhs) );
13277  SCIP_CALL( chgRhs(scip, consstay, rhs) );
13278  if( !consdata0->upgraded )
13279  {
13280  assert(consstay == cons0);
13281  cons0lhs = consdata0->lhs;
13282  cons0rhs = consdata0->rhs;
13283  }
13284 
13285  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13286  SCIP_CALL( SCIPupdateConsFlags(scip, consstay, consdel) );
13287 
13288  assert( !consdatastay->upgraded );
13289  /* delete consdel */
13290  SCIP_CALL( SCIPdelCons(scip, consdel) );
13291  conss[consinddel] = NULL;
13292  if( !consdatadel->upgraded )
13293  (*ndelconss)++;
13294  continue;
13295  }
13296 
13297  /* check for domination: remove dominated sides, but don't touch equalities as long as they are not totally
13298  * redundant
13299  */
13300  if( cons1dominateslhs && (!cons0isequality || cons1dominatesrhs || SCIPisInfinity(scip, consdata0->rhs) ) )
13301  {
13302  /* left hand side is dominated by consdata1: delete left hand side of consdata0 */
13303  SCIPdebugMsg(scip, "left hand side of linear constraint <%s> is dominated by <%s>:\n",
13304  SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13305  SCIPdebugPrintCons(scip, cons0, NULL);
13306  SCIPdebugPrintCons(scip, cons1, NULL);
13307 
13308  /* check for infeasibility */
13309  if( SCIPisFeasGT(scip, consdata1->lhs, consdata0->rhs) )
13310  {
13311  SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13312  *cutoff = TRUE;
13313  break;
13314  }
13315 
13316  /* remove redundant left hand side */
13317  if( !SCIPisInfinity(scip, -consdata0->lhs) )
13318  {
13319  SCIP_CALL( chgLhs(scip, cons0, -SCIPinfinity(scip)) );
13320  cons0lhs = consdata0->lhs;
13321  cons0isequality = FALSE;
13322  if( !consdata0->upgraded )
13323  {
13324  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13325  SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
13326 
13327  (*nchgsides)++;
13328  }
13329  }
13330  }
13331  else if( cons0dominateslhs && (!cons1isequality || cons0dominatesrhs || SCIPisInfinity(scip, consdata1->rhs)) )
13332  {
13333  /* left hand side is dominated by consdata0: delete left hand side of consdata1 */
13334  SCIPdebugMsg(scip, "left hand side of linear constraint <%s> is dominated by <%s>:\n",
13335  SCIPconsGetName(cons1), SCIPconsGetName(cons0));
13336  SCIPdebugPrintCons(scip, cons1, NULL);
13337  SCIPdebugPrintCons(scip, cons0, NULL);
13338 
13339  /* check for infeasibility */
13340  if( SCIPisFeasGT(scip, consdata0->lhs, consdata1->rhs) )
13341  {
13342  SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13343  *cutoff = TRUE;
13344  break;
13345  }
13346 
13347  /* remove redundant left hand side */
13348  if( !SCIPisInfinity(scip, -consdata1->lhs) )
13349  {
13350  SCIP_CALL( chgLhs(scip, cons1, -SCIPinfinity(scip)) );
13351  cons1isequality = FALSE;
13352  if( !consdata1->upgraded )
13353  {
13354  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13355  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
13356 
13357  (*nchgsides)++;
13358  }
13359  }
13360  }
13361  if( cons1dominatesrhs && (!cons0isequality || cons1dominateslhs || SCIPisInfinity(scip, -consdata0->lhs)) )
13362  {
13363  /* right hand side is dominated by consdata1: delete right hand side of consdata0 */
13364  SCIPdebugMsg(scip, "right hand side of linear constraint <%s> is dominated by <%s>:\n",
13365  SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13366  SCIPdebugPrintCons(scip, cons0, NULL);
13367  SCIPdebugPrintCons(scip, cons1, NULL);
13368 
13369  /* check for infeasibility */
13370  if( SCIPisFeasLT(scip, consdata1->rhs, consdata0->lhs) )
13371  {
13372  SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13373  *cutoff = TRUE;
13374  break;
13375  }
13376 
13377  /* remove redundant right hand side */
13378  if( !SCIPisInfinity(scip, consdata0->rhs) )
13379  {
13380  SCIP_CALL( chgRhs(scip, cons0, SCIPinfinity(scip)) );
13381  cons0rhs = consdata0->rhs;
13382  cons0isequality = FALSE;
13383  if( !consdata0->upgraded )
13384  {
13385  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13386  SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
13387 
13388  (*nchgsides)++;
13389  }
13390  }
13391  }
13392  else if( cons0dominatesrhs && (!cons1isequality || cons0dominateslhs || SCIPisInfinity(scip, -consdata1->lhs)) )
13393  {
13394  /* right hand side is dominated by consdata0: delete right hand side of consdata1 */
13395  SCIPdebugMsg(scip, "right hand side of linear constraint <%s> is dominated by <%s>:\n",
13396  SCIPconsGetName(cons1), SCIPconsGetName(cons0));
13397  SCIPdebugPrintCons(scip, cons1, NULL);
13398  SCIPdebugPrintCons(scip, cons0, NULL);
13399 
13400  /* check for infeasibility */
13401  if( SCIPisFeasLT(scip, consdata0->rhs, consdata1->lhs) )
13402  {
13403  SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13404  *cutoff = TRUE;
13405  break;
13406  }
13407 
13408  /* remove redundant right hand side */
13409  if( !SCIPisInfinity(scip, consdata1->rhs) )
13410  {
13411  SCIP_CALL( chgRhs(scip, cons1, SCIPinfinity(scip)) );
13412  cons1isequality = FALSE;
13413  if( !consdata1->upgraded )
13414  {
13415  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13416  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
13417 
13418  (*nchgsides)++;
13419  }
13420  }
13421  }
13422 
13423  /* check for now redundant constraints */
13424  if( SCIPisInfinity(scip, -consdata0->lhs) && SCIPisInfinity(scip, consdata0->rhs) )
13425  {
13426  /* consdata0 became redundant */
13427  SCIPdebugMsg(scip, "linear constraint <%s> is redundant\n", SCIPconsGetName(cons0));
13428  SCIP_CALL( SCIPdelCons(scip, cons0) );
13429  conss[chkind] = NULL;
13430  if( !consdata0->upgraded )
13431  {
13432  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13433  SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
13434 
13435  (*ndelconss)++;
13436  }
13437  continue;
13438  }
13439  if( SCIPisInfinity(scip, -consdata1->lhs) && SCIPisInfinity(scip, consdata1->rhs) )
13440  {
13441  /* consdata1 became redundant */
13442  SCIPdebugMsg(scip, "linear constraint <%s> is redundant\n", SCIPconsGetName(cons1));
13443  SCIP_CALL( SCIPdelCons(scip, cons1) );
13444  conss[c] = NULL;
13445  if( !consdata1->upgraded )
13446  {
13447  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13448  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
13449 
13450  (*ndelconss)++;
13451  }
13452  continue;
13453  }
13454 
13455  /* check, if we want to aggregate an (in)equality with an equality:
13456  * consdata0 := a * consdata0 + b * consdata1 or consdata1 := a * consdata1 + b * consdata0
13457  */
13458  if( tryaggregation )
13459  {
13460  SCIP_Bool aggregated;
13461 
13462  assert(consdata0->nvars == nvarscommon + nvars0minus1);
13463  assert(consdata1->nvars == nvarscommon + nvars1minus0);
13464 
13465  aggregated = FALSE;
13466  if( cons1isequality && !consdata0->upgraded && commonidxweight > diffidx1minus0weight )
13467  {
13468  /* W_c > W_1: try to aggregate consdata0 := a * consdata0 + b * consdata1 */
13469  SCIP_CALL( aggregateConstraints(scip, cons0, cons1, commonidx0, commonidx1, diffidx0minus1, diffidx1minus0,
13470  nvarscommon, commonidxweight, diffidx0minus1weight, diffidx1minus0weight, maxaggrnormscale,
13471  nchgcoefs, &aggregated) );
13472 
13473  /* update array of active constraints */
13474  if( aggregated )
13475  {
13476  assert(!SCIPconsIsActive(cons0));
13477  assert(SCIPconsIsActive(cons1));
13478  conss[chkind] = NULL;
13479  }
13480  }
13481  if( !aggregated && cons0isequality && !consdata1->upgraded && commonidxweight > diffidx0minus1weight )
13482  {
13483  /* W_c > W_0: try to aggregate consdata1 := a * consdata1 + b * consdata0 */
13484  SCIP_CALL( aggregateConstraints(scip, cons1, cons0, commonidx1, commonidx0, diffidx1minus0, diffidx0minus1,
13485  nvarscommon, commonidxweight, diffidx1minus0weight, diffidx0minus1weight, maxaggrnormscale,
13486  nchgcoefs, &aggregated) );
13487 
13488  /* update array of active constraints */
13489  if( aggregated )
13490  {
13491  assert(!SCIPconsIsActive(cons1));
13492  assert(SCIPconsIsActive(cons0));
13493  conss[c] = NULL;
13494  }
13495  }
13496  }
13497  }
13498 
13499  /* free temporary memory */
13500  SCIPfreeBufferArray(scip, &diffidx1minus0);
13501  SCIPfreeBufferArray(scip, &diffidx0minus1);
13502  SCIPfreeBufferArray(scip, &commonidx1);
13503  SCIPfreeBufferArray(scip, &commonidx0);
13504 
13505  return SCIP_OKAY;
13506 }
13507 
13508 /** do stuffing presolving on a single constraint */
13509 static
13511  SCIP* scip, /**< SCIP data structure */
13512  SCIP_CONS* cons, /**< linear constraint */
13513  SCIP_Bool singletonstuffing, /**< should stuffing of singleton continuous variables be performed? */
13514  SCIP_Bool singlevarstuffing, /**< should single variable stuffing be performed, which tries to fulfill
13515  * constraints using the cheapest variable? */
13516  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
13517  int* nfixedvars, /**< pointer to count the total number of fixed variables */
13518  int* nchgbds /**< pointer to count the total number of tightened bounds */
13519  )
13520 {
13521  SCIP_CONSDATA* consdata;
13522  SCIP_Real* ratios;
13523  int* varpos;
13524  SCIP_Bool* swapped;
13525  SCIP_VAR** vars;
13526  SCIP_Real* vals;
13527  SCIP_VAR* var;
13528  SCIP_Real lb;
13529  SCIP_Real ub;
13530  SCIP_Real minactivity;
13531  SCIP_Real maxactivity;
13532  SCIP_Real maxcondactivity;
13533  SCIP_Real mincondactivity;
13534  SCIP_Real rhs;
13535  SCIP_Real val;
13536  SCIP_Real obj;
13537  SCIP_Real factor;
13538  SCIP_Bool minactisrelax;
13539  SCIP_Bool maxactisrelax;
13540  SCIP_Bool tryfixing;
13541  int nsingletons;
13542  int idx;
13543  int v;
13544  int nvars;
13545 
13546  assert(scip != NULL);
13547  assert(cons != NULL);
13548  assert(nfixedvars != NULL);
13549 
13550  consdata = SCIPconsGetData(cons);
13551 
13552  /* we only want to run for inequalities */
13553  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, -consdata->lhs) )
13554  return SCIP_OKAY;
13555 
13556  if( singlevarstuffing )
13557  {
13558  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
13559  }
13560  else
13561  {
13562  minactivity = SCIP_INVALID;
13563  maxactivity = SCIP_INVALID;
13564  }
13565 
13566  /* we want to have a <= constraint, if the rhs is infinite, we implicitly multiply the constraint by -1,
13567  * the new maxactivity is minus the old minactivity then
13568  */
13569  if( SCIPisInfinity(scip, consdata->rhs) )
13570  {
13571  SCIP_Real tmp;
13572  rhs = -consdata->lhs;
13573  factor = -1.0;
13574  tmp = maxactivity;
13575  maxactivity = -minactivity;
13576  minactivity = -tmp;
13577  }
13578  else
13579  {
13580  assert(SCIPisInfinity(scip, -consdata->lhs));
13581  rhs = consdata->rhs;
13582  factor = 1.0;
13583  }
13584 
13585  nvars = consdata->nvars;
13586  vars = consdata->vars;
13587  vals = consdata->vals;
13588 
13589  /* check for continuous singletons */
13590  if( singletonstuffing )
13591  {
13592  for( v = 0; v < nvars; ++v )
13593  {
13594  var = vars[v];
13595 
13596  if( (SCIPvarGetNLocksUp(var) + SCIPvarGetNLocksDown(var)) == 1 &&
13598  break;
13599  }
13600  }
13601  else
13602  /* we don't want to go into the next block */
13603  v = nvars;
13604 
13605  /* a singleton was found -> perform singleton variable stuffing */
13606  if( v < nvars )
13607  {
13608  assert(singletonstuffing);
13609 
13610  SCIP_CALL( SCIPallocBufferArray(scip, &varpos, nvars) );
13611  SCIP_CALL( SCIPallocBufferArray(scip, &ratios, nvars) );
13612  SCIP_CALL( SCIPallocBufferArray(scip, &swapped, nvars) );
13613 
13614  tryfixing = TRUE;
13615  nsingletons = 0;
13616  mincondactivity = 0.0;
13617  maxcondactivity = 0.0;
13618 
13619  for( v = 0; v < nvars; ++v )
13620  {
13621  var = vars[v];
13622  lb = SCIPvarGetLbGlobal(var);
13623  ub = SCIPvarGetUbGlobal(var);
13624  obj = SCIPvarGetObj(var);
13625  val = factor * vals[v];
13626 
13627  assert(!SCIPisZero(scip, val));
13628 
13629  /* the variable is a singleton and continuous */
13630  if( (SCIPvarGetNLocksUp(var) + SCIPvarGetNLocksDown(var)) == 1 &&
13632  {
13633  if( SCIPisNegative(scip, obj) && val > 0 )
13634  {
13635  /* case 1: obj < 0 and coef > 0 */
13636  if( SCIPisInfinity(scip, -lb) )
13637  {
13638  tryfixing = FALSE;
13639  break;
13640  }
13641 
13642  maxcondactivity += val * lb;
13643  mincondactivity += val * lb;
13644  swapped[v] = FALSE;
13645  ratios[nsingletons] = obj / val;
13646  varpos[nsingletons] = v;
13647  nsingletons++;
13648  }
13649  else if( SCIPisPositive(scip, obj) && val < 0 )
13650  {
13651  /* case 2: obj > 0 and coef < 0 */
13652  if( SCIPisInfinity(scip, ub) )
13653  {
13654  tryfixing = FALSE;
13655  break;
13656  }
13657  /* multiply column by (-1) to become case 1.
13658  * now bounds are swapped: ub := -lb, lb := -ub
13659  */
13660 
13661  maxcondactivity += val * ub;
13662  mincondactivity += val * ub;
13663  swapped[v] = TRUE;
13664  ratios[nsingletons] = obj / val;
13665  varpos[nsingletons] = v;
13666  nsingletons++;
13667  }
13668  else if( val > 0 )
13669  {
13670  /* case 3: obj >= 0 and coef >= 0 is handled by duality fixing.
13671  * we only consider the lower bound for the constants
13672  */
13673  assert(!SCIPisNegative(scip, obj));
13674 
13675  if( SCIPisInfinity(scip, -lb) )
13676  {
13677  /* maybe unbounded */
13678  tryfixing = FALSE;
13679  break;
13680  }
13681 
13682  maxcondactivity += val * lb;
13683  mincondactivity += val * lb;
13684  }
13685  else
13686  {
13687  /* case 4: obj <= 0 and coef <= 0 is also handled by duality fixing.
13688  * we only consider the upper bound for the constants
13689  */
13690  assert(!SCIPisPositive(scip, obj));
13691  assert(val < 0);
13692 
13693  if( SCIPisInfinity(scip, ub) )
13694  {
13695  /* maybe unbounded */
13696  tryfixing = FALSE;
13697  break;
13698  }
13699 
13700  maxcondactivity += val * ub;
13701  mincondactivity += val * ub;
13702  }
13703  }
13704  else
13705  {
13706  /* consider contribution of discrete variables, non-singleton
13707  * continuous variables and variables with more than one lock
13708  */
13709  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
13710  {
13711  tryfixing = FALSE;
13712  break;
13713  }
13714 
13715  if( val > 0 )
13716  {
13717  maxcondactivity += val * ub;
13718  mincondactivity += val * lb;
13719  }
13720  else
13721  {
13722  maxcondactivity += val * lb;
13723  mincondactivity += val * ub;
13724  }
13725  }
13726  }
13727  if( tryfixing && nsingletons > 0 && (SCIPisGT(scip, rhs, maxcondactivity) || SCIPisLE(scip, rhs, mincondactivity)) )
13728  {
13729  SCIP_Real delta;
13730  SCIP_Bool tightened;
13731 #ifdef SCIP_DEBUG
13732  int oldnfixedvars = *nfixedvars;
13733  int oldnchgbds = *nchgbds;
13734 #endif
13735 
13736  SCIPsortRealInt(ratios, varpos, nsingletons);
13737 
13738  /* verify which singleton continuous variables can be fixed */
13739  for( v = 0; v < nsingletons; ++v )
13740  {
13741  idx = varpos[v];
13742  var = vars[idx];
13743  val = factor * vals[idx];
13744  lb = SCIPvarGetLbGlobal(var);
13745  ub = SCIPvarGetUbGlobal(var);
13746 
13747  assert(val > 0 || SCIPisPositive(scip, SCIPvarGetObj(var)));
13748  assert((val < 0) == swapped[idx]);
13749  val = REALABS(val);
13750 
13751  /* stop fixing if variable bounds are not finite */
13752  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
13753  break;
13754 
13755  assert((SCIPvarGetNLocksUp(var) + SCIPvarGetNLocksDown(var)) == 1);
13756  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
13757 
13758  /* calculate the change in the row activities if this variable changes
13759  * its value from its worst to its best bound
13760  */
13761  if( swapped[idx] )
13762  delta = -(lb - ub) * val;
13763  else
13764  delta = (ub - lb) * val;
13765 
13766  assert(!SCIPisNegative(scip, delta));
13767 
13768  if( SCIPisLE(scip, delta, rhs - maxcondactivity) )
13769  {
13770  if( swapped[idx] )
13771  {
13772  SCIPdebugMsg(scip, "fix <%s> to its lower bound %g\n", SCIPvarGetName(var), lb);
13773  SCIP_CALL( SCIPfixVar(scip, var, lb, cutoff, &tightened) );
13774 
13775  }
13776  else
13777  {
13778  SCIPdebugMsg(scip, "fix <%s> to its upper bound %g\n", SCIPvarGetName(var), ub);
13779  SCIP_CALL( SCIPfixVar(scip, var, ub, cutoff, &tightened) );
13780  }
13781 
13782  if( *cutoff )
13783  break;
13784  if( tightened )
13785  {
13786  (*nfixedvars)++;
13787  }
13788  }
13789  /* @note: we could in theory tighten the bound of the first singleton variable which does not fall into the above case,
13790  * since it cannot be fully fixed. However, this is not needed and should be done by activity-based bound tightening
13791  * anyway after all other continuous singleton columns were fixed; doing it here may introduce numerical
13792  * troubles in case of large bounds.
13793  */
13794  else if( SCIPisLE(scip, rhs, mincondactivity) )
13795  {
13796  if( swapped[idx] )
13797  {
13798  SCIPdebugMsg(scip, "fix <%s> to its upper bound %g\n", SCIPvarGetName(var), ub);
13799  SCIP_CALL( SCIPfixVar(scip, var, ub, cutoff, &tightened) );
13800  }
13801  else
13802  {
13803  SCIPdebugMsg(scip, "fix <%s> to its lower bound %g\n", SCIPvarGetName(var), lb);
13804  SCIP_CALL( SCIPfixVar(scip, var, lb, cutoff, &tightened) );
13805  }
13806 
13807  if( *cutoff )
13808  break;
13809  if( tightened )
13810  {
13811  (*nfixedvars)++;
13812  }
13813  }
13814 
13815  maxcondactivity += delta;
13816  mincondactivity += delta;
13817  }
13818 
13819 #ifdef SCIP_DEBUG
13820  if( *nfixedvars - oldnfixedvars > 0 || *nchgbds - oldnchgbds > 0 )
13821  {
13822  SCIPdebugMsg(scip, "### stuffing fixed %d variables and changed %d bounds\n", *nfixedvars - oldnfixedvars, *nchgbds - oldnchgbds);
13823  }
13824 #endif
13825  }
13826 
13827  SCIPfreeBufferArray(scip, &swapped);
13828  SCIPfreeBufferArray(scip, &ratios);
13829  SCIPfreeBufferArray(scip, &varpos);
13830  }
13831 
13832  /* perform single-variable stuffing:
13833  * for a linear inequality
13834  * a_1 x_1 + a_2 x_2 + ... + a_n x_n <= b
13835  * with a_i > 0 and objective coefficients c_i < 0,
13836  * setting all variables to their upper bound (giving us the maximal activity of the constraint) is worst w.r.t.
13837  * feasibility of the constraint. On the other hand, this gives the best objective function contribution of the
13838  * variables contained in the constraint. The maximal activity should be larger than the rhs, otherwise the constraint
13839  * is redundant.
13840  * Now we are searching for a variable x_k with maximal ratio c_k / a_k (note that all these ratios are negative), so
13841  * that by reducing the value of this variable we reduce the activity of the constraint while having the smallest
13842  * objective deterioration per activity unit. If x_k has no downlocks, is continuous, and can be reduced enough to
13843  * render the constraint feasible, and ALL other variables have only the one uplock installed by the current constraint,
13844  * we can reduce the upper bound of x_k such that the maxactivity equals the rhs and fix all other variables to their
13845  * upper bound.
13846  * Note that the others variables may have downlocks from other constraints, which we do not need to care
13847  * about since we are setting them to the highest possible value. Also, they may be integer or binary, because the
13848  * computed ratio is still a lower bound on the change in the objective caused by reducing those variable to reach
13849  * constraint feasibility. On the other hand, uplocks on x_k from other constraint do no interfer with the method.
13850  * With a slight adjustment, the procedure even works for integral x_k. If (maxactivity - rhs)/val is integral,
13851  * the variable gets an integral value in order to fulfill the constraint tightly, and we can just apply the procedure.
13852  * If (maxactivity - rhs)/val is fractional, we need to check, if overfulfilling the constraint by setting x_k to
13853  * ceil((maxactivity - rhs)/val) is still better than setting x_k to ceil((maxactivity - rhs)/val) - 1 and
13854  * filling the remaining gap in the constraint with the next-best variable. For this, we check that
13855  * c_k * ceil((maxactivity - rhs)/val) is still better than
13856  * c_k * floor((maxactivity - rhs)/val) + c_j * ((maxactivity - rhs) - (floor((maxactivity - rhs)/val) * val))/a_j.
13857  * In this case, the upper bound of x_k is decreased to ub_k - ceil(maxactivity - rhs).
13858  * If there are variables with a_i < 0 and c_i > 0, they are negated to obtain the above form, variables with same
13859  * sign of coefficients in constraint and objective prevent the use of this method.
13860  */
13861  if( singlevarstuffing && !SCIPisInfinity(scip, -minactivity) )
13862  {
13863  SCIP_Real bestratio = -SCIPinfinity(scip);
13864  SCIP_Real secondbestratio = -SCIPinfinity(scip);
13865  SCIP_Real ratio;
13866  int bestindex = -1;
13867  int bestuplocks = 0;
13868  int bestdownlocks = 1;
13869  int downlocks;
13870  int uplocks;
13871  int oldnfixedvars;
13872  int oldnchgbds;
13873 
13874  SCIPdebug( oldnfixedvars = *nfixedvars; )
13875  SCIPdebug( oldnchgbds = *nchgbds; )
13876  /* loop over all variables to identify the best and second-best ratio */
13877  for( v = 0; v < nvars; ++v )
13878  {
13879  var = vars[v];
13880  obj = SCIPvarGetObj(var);
13881  val = factor * vals[v];
13882 
13883  assert(!SCIPisZero(scip, val));
13884 
13885  ratio = obj / val;
13886 
13887  /* if both objective and constraint push the variable to the same direction, we can do nothing here */
13888  if( !SCIPisNegative(scip, ratio) )
13889  {
13890  bestindex = -1;
13891  break;
13892  }
13893 
13894  if( val > 0 )
13895  {
13896  downlocks = SCIPvarGetNLocksDown(var);
13897  uplocks = SCIPvarGetNLocksUp(var);
13898  }
13899  else
13900  {
13901  downlocks = SCIPvarGetNLocksUp(var);
13902  uplocks = SCIPvarGetNLocksDown(var);
13903  }
13904 
13905  /* better ratio, update best candidate
13906  * @todo use some tolerance
13907  * @todo check size of domain and updated ratio for integer variables already?
13908  */
13909  if( ratio > bestratio || ((ratio == bestratio) && downlocks == 0 && (bestdownlocks > 0 /*lint !e777*/
13910  || (SCIPvarGetType(vars[bestindex]) != SCIP_VARTYPE_CONTINUOUS
13911  && SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS))) )
13912  {
13913  /* best index becomes second-best*/
13914  if( bestindex != -1 )
13915  {
13916  /* second-best index must not have more than 1 uplock */
13917  if( bestuplocks > 1 )
13918  {
13919  bestindex = -1;
13920  break;
13921  }
13922  else
13923  {
13924  secondbestratio = bestratio;
13925  }
13926  }
13927  bestdownlocks = downlocks;
13928  bestuplocks = uplocks;
13929  bestratio = ratio;
13930  bestindex = v;
13931 
13932  /* if this variable is the best in the end, we cannot do reductions since it has a downlocks,
13933  * if it is not the best, it has too many uplocks -> not applicable
13934  */
13935  if( bestdownlocks > 0 && bestuplocks > 1 )
13936  {
13937  bestindex = -1;
13938  break;
13939  }
13940  }
13941  else
13942  {
13943  /* non-best index must not have more than 1 uplock */
13944  if( uplocks > 1 )
13945  {
13946  bestindex = -1;
13947  break;
13948  }
13949  /* update second-best ratio */
13950  if( ratio > secondbestratio )
13951  {
13952  secondbestratio = ratio;
13953  }
13954  }
13955  }
13956 
13957  /* check if we can apply single variable stuffing */
13958  if( bestindex != -1 && bestdownlocks == 0 )
13959  {
13960  SCIP_Bool tightened = FALSE;
13961  SCIP_Real bounddelta;
13962 
13963  var = vars[bestindex];
13964  obj = SCIPvarGetObj(var);
13965  val = factor * vals[bestindex];
13966  lb = SCIPvarGetLbGlobal(var);
13967  ub = SCIPvarGetUbGlobal(var);
13968  tryfixing = TRUE;
13969 
13970  if( val < 0 )
13971  {
13972  assert(!SCIPisNegative(scip, obj));
13973 
13974  /* the best variable is integer, and we need to overfulfill the constraint when using just the variable */
13975  if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisIntegral(scip, (maxactivity - rhs)/-val) )
13976  {
13977  SCIP_Real bestvarfloor = SCIPfloor(scip, (maxactivity - rhs)/-val);
13978  SCIP_Real activitydelta = (maxactivity - rhs) - (bestvarfloor * -val);
13979  assert(SCIPisPositive(scip, activitydelta));
13980 
13981  tryfixing = SCIPisLE(scip, obj, -activitydelta * secondbestratio);
13982 
13983  bounddelta = SCIPceil(scip, (maxactivity - rhs)/-val);
13984  assert(SCIPisPositive(scip, bounddelta));
13985  }
13986  else
13987  bounddelta = (maxactivity - rhs)/-val;
13988 
13989  tryfixing = tryfixing && SCIPisLE(scip, bounddelta, ub - lb);
13990 
13991  if( tryfixing )
13992  {
13993  assert(SCIPvarGetNLocksUp(var) == 0);
13994 
13995  if( SCIPisEQ(scip, lb + bounddelta, ub) )
13996  {
13997  SCIPdebugMsg(scip, "fix var <%s> to %g\n", SCIPvarGetName(var), lb + bounddelta);
13998  SCIP_CALL( SCIPfixVar(scip, var, lb + bounddelta, cutoff, &tightened) );
13999  }
14000  else
14001  {
14002  SCIPdebugMsg(scip, "tighten the lower bound of <%s> from %g to %g (ub=%g)\n", SCIPvarGetName(var), lb, lb + bounddelta, ub);
14003  SCIP_CALL( SCIPtightenVarLb(scip, var, lb + bounddelta, FALSE, cutoff, &tightened) );
14004  }
14005  }
14006  }
14007  else
14008  {
14009  assert(!SCIPisPositive(scip, obj));
14010 
14011  /* the best variable is integer, and we need to overfulfill the constraint when using just the variable */
14012  if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisIntegral(scip, (maxactivity - rhs)/val))
14013  {
14014  SCIP_Real bestvarfloor = SCIPfloor(scip, (maxactivity - rhs)/val);
14015  SCIP_Real activitydelta = (maxactivity - rhs) - (bestvarfloor * val);
14016  assert(SCIPisPositive(scip, activitydelta));
14017 
14018  tryfixing = SCIPisLE(scip, -obj, activitydelta * secondbestratio);
14019 
14020  bounddelta = SCIPceil(scip, (maxactivity - rhs)/val);
14021  assert(SCIPisPositive(scip, bounddelta));
14022  }
14023  else
14024  bounddelta = (maxactivity - rhs)/val;
14025 
14026  tryfixing = tryfixing && SCIPisLE(scip, bounddelta, ub - lb);
14027 
14028  if( tryfixing )
14029  {
14030  assert(SCIPvarGetNLocksDown(var) == 0);
14031 
14032  if( SCIPisEQ(scip, ub - bounddelta, lb) )
14033  {
14034  SCIPdebugMsg(scip, "fix var <%s> to %g\n", SCIPvarGetName(var), ub - bounddelta);
14035  SCIP_CALL( SCIPfixVar(scip, var, ub - bounddelta, cutoff, &tightened) );
14036  }
14037  else
14038  {
14039  SCIPdebugMsg(scip, "tighten the upper bound of <%s> from %g to %g (lb=%g)\n", SCIPvarGetName(var), ub, ub - bounddelta, lb);
14040  SCIP_CALL( SCIPtightenVarUb(scip, var, ub - bounddelta, FALSE, cutoff, &tightened) );
14041  }
14042  }
14043  }
14044 
14045  if( *cutoff )
14046  return SCIP_OKAY;
14047  if( tightened )
14048  {
14049  if( SCIPisEQ(scip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)) )
14050  ++(*nfixedvars);
14051  else
14052  ++(*nchgbds);
14053 
14054  SCIPdebugMsg(scip, "cons <%s>: %g <=\n", SCIPconsGetName(cons), factor > 0 ? consdata->lhs : -consdata->rhs);
14055  for( v = 0; v < nvars; ++v )
14056  {
14057  SCIPdebugMsg(scip, "%+g <%s>([%g,%g],%g,[%d,%d],%s)\n", factor * vals[v], SCIPvarGetName(vars[v]), SCIPvarGetLbGlobal(vars[v]),
14058  SCIPvarGetUbGlobal(vars[v]), SCIPvarGetObj(vars[v]), SCIPvarGetNLocksDown(vars[v]), SCIPvarGetNLocksUp(vars[v]),
14059  SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS ? "C" : "I");
14060  }
14061  SCIPdebugMsg(scip, "<= %g\n", factor > 0 ? consdata->rhs : -consdata->lhs);
14062 
14063  for( v = 0; v < nvars; ++v )
14064  {
14065  if( v == bestindex )
14066  continue;
14067 
14068  if( factor * vals[v] < 0 )
14069  {
14070  assert(SCIPvarGetNLocksDown(vars[v]) == 1);
14071  SCIPdebugMsg(scip, "fix <%s> to its lower bound (%g)\n", SCIPvarGetName(vars[v]), SCIPvarGetLbGlobal(vars[v]));
14072  SCIP_CALL( SCIPfixVar(scip, vars[v], SCIPvarGetLbGlobal(vars[v]), cutoff, &tightened) );
14073  }
14074  else
14075  {
14076  assert(SCIPvarGetNLocksUp(vars[v]) == 1);
14077  SCIPdebugMsg(scip, "fix <%s> to its upper bound (%g)\n", SCIPvarGetName(vars[v]), SCIPvarGetUbGlobal(vars[v]));
14078  SCIP_CALL( SCIPfixVar(scip, vars[v], SCIPvarGetUbGlobal(vars[v]), cutoff, &tightened) );
14079  }
14080 
14081  if( *cutoff )
14082  return SCIP_OKAY;
14083  if( tightened )
14084  ++(*nfixedvars);
14085  }
14086  SCIPdebugMsg(scip, "### new stuffing fixed %d vars, tightened %d bounds\n", *nfixedvars - oldnfixedvars, *nchgbds - oldnchgbds);
14087  }
14088  }
14089  }
14090 
14091  return SCIP_OKAY;
14092 }
14093 
14094 /** applies full dual presolving on variables that only appear in linear constraints */
14095 static
14097  SCIP* scip, /**< SCIP data structure */
14098  SCIP_CONS** conss, /**< constraint set */
14099  int nconss, /**< number of constraints */
14100  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
14101  int* nchgbds /**< pointer to count the number of bound changes */
14102  )
14103 {
14104  SCIP_Real* redlb;
14105  SCIP_Real* redub;
14106  int* nlocksdown;
14107  int* nlocksup;
14108  SCIP_Bool* isimplint;
14109  SCIP_VAR** origvars;
14110  SCIP_VAR** vars;
14111  SCIP_VAR** conscontvars;
14112  int nvars;
14113  int nbinvars;
14114  int nintvars;
14115  int ncontvars;
14116  int v;
14117  int c;
14118 
14119  /* we calculate redundancy bounds with the following meaning:
14120  * redlb[v] == k : if x_v >= k, we can always round x_v down to x_v == k without violating any constraint
14121  * redub[v] == k : if x_v <= k, we can always round x_v up to x_v == k without violating any constraint
14122  * then:
14123  * c_v >= 0 : x_v <= redlb[v] is feasible due to optimality
14124  * c_v <= 0 : x_v >= redub[v] is feasible due to optimality
14125  */
14126 
14127  /* Additionally, we detect continuous variables that are implicitly integral.
14128  * A continuous variable j is implicit integral if it only has only +/-1 coefficients,
14129  * and all constraints (including the bounds as trivial constraints) in which:
14130  * c_j > 0: the variable is down-locked,
14131  * c_j < 0: the variable is up-locked,
14132  * c_j = 0: the variable appears
14133  * have, apart from j, only integer variables with integral coefficients and integral sides.
14134  * This is because then, the value of the variable is either determined by one of its bounds or
14135  * by one of these constraints, and in all cases, the value of the variable is integral.
14136  */
14137 
14138  assert(scip != NULL);
14139  assert(nconss == 0 || conss != NULL);
14140  assert(nchgbds != NULL);
14141  assert(!SCIPinProbing(scip));
14142 
14143  /* get active variables */
14144  nvars = SCIPgetNVars(scip);
14145  origvars = SCIPgetVars(scip);
14146 
14147  /* if the problem is a pure binary program, nothing can be achieved by full dual presolve */
14148  nbinvars = SCIPgetNBinVars(scip);
14149  if( nbinvars == nvars )
14150  return SCIP_OKAY;
14151 
14152  /* get number of continuous variables */
14153  ncontvars = SCIPgetNContVars(scip);
14154  nintvars = nvars - ncontvars;
14155 
14156  /* copy the variable array since this array might change during the curse of this algorithm */
14157  nvars = nvars - nbinvars;
14158  SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, &(origvars[nbinvars]), nvars) );
14159 
14160  /* allocate temporary memory */
14161  SCIP_CALL( SCIPallocBufferArray(scip, &redlb, nvars) );
14162  SCIP_CALL( SCIPallocBufferArray(scip, &redub, nvars) );
14163  SCIP_CALL( SCIPallocBufferArray(scip, &nlocksdown, nvars) );
14164  SCIP_CALL( SCIPallocBufferArray(scip, &nlocksup, nvars) );
14165  SCIP_CALL( SCIPallocBufferArray(scip, &isimplint, ncontvars) );
14166  SCIP_CALL( SCIPallocBufferArray(scip, &conscontvars, ncontvars) );
14167 
14168  /* initialize redundancy bounds */
14169  for( v = 0; v < nvars; ++v )
14170  {
14171  assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_BINARY);
14172  redlb[v] = SCIPvarGetLbGlobal(vars[v]);
14173  redub[v] = SCIPvarGetUbGlobal(vars[v]);
14174  }
14175  BMSclearMemoryArray(nlocksdown, nvars);
14176  BMSclearMemoryArray(nlocksup, nvars);
14177 
14178  /* Initialize isimplint array: variable may be implied integer if rounded to their best bound they are integral.
14179  * We better not use SCIPisFeasIntegral() in these checks.
14180  */
14181  for( v = 0; v < ncontvars; v++ )
14182  {
14183  SCIP_VAR* var;
14184  SCIP_Real obj;
14185  SCIP_Real lb;
14186  SCIP_Real ub;
14187 
14188  var = vars[v + nintvars - nbinvars];
14189  lb = SCIPvarGetLbGlobal(var);
14190  ub = SCIPvarGetUbGlobal(var);
14191 
14192  obj = SCIPvarGetObj(var);
14193  if( SCIPisZero(scip, obj) )
14194  isimplint[v] = (SCIPisInfinity(scip, -lb) || SCIPisIntegral(scip, lb)) && (SCIPisInfinity(scip, ub) || SCIPisIntegral(scip, ub));
14195  else
14196  {
14197  if( SCIPisPositive(scip, obj) )
14198  isimplint[v] = (SCIPisInfinity(scip, -lb) || SCIPisIntegral(scip, lb));
14199  else
14200  {
14201  assert(SCIPisNegative(scip, obj));
14202  isimplint[v] = (SCIPisInfinity(scip, ub) || SCIPisIntegral(scip, ub));
14203  }
14204  }
14205  }
14206 
14207  /* scan all constraints */
14208  for( c = 0; c < nconss; ++c )
14209  {
14210  /* we only need to consider constraints that have been locked (i.e., checked constraints or constraints that are
14211  * part of checked disjunctions)
14212  */
14213  if( SCIPconsIsLocked(conss[c]) )
14214  {
14215  SCIP_CONSDATA* consdata;
14216  SCIP_Bool lhsexists;
14217  SCIP_Bool rhsexists;
14218  SCIP_Bool hasimpliedpotential;
14219  SCIP_Bool integralcoefs;
14220  int nlockspos;
14221  int contvarpos;
14222  int nconscontvars;
14223  int i;
14224 
14225  consdata = SCIPconsGetData(conss[c]);
14226  assert(consdata != NULL);
14227 
14228  /* get number of times the constraint was locked */
14229  nlockspos = SCIPconsGetNLocksPos(conss[c]);
14230 
14231  /* we do not want to include constraints with locked negation (this would be too weird) */
14232  if( SCIPconsGetNLocksNeg(conss[c]) > 0 )
14233  {
14234  /* mark all continuous variables as not being implicit integral */
14235  for( i = 0; i < consdata->nvars; ++i )
14236  {
14237  SCIP_VAR* var;
14238 
14239  var = consdata->vars[i];
14241  {
14242  int contv;
14243  contv = SCIPvarGetProbindex(var) - nintvars;
14244  assert(0 <= contv && contv < ncontvars); /* variable should be active due to applyFixings() */
14245  isimplint[contv] = FALSE;
14246  }
14247  }
14248  continue;
14249  }
14250 
14251  /* check for existing sides */
14252  lhsexists = !SCIPisInfinity(scip, -consdata->lhs);
14253  rhsexists = !SCIPisInfinity(scip, consdata->rhs);
14254 
14255  /* count locks and update redundancy bounds */
14256  contvarpos = -1;
14257  nconscontvars = 0;
14258  hasimpliedpotential = FALSE;
14259  integralcoefs = !SCIPconsIsModifiable(conss[c]);
14260 
14261  for( i = 0; i < consdata->nvars; ++i )
14262  {
14263  SCIP_VAR* var;
14264  SCIP_Real val;
14265  SCIP_Real minresactivity;
14266  SCIP_Real maxresactivity;
14267  SCIP_Real newredlb;
14268  SCIP_Real newredub;
14269  SCIP_Bool minisrelax;
14270  SCIP_Bool maxisrelax;
14271  SCIP_Bool isminsettoinfinity;
14272  SCIP_Bool ismaxsettoinfinity;
14273  int arrayindex;
14274 
14275  var = consdata->vars[i];
14276  val = consdata->vals[i];
14277 
14278  /* check if still all integer variables have integral coefficients */
14279  if( SCIPvarIsIntegral(var) )
14280  integralcoefs = integralcoefs && SCIPisIntegral(scip, val);
14281 
14282  /* we do not need to process binary variables */
14283  if( SCIPvarIsBinary(var) )
14284  continue;
14285 
14286  if( SCIPconsIsModifiable(conss[c]) )
14287  {
14288  minresactivity = -SCIPinfinity(scip);
14289  maxresactivity = SCIPinfinity(scip);
14290  isminsettoinfinity = TRUE;
14291  ismaxsettoinfinity = TRUE;
14292  }
14293  else
14294  {
14295  /* calculate residual activity bounds if variable would be fixed to zero */
14296  consdataGetGlbActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
14297  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
14298 
14299  /* We called consdataGetGlbActivityResiduals() saying that we do not need a good relaxation,
14300  * so whenever we have a relaxed activity, it should be relaxed to +/- infinity.
14301  * This is needed, because we do not want to rely on relaxed finite resactivities.
14302  */
14303  assert((!minisrelax || isminsettoinfinity) && (!maxisrelax || ismaxsettoinfinity));
14304 
14305  /* check minresactivity for reliability */
14306  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastglbminactivity) )
14307  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, TRUE);
14308 
14309  /* check maxresactivity for reliability */
14310  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastglbmaxactivity) )
14311  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, TRUE);
14312  }
14313 
14314  arrayindex = SCIPvarGetProbindex(var) - nbinvars;
14315 
14316  assert(0 <= arrayindex && arrayindex < nvars); /* variable should be active due to applyFixings() */
14317 
14318  newredlb = redlb[arrayindex];
14319  newredub = redub[arrayindex];
14320  if( val > 0.0 )
14321  {
14322  if( lhsexists )
14323  {
14324  /* lhs <= d*x + a*y, d > 0 -> redundant in y if x >= (lhs - min{a*y})/d */
14325  nlocksdown[arrayindex] += nlockspos;
14326  newredlb = (isminsettoinfinity ? SCIPinfinity(scip) : (consdata->lhs - minresactivity)/val);
14327  }
14328  if( rhsexists )
14329  {
14330  /* d*x + a*y <= rhs, d > 0 -> redundant in y if x <= (rhs - max{a*y})/d */
14331  nlocksup[arrayindex] += nlockspos;
14332  newredub = (ismaxsettoinfinity ? -SCIPinfinity(scip) : (consdata->rhs - maxresactivity)/val);
14333  }
14334  }
14335  else
14336  {
14337  if( lhsexists )
14338  {
14339  /* lhs <= d*x + a*y, d < 0 -> redundant in y if x <= (lhs - min{a*y})/d */
14340  nlocksup[arrayindex] += nlockspos;
14341  newredub = (isminsettoinfinity ? -SCIPinfinity(scip) : (consdata->lhs - minresactivity)/val);
14342  }
14343  if( rhsexists )
14344  {
14345  /* d*x + a*y <= rhs, d < 0 -> redundant in y if x >= (rhs - max{a*y})/d */
14346  nlocksdown[arrayindex] += nlockspos;
14347  newredlb = (ismaxsettoinfinity ? SCIPinfinity(scip) : (consdata->rhs - maxresactivity)/val);
14348  }
14349  }
14350 
14351  /* if the variable is integer, we have to round the value to the next integral value */
14352  if( SCIPvarIsIntegral(var) )
14353  {
14354  if( !SCIPisInfinity(scip, newredlb) )
14355  newredlb = SCIPceil(scip, newredlb);
14356  if( !SCIPisInfinity(scip, -newredub) )
14357  newredub = SCIPfloor(scip, newredub);
14358  }
14359 
14360  /* update redundancy bounds */
14361  redlb[arrayindex] = MAX(redlb[arrayindex], newredlb);
14362  redub[arrayindex] = MIN(redub[arrayindex], newredub);
14363 
14364  /* collect the continuous variables of the constraint */
14366  {
14367  int contv;
14368 
14369  assert(nconscontvars < ncontvars);
14370  contvarpos = i;
14371  conscontvars[nconscontvars] = var;
14372  nconscontvars++;
14373 
14374  contv = SCIPvarGetProbindex(var) - nintvars;
14375  assert(0 <= contv && contv < ncontvars);
14376  hasimpliedpotential = hasimpliedpotential || isimplint[contv];
14377  }
14378  }
14379 
14380  /* update implied integer status of continuous variables */
14381  if( hasimpliedpotential )
14382  {
14383  if( nconscontvars > 1 || !integralcoefs )
14384  {
14385  /* there is more than one continuous variable or the integer variables have fractional coefficients:
14386  * none of the continuous variables is implied integer
14387  */
14388  for( i = 0; i < nconscontvars; i++ )
14389  {
14390  int contv;
14391  contv = SCIPvarGetProbindex(conscontvars[i]) - nintvars;
14392  assert(0 <= contv && contv < ncontvars);
14393  isimplint[contv] = FALSE;
14394  }
14395  }
14396  else
14397  {
14398  SCIP_VAR* var;
14399  SCIP_Real val;
14400  SCIP_Real absval;
14401  int contv;
14402 
14403  /* there is exactly one continuous variable and the integer variables have integral coefficients:
14404  * this is the interesting case, and we have to check whether the coefficient is +/-1 and the corresponding
14405  * side(s) of the constraint is integral
14406  */
14407  assert(nconscontvars == 1);
14408  assert(0 <= contvarpos && contvarpos < consdata->nvars);
14409  var = consdata->vars[contvarpos];
14410  val = consdata->vals[contvarpos];
14411  contv = SCIPvarGetProbindex(var) - nintvars;
14412  assert(0 <= contv && contv < ncontvars);
14413  assert(isimplint[contv]);
14414 
14415  absval = REALABS(val);
14416  if( !SCIPisEQ(scip, absval, 1.0) )
14417  isimplint[contv] = FALSE;
14418  else
14419  {
14420  SCIP_Real obj;
14421 
14422  obj = SCIPvarGetObj(var);
14423  if( obj * val >= 0.0 && lhsexists )
14424  {
14425  /* the variable may be blocked by the constraint's left hand side */
14426  isimplint[contv] = isimplint[contv] && SCIPisIntegral(scip, consdata->lhs);
14427  }
14428  if( obj * val <= 0.0 && rhsexists )
14429  {
14430  /* the variable may be blocked by the constraint's left hand side */
14431  isimplint[contv] = isimplint[contv] && SCIPisIntegral(scip, consdata->rhs);
14432  }
14433  }
14434  }
14435  }
14436  }
14437  }
14438 
14439  /* check if any bounds can be tightened due to optimality */
14440  for( v = 0; v < nvars; ++v )
14441  {
14442  SCIP_VAR* var;
14443  SCIP_Real obj;
14444  SCIP_Bool infeasible;
14445  SCIP_Bool tightened;
14446 
14447  assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_BINARY);
14448  assert(SCIPvarGetNLocksDown(vars[v]) >= nlocksdown[v]);
14449  assert(SCIPvarGetNLocksUp(vars[v]) >= nlocksup[v]);
14450 
14451  var = vars[v];
14452  obj = SCIPvarGetObj(var);
14453  if( obj >= 0.0 )
14454  {
14455  /* making the variable as small as possible does not increase the objective:
14456  * check if all down locks of the variables are due to linear constraints;
14457  * if largest bound to make constraints redundant is -infinity, we better do nothing for numerical reasons
14458  */
14459  if( SCIPvarGetNLocksDown(var) == nlocksdown[v]
14460  && !SCIPisInfinity(scip, -redlb[v])
14461  && redlb[v] < SCIPvarGetUbGlobal(var) )
14462  {
14463  SCIP_Real ub;
14464 
14465  /* if x_v >= redlb[v], we can always round x_v down to x_v == redlb[v] without violating any constraint
14466  * -> tighten upper bound to x_v <= redlb[v]
14467  */
14468  SCIPdebugMsg(scip, "variable <%s> only locked down in linear constraints: dual presolve <%s>[%.15g,%.15g] <= %.15g\n",
14470  redlb[v]);
14471  SCIP_CALL( SCIPtightenVarUb(scip, var, redlb[v], FALSE, &infeasible, &tightened) );
14472  assert(!infeasible);
14473 
14474  ub = SCIPvarGetUbGlobal(var);
14475  redub[v] = MIN(redub[v], ub);
14476  if( tightened )
14477  (*nchgbds)++;
14478  }
14479  }
14480  if( obj <= 0.0 )
14481  {
14482  /* making the variable as large as possible does not increase the objective:
14483  * check if all up locks of the variables are due to linear constraints;
14484  * if smallest bound to make constraints redundant is +infinity, we better do nothing for numerical reasons
14485  */
14486  if( SCIPvarGetNLocksUp(var) == nlocksup[v]
14487  && !SCIPisInfinity(scip, redub[v])
14488  && redub[v] > SCIPvarGetLbGlobal(var) )
14489  {
14490  SCIP_Real lb;
14491 
14492  /* if x_v <= redub[v], we can always round x_v up to x_v == redub[v] without violating any constraint
14493  * -> tighten lower bound to x_v >= redub[v]
14494  */
14495  SCIPdebugMsg(scip, "variable <%s> only locked up in linear constraints: dual presolve <%s>[%.15g,%.15g] >= %.15g\n",
14497  redub[v]);
14498  SCIP_CALL( SCIPtightenVarLb(scip, var, redub[v], FALSE, &infeasible, &tightened) );
14499  assert(!infeasible);
14500 
14501  lb = SCIPvarGetLbGlobal(var);
14502  redlb[v] = MAX(redlb[v], lb);
14503  if( tightened )
14504  (*nchgbds)++;
14505  }
14506  }
14507  }
14508 
14509  /* upgrade continuous variables to implied integers */
14510  for( v = nintvars - nbinvars; v < nvars; ++v )
14511  {
14512  SCIP_VAR* var;
14513  SCIP_Bool infeasible;
14514 
14515  var = vars[v];
14516  assert(var != NULL);
14517 
14518  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
14519  assert(SCIPvarGetNLocksDown(var) >= nlocksdown[v]);
14520  assert(SCIPvarGetNLocksUp(var) >= nlocksup[v]);
14521  assert(0 <= v - nintvars + nbinvars && v - nintvars + nbinvars < ncontvars);
14522 
14523  /* we can only conclude implied integrality if the variable appears in no other constraint */
14524  if( isimplint[v - nintvars + nbinvars]
14525  && SCIPvarGetNLocksDown(var) == nlocksdown[v]
14526  && SCIPvarGetNLocksUp(var) == nlocksup[v] )
14527  {
14528 
14529  /* since we locally copied the variable array we can change the variable type immediately */
14530  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
14531 
14532  if( infeasible )
14533  {
14534  SCIPdebugMsg(scip, "infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
14535  *cutoff = TRUE;
14536 
14537  break;
14538  }
14539 
14540  SCIPdebugMsg(scip, "dual presolve: converting continuous variable <%s>[%g,%g] to implicit integer\n",
14542  }
14543  }
14544 
14545  /* free temporary memory */
14546  SCIPfreeBufferArray(scip, &conscontvars);
14547  SCIPfreeBufferArray(scip, &isimplint);
14548  SCIPfreeBufferArray(scip, &nlocksup);
14549  SCIPfreeBufferArray(scip, &nlocksdown);
14550  SCIPfreeBufferArray(scip, &redub);
14551  SCIPfreeBufferArray(scip, &redlb);
14552 
14553  SCIPfreeBufferArray(scip, &vars);
14554 
14555  return SCIP_OKAY;
14556 }
14557 
14558 /** helper function to enforce constraints */
14559 static
14561  SCIP* scip, /**< SCIP data structure */
14562  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
14563  SCIP_CONS** conss, /**< constraints to process */
14564  int nconss, /**< number of constraints */
14565  int nusefulconss, /**< number of useful (non-obsolete) constraints to process */
14566  SCIP_SOL* sol, /**< solution to enforce (NULL for the LP solution) */
14567  SCIP_RESULT* result /**< pointer to store the result of the enforcing call */
14568  )
14569 {
14570  SCIP_CONSHDLRDATA* conshdlrdata;
14571  SCIP_Bool checkrelmaxabs;
14572  SCIP_Bool violated;
14573  SCIP_Bool cutoff = FALSE;
14574  int c;
14575 
14576  assert(scip != NULL);
14577  assert(conshdlr != NULL);
14578  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14579  assert(result != NULL);
14580 
14581  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14582  assert(conshdlrdata != NULL);
14583 
14584  checkrelmaxabs = conshdlrdata->checkrelmaxabs;
14585 
14586  SCIPdebugMsg(scip, "Enforcement method of linear constraints for %s solution\n", sol == NULL ? "LP" : "relaxation");
14587 
14588  /* check for violated constraints
14589  * LP is processed at current node -> we can add violated linear constraints to the SCIP_LP
14590  */
14591  *result = SCIP_FEASIBLE;
14592 
14593  /* check all useful linear constraints for feasibility */
14594  for( c = 0; c < nusefulconss; ++c )
14595  {
14596  SCIP_CALL( checkCons(scip, conss[c], sol, FALSE, checkrelmaxabs, &violated) );
14597 
14598  if( violated )
14599  {
14600  /* insert LP row as cut */
14601  SCIP_CALL( addRelaxation(scip, conss[c], sol, &cutoff) );
14602  if ( cutoff )
14603  *result = SCIP_CUTOFF;
14604  else
14605  *result = SCIP_SEPARATED;
14606  }
14607  }
14608 
14609  /* check all obsolete linear constraints for feasibility */
14610  for( c = nusefulconss; c < nconss && *result == SCIP_FEASIBLE; ++c )
14611  {
14612  SCIP_CALL( checkCons(scip, conss[c], sol, FALSE, checkrelmaxabs, &violated) );
14613 
14614  if( violated )
14615  {
14616  /* insert LP row as cut */
14617  SCIP_CALL( addRelaxation(scip, conss[c], sol, &cutoff) );
14618  if ( cutoff )
14619  *result = SCIP_CUTOFF;
14620  else
14621  *result = SCIP_SEPARATED;
14622  }
14623  }
14624 
14625  SCIPdebugMsg(scip, "-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
14626 
14627  return SCIP_OKAY;
14628 }
14629 
14630 /*
14631  * Callback methods of constraint handler
14632  */
14633 
14634 /** copy method for constraint handler plugins (called when SCIP copies plugins) */
14635 static
14636 SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinear)
14637 { /*lint --e{715}*/
14638  assert(scip != NULL);
14639  assert(conshdlr != NULL);
14640  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14641 
14642  /* call inclusion method of constraint handler */
14644 
14645  *valid = TRUE;
14646 
14647  return SCIP_OKAY;
14648 }
14649 
14650 /** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
14651 static
14652 SCIP_DECL_CONSFREE(consFreeLinear)
14653 { /*lint --e{715}*/
14654  SCIP_CONSHDLRDATA* conshdlrdata;
14655 
14656  assert(scip != NULL);
14657  assert(conshdlr != NULL);
14658  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
14659 
14660  /* free constraint handler data */
14661  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14662  assert(conshdlrdata != NULL);
14663 
14664  conshdlrdataFree(scip, &conshdlrdata);
14665 
14666  SCIPconshdlrSetData(conshdlr, NULL);
14667 
14668  return SCIP_OKAY;
14670 
14671 
14672 /** initialization method of constraint handler (called after problem was transformed) */
14673 static
14674 SCIP_DECL_CONSINIT(consInitLinear)
14675 {
14676  SCIP_CONSHDLRDATA* conshdlrdata;
14677  int c;
14678 
14679  assert(scip != NULL);
14680 
14681  /* check for event handler */
14682  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14683  assert(conshdlrdata != NULL);
14684  assert(conshdlrdata->eventhdlr != NULL);
14685  assert(nconss == 0 || conss != NULL);
14686 
14687  /* catch events for the constraints */
14688  for( c = 0; c < nconss; ++c )
14689  {
14690  /* catch all events */
14691  SCIP_CALL( consCatchAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
14692  }
14693 
14694  return SCIP_OKAY;
14695 }
14696 
14697 
14698 /** deinitialization method of constraint handler (called before transformed problem is freed) */
14699 static
14700 SCIP_DECL_CONSEXIT(consExitLinear)
14701 {
14702  SCIP_CONSHDLRDATA* conshdlrdata;
14703  int c;
14704 
14705  assert(scip != NULL);
14706 
14707  /* check for event handler */
14708  conshdlrdata = SCIPconshdlrGetData(conshdlr);
14709  assert(conshdlrdata != NULL);
14710  assert(conshdlrdata->eventhdlr != NULL);
14711 
14712  /* drop events for the constraints */
14713  for( c = nconss - 1; c >= 0; --c )
14714  {
14715  SCIP_CONSDATA* consdata;
14716 
14717  consdata = SCIPconsGetData(conss[c]);
14718  assert(consdata != NULL);
14719 
14720  if( consdata->eventdata != NULL )
14721  {
14722  /* drop all events */
14723  SCIP_CALL( consDropAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
14724  assert(consdata->eventdata == NULL);
14725  }
14726  }
14727 
14728  return SCIP_OKAY;
14729 
14730 }
14731 
14732 #ifdef WITH_PRINTORIGCONSTYPES
14733 
14734 /** is constraint ranged row, i.e., -inf < lhs < rhs < inf? */
14735 static
14736 SCIP_Bool isRangedRow(
14737  SCIP* scip, /**< SCIP data structure */
14738  SCIP_CONS* cons /**< constraint */
14739  )
14740 {
14741  assert(scip != NULL);
14742  assert(cons != NULL);
14743  assert(SCIPconsGetData(cons) != NULL);
14744 
14745  return !(SCIPisEQ(scip, SCIPconsGetData(cons)->lhs, SCIPconsGetData(cons)->rhs)
14746  || SCIPisInfinity(scip, -SCIPconsGetData(cons)->lhs) || SCIPisInfinity(scip, SCIPconsGetData(cons)->rhs) );
14747 }
14748 
14749 /** is constraint ranged row, i.e., -inf < lhs < rhs < inf? */
14750 static
14751 SCIP_Bool isFiniteNonnegativeIntegral(
14752  SCIP* scip, /**< SCIP data structure */
14753  SCIP_Real x /**< value */
14754  )
14755 {
14756  assert(scip != NULL);
14757 
14758  return (!SCIPisInfinity(scip, x) && !SCIPisNegative(scip, x) && SCIPisIntegral(scip, x));
14759 }
14760 
14761 /** presolving initialization method of constraint handler (called when presolving is about to begin) */
14762 static
14763 SCIP_DECL_CONSINITPRE(consInitpreLinear)
14764 { /*lint --e{715}*/
14765  int counter[(int)SCIP_CONSTYPE_GENERAL + 1];
14766  int c;
14767 
14768  assert(scip != NULL);
14769 
14770  /* initialize counter for constraint types to zero */
14771  BMSclearMemoryArray(counter, (int)SCIP_CONSTYPE_GENERAL + 1);
14772 
14773  /* loop through all constraints */
14774  for( c = 0; c < nconss; c++ )
14775  {
14776  SCIP_CONS* cons;
14777  SCIP_CONSDATA* consdata;
14778  int i;
14779 
14780  /* get constraint */
14781  cons = conss[c];
14782  assert(cons != NULL);
14783 
14784  /* get constraint data */
14785  consdata = SCIPconsGetData(cons);
14786  assert(consdata != NULL);
14787 
14788  /* merge multiples and delete variables with zero coefficient */
14789  SCIP_CALL( mergeMultiples(scip, cons) );
14790  for( i = 0; i < consdata->nvars; i++ )
14791  {
14792  assert(!SCIPisZero(scip, consdata->vals[i]));
14793  }
14794 
14795  /* is constraint of type SCIP_CONSTYPE_EMPTY? */
14796  if( consdata->nvars == 0 )
14797  {
14798  SCIPdebugMsg(scip, "classified as EMPTY: ");
14799  SCIPdebugPrintCons(scip, cons, NULL);
14800  counter[SCIP_CONSTYPE_EMPTY]++;
14801  continue;
14802  }
14803 
14804  /* is constraint of type SCIP_CONSTYPE_FREE? */
14805  if( SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, -consdata->lhs) )
14806  {
14807  SCIPdebugMsg(scip, "classified as FREE: ");
14808  SCIPdebugPrintCons(scip, cons, NULL);
14809  counter[SCIP_CONSTYPE_FREE]++;
14810  continue;
14811  }
14812 
14813  /* is constraint of type SCIP_CONSTYPE_SINGLETON? */
14814  if( consdata->nvars == 1 )
14815  {
14816  SCIPdebugMsg(scip, "classified as SINGLETON: ");
14817  SCIPdebugPrintCons(scip, cons, NULL);
14818  counter[SCIP_CONSTYPE_SINGLETON] += isRangedRow(scip, cons) ? 2 : 1;
14819  continue;
14820  }
14821 
14822  /* is constraint of type SCIP_CONSTYPE_AGGREGATION? */
14823  if( consdata->nvars == 2 && SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
14824  {
14825  SCIPdebugMsg(scip, "classified as AGGREGATION: ");
14826  SCIPdebugPrintCons(scip, cons, NULL);
14827  counter[SCIP_CONSTYPE_AGGREGATION]++;
14828  continue;
14829  }
14830 
14831  /* is constraint of type SCIP_CONSTYPE_{VARBOUND}? */
14832  if( consdata->nvars == 2 )
14833  {
14834  SCIPdebugMsg(scip, "classified as VARBOUND: ");
14835  SCIPdebugPrintCons(scip, cons, NULL);
14836  counter[SCIP_CONSTYPE_VARBOUND] += isRangedRow(scip, cons) ? 2 : 1;
14837  continue;
14838  }
14839 
14840  /* is constraint of type SCIP_CONSTYPE_{SETPARTITION, SETPACKING, SETCOVERING, CARDINALITY, INVKNAPSACK}? */
14841  {
14842  SCIP_Real scale;
14843  SCIP_Real b;
14844  SCIP_Bool unmatched;
14845  int nnegbinvars;
14846 
14847  unmatched = FALSE;
14848  nnegbinvars = 0;
14849 
14850  scale = REALABS(consdata->vals[0]);
14851  for( i = 0; i < consdata->nvars && !unmatched; i++ )
14852  {
14853  unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
14854  unmatched = unmatched || SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0);
14855  unmatched = unmatched || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0);
14856  unmatched = unmatched || !SCIPisEQ(scip, REALABS(consdata->vals[i]), scale);
14857 
14858  if( consdata->vals[i] < 0.0 )
14859  nnegbinvars++;
14860  }
14861 
14862  if( !unmatched )
14863  {
14864  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
14865  {
14866  b = consdata->rhs/scale + nnegbinvars;
14867  if( SCIPisEQ(scip, 1.0, b) )
14868  {
14869  SCIPdebugMsg(scip, "classified as SETPARTITION: ");
14870  SCIPdebugPrintCons(scip, cons, NULL);
14871  counter[SCIP_CONSTYPE_SETPARTITION]++;
14872  continue;
14873  }
14874  else if( SCIPisIntegral(scip, b) && !SCIPisNegative(scip, b) )
14875  {
14876  SCIPdebugMsg(scip, "classified as CARDINALITY: ");
14877  SCIPdebugPrintCons(scip, cons, NULL);
14878  counter[SCIP_CONSTYPE_CARDINALITY]++;
14879  continue;
14880  }
14881  }
14882 
14883  b = consdata->rhs/scale + nnegbinvars;
14884  if( SCIPisEQ(scip, 1.0, b) )
14885  {
14886  SCIPdebugMsg(scip, "classified as SETPACKING: ");
14887  SCIPdebugPrintCons(scip, cons, NULL);
14888  counter[SCIP_CONSTYPE_SETPACKING]++;
14889  consdata->rhs = SCIPinfinity(scip);
14890  }
14891  else if( SCIPisIntegral(scip, b) && !SCIPisNegative(scip, b) )
14892  {
14893  SCIPdebugMsg(scip, "classified as INVKNAPSACK: ");
14894  SCIPdebugPrintCons(scip, cons, NULL);
14895  counter[SCIP_CONSTYPE_INVKNAPSACK]++;
14896  consdata->rhs = SCIPinfinity(scip);
14897  }
14898 
14899  b = consdata->lhs/scale + nnegbinvars;
14900  if( SCIPisEQ(scip, 1.0, b) )
14901  {
14902  SCIPdebugMsg(scip, "classified as SETCOVERING: ");
14903  SCIPdebugPrintCons(scip, cons, NULL);
14904  counter[SCIP_CONSTYPE_SETCOVERING]++;
14905  consdata->lhs = -SCIPinfinity(scip);
14906  }
14907 
14908  if( SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, consdata->rhs) )
14909  continue;
14910  }
14911  }
14912 
14913  /* is constraint of type SCIP_CONSTYPE_{EQKNAPSACK, BINPACKING, KNAPSACK}? */
14914  /* @todo If coefficients or rhs are not integral, we currently do not check
14915  * if the constraint could be scaled (finitely), such that they are.
14916  */
14917  {
14918  SCIP_Real b;
14919  SCIP_Bool unmatched;
14920 
14921  b = consdata->rhs;
14922  unmatched = FALSE;
14923  for( i = 0; i < consdata->nvars && !unmatched; i++ )
14924  {
14925  unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
14926  unmatched = unmatched || SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0);
14927  unmatched = unmatched || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0);
14928  unmatched = unmatched || !SCIPisIntegral(scip, consdata->vals[i]);
14929 
14930  if( SCIPisNegative(scip, consdata->vals[i]) )
14931  b -= consdata->vals[i];
14932  }
14933  unmatched = unmatched || !isFiniteNonnegativeIntegral(scip, b);
14934 
14935  if( !unmatched )
14936  {
14937  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
14938  {
14939  SCIPdebugMsg(scip, "classified as EQKNAPSACK: ");
14940  SCIPdebugPrintCons(scip, cons, NULL);
14941  counter[SCIP_CONSTYPE_EQKNAPSACK]++;
14942  continue;
14943  }
14944  else
14945  {
14946  SCIP_Bool matched;
14947 
14948  matched = FALSE;
14949  for( i = 0; i < consdata->nvars && !matched; i++ )
14950  {
14951  matched = matched || SCIPisEQ(scip, b, REALABS(consdata->vals[i]));
14952  }
14953 
14954  SCIPdebugMsg(scip, "classified as %s: ", matched ? "BINPACKING" : "KNAPSACK");
14955  SCIPdebugPrintCons(scip, cons, NULL);
14956  counter[matched ? SCIP_CONSTYPE_BINPACKING : SCIP_CONSTYPE_KNAPSACK]++;
14957  }
14958 
14959  if( SCIPisInfinity(scip, -consdata->lhs) )
14960  continue;
14961  else
14962  consdata->rhs = SCIPinfinity(scip);
14963  }
14964  }
14965 
14966  /* is constraint of type SCIP_CONSTYPE_{INTKNAPSACK}? */
14967  {
14968  SCIP_Real b;
14969  SCIP_Bool unmatched;
14970 
14971  unmatched = FALSE;
14972 
14973  b = consdata->rhs;
14974  unmatched = unmatched || !isFiniteNonnegativeIntegral(scip, b);
14975 
14976  for( i = 0; i < consdata->nvars && !unmatched; i++ )
14977  {
14978  unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
14979  unmatched = unmatched || SCIPisNegative(scip, SCIPvarGetLbGlobal(consdata->vars[i]));
14980  unmatched = unmatched || !SCIPisIntegral(scip, consdata->vals[i]);
14981  unmatched = unmatched || SCIPisNegative(scip, consdata->vals[i]);
14982  }
14983 
14984  if( !unmatched )
14985  {
14986  SCIPdebugMsg(scip, "classified as INTKNAPSACK: ");
14987  SCIPdebugPrintCons(scip, cons, NULL);
14988  counter[SCIP_CONSTYPE_INTKNAPSACK]++;
14989 
14990  if( SCIPisInfinity(scip, -consdata->lhs) )
14991  continue;
14992  else
14993  consdata->rhs = SCIPinfinity(scip);
14994  }
14995  }
14996 
14997  /* is constraint of type SCIP_CONSTYPE_{MIXEDBINARY}? */
14998  {
14999  SCIP_Bool unmatched;
15000 
15001  unmatched = FALSE;
15002  for( i = 0; i < consdata->nvars && !unmatched; i++ )
15003  {
15004  if( SCIPvarGetType(consdata->vars[i]) != SCIP_VARTYPE_CONTINUOUS
15005  && (SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0)
15006  || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0)) )
15007  unmatched = TRUE;
15008  }
15009 
15010  if( !unmatched )
15011  {
15012  SCIPdebugMsg(scip, "classified as MIXEDBINARY (%d): ", isRangedRow(scip, cons) ? 2 : 1);
15013  SCIPdebugPrintCons(scip, cons, NULL);
15014  counter[SCIP_CONSTYPE_MIXEDBINARY] += isRangedRow(scip, cons) ? 2 : 1;
15015  continue;
15016  }
15017  }
15018 
15019  /* no special structure detected */
15020  SCIPdebugMsg(scip, "classified as GENERAL: ");
15021  SCIPdebugPrintCons(scip, cons, NULL);
15022  counter[SCIP_CONSTYPE_GENERAL] += isRangedRow(scip, cons) ? 2 : 1;
15023  }
15024 
15025  /* print statistics */
15026  SCIPinfoMessage(scip, NULL, "\n");
15027  SCIPinfoMessage(scip, NULL, "Number of constraints according to type:\n");
15028  SCIPinfoMessage(scip, NULL, "----------------------------------------\n");
15029  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_EMPTY %6d\n", 0, counter[ 0]);
15030  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_FREE %6d\n", 1, counter[ 1]);
15031  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_SINGLETON %6d\n", 2, counter[ 2]);
15032  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_AGGREGATION %6d\n", 3, counter[ 3]);
15033  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_VARBOUND %6d\n", 4, counter[ 4]);
15034  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_SETPARTITION %6d\n", 5, counter[ 5]);
15035  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_SETPACKING %6d\n", 6, counter[ 6]);
15036  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_SETCOVERING %6d\n", 7, counter[ 7]);
15037  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_CARDINALITY %6d\n", 8, counter[ 8]);
15038  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_INVKNAPSACK %6d\n", 9, counter[ 9]);
15039  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_EQKNAPSACK %6d\n", 10, counter[10]);
15040  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_BINPACKING %6d\n", 11, counter[11]);
15041  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_KNAPSACK %6d\n", 12, counter[12]);
15042  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_INTKNAPSACK %6d\n", 13, counter[13]);
15043  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_MIXEDBINARY %6d\n", 14, counter[14]);
15044  SCIPinfoMessage(scip, NULL, "%2d SCIP_CONSTYPE_GENERAL %6d\n", 15, counter[15]);
15045  SCIPinfoMessage(scip, NULL, "----------------------------------------\n\n");
15046 
15047  SCIPinfoMessage(scip, NULL, " EMPTY");
15048  SCIPinfoMessage(scip, NULL, " FREE");
15049  SCIPinfoMessage(scip, NULL, " SING");
15050  SCIPinfoMessage(scip, NULL, " AGGR");
15051  SCIPinfoMessage(scip, NULL, " VARBD");
15052  SCIPinfoMessage(scip, NULL, " SETPART");
15053  SCIPinfoMessage(scip, NULL, " SETPACK");
15054  SCIPinfoMessage(scip, NULL, " SETCOV");
15055  SCIPinfoMessage(scip, NULL, " CARD");
15056  SCIPinfoMessage(scip, NULL, " INVKNAP");
15057  SCIPinfoMessage(scip, NULL, " EQKNAP");
15058  SCIPinfoMessage(scip, NULL, " BINPACK");
15059  SCIPinfoMessage(scip, NULL, " KNAP");
15060  SCIPinfoMessage(scip, NULL, " INTKNAP");
15061  SCIPinfoMessage(scip, NULL, " MIXBIN");
15062  SCIPinfoMessage(scip, NULL, " GEN\n");
15063  for( c = 0; c <= (int)SCIP_CONSTYPE_GENERAL; c++ )
15064  {
15065  SCIPinfoMessage(scip, NULL, "%9d", counter[c]);
15066  }
15067 
15068  SCIPinfoMessage(scip, NULL, "\n\n");
15069  SCIPinfoMessage(scip, NULL, "----------------------------------------\n\n");
15070 
15071  return SCIP_OKAY;
15072 }
15073 #endif
15074 
15075 
15076 /** presolving deinitialization method of constraint handler (called after presolving has been finished) */
15077 static
15078 SCIP_DECL_CONSEXITPRE(consExitpreLinear)
15079 { /*lint --e{715}*/
15080  int c;
15081 #ifdef SCIP_STATISTIC
15082  SCIP_CONSHDLRDATA* conshdlrdata;
15083  int ngoodconss;
15084  int nallconss;
15085 #endif
15086 
15087  /* delete all linear constraints that were upgraded to a more specific constraint type;
15088  * make sure, only active variables remain in the remaining constraints
15089  */
15090  assert(scip != NULL);
15091 
15092 #ifdef SCIP_STATISTIC
15093  /* count number of well behaved linear constraints */
15094  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15095  assert(conshdlrdata != NULL);
15096 
15097  ngoodconss = 0;
15098  nallconss = 0;
15099 
15100  for( c = 0; c < nconss; ++c )
15101  {
15102  SCIP_CONSDATA* consdata;
15103 
15104  if( SCIPconsIsDeleted(conss[c]) )
15105  continue;
15106 
15107  consdata = SCIPconsGetData(conss[c]);
15108  assert(consdata != NULL);
15109 
15110  if( consdata->upgraded )
15111  continue;
15112 
15113  nallconss++;
15114 
15115  consdataRecomputeMaxActivityDelta(scip, consdata);
15116 
15117  if( SCIPisLT(scip, consdata->maxactdelta, conshdlrdata->maxeasyactivitydelta) )
15118  ngoodconss++;
15119  }
15120  if( nallconss )
15121  {
15122  SCIPstatisticMessage("below threshold: %d / %d ratio= %g\n", ngoodconss, nallconss, (100.0 * ngoodconss / nallconss));
15123  }
15124 #endif
15125 
15126  for( c = 0; c < nconss; ++c )
15127  {
15128  SCIP_CONSDATA* consdata;
15129 
15130  if( SCIPconsIsDeleted(conss[c]) )
15131  continue;
15132 
15133  consdata = SCIPconsGetData(conss[c]);
15134  assert(consdata != NULL);
15135 
15136  if( consdata->upgraded )
15137  {
15138  /* this is no problem reduction, because the upgraded constraint was added to the problem before, and the
15139  * (redundant) linear constraint was only kept in order to support presolving the the linear constraint handler
15140  */
15141  SCIP_CALL( SCIPdelCons(scip, conss[c]) );
15142  }
15143  else
15144  {
15145  /* since we are not allowed to detect infeasibility in the exitpre stage, we dont give an infeasible pointer */
15146  SCIP_CALL( applyFixings(scip, conss[c], NULL) );
15147  }
15148  }
15149 
15150  return SCIP_OKAY;
15151 }
15152 
15153 
15154 /** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
15155 static
15156 SCIP_DECL_CONSEXITSOL(consExitsolLinear)
15157 { /*lint --e{715}*/
15158  int c;
15159 
15160  assert(scip != NULL);
15161 
15162  /* release the rows of all constraints */
15163  for( c = 0; c < nconss; ++c )
15164  {
15165  SCIP_CONSDATA* consdata;
15166 
15167  consdata = SCIPconsGetData(conss[c]);
15168  assert(consdata != NULL);
15169 
15170  if( consdata->row != NULL )
15171  {
15172  SCIP_CALL( SCIPreleaseRow(scip, &consdata->row) );
15173  }
15174  }
15175 
15176  /* if this is a restart, convert cutpool rows into linear constraints */
15177  if( restart )
15178  {
15179  int ncutsadded;
15180 
15181  ncutsadded = 0;
15182 
15183  /* create out of all active cuts in cutpool linear constraints */
15184  SCIP_CALL( SCIPconvertCutsToConss(scip, NULL, NULL, TRUE, &ncutsadded) );
15185 
15186  if( ncutsadded > 0 )
15187  {
15189  "(restart) converted %d cuts from the global cut pool into linear constraints\n", ncutsadded);
15190  /* an extra blank line should be printed separately since the buffer message handler only handles up to one
15191  * line correctly
15192  */
15194  }
15195  }
15196 
15197  return SCIP_OKAY;
15198 }
15199 
15200 
15201 /** frees specific constraint data */
15202 static
15203 SCIP_DECL_CONSDELETE(consDeleteLinear)
15204 { /*lint --e{715}*/
15205  SCIP_CONSHDLRDATA* conshdlrdata;
15206 
15207  assert(scip != NULL);
15208  assert(conshdlr != NULL);
15209  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15210 
15211  /* check for event handler */
15212  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15213  assert(conshdlrdata != NULL);
15214  assert(conshdlrdata->eventhdlr != NULL);
15215 
15216  /* free event datas */
15217  if( (*consdata)->eventdata != NULL )
15218  {
15219  /* drop bound change events of variables */
15220  SCIP_CALL( consDropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
15221  }
15222  assert((*consdata)->eventdata == NULL);
15223 
15224  /* free linear constraint */
15225  SCIP_CALL( consdataFree(scip, consdata) );
15226 
15227  return SCIP_OKAY;
15228 }
15229 
15230 
15231 /** transforms constraint data into data belonging to the transformed problem */
15232 static
15233 SCIP_DECL_CONSTRANS(consTransLinear)
15234 { /*lint --e{715}*/
15235  SCIP_CONSDATA* sourcedata;
15236  SCIP_CONSDATA* targetdata;
15237 
15238  /*debugMsg(scip, "Trans method of linear constraints\n");*/
15239 
15240  assert(scip != NULL);
15241  assert(conshdlr != NULL);
15242  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15243  assert(SCIPgetStage(scip) == SCIP_STAGE_TRANSFORMING);
15244  assert(sourcecons != NULL);
15245  assert(targetcons != NULL);
15246 
15247  sourcedata = SCIPconsGetData(sourcecons);
15248  assert(sourcedata != NULL);
15249  assert(sourcedata->row == NULL); /* in original problem, there cannot be LP rows */
15251  /* create linear constraint data for target constraint */
15252  SCIP_CALL( consdataCreate(scip, &targetdata, sourcedata->nvars, sourcedata->vars, sourcedata->vals, sourcedata->lhs, sourcedata->rhs) );
15253 
15254  /* create target constraint */
15255  SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
15256  SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
15257  SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
15258  SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
15259  SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
15260 
15261  return SCIP_OKAY;
15262 }
15263 
15264 
15265 /** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
15266 static
15267 SCIP_DECL_CONSINITLP(consInitlpLinear)
15268 { /*lint --e{715}*/
15269  int c;
15270 
15271  assert(scip != NULL);
15272  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15273 
15274  *infeasible = FALSE;
15275 
15276  for( c = 0; c < nconss && !(*infeasible); ++c )
15277  {
15278  assert(SCIPconsIsInitial(conss[c]));
15279  SCIP_CALL( addRelaxation(scip, conss[c], NULL, infeasible) );
15280  }
15281 
15282  return SCIP_OKAY;
15283 }
15285 
15286 /** separation method of constraint handler for LP solutions */
15287 static
15288 SCIP_DECL_CONSSEPALP(consSepalpLinear)
15289 { /*lint --e{715}*/
15290  SCIP_CONSHDLRDATA* conshdlrdata;
15291  SCIP_Real loclowerbound;
15292  SCIP_Real glblowerbound;
15293  SCIP_Real cutoffbound;
15294  SCIP_Real maxbound;
15295  SCIP_Bool separatecards;
15296  SCIP_Bool cutoff;
15297  int c;
15298  int depth;
15299  int nrounds;
15300  int maxsepacuts;
15301  int ncuts;
15302 
15303  assert(scip != NULL);
15304  assert(conshdlr != NULL);
15305  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15306  assert(result != NULL);
15307 
15308  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15309  assert(conshdlrdata != NULL);
15310  depth = SCIPgetDepth(scip);
15311  nrounds = SCIPgetNSepaRounds(scip);
15312 
15313  /*debugMsg(scip, "Sepa method of linear constraints\n");*/
15314 
15315  *result = SCIP_DIDNOTRUN;
15316 
15317  /* only call the separator a given number of times at each node */
15318  if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
15319  || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
15320  return SCIP_OKAY;
15321 
15322  /* get the maximal number of cuts allowed in a separation round */
15323  maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
15324 
15325  /* check if we want to produce knapsack cardinality cuts at this node */
15326  loclowerbound = SCIPgetLocalLowerbound(scip);
15327  glblowerbound = SCIPgetLowerbound(scip);
15328  cutoffbound = SCIPgetCutoffbound(scip);
15329  maxbound = glblowerbound + conshdlrdata->maxcardbounddist * (cutoffbound - glblowerbound);
15330  separatecards = SCIPisLE(scip, loclowerbound, maxbound);
15331  separatecards = separatecards && (SCIPgetNLPBranchCands(scip) > 0);
15332 
15333  *result = SCIP_DIDNOTFIND;
15334  ncuts = 0;
15335  cutoff = FALSE;
15336 
15337  /* check all useful linear constraints for feasibility */
15338  for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
15339  {
15340  /*debugMsg(scip, "separating linear constraint <%s>\n", SCIPconsGetName(conss[c]));*/
15341  SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, NULL, separatecards, conshdlrdata->separateall, &ncuts, &cutoff) );
15342  }
15343 
15344  /* adjust return value */
15345  if( cutoff )
15346  *result = SCIP_CUTOFF;
15347  else if( ncuts > 0 )
15348  *result = SCIP_SEPARATED;
15349 
15350  /* combine linear constraints to get more cuts */
15351  /**@todo further cuts of linear constraints */
15352 
15353  return SCIP_OKAY;
15354 }
15355 
15356 
15357 /** separation method of constraint handler for arbitrary primal solutions */
15358 static
15359 SCIP_DECL_CONSSEPASOL(consSepasolLinear)
15360 { /*lint --e{715}*/
15361  SCIP_CONSHDLRDATA* conshdlrdata;
15362  int c;
15363  int depth;
15364  int nrounds;
15365  int maxsepacuts;
15366  int ncuts;
15367  SCIP_Bool cutoff;
15368 
15369  assert(scip != NULL);
15370  assert(conshdlr != NULL);
15371  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15372  assert(result != NULL);
15373 
15374  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15375  assert(conshdlrdata != NULL);
15376  depth = SCIPgetDepth(scip);
15377  nrounds = SCIPgetNSepaRounds(scip);
15378 
15379  /*debugMsg(scip, "Sepa method of linear constraints\n");*/
15380 
15381  *result = SCIP_DIDNOTRUN;
15382 
15383  /* only call the separator a given number of times at each node */
15384  if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
15385  || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
15386  return SCIP_OKAY;
15387 
15388  /* get the maximal number of cuts allowed in a separation round */
15389  maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
15390 
15391  *result = SCIP_DIDNOTFIND;
15392  ncuts = 0;
15393  cutoff = FALSE;
15394 
15395  /* check all useful linear constraints for feasibility */
15396  for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
15397  {
15398  /*debugMsg(scip, "separating linear constraint <%s>\n", SCIPconsGetName(conss[c]));*/
15399  SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, sol, TRUE, conshdlrdata->separateall, &ncuts, &cutoff) );
15400  }
15401 
15402  /* adjust return value */
15403  if( cutoff )
15404  *result = SCIP_CUTOFF;
15405  else if( ncuts > 0 )
15406  *result = SCIP_SEPARATED;
15407 
15408  /* combine linear constraints to get more cuts */
15409  /**@todo further cuts of linear constraints */
15410 
15411  return SCIP_OKAY;
15412 }
15413 
15414 
15415 /** constraint enforcing method of constraint handler for LP solutions */
15416 static
15417 SCIP_DECL_CONSENFOLP(consEnfolpLinear)
15418 { /*lint --e{715}*/
15419  SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, NULL, result) );
15420 
15421  return SCIP_OKAY;
15422 }
15423 
15424 /** constraint enforcing method of constraint handler for relaxation solutions */
15425 static
15426 SCIP_DECL_CONSENFORELAX(consEnforelaxLinear)
15427 { /*lint --e{715}*/
15428  SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, sol, result) );
15429 
15430  return SCIP_OKAY;
15431 }
15432 
15433 /** constraint enforcing method of constraint handler for pseudo solutions */
15434 static
15435 SCIP_DECL_CONSENFOPS(consEnfopsLinear)
15436 { /*lint --e{715}*/
15437  SCIP_CONSHDLRDATA* conshdlrdata;
15438  SCIP_Bool checkrelmaxabs;
15439  SCIP_Bool violated;
15440  int c;
15441 
15442  assert(scip != NULL);
15443  assert(conshdlr != NULL);
15444  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15445  assert(result != NULL);
15446 
15447  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15448  assert(conshdlrdata != NULL);
15449 
15450  checkrelmaxabs = conshdlrdata->checkrelmaxabs;
15451 
15452  SCIPdebugMsg(scip, "Enfops method of linear constraints\n");
15453 
15454  /* if the solution is infeasible anyway due to objective value, skip the enforcement */
15455  if( objinfeasible )
15456  {
15457  SCIPdebugMsg(scip, "-> pseudo solution is objective infeasible, return.\n");
15458 
15459  *result = SCIP_DIDNOTRUN;
15460  return SCIP_OKAY;
15461  }
15462 
15463  /* check all linear constraints for feasibility */
15464  violated = FALSE;
15465  for( c = 0; c < nconss && !violated; ++c )
15466  {
15467  SCIP_CALL( checkCons(scip, conss[c], NULL, TRUE, checkrelmaxabs, &violated) );
15468  }
15469 
15470  if( violated )
15471  *result = SCIP_INFEASIBLE;
15472  else
15473  *result = SCIP_FEASIBLE;
15474 
15475  SCIPdebugMsg(scip, "-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
15476 
15477  return SCIP_OKAY;
15478 }
15479 
15480 
15481 /** feasibility check method of constraint handler for integral solutions */
15482 static
15483 SCIP_DECL_CONSCHECK(consCheckLinear)
15484 { /*lint --e{715}*/
15485  SCIP_CONSHDLRDATA* conshdlrdata;
15486  SCIP_Bool checkrelmaxabs;
15487  int c;
15488 
15489  assert(scip != NULL);
15490  assert(conshdlr != NULL);
15491  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15492  assert(result != NULL);
15493 
15494  *result = SCIP_FEASIBLE;
15495 
15496  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15497  assert(conshdlrdata != NULL);
15498 
15499  checkrelmaxabs = conshdlrdata->checkrelmaxabs;
15501  /*debugMsg(scip, "Check method of linear constraints\n");*/
15502 
15503  /* check all linear constraints for feasibility */
15504  for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
15505  {
15506  SCIP_Bool violated = FALSE;
15507  SCIP_CALL( checkCons(scip, conss[c], sol, checklprows, checkrelmaxabs, &violated) );
15508 
15509  if( violated )
15510  {
15511  *result = SCIP_INFEASIBLE;
15512 
15513  if( printreason )
15514  {
15515  SCIP_CONSDATA* consdata;
15516  SCIP_Real activity;
15517 
15518  consdata = SCIPconsGetData(conss[c]);
15519  assert( consdata != NULL);
15520 
15521  activity = consdataGetActivity(scip, consdata, sol);
15522 
15523  SCIP_CALL( SCIPprintCons(scip, conss[c], NULL ) );
15524  SCIPinfoMessage(scip, NULL, ";\n");
15525 
15526  if( activity == SCIP_INVALID ) /*lint !e777*/
15527  SCIPinfoMessage(scip, NULL, "activity invalid due to positive and negative infinity contributions\n");
15528  else if( SCIPisFeasLT(scip, activity, consdata->lhs) )
15529  SCIPinfoMessage(scip, NULL, "violation: left hand side is violated by %.15g\n", consdata->lhs - activity);
15530  else if( SCIPisFeasGT(scip, activity, consdata->rhs) )
15531  SCIPinfoMessage(scip, NULL, "violation: right hand side is violated by %.15g\n", activity - consdata->rhs);
15532  }
15533  }
15534  }
15535 
15536  return SCIP_OKAY;
15537 }
15538 
15539 
15540 /** domain propagation method of constraint handler */
15541 static
15542 SCIP_DECL_CONSPROP(consPropLinear)
15543 { /*lint --e{715}*/
15544  SCIP_CONSHDLRDATA* conshdlrdata;
15545  SCIP_Bool rangedrowpropagation = FALSE;
15546  SCIP_Bool tightenbounds;
15547  SCIP_Bool cutoff;
15548 
15549  int nchgbds;
15550  int i;
15551 
15552  assert(scip != NULL);
15553  assert(conshdlr != NULL);
15554  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15555  assert(result != NULL);
15556 
15557  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15558  assert(conshdlrdata != NULL);
15560  /*debugMsg(scip, "Prop method of linear constraints\n");*/
15561 
15562  /* check, if we want to tighten variable's bounds (in probing, we always want to tighten the bounds) */
15563  if( SCIPinProbing(scip) )
15564  tightenbounds = TRUE;
15565  else
15566  {
15567  int depth;
15568  int propfreq;
15569  int tightenboundsfreq;
15570  int rangedrowfreq;
15571 
15572  depth = SCIPgetDepth(scip);
15573  propfreq = SCIPconshdlrGetPropFreq(conshdlr);
15574  tightenboundsfreq = propfreq * conshdlrdata->tightenboundsfreq;
15575  tightenbounds = (conshdlrdata->tightenboundsfreq >= 0)
15576  && ((tightenboundsfreq == 0 && depth == 0) || (tightenboundsfreq >= 1 && (depth % tightenboundsfreq == 0)));
15577 
15578  /* check if we want to do ranged row propagation */
15579  rangedrowpropagation = conshdlrdata->rangedrowpropagation;
15580  rangedrowpropagation = rangedrowpropagation && !SCIPinRepropagation(scip);
15581  rangedrowpropagation = rangedrowpropagation && (depth <= conshdlrdata->rangedrowmaxdepth);
15582  rangedrowfreq = propfreq * conshdlrdata->rangedrowfreq;
15583  rangedrowpropagation = rangedrowpropagation && (depth % rangedrowfreq == 0);
15584  }
15585 
15586  cutoff = FALSE;
15587  nchgbds = 0;
15588 
15589  /* process constraints marked for propagation */
15590  for( i = 0; i < nmarkedconss && !cutoff; i++ )
15591  {
15592  SCIP_CALL( SCIPunmarkConsPropagate(scip, conss[i]) );
15593  SCIP_CALL( propagateCons(scip, conss[i], tightenbounds, rangedrowpropagation,
15594  conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars, &cutoff, &nchgbds) );
15595  }
15596 
15597  /* adjust result code */
15598  if( cutoff )
15599  *result = SCIP_CUTOFF;
15600  else if( nchgbds > 0 )
15601  *result = SCIP_REDUCEDDOM;
15602  else
15603  *result = SCIP_DIDNOTFIND;
15604 
15605  return SCIP_OKAY;
15606 }
15607 
15608 
15609 #define MAXCONSPRESOLROUNDS 10
15610 /** presolving method of constraint handler */
15611 static
15612 SCIP_DECL_CONSPRESOL(consPresolLinear)
15613 { /*lint --e{715}*/
15614  SCIP_CONSHDLRDATA* conshdlrdata;
15615  SCIP_CONS* cons;
15616  SCIP_CONSDATA* consdata;
15617  SCIP_Real minactivity;
15618  SCIP_Real maxactivity;
15619  SCIP_Bool minactisrelax;
15620  SCIP_Bool maxactisrelax;
15621  SCIP_Bool cutoff;
15622  int oldnfixedvars;
15623  int oldnaggrvars;
15624  int oldnchgbds;
15625  int oldndelconss;
15626  int oldnupgdconss;
15627  int oldnchgcoefs;
15628  int oldnchgsides;
15629  int firstchange;
15630  int firstupgradetry;
15631  int c;
15632 
15633  assert(scip != NULL);
15634  assert(conshdlr != NULL);
15635  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15636  assert(result != NULL);
15637 
15638  /*debugMsg(scip, "Presol method of linear constraints\n");*/
15639 
15640  /* remember old preprocessing counters */
15641  cutoff = FALSE;
15642  oldnfixedvars = *nfixedvars;
15643  oldnaggrvars = *naggrvars;
15644  oldnchgbds = *nchgbds;
15645  oldndelconss = *ndelconss;
15646  oldnupgdconss = *nupgdconss;
15647  oldnchgcoefs = *nchgcoefs;
15648  oldnchgsides = *nchgsides;
15649 
15650  /* get constraint handler data */
15651  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15652  assert(conshdlrdata != NULL);
15653 
15654  /* process single constraints */
15655  firstchange = INT_MAX;
15656  firstupgradetry = INT_MAX;
15657  for( c = 0; c < nconss && !cutoff && !SCIPisStopped(scip); ++c )
15658  {
15659  int npresolrounds;
15660  SCIP_Bool infeasible;
15661 
15662  infeasible = FALSE;
15663 
15664  cons = conss[c];
15665  assert(SCIPconsIsActive(cons));
15666  consdata = SCIPconsGetData(cons);
15667  assert(consdata != NULL);
15668 
15669  /* constraint should not be already presolved in the initial round */
15670  assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || SCIPconsIsMarkedPropagate(cons));
15671  assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || consdata->boundstightened == 0);
15672  assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || !consdata->presolved);
15673  assert(!SCIPconsIsMarkedPropagate(cons) || !consdata->presolved);
15674 
15675  /* incorporate fixings and aggregations in constraint */
15676  SCIP_CALL( applyFixings(scip, cons, &infeasible) );
15677 
15678  if( infeasible )
15679  {
15680  SCIPdebugMsg(scip, " -> infeasible fixing\n");
15681  cutoff = TRUE;
15682  break;
15683  }
15684 
15685  assert(consdata->removedfixings);
15686 
15687  /* we can only presolve linear constraints, that are not modifiable */
15688  if( SCIPconsIsModifiable(cons) )
15689  continue;
15690 
15691  /* remember the first changed constraint to begin the next aggregation round with */
15692  if( firstchange == INT_MAX && consdata->changed )
15693  firstchange = c;
15694 
15695  /* remember the first constraint that was not yet tried to be upgraded, to begin the next upgrading round with */
15696  if( firstupgradetry == INT_MAX && !consdata->upgradetried )
15697  firstupgradetry = c;
15698 
15699  /* check, if constraint is already preprocessed */
15700  if( consdata->presolved )
15701  continue;
15702 
15703  assert(SCIPconsIsActive(cons));
15704 
15705  SCIPdebugMsg(scip, "presolving linear constraint <%s>\n", SCIPconsGetName(cons));
15706  SCIPdebugPrintCons(scip, cons, NULL);
15707 
15708  /* apply presolving as long as possible on the single constraint (however, abort after a certain number of rounds
15709  * to avoid nearly infinite cycling due to very small bound changes)
15710  */
15711  npresolrounds = 0;
15712  while( !consdata->presolved && npresolrounds < MAXCONSPRESOLROUNDS && !SCIPisStopped(scip) )
15713  {
15714  assert(!cutoff);
15715  npresolrounds++;
15716 
15717  /* mark constraint being presolved and propagated */
15718  consdata->presolved = TRUE;
15719  SCIP_CALL( SCIPunmarkConsPropagate(scip, cons) );
15720 
15721  /* normalize constraint */
15722  SCIP_CALL( normalizeCons(scip, cons) );
15723 
15724  /* tighten left and right hand side due to integrality */
15725  SCIP_CALL( tightenSides(scip, cons, nchgsides) );
15726 
15727  /* check bounds */
15728  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
15729  {
15730  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
15731  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
15732  cutoff = TRUE;
15733  break;
15734  }
15735 
15736  /* tighten variable's bounds */
15737  SCIP_CALL( tightenBounds(scip, cons, conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars, &cutoff, nchgbds) );
15738  if( cutoff )
15739  break;
15740 
15741  /* check for fixed variables */
15742  SCIP_CALL( fixVariables(scip, cons, &cutoff, nfixedvars) );
15743  if( cutoff )
15744  break;
15745 
15746  /* check constraint for infeasibility and redundancy */
15747  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax);
15748  if( SCIPisFeasGT(scip, minactivity, consdata->rhs) || SCIPisFeasLT(scip, maxactivity, consdata->lhs) )
15749  {
15750  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
15751  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
15752  cutoff = TRUE;
15753  break;
15754  }
15755  else if( SCIPisFeasGE(scip, minactivity, consdata->lhs) && SCIPisFeasLE(scip, maxactivity, consdata->rhs) )
15756  {
15757  SCIPdebugMsg(scip, "linear constraint <%s> is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
15758  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
15759  SCIP_CALL( SCIPdelCons(scip, cons) );
15760  assert(!SCIPconsIsActive(cons));
15761 
15762  if( !consdata->upgraded )
15763  (*ndelconss)++;
15764  break;
15765  }
15766  else if( !SCIPisInfinity(scip, -consdata->lhs) && SCIPisFeasGE(scip, minactivity, consdata->lhs) )
15767  {
15768  SCIPdebugMsg(scip, "linear constraint <%s> left hand side is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
15769  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
15770  SCIP_CALL( chgLhs(scip, cons, -SCIPinfinity(scip)) );
15771  if( !consdata->upgraded )
15772  (*nchgsides)++;
15773  }
15774  else if( !SCIPisInfinity(scip, consdata->rhs) && SCIPisFeasLE(scip, maxactivity, consdata->rhs) )
15775  {
15776  SCIPdebugMsg(scip, "linear constraint <%s> right hand side is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
15777  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
15778  SCIP_CALL( chgRhs(scip, cons, SCIPinfinity(scip)) );
15779  if( !consdata->upgraded )
15780  (*nchgsides)++;
15781  }
15782  assert(consdata->nvars >= 1); /* otherwise, it should be redundant or infeasible */
15783 
15784  /* handle empty constraint */
15785  if( consdata->nvars == 0 )
15786  {
15787  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
15788  {
15789  SCIPdebugMsg(scip, "empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
15790  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
15791  cutoff = TRUE;
15792  }
15793  else
15794  {
15795  SCIPdebugMsg(scip, "empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
15796  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
15797  SCIP_CALL( SCIPdelCons(scip, cons) );
15798  assert(!SCIPconsIsActive(cons));
15799 
15800  if( !consdata->upgraded )
15801  (*ndelconss)++;
15802  }
15803  break;
15804  }
15805 
15806  /* reduce big-M coefficients, that make the constraint redundant if the variable is on a bound */
15807  SCIP_CALL( consdataTightenCoefs(scip, cons, nchgcoefs, nchgsides) );
15808 
15809  /* try to simplify inequalities */
15810  if( conshdlrdata->simplifyinequalities )
15811  {
15812  SCIP_CALL( simplifyInequalities(scip, cons, nchgcoefs, nchgsides) );
15813  }
15814 
15815  /* aggregation variable in equations */
15816  if( conshdlrdata->aggregatevariables )
15817  {
15818  SCIP_CALL( aggregateVariables(scip, cons, &cutoff, nfixedvars, naggrvars, ndelconss) );
15819  if( cutoff )
15820  break;
15821  }
15822  }
15823 
15824  if( !cutoff && !SCIPisStopped(scip) )
15825  {
15826  /* perform ranged row propagation */
15827  if( conshdlrdata->rangedrowpropagation )
15828  {
15829  int lastnfixedvars;
15830 
15831  lastnfixedvars = *nfixedvars;
15832 
15833  SCIP_CALL( rangedRowPropagation(scip, cons, &cutoff, nfixedvars, nchgbds, naddconss) );
15834  if( !cutoff )
15835  {
15836  if( lastnfixedvars < *nfixedvars )
15837  {
15838  SCIP_CALL( applyFixings(scip, cons, &cutoff) );
15839  }
15840  }
15841  }
15842 
15843  /* extract cliques from constraint */
15844  if( !cutoff && SCIPconsIsActive(cons) )
15845  {
15846  SCIP_CALL( extractCliques(scip, cons, conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars,
15847  nfixedvars, nchgbds, &cutoff) );
15848 
15849  /* check if the constraint got redundant or infeasible */
15850  if( !cutoff && SCIPconsIsActive(cons) && consdata->nvars == 0 )
15851  {
15852  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
15853  {
15854  SCIPdebugMsg(scip, "empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
15855  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
15856  cutoff = TRUE;
15857  }
15858  else
15859  {
15860  SCIPdebugMsg(scip, "empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
15861  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
15862  SCIP_CALL( SCIPdelCons(scip, cons) );
15863  assert(!SCIPconsIsActive(cons));
15864 
15865  if( !consdata->upgraded )
15866  (*ndelconss)++;
15867  }
15868  }
15869  }
15870 
15871  /* convert special equalities */
15872  if( !cutoff && SCIPconsIsActive(cons) )
15873  {
15874  SCIP_CALL( convertEquality(scip, cons, conshdlrdata, &cutoff, nfixedvars, naggrvars, ndelconss) );
15875  }
15876 
15877  /* apply dual presolving for variables that appear in only one constraint */
15878  if( !cutoff && SCIPconsIsActive(cons) && conshdlrdata->dualpresolving && SCIPallowDualReds(scip) )
15879  {
15880  SCIP_CALL( dualPresolve(scip, cons, &cutoff, nfixedvars, naggrvars, ndelconss) );
15881  }
15882 
15883  /* check if an inequality is parallel to the objective function */
15884  if( !cutoff && SCIPconsIsActive(cons) )
15885  {
15886  SCIP_CALL( checkParallelObjective(scip, cons, conshdlrdata) );
15887  }
15888 
15889  /* remember the first changed constraint to begin the next aggregation round with */
15890  if( firstchange == INT_MAX && consdata->changed )
15891  firstchange = c;
15892 
15893  /* remember the first constraint that was not yet tried to be upgraded, to begin the next upgrading round with */
15894  if( firstupgradetry == INT_MAX && !consdata->upgradetried )
15895  firstupgradetry = c;
15896  }
15897 
15898  /* singleton column stuffing */
15899  if( !cutoff && SCIPconsIsActive(cons) && SCIPconsIsChecked(cons) &&
15900  (conshdlrdata->singletonstuffing || conshdlrdata->singlevarstuffing) && SCIPallowDualReds(scip) )
15901  {
15902  SCIP_CALL( presolStuffing(scip, cons, conshdlrdata->singletonstuffing,
15903  conshdlrdata->singlevarstuffing, &cutoff, nfixedvars, nchgbds) );
15904 
15905  /* handle empty constraint */
15906  if( consdata->nvars == 0 )
15907  {
15908  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
15909  {
15910  SCIPdebugMsg(scip, "empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
15911  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
15912  cutoff = TRUE;
15913  }
15914  else
15915  {
15916  SCIPdebugMsg(scip, "empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
15917  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
15918  SCIP_CALL( SCIPdelCons(scip, cons) );
15919  assert(!SCIPconsIsActive(cons));
15920 
15921  if( !consdata->upgraded )
15922  (*ndelconss)++;
15923  }
15924  break;
15925  }
15926  }
15927  }
15928 
15929  /* process pairs of constraints: check them for redundancy and try to aggregate them;
15930  * only apply this expensive procedure in exhaustive presolving timing
15931  */
15932  if( !cutoff && (presoltiming & SCIP_PRESOLTIMING_EXHAUSTIVE) != 0 && (conshdlrdata->presolusehashing || conshdlrdata->presolpairwise) && !SCIPisStopped(scip) )
15933  {
15934  assert(firstchange >= 0);
15935 
15936  if( firstchange < nconss && conshdlrdata->presolusehashing )
15937  {
15938  /* detect redundant constraints; fast version with hash table instead of pairwise comparison */
15939  SCIP_CALL( detectRedundantConstraints(scip, SCIPblkmem(scip), conss, nconss, &firstchange, &cutoff,
15940  ndelconss, nchgsides) );
15941  }
15942 
15943  if( firstchange < nconss && conshdlrdata->presolpairwise )
15944  {
15945  SCIP_CONS** usefulconss;
15946  int nusefulconss;
15947  int firstchangenew;
15948  SCIP_Longint npaircomparisons;
15949 
15950  npaircomparisons = 0;
15951  oldndelconss = *ndelconss;
15952  oldnchgsides = *nchgsides;
15953  oldnchgcoefs = *nchgcoefs;
15954 
15955  /* allocate temporary memory */
15956  SCIP_CALL( SCIPallocBufferArray(scip, &usefulconss, nconss) );
15957 
15958  nusefulconss = 0;
15959  firstchangenew = -1;
15960  for( c = 0; c < nconss; ++c )
15961  {
15962  /* update firstchange */
15963  if( c == firstchange )
15964  firstchangenew = nusefulconss;
15965 
15966  /* ignore inactive and modifiable constraints */
15967  if( !SCIPconsIsActive(conss[c]) || SCIPconsIsModifiable(conss[c]) )
15968  continue;
15969 
15970  usefulconss[nusefulconss] = conss[c];
15971  ++nusefulconss;
15972  }
15973  firstchange = firstchangenew;
15974  assert(firstchangenew >= 0 && firstchangenew <= nusefulconss);
15975 
15976  for( c = firstchange; c < nusefulconss && !cutoff && !SCIPisStopped(scip); ++c )
15977  {
15978  /* constraint has become inactive or modifiable during pairwise presolving */
15979  if( usefulconss[c] == NULL )
15980  continue;
15981 
15982  npaircomparisons += (SCIPconsGetData(conss[c])->changed) ? c : (c - firstchange); /*lint !e776*/
15983 
15984  assert(SCIPconsIsActive(usefulconss[c]) && !SCIPconsIsModifiable(usefulconss[c]));
15985  SCIP_CALL( preprocessConstraintPairs(scip, usefulconss, firstchange, c, conshdlrdata->maxaggrnormscale,
15986  &cutoff, ndelconss, nchgsides, nchgcoefs) );
15987 
15988  if( npaircomparisons > conshdlrdata->nmincomparisons )
15989  {
15990  assert(npaircomparisons > 0);
15991  if( ((*ndelconss - oldndelconss) + (*nchgsides - oldnchgsides)/2.0 + (*nchgcoefs - oldnchgcoefs)/10.0) / ((SCIP_Real) npaircomparisons) < conshdlrdata->mingainpernmincomp )
15992  break;
15993  oldndelconss = *ndelconss;
15994  oldnchgsides = *nchgsides;
15995  oldnchgcoefs = *nchgcoefs;
15996  npaircomparisons = 0;
15997  }
15998  }
15999  /* free temporary memory */
16000  SCIPfreeBufferArray(scip, &usefulconss);
16001  }
16002  }
16003 
16004  /* before upgrading, check whether we can apply some additional dual presolving, because a variable only appears
16005  * in linear constraints and we therefore have full information about it
16006  */
16007  if( !cutoff && firstupgradetry < nconss
16008  && *nfixedvars == oldnfixedvars && *naggrvars == oldnaggrvars && *nchgbds == oldnchgbds && *ndelconss == oldndelconss
16009  && *nupgdconss == oldnupgdconss && *nchgcoefs == oldnchgcoefs && *nchgsides == oldnchgsides
16010  )
16011  {
16012  if( conshdlrdata->dualpresolving && SCIPallowDualReds(scip) && !SCIPisStopped(scip) )
16013  {
16014  SCIP_CALL( fullDualPresolve(scip, conss, nconss, &cutoff, nchgbds) );
16015  }
16016  }
16017 
16018  /* try to upgrade constraints into a more specific constraint type;
16019  * only upgrade constraints, if no reductions were found in this round (otherwise, the linear constraint handler
16020  * may find additional reductions before giving control away to other (less intelligent?) constraint handlers)
16021  */
16022  if( !cutoff && (presoltiming & SCIP_PRESOLTIMING_EXHAUSTIVE) != 0 && SCIPisPresolveFinished(scip) )
16023  {
16024  for( c = firstupgradetry; c < nconss && !SCIPisStopped(scip); ++c )
16025  {
16026  cons = conss[c];
16027 
16028  /* don't upgrade modifiable constraints */
16029  if( SCIPconsIsModifiable(cons) )
16030  continue;
16031 
16032  consdata = SCIPconsGetData(cons);
16033  assert(consdata != NULL);
16034 
16035  /* only upgrade completely presolved constraints, that changed since the last upgrading call */
16036  if( consdata->upgradetried )
16037  continue;
16038  /* @todo force that upgrade will be performed later? */
16039  if( !consdata->presolved )
16040  continue;
16041 
16042  consdata->upgradetried = TRUE;
16043  if( SCIPconsIsActive(cons) )
16044  {
16045  SCIP_CONS* upgdcons;
16046 
16047  SCIP_CALL( SCIPupgradeConsLinear(scip, cons, &upgdcons) );
16048  if( upgdcons != NULL )
16049  {
16050  /* add the upgraded constraint to the problem */
16051  SCIP_CALL( SCIPaddCons(scip, upgdcons) );
16052  SCIP_CALL( SCIPreleaseCons(scip, &upgdcons) );
16053  (*nupgdconss)++;
16054 
16055  /* mark the linear constraint being upgraded and to be removed after presolving;
16056  * don't delete it directly, because it may help to preprocess other linear constraints
16057  */
16058  assert(!consdata->upgraded);
16059  consdata->upgraded = TRUE;
16060 
16061  /* delete upgraded inequalities immediately;
16062  * delete upgraded equalities, if we don't need it anymore for aggregation and redundancy checking
16063  */
16064  if( SCIPisLT(scip, consdata->lhs, consdata->rhs)
16065  || !conshdlrdata->presolpairwise
16066  || (conshdlrdata->maxaggrnormscale == 0.0) )
16067  {
16068  SCIP_CALL( SCIPdelCons(scip, cons) );
16069  }
16070  }
16071  }
16072  }
16073  }
16074 
16075  /* return the correct result code */
16076  if( cutoff )
16077  *result = SCIP_CUTOFF;
16078  else if( *nfixedvars > oldnfixedvars || *naggrvars > oldnaggrvars || *nchgbds > oldnchgbds || *ndelconss > oldndelconss
16079  || *nupgdconss > oldnupgdconss || *nchgcoefs > oldnchgcoefs || *nchgsides > oldnchgsides )
16080  *result = SCIP_SUCCESS;
16081  else
16082  *result = SCIP_DIDNOTFIND;
16083 
16084  return SCIP_OKAY;
16085 }
16086 
16087 
16088 /** propagation conflict resolving method of constraint handler */
16089 static
16090 SCIP_DECL_CONSRESPROP(consRespropLinear)
16091 { /*lint --e{715}*/
16092 
16093  assert(scip != NULL);
16094  assert(cons != NULL);
16095  assert(result != NULL);
16096 
16097  SCIP_CALL( resolvePropagation(scip, cons, infervar, intToInferInfo(inferinfo), boundtype, bdchgidx, result) );
16098 
16099  return SCIP_OKAY;
16100 }
16101 
16102 
16103 /** variable rounding lock method of constraint handler */
16104 static
16105 SCIP_DECL_CONSLOCK(consLockLinear)
16106 { /*lint --e{715}*/
16107  SCIP_CONSDATA* consdata;
16108  SCIP_Bool haslhs;
16109  SCIP_Bool hasrhs;
16110  int i;
16111 
16112  assert(scip != NULL);
16113  assert(cons != NULL);
16114  consdata = SCIPconsGetData(cons);
16115  assert(consdata != NULL);
16116 
16117  haslhs = !SCIPisInfinity(scip, -consdata->lhs);
16118  hasrhs = !SCIPisInfinity(scip, consdata->rhs);
16119 
16120  /* update rounding locks of every single variable */
16121  for( i = 0; i < consdata->nvars; ++i )
16122  {
16123  if( SCIPisPositive(scip, consdata->vals[i]) )
16124  {
16125  if( haslhs )
16126  {
16127  SCIP_CALL( SCIPaddVarLocks(scip, consdata->vars[i], nlockspos, nlocksneg) );
16128  }
16129  if( hasrhs )
16130  {
16131  SCIP_CALL( SCIPaddVarLocks(scip, consdata->vars[i], nlocksneg, nlockspos) );
16132  }
16133  }
16134  else
16135  {
16136  if( haslhs )
16137  {
16138  SCIP_CALL( SCIPaddVarLocks(scip, consdata->vars[i], nlocksneg, nlockspos) );
16139  }
16140  if( hasrhs )
16141  {
16142  SCIP_CALL( SCIPaddVarLocks(scip, consdata->vars[i], nlockspos, nlocksneg) );
16143  }
16144  }
16145  }
16146 
16147  return SCIP_OKAY;
16148 }
16149 
16150 
16151 /** variable deletion method of constraint handler */
16152 static
16153 SCIP_DECL_CONSDELVARS(consDelvarsLinear)
16154 {
16155  assert(scip != NULL);
16156  assert(conshdlr != NULL);
16157  assert(conss != NULL || nconss == 0);
16158 
16159  if( nconss > 0 )
16160  {
16161  SCIP_CALL( performVarDeletions(scip, conshdlr, conss, nconss) );
16162  }
16163 
16164  return SCIP_OKAY;
16165 }
16166 
16167 /** constraint display method of constraint handler */
16168 static
16169 SCIP_DECL_CONSPRINT(consPrintLinear)
16170 { /*lint --e{715}*/
16171  assert(scip != NULL);
16172  assert(conshdlr != NULL);
16173  assert(cons != NULL);
16174 
16175  SCIP_CALL( consdataPrint(scip, SCIPconsGetData(cons), file) );
16176 
16177  return SCIP_OKAY;
16178 }
16179 
16180 /** constraint copying method of constraint handler */
16181 static
16182 SCIP_DECL_CONSCOPY(consCopyLinear)
16183 { /*lint --e{715}*/
16184  SCIP_VAR** sourcevars;
16185  SCIP_Real* sourcecoefs;
16186  const char* consname;
16187  int nvars;
16188 
16189  assert(scip != NULL);
16190  assert(sourcescip != NULL);
16191  assert(sourcecons != NULL);
16192 
16193  /* get variables and coefficients of the source constraint */
16194  sourcevars = SCIPgetVarsLinear(sourcescip, sourcecons);
16195  sourcecoefs = SCIPgetValsLinear(sourcescip, sourcecons);
16196  nvars = SCIPgetNVarsLinear(sourcescip, sourcecons);
16197 
16198  if( name != NULL )
16199  consname = name;
16200  else
16201  consname = SCIPconsGetName(sourcecons);
16202 
16203  SCIP_CALL( SCIPcopyConsLinear(scip, cons, sourcescip, consname, nvars, sourcevars, sourcecoefs,
16204  SCIPgetLhsLinear(sourcescip, sourcecons), SCIPgetRhsLinear(sourcescip, sourcecons), varmap, consmap,
16205  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, global, valid) );
16206  assert(cons != NULL || *valid == FALSE);
16207 
16208  return SCIP_OKAY;
16209 }
16210 
16211 /* find operators '<=', '==', '>=', [free] in input string and return those places. There should only be one operator,
16212  * except for ranged rows for which exactly two operators '<=' must be present
16213  */
16214 static
16216  const char* str, /**< null terminated input string */
16217  char** firstoperator, /**< pointer to store the string starting at the first operator */
16218  char** secondoperator, /**< pointer to store the string starting at the second operator */
16219  SCIP_Bool* success /**< pointer to store if the line contains a valid operator order */
16220  )
16221 {
16222  char* curr;
16223 
16224  assert(str != NULL);
16225  assert(firstoperator != NULL);
16226  assert(secondoperator != NULL);
16227 
16228  *firstoperator = NULL;
16229  *secondoperator = NULL;
16230 
16231  curr = (char*)str;
16232  *success = TRUE;
16233 
16234  /* loop over the input string to find all operators */
16235  while( *curr && *success )
16236  {
16237  SCIP_Bool found = FALSE;
16238  int increment = 1;
16239 
16240  /* try if we found a possible operator */
16241  switch( *curr )
16242  {
16243  case '<':
16244  case '=':
16245  case '>':
16246 
16247  /* check if the two characters curr[0,1] form an operator together */
16248  if( curr[1] == '=' )
16249  {
16250  found = TRUE;
16251 
16252  /* update increment to continue after this operator */
16253  increment = 2;
16254  }
16255  break;
16256  case '[':
16257  if( strncmp(curr, "[free]", 6) == 0 )
16258  {
16259  found = TRUE;
16260 
16261  /* update increment to continue after this operator */
16262  increment = 6;
16263  }
16264  break;
16265  default:
16266  break;
16267 
16268  }
16269 
16270  /* assign the found operator to the first or second pointer and check for violations of the linear constraint grammar */
16271  if( found )
16272  {
16273  if( *firstoperator == NULL )
16274  {
16275  *firstoperator = curr;
16276  }
16277  else
16278  {
16279  if( *secondoperator != NULL )
16280  {
16281  SCIPerrorMessage("Found more than two operators in line %s\n", str);
16282  *success = FALSE;
16283  }
16284  else if( strncmp(*firstoperator, "<=", 2) != 0 )
16285  {
16286  SCIPerrorMessage("Two operators in line that is not a ranged row: %s", str);
16287  *success = FALSE;
16288  }
16289  else if( strncmp(curr, "<=", 2) != 0 )
16290  {
16291  SCIPerrorMessage("Bad second operator, expected ranged row specification: %s", str);
16292  *success = FALSE;
16293  }
16294 
16295  *secondoperator = curr;
16296  }
16297  }
16298 
16299  curr += increment;
16300  }
16301 
16302  /* check if we did find at least one operator */
16303  if( *success )
16304  {
16305  if( *firstoperator == NULL )
16306  {
16307  SCIPerrorMessage("Could not find any operator in line %s\n", str);
16308  *success = FALSE;
16309  }
16310  }
16311 
16312  return SCIP_OKAY;
16313 }
16314 
16315 /** constraint parsing method of constraint handler */
16316 static
16317 SCIP_DECL_CONSPARSE(consParseLinear)
16318 { /*lint --e{715}*/
16319  SCIP_VAR** vars;
16320  SCIP_Real* coefs;
16321  int nvars;
16322  int coefssize;
16323  int requsize;
16324  SCIP_Real lhs;
16325  SCIP_Real rhs;
16326  char* endptr;
16327  char* firstop;
16328  char* secondop;
16329  SCIP_Bool operatorsuccess;
16330  char* lhsstrptr;
16331  char* rhsstrptr;
16332  char* varstrptr;
16333 
16334  assert(scip != NULL);
16335  assert(success != NULL);
16336  assert(str != NULL);
16337  assert(name != NULL);
16338  assert(cons != NULL);
16339 
16340  /* set left and right hand side to their default values */
16341  lhs = -SCIPinfinity(scip);
16342  rhs = SCIPinfinity(scip);
16343 
16344  (*success) = FALSE;
16345 
16346  /* return of string empty */
16347  if( !*str )
16348  return SCIP_OKAY;
16349 
16350  /* ignore whitespace */
16351  while( isspace((unsigned char)*str) )
16352  ++str;
16353 
16354  /* find operators in the line first, all other remaining parsing depends on occurence of the operators '<=', '>=', '==',
16355  * and the special word [free]
16356  */
16357  SCIP_CALL( findOperators(str, &firstop, &secondop, &operatorsuccess) );
16358 
16359  /* if the grammar is not valid for parsing a linear constraint, return */
16360  if( ! operatorsuccess )
16361  return SCIP_OKAY;
16362 
16363  varstrptr = (char *)str;
16364  lhsstrptr = rhsstrptr = NULL;
16365  assert(firstop != NULL);
16366 
16367  /* assign the strings for parsing the left hand side, right hand side, and the linear variable sum */
16368  switch( *firstop )
16369  {
16370  case '<':
16371  assert(firstop[1] == '=');
16372  /* we have ranged row lhs <= a_1 x_1 + ... + a_n x_n <= rhs */
16373  if( secondop != NULL )
16374  {
16375  assert(secondop[0] == '<' && secondop[1] == '=');
16376  lhsstrptr = (char *)str;
16377  varstrptr = firstop + 2;
16378  rhsstrptr = secondop + 2;
16379  }
16380  else
16381  {
16382  /* we have an inequality with infinite left hand side a_1 x_1 + ... + a_n x_n <= rhs */
16383  lhsstrptr = NULL;
16384  varstrptr = (char *)str;
16385  rhsstrptr = firstop + 2;
16386  }
16387  break;
16388  case '>':
16389  assert(firstop[1] == '=');
16390  assert(secondop == NULL);
16391  /* we have a_1 x_1 + ... + a_n x_n >= lhs */
16392  lhsstrptr = firstop + 2;
16393  break;
16394  case '=':
16395  assert(firstop[1] == '=');
16396  assert(secondop == NULL);
16397  /* we have a_1 x_1 + ... + a_n x_n == lhs (rhs) */
16398  rhsstrptr = firstop + 2;
16399  lhsstrptr = firstop + 2;
16400  break;
16401  case '[':
16402  assert(strncmp(firstop, "[free]", 6) == 0);
16403  assert(secondop == NULL);
16404  /* nothing to assign in case of a free a_1 x_1 + ... + a_n x_n [free] */
16405  break;
16406  default:
16407  /* it should not be possible that a different character appears in that position */
16408  SCIPerrorMessage("Parsing has wrong operator character '%c', should be one of <=>[", *firstop);
16409  return SCIP_READERROR;
16410  }
16411 
16412  /* parse left hand side, if necessary */
16413  if( lhsstrptr != NULL )
16414  {
16415  if( ! SCIPparseReal(scip, lhsstrptr, &lhs, &endptr) )
16416  {
16417  SCIPerrorMessage("error parsing left hand side number from <%s>\n", lhsstrptr);
16418  return SCIP_OKAY;
16419  }
16420 
16421  /* in case of an equation, assign the left also to the right hand side */
16422  if( rhsstrptr == lhsstrptr )
16423  rhs = lhs;
16424  }
16425 
16426  /* parse right hand side, if different from left hand side */
16427  if( rhsstrptr != NULL && rhsstrptr != lhsstrptr )
16428  {
16429  if( ! SCIPparseReal(scip, rhsstrptr, &rhs, &endptr) )
16430  {
16431  SCIPerrorMessage("error parsing right hand side number from <%s>\n", lhsstrptr);
16432  return SCIP_OKAY;
16433  }
16434  }
16435 
16436  /* initialize buffers for storing the variables and coefficients */
16437  coefssize = 100;
16438  SCIP_CALL( SCIPallocBufferArray(scip, &vars, coefssize) );
16439  SCIP_CALL( SCIPallocBufferArray(scip, &coefs, coefssize) );
16440 
16441  assert(varstrptr != NULL);
16442 
16443  /* parse linear sum to get variables and coefficients */
16444  SCIP_CALL( SCIPparseVarsLinearsum(scip, varstrptr, vars, coefs, &nvars, coefssize, &requsize, &endptr, success) );
16445 
16446  if( *success && requsize > coefssize )
16447  {
16448  /* realloc buffers and try again */
16449  coefssize = requsize;
16450  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, coefssize) );
16451  SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, coefssize) );
16452 
16453  SCIP_CALL( SCIPparseVarsLinearsum(scip, varstrptr, vars, coefs, &nvars, coefssize, &requsize, &endptr, success) );
16454  assert(!*success || requsize <= coefssize); /* if successful, then should have had enough space now */
16455  }
16456 
16457  if( !*success )
16458  {
16459  SCIPerrorMessage("no luck in parsing linear sum '%s'\n", varstrptr);
16460  }
16461  else
16462  {
16463  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
16464  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
16465  }
16466 
16467  SCIPfreeBufferArray(scip, &coefs);
16468  SCIPfreeBufferArray(scip, &vars);
16469 
16470  return SCIP_OKAY;
16471 }
16472 
16473 
16474 /** constraint method of constraint handler which returns the variables (if possible) */
16475 static
16476 SCIP_DECL_CONSGETVARS(consGetVarsLinear)
16477 { /*lint --e{715}*/
16478  SCIP_CONSDATA* consdata;
16479 
16480  consdata = SCIPconsGetData(cons);
16481  assert(consdata != NULL);
16482 
16483  if( varssize < consdata->nvars )
16484  (*success) = FALSE;
16485  else
16486  {
16487  assert(vars != NULL);
16488 
16489  BMScopyMemoryArray(vars, consdata->vars, consdata->nvars);
16490  (*success) = TRUE;
16491  }
16492 
16493  return SCIP_OKAY;
16494 }
16495 
16496 /**! [Callback for the number of variables]*/
16497 /** constraint method of constraint handler which returns the number of variables (if possible) */
16498 static
16499 SCIP_DECL_CONSGETNVARS(consGetNVarsLinear)
16500 { /*lint --e{715}*/
16501  SCIP_CONSDATA* consdata;
16502 
16503  consdata = SCIPconsGetData(cons);
16504  assert(consdata != NULL);
16505 
16506  (*nvars) = consdata->nvars;
16507  (*success) = TRUE;
16508 
16509  return SCIP_OKAY;
16510 }
16511 /**! [Callback for the number of variables]*/
16512 
16513 /*
16514  * Callback methods of event handler
16515  */
16517 static
16518 SCIP_DECL_EVENTEXEC(eventExecLinear)
16519 { /*lint --e{715}*/
16520  SCIP_CONS* cons;
16521  SCIP_CONSDATA* consdata;
16522  SCIP_VAR* var;
16523  SCIP_EVENTTYPE eventtype;
16524 
16525  assert(scip != NULL);
16526  assert(eventhdlr != NULL);
16527  assert(eventdata != NULL);
16528  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
16529  assert(event != NULL);
16530 
16531  cons = eventdata->cons;
16532  assert(cons != NULL);
16533  consdata = SCIPconsGetData(cons);
16534  assert(consdata != NULL);
16536  /* we can skip events droped for deleted constraints */
16537  if( SCIPconsIsDeleted(cons) )
16538  return SCIP_OKAY;
16539 
16540  eventtype = SCIPeventGetType(event);
16541  var = SCIPeventGetVar(event);
16542 
16543  if( (eventtype & SCIP_EVENTTYPE_BOUNDCHANGED) != 0 )
16544  {
16545  SCIP_Real oldbound;
16546  SCIP_Real newbound;
16547  SCIP_Real val;
16548  int varpos;
16549 
16550  varpos = eventdata->varpos;
16551  assert(0 <= varpos && varpos < consdata->nvars);
16552  oldbound = SCIPeventGetOldbound(event);
16553  newbound = SCIPeventGetNewbound(event);
16554  assert(var != NULL);
16555  assert(consdata->vars[varpos] == var);
16556  val = consdata->vals[varpos];
16557 
16558  /* we only need to update the activities if the constraint is active,
16559  * otherwise we mark them to be invalid
16560  */
16561  if( SCIPconsIsActive(cons) )
16562  {
16563  /* update the activity values */
16564  if( (eventtype & SCIP_EVENTTYPE_LBCHANGED) != 0 )
16565  consdataUpdateActivitiesLb(scip, consdata, var, oldbound, newbound, val, TRUE);
16566  else
16567  {
16568  assert((eventtype & SCIP_EVENTTYPE_UBCHANGED) != 0);
16569  consdataUpdateActivitiesUb(scip, consdata, var, oldbound, newbound, val, TRUE);
16570  }
16571  }
16572  else
16573  consdataInvalidateActivities(consdata);
16574 
16575  consdata->presolved = FALSE;
16576  consdata->rangedrowpropagated = 0;
16577 
16578  /* bound change can turn the constraint infeasible or redundant only if it was a tightening */
16579  if( (eventtype & SCIP_EVENTTYPE_BOUNDTIGHTENED) != 0 )
16580  {
16581  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
16582 
16583  /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
16584  if( consdata->maxactdeltavar == var )
16585  {
16586  consdata->maxactdelta = SCIP_INVALID;
16587  consdata->maxactdeltavar = NULL;
16588  }
16589 
16590  /* check whether bound tightening might now be successful */
16591  if( consdata->boundstightened > 0)
16592  {
16593  switch( eventtype )
16594  {
16596  if( (val > 0.0 ? !SCIPisInfinity(scip, consdata->rhs) : !SCIPisInfinity(scip, -consdata->lhs)) )
16597  consdata->boundstightened = 0;
16598  break;
16600  if( (val > 0.0 ? !SCIPisInfinity(scip, -consdata->lhs) : !SCIPisInfinity(scip, consdata->rhs)) )
16601  consdata->boundstightened = 0;
16602  break;
16603  default:
16604  SCIPerrorMessage("invalid event type %d\n", eventtype);
16605  return SCIP_INVALIDDATA;
16606  }
16607  }
16608  }
16609  /* update maximal activity delta if a bound was relaxed */
16610  else if( !SCIPisInfinity(scip, consdata->maxactdelta) )
16611  {
16612  SCIP_Real lb;
16613  SCIP_Real ub;
16614  SCIP_Real domain;
16615  SCIP_Real delta;
16616 
16617  assert((eventtype & SCIP_EVENTTYPE_BOUNDRELAXED) != 0);
16618 
16619  lb = SCIPvarGetLbLocal(var);
16620  ub = SCIPvarGetUbLocal(var);
16621 
16622  domain = ub - lb;
16623  delta = REALABS(val) * domain;
16624 
16625  if( delta > consdata->maxactdelta )
16626  {
16627  consdata->maxactdelta = delta;
16628  consdata->maxactdeltavar = var;
16629  }
16630  }
16631  }
16632  else if( (eventtype & SCIP_EVENTTYPE_VARFIXED) != 0 )
16633  {
16634  /* we want to remove the fixed variable */
16635  consdata->presolved = FALSE;
16636  consdata->removedfixings = FALSE;
16637  consdata->rangedrowpropagated = 0;
16638 
16639  /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
16640  if( consdata->maxactdeltavar == var )
16641  {
16642  consdata->maxactdelta = SCIP_INVALID;
16643  consdata->maxactdeltavar = NULL;
16644  }
16645  }
16646 
16647  else if( (eventtype & SCIP_EVENTTYPE_VARUNLOCKED) != 0 )
16648  {
16649  /* there is only one lock left: we may multi-aggregate the variable as slack of an equation */
16650  assert(SCIPvarGetNLocksDown(var) <= 1);
16651  assert(SCIPvarGetNLocksUp(var) <= 1);
16652  consdata->presolved = FALSE;
16653  }
16654  else if( (eventtype & SCIP_EVENTTYPE_GBDCHANGED) != 0 )
16655  {
16656  SCIP_Real oldbound;
16657  SCIP_Real newbound;
16658  SCIP_Real val;
16659  int varpos;
16660 
16661  varpos = eventdata->varpos;
16662  assert(0 <= varpos && varpos < consdata->nvars);
16663  oldbound = SCIPeventGetOldbound(event);
16664  newbound = SCIPeventGetNewbound(event);
16665  assert(var != NULL);
16666  assert(consdata->vars[varpos] == var);
16667  val = consdata->vals[varpos];
16668 
16669  consdata->rangedrowpropagated = 0;
16670 
16671  /* update the activity values */
16672  if( (eventtype & SCIP_EVENTTYPE_GLBCHANGED) != 0 )
16673  consdataUpdateActivitiesGlbLb(scip, consdata, oldbound, newbound, val, TRUE);
16674  else
16675  {
16676  assert((eventtype & SCIP_EVENTTYPE_GUBCHANGED) != 0);
16677  consdataUpdateActivitiesGlbUb(scip, consdata, oldbound, newbound, val, TRUE);
16678  }
16679  }
16680  else
16681  {
16682  assert((eventtype & SCIP_EVENTTYPE_VARDELETED) != 0);
16683  consdata->varsdeleted = TRUE;
16684  }
16685 
16686  return SCIP_OKAY;
16687 }
16688 
16689 
16690 /*
16691  * Callback methods of conflict handler
16692  */
16693 
16694 static
16695 SCIP_DECL_CONFLICTEXEC(conflictExecLinear)
16696 { /*lint --e{715}*/
16697  SCIP_VAR** vars;
16698  SCIP_Real* vals;
16699  SCIP_Real lhs;
16700  int i;
16701 
16702  assert(scip != NULL);
16703  assert(conflicthdlr != NULL);
16704  assert(strcmp(SCIPconflicthdlrGetName(conflicthdlr), CONFLICTHDLR_NAME) == 0);
16705  assert(bdchginfos != NULL || nbdchginfos == 0);
16706  assert(result != NULL);
16707 
16708  /* don't process already resolved conflicts */
16709  if( resolved )
16710  {
16711  *result = SCIP_DIDNOTRUN;
16712  return SCIP_OKAY;
16713  }
16714 
16715  *result = SCIP_DIDNOTFIND;
16716 
16717  /* create array of variables and coefficients: sum_{i \in P} x_i - sum_{i \in N} x_i >= 1 - |N| */
16718  SCIP_CALL( SCIPallocBufferArray(scip, &vars, nbdchginfos) );
16719  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nbdchginfos) );
16720  lhs = 1.0;
16721  for( i = 0; i < nbdchginfos; ++i )
16722  {
16723  assert(bdchginfos != NULL);
16724 
16725  vars[i] = SCIPbdchginfoGetVar(bdchginfos[i]);
16726 
16727  /* we can only treat binary variables */
16728  /**@todo extend linear conflict constraints to some non-binary cases */
16729  if( !SCIPvarIsBinary(vars[i]) )
16730  break;
16731 
16732  /* check whether the variable is fixed to zero (P) or one (N) in the conflict set */
16733  if( SCIPbdchginfoGetNewbound(bdchginfos[i]) < 0.5 )
16734  vals[i] = 1.0;
16735  else
16736  {
16737  vals[i] = -1.0;
16738  lhs -= 1.0;
16739  }
16740  }
16741 
16742  if( i == nbdchginfos )
16743  {
16744  SCIP_CONS* cons;
16745  SCIP_CONS* upgdcons;
16746  char consname[SCIP_MAXSTRLEN];
16747 
16748  /* create a constraint out of the conflict set */
16749  (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "cf%" SCIP_LONGINT_FORMAT, SCIPgetNConflictConssApplied(scip));
16750  SCIP_CALL( SCIPcreateConsLinear(scip, &cons, consname, nbdchginfos, vars, vals, lhs, SCIPinfinity(scip),
16751  FALSE, separate, FALSE, FALSE, TRUE, local, FALSE, dynamic, removable, FALSE) );
16752 
16753  /* try to automatically convert a linear constraint into a more specific and more specialized constraint */
16754  SCIP_CALL( SCIPupgradeConsLinear(scip, cons, &upgdcons) );
16755  if( upgdcons != NULL )
16756  {
16757  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
16758  cons = upgdcons;
16759  }
16760 
16761  /* add conflict to SCIP */
16762  SCIP_CALL( SCIPaddConflict(scip, node, cons, validnode, conftype, cutoffinvolved) );
16763 
16764  *result = SCIP_CONSADDED;
16765  }
16766 
16767  /* free temporary memory */
16768  SCIPfreeBufferArray(scip, &vals);
16769  SCIPfreeBufferArray(scip, &vars);
16770 
16771  return SCIP_OKAY;
16772 }
16773 
16774 
16775 /*
16776  * Quadratic constraint upgrading
16777  */
16778 
16779 
16780 /** upgrades quadratic constraints with only and at least one linear variables into a linear constraint
16781  */
16782 static
16783 SCIP_DECL_QUADCONSUPGD(upgradeConsQuadratic)
16784 { /*lint --e{715}*/
16785  assert(scip != NULL);
16786  assert(cons != NULL);
16787  assert(nupgdconss != NULL);
16788  assert(upgdconss != NULL);
16789 
16790  *nupgdconss = 0;
16791 
16792  SCIPdebugMsg(scip, "upgradeConsQuadratic called for constraint <%s>\n", SCIPconsGetName(cons));
16793  SCIPdebugPrintCons(scip, cons, NULL);
16794 
16795  if( SCIPgetNQuadVarTermsQuadratic(scip, cons) > 0 )
16796  return SCIP_OKAY;
16797  if( SCIPgetNLinearVarsQuadratic(scip, cons) == 0 )
16798  return SCIP_OKAY;
16799 
16800  if( upgdconsssize < 1 )
16801  {
16802  /* signal that we need more memory */
16803  *nupgdconss = -1;
16804  return SCIP_OKAY;
16805  }
16806 
16807  *nupgdconss = 1;
16808  SCIP_CALL( SCIPcreateConsLinear(scip, &upgdconss[0], SCIPconsGetName(cons),
16809  SCIPgetNLinearVarsQuadratic(scip, cons),
16810  SCIPgetLinearVarsQuadratic(scip, cons),
16811  SCIPgetCoefsLinearVarsQuadratic(scip, cons),
16812  SCIPgetLhsQuadratic(scip, cons), SCIPgetRhsQuadratic(scip, cons),
16816  SCIPconsIsStickingAtNode(cons)) );
16817  SCIPdebugMsg(scip, "created linear constraint:\n");
16818  SCIPdebugPrintCons(scip, upgdconss[0], NULL);
16819 
16820  return SCIP_OKAY;
16821 }
16822 
16823 /** tries to upgrade a nonlinear constraint into a linear constraint */
16824 static
16825 SCIP_DECL_NONLINCONSUPGD(upgradeConsNonlinear)
16826 {
16827  assert(nupgdconss != NULL);
16828  assert(upgdconss != NULL);
16829 
16830  *nupgdconss = 0;
16831 
16832  /* no interest in nonlinear constraints */
16833  if( SCIPgetExprgraphNodeNonlinear(scip, cons) != NULL )
16834  return SCIP_OKAY;
16835 
16836  /* no interest in constant constraints */
16837  if( SCIPgetNLinearVarsNonlinear(scip, cons) == 0 )
16838  return SCIP_OKAY;
16839 
16840  if( upgdconsssize < 1 )
16841  {
16842  /* request larger upgdconss array */
16843  *nupgdconss = -1;
16844  return SCIP_OKAY;
16845  }
16846 
16847  *nupgdconss = 1;
16848  SCIP_CALL( SCIPcreateConsLinear(scip, &upgdconss[0], SCIPconsGetName(cons),
16850  SCIPgetLhsNonlinear(scip, cons), SCIPgetRhsNonlinear(scip, cons),
16854  SCIPconsIsStickingAtNode(cons)) );
16855 
16856  return SCIP_OKAY;
16857 }
16858 
16859 /*
16860  * constraint specific interface methods
16861  */
16862 
16863 /** creates the handler for linear constraints and includes it in SCIP */
16865  SCIP* scip /**< SCIP data structure */
16866  )
16867 {
16868  SCIP_CONSHDLRDATA* conshdlrdata;
16869  SCIP_CONSHDLR* conshdlr;
16870  SCIP_EVENTHDLR* eventhdlr;
16871  SCIP_CONFLICTHDLR* conflicthdlr;
16872 
16873  assert(scip != NULL);
16874 
16875  /* create event handler for bound change events */
16877  eventExecLinear, NULL) );
16878 
16879  /* create conflict handler for linear constraints */
16881  conflictExecLinear, NULL) );
16882 
16883  /* create constraint handler data */
16884  SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
16885 
16886  /* include constraint handler */
16889  consEnfolpLinear, consEnfopsLinear, consCheckLinear, consLockLinear,
16890  conshdlrdata) );
16891 
16892  assert(conshdlr != NULL);
16893 
16894  /* set non-fundamental callbacks via specific setter functions */
16895  SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyLinear, consCopyLinear) );
16896  SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteLinear) );
16897  SCIP_CALL( SCIPsetConshdlrDelvars(scip, conshdlr, consDelvarsLinear) );
16898  SCIP_CALL( SCIPsetConshdlrExit(scip, conshdlr, consExitLinear) );
16899  SCIP_CALL( SCIPsetConshdlrExitpre(scip, conshdlr, consExitpreLinear) );
16900  SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolLinear) );
16901  SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeLinear) );
16902  SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsLinear) );
16903  SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsLinear) );
16904  SCIP_CALL( SCIPsetConshdlrInit(scip, conshdlr, consInitLinear) );
16905  SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpLinear) );
16906 #ifdef WITH_PRINTORIGCONSTYPES
16907  SCIP_CALL( SCIPsetConshdlrInitpre(scip, conshdlr, consInitpreLinear) );
16908 #endif
16909  SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseLinear) );
16910  SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolLinear, CONSHDLR_MAXPREROUNDS, CONSHDLR_PRESOLTIMING) );
16911  SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintLinear) );
16912  SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropLinear, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP,
16914  SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropLinear) );
16915  SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpLinear, consSepasolLinear, CONSHDLR_SEPAFREQ,
16917  SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransLinear) );
16918  SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxLinear) );
16919 
16920  if( SCIPfindConshdlr(scip, "quadratic") != NULL )
16921  {
16922  /* include function that upgrades quadratic constraint to linear constraints */
16924  }
16925 
16926  if( SCIPfindConshdlr(scip, "nonlinear") != NULL )
16927  {
16928  /* include the linear constraint upgrade in the nonlinear constraint handler */
16930  }
16931 
16932  /* add linear constraint handler parameters */
16933  SCIP_CALL( SCIPaddIntParam(scip,
16934  "constraints/" CONSHDLR_NAME "/tightenboundsfreq",
16935  "multiplier on propagation frequency, how often the bounds are tightened (-1: never, 0: only at root)",
16936  &conshdlrdata->tightenboundsfreq, TRUE, DEFAULT_TIGHTENBOUNDSFREQ, -1, SCIP_MAXTREEDEPTH, NULL, NULL) );
16937  SCIP_CALL( SCIPaddIntParam(scip,
16938  "constraints/" CONSHDLR_NAME "/maxrounds",
16939  "maximal number of separation rounds per node (-1: unlimited)",
16940  &conshdlrdata->maxrounds, FALSE, DEFAULT_MAXROUNDS, -1, INT_MAX, NULL, NULL) );
16941  SCIP_CALL( SCIPaddIntParam(scip,
16942  "constraints/" CONSHDLR_NAME "/maxroundsroot",
16943  "maximal number of separation rounds per node in the root node (-1: unlimited)",
16944  &conshdlrdata->maxroundsroot, FALSE, DEFAULT_MAXROUNDSROOT, -1, INT_MAX, NULL, NULL) );
16945  SCIP_CALL( SCIPaddIntParam(scip,
16946  "constraints/" CONSHDLR_NAME "/maxsepacuts",
16947  "maximal number of cuts separated per separation round",
16948  &conshdlrdata->maxsepacuts, FALSE, DEFAULT_MAXSEPACUTS, 0, INT_MAX, NULL, NULL) );
16949  SCIP_CALL( SCIPaddIntParam(scip,
16950  "constraints/" CONSHDLR_NAME "/maxsepacutsroot",
16951  "maximal number of cuts separated per separation round in the root node",
16952  &conshdlrdata->maxsepacutsroot, FALSE, DEFAULT_MAXSEPACUTSROOT, 0, INT_MAX, NULL, NULL) );
16954  "constraints/" CONSHDLR_NAME "/presolpairwise",
16955  "should pairwise constraint comparison be performed in presolving?",
16956  &conshdlrdata->presolpairwise, TRUE, DEFAULT_PRESOLPAIRWISE, NULL, NULL) );
16958  "constraints/" CONSHDLR_NAME "/presolusehashing",
16959  "should hash table be used for detecting redundant constraints in advance",
16960  &conshdlrdata->presolusehashing, TRUE, DEFAULT_PRESOLUSEHASHING, NULL, NULL) );
16961  SCIP_CALL( SCIPaddIntParam(scip,
16962  "constraints/" CONSHDLR_NAME "/nmincomparisons",
16963  "number for minimal pairwise presolve comparisons",
16964  &conshdlrdata->nmincomparisons, TRUE, DEFAULT_NMINCOMPARISONS, 1, INT_MAX, NULL, NULL) );
16966  "constraints/" CONSHDLR_NAME "/mingainpernmincomparisons",
16967  "minimal gain per minimal pairwise presolve comparisons to repeat pairwise comparison round",
16968  &conshdlrdata->mingainpernmincomp, TRUE, DEFAULT_MINGAINPERNMINCOMP, 0.0, 1.0, NULL, NULL) );
16970  "constraints/" CONSHDLR_NAME "/maxaggrnormscale",
16971  "maximal allowed relative gain in maximum norm for constraint aggregation (0.0: disable constraint aggregation)",
16972  &conshdlrdata->maxaggrnormscale, TRUE, DEFAULT_MAXAGGRNORMSCALE, 0.0, SCIP_REAL_MAX, NULL, NULL) );
16974  "constraints/" CONSHDLR_NAME "/maxeasyactivitydelta",
16975  "maximum activity delta to run easy propagation on linear constraint (faster, but numerically less stable)",
16976  &conshdlrdata->maxeasyactivitydelta, TRUE, DEFAULT_MAXEASYACTIVITYDELTA, 0.0, SCIP_REAL_MAX, NULL, NULL) );
16978  "constraints/" CONSHDLR_NAME "/maxcardbounddist",
16979  "maximal relative distance from current node's dual bound to primal bound compared to best node's dual bound for separating knapsack cardinality cuts",
16980  &conshdlrdata->maxcardbounddist, TRUE, DEFAULT_MAXCARDBOUNDDIST, 0.0, 1.0, NULL, NULL) );
16982  "constraints/" CONSHDLR_NAME "/separateall",
16983  "should all constraints be subject to cardinality cut generation instead of only the ones with non-zero dual value?",
16984  &conshdlrdata->separateall, FALSE, DEFAULT_SEPARATEALL, NULL, NULL) );
16986  "constraints/" CONSHDLR_NAME "/aggregatevariables",
16987  "should presolving search for aggregations in equations",
16988  &conshdlrdata->aggregatevariables, TRUE, DEFAULT_AGGREGATEVARIABLES, NULL, NULL) );
16990  "constraints/" CONSHDLR_NAME "/simplifyinequalities",
16991  "should presolving try to simplify inequalities",
16992  &conshdlrdata->simplifyinequalities, TRUE, DEFAULT_SIMPLIFYINEQUALITIES, NULL, NULL) );
16994  "constraints/" CONSHDLR_NAME "/dualpresolving",
16995  "should dual presolving steps be performed?",
16996  &conshdlrdata->dualpresolving, TRUE, DEFAULT_DUALPRESOLVING, NULL, NULL) );
16998  "constraints/" CONSHDLR_NAME "/singletonstuffing",
16999  "should stuffing of singleton continuous variables be performed?",
17000  &conshdlrdata->singletonstuffing, TRUE, DEFAULT_SINGLETONSTUFFING, NULL, NULL) );
17002  "constraints/" CONSHDLR_NAME "/singlevarstuffing",
17003  "should single variable stuffing be performed, which tries to fulfill constraints using the cheapest variable?",
17004  &conshdlrdata->singlevarstuffing, TRUE, DEFAULT_SINGLEVARSTUFFING, NULL, NULL) );
17006  "constraints/" CONSHDLR_NAME "/sortvars", "apply binaries sorting in decr. order of coeff abs value?",
17007  &conshdlrdata->sortvars, TRUE, DEFAULT_SORTVARS, NULL, NULL) );
17009  "constraints/" CONSHDLR_NAME "/checkrelmaxabs",
17010  "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)?",
17011  &conshdlrdata->checkrelmaxabs, TRUE, DEFAULT_CHECKRELMAXABS, NULL, NULL) );
17013  "constraints/" CONSHDLR_NAME "/detectcutoffbound",
17014  "should presolving try to detect constraints parallel to the objective function defining an upper bound and prevent these constraints from entering the LP?",
17015  &conshdlrdata->detectcutoffbound, TRUE, DEFAULT_DETECTCUTOFFBOUND, NULL, NULL) );
17017  "constraints/" CONSHDLR_NAME "/detectlowerbound",
17018  "should presolving try to detect constraints parallel to the objective function defining a lower bound and prevent these constraints from entering the LP?",
17019  &conshdlrdata->detectlowerbound, TRUE, DEFAULT_DETECTLOWERBOUND, NULL, NULL) );
17021  "constraints/" CONSHDLR_NAME "/detectpartialobjective",
17022  "should presolving try to detect subsets of constraints parallel to the objective function?",
17023  &conshdlrdata->detectpartialobjective, TRUE, DEFAULT_DETECTPARTIALOBJECTIVE, NULL, NULL) );
17025  "constraints/" CONSHDLR_NAME "/rangedrowpropagation",
17026  "should presolving and propagation try to improve bounds, detect infeasibility, and extract sub-constraints from ranged rows and equations?",
17027  &conshdlrdata->rangedrowpropagation, TRUE, DEFAULT_RANGEDROWPROPAGATION, NULL, NULL) );
17029  "constraints/" CONSHDLR_NAME "/rangedrowartcons",
17030  "should presolving and propagation extract sub-constraints from ranged rows and equations?",
17031  &conshdlrdata->rangedrowartcons, TRUE, DEFAULT_RANGEDROWARTCONS, NULL, NULL) );
17032  SCIP_CALL( SCIPaddIntParam(scip,
17033  "constraints/" CONSHDLR_NAME "/rangedrowmaxdepth",
17034  "maximum depth to apply ranged row propagation",
17035  &conshdlrdata->rangedrowmaxdepth, TRUE, DEFAULT_RANGEDROWMAXDEPTH, 0, INT_MAX, NULL, NULL) );
17036  SCIP_CALL( SCIPaddIntParam(scip,
17037  "constraints/" CONSHDLR_NAME "/rangedrowfreq",
17038  "frequency for applying ranged row propagation",
17039  &conshdlrdata->rangedrowfreq, TRUE, DEFAULT_RANGEDROWFREQ, 1, SCIP_MAXTREEDEPTH, NULL, NULL) );
17041  "constraints/" CONSHDLR_NAME "/multaggrremove",
17042  "should multi-aggregations only be performed if the constraint can be removed afterwards?",
17043  &conshdlrdata->multaggrremove, TRUE, DEFAULT_MULTAGGRREMOVE, NULL, NULL) );
17044 
17045  return SCIP_OKAY;
17046 }
17047 
17048 /** includes a linear constraint update method into the linear constraint handler */
17050  SCIP* scip, /**< SCIP data structure */
17051  SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
17052  int priority, /**< priority of upgrading method */
17053  const char* conshdlrname /**< name of the constraint handler */
17054  )
17055 {
17056  SCIP_CONSHDLR* conshdlr;
17057  SCIP_CONSHDLRDATA* conshdlrdata;
17058  SCIP_LINCONSUPGRADE* linconsupgrade;
17059  char paramname[SCIP_MAXSTRLEN];
17060  char paramdesc[SCIP_MAXSTRLEN];
17061 
17062  assert(scip != NULL);
17063  assert(linconsupgd != NULL);
17064  assert(conshdlrname != NULL );
17065 
17066  /* find the linear constraint handler */
17067  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
17068  if( conshdlr == NULL )
17069  {
17070  SCIPerrorMessage("linear constraint handler not found\n");
17071  return SCIP_PLUGINNOTFOUND;
17072  }
17073 
17074  conshdlrdata = SCIPconshdlrGetData(conshdlr);
17075  assert(conshdlrdata != NULL);
17076 
17077  /* check if linear constraint update method already exists in constraint handler data */
17078  if( !conshdlrdataHasUpgrade(scip, conshdlrdata, linconsupgd, conshdlrname) )
17079  {
17080  /* create a linear constraint upgrade data object */
17081  SCIP_CALL( linconsupgradeCreate(scip, &linconsupgrade, linconsupgd, priority) );
17082 
17083  /* insert linear constraint update method into constraint handler data */
17084  SCIP_CALL( conshdlrdataIncludeUpgrade(scip, conshdlrdata, linconsupgrade) );
17085 
17086  /* adds parameter to turn on and off the upgrading step */
17087  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "constraints/linear/upgrade/%s", conshdlrname);
17088  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "enable linear upgrading for constraint handler <%s>", conshdlrname);
17090  paramname, paramdesc,
17091  &linconsupgrade->active, FALSE, TRUE, NULL, NULL) );
17092  }
17093 
17094  return SCIP_OKAY;
17095 }
17096 
17097 /** creates and captures a linear constraint
17098  *
17099  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
17100  */
17102  SCIP* scip, /**< SCIP data structure */
17103  SCIP_CONS** cons, /**< pointer to hold the created constraint */
17104  const char* name, /**< name of constraint */
17105  int nvars, /**< number of nonzeros in the constraint */
17106  SCIP_VAR** vars, /**< array with variables of constraint entries */
17107  SCIP_Real* vals, /**< array with coefficients of constraint entries */
17108  SCIP_Real lhs, /**< left hand side of constraint */
17109  SCIP_Real rhs, /**< right hand side of constraint */
17110  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
17111  * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
17112  SCIP_Bool separate, /**< should the constraint be separated during LP processing?
17113  * Usually set to TRUE. */
17114  SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
17115  * TRUE for model constraints, FALSE for additional, redundant constraints. */
17116  SCIP_Bool check, /**< should the constraint be checked for feasibility?
17117  * TRUE for model constraints, FALSE for additional, redundant constraints. */
17118  SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
17119  * Usually set to TRUE. */
17120  SCIP_Bool local, /**< is constraint only valid locally?
17121  * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
17122  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
17123  * Usually set to FALSE. In column generation applications, set to TRUE if pricing
17124  * adds coefficients to this constraint. */
17125  SCIP_Bool dynamic, /**< is constraint subject to aging?
17126  * Usually set to FALSE. Set to TRUE for own cuts which
17127  * are separated as constraints. */
17128  SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
17129  * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
17130  SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
17131  * if it may be moved to a more global node?
17132  * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
17133  )
17134 {
17135  SCIP_CONSHDLRDATA* conshdlrdata;
17136  SCIP_CONSHDLR* conshdlr;
17137  SCIP_CONSDATA* consdata;
17138 
17139  assert(scip != NULL);
17140  assert(cons != NULL);
17141 
17142  /* find the linear constraint handler */
17143  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
17144  if( conshdlr == NULL )
17145  {
17146  SCIPerrorMessage("linear constraint handler not found\n");
17147  return SCIP_PLUGINNOTFOUND;
17148  }
17149 
17150  /* check for event handler */
17151  conshdlrdata = SCIPconshdlrGetData(conshdlr);
17152  assert(conshdlrdata != NULL);
17153  assert(conshdlrdata->eventhdlr != NULL);
17154 
17155  /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
17156  * constraint after presolving we have to ensure that it holds active variables
17157  */
17158  if( SCIPgetStage(scip) >= SCIP_STAGE_EXITPRESOLVE && nvars > 0 )
17159  {
17160  SCIP_VAR** consvars;
17161  SCIP_Real* consvals;
17162  SCIP_Real constant = 0.0;
17163  int nconsvars;
17164  int requiredsize;
17165 
17166  nconsvars = nvars;
17167  SCIP_CALL( SCIPduplicateBufferArray(scip, &consvars, vars, nconsvars) );
17168  SCIP_CALL( SCIPduplicateBufferArray(scip, &consvals, vals, nconsvars) );
17169 
17170  /* get active variables for new constraint */
17171  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, nconsvars, &constant, &requiredsize, TRUE) );
17172 
17173  /* if space was not enough we need to resize the buffers */
17174  if( requiredsize > nconsvars )
17175  {
17176  SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
17177  SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
17178 
17179  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize, TRUE) );
17180  assert(requiredsize <= nconsvars);
17181  }
17182 
17183  /* adjust sides and check that we do not subtract infinity values */
17184  if( SCIPisInfinity(scip, REALABS(constant)) )
17185  {
17186  if( constant < 0.0 )
17187  {
17188  if( SCIPisInfinity(scip, lhs) )
17189  {
17190  SCIPfreeBufferArray(scip, &consvals);
17191  SCIPfreeBufferArray(scip, &consvars);
17192 
17193  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);
17194 
17195  SCIPABORT();
17196  return SCIP_INVALIDDATA; /*lint !e527*/
17197  }
17198  if( SCIPisInfinity(scip, rhs) )
17199  {
17200  SCIPfreeBufferArray(scip, &consvals);
17201  SCIPfreeBufferArray(scip, &consvars);
17202 
17203  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);
17204 
17205  SCIPABORT();
17206  return SCIP_INVALIDDATA; /*lint !e527*/
17207  }
17208 
17209  lhs = -SCIPinfinity(scip);
17210  rhs = -SCIPinfinity(scip);
17211  }
17212  else
17213  {
17214  if( SCIPisInfinity(scip, -lhs) )
17215  {
17216  SCIPfreeBufferArray(scip, &consvals);
17217  SCIPfreeBufferArray(scip, &consvars);
17218 
17219  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);
17220 
17221  SCIPABORT();
17222  return SCIP_INVALIDDATA; /*lint !e527*/
17223  }
17224  if( SCIPisInfinity(scip, -rhs) )
17225  {
17226  SCIPfreeBufferArray(scip, &consvals);
17227  SCIPfreeBufferArray(scip, &consvars);
17228 
17229  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);
17230 
17231  SCIPABORT();
17232  return SCIP_INVALIDDATA; /*lint !e527*/
17233  }
17234 
17235  lhs = SCIPinfinity(scip);
17236  rhs = SCIPinfinity(scip);
17237  }
17238  }
17239  else
17240  {
17241  if( !SCIPisInfinity(scip, REALABS(lhs)) )
17242  lhs -= constant;
17243  if( !SCIPisInfinity(scip, REALABS(rhs)) )
17244  rhs -= constant;
17245 
17246  if( SCIPisInfinity(scip, -lhs) )
17247  lhs = -SCIPinfinity(scip);
17248  else if( SCIPisInfinity(scip, lhs) )
17249  lhs = SCIPinfinity(scip);
17250 
17251  if( SCIPisInfinity(scip, rhs) )
17252  rhs = SCIPinfinity(scip);
17253  else if( SCIPisInfinity(scip, -rhs) )
17254  rhs = -SCIPinfinity(scip);
17255  }
17256 
17257  /* create constraint data */
17258  SCIP_CALL( consdataCreate(scip, &consdata, nconsvars, consvars, consvals, lhs, rhs) );
17259  assert(consdata != NULL);
17260 
17261  SCIPfreeBufferArray(scip, &consvals);
17262  SCIPfreeBufferArray(scip, &consvars);
17263  }
17264  else
17265  {
17266  /* create constraint data */
17267  SCIP_CALL( consdataCreate(scip, &consdata, nvars, vars, vals, lhs, rhs) );
17268  assert(consdata != NULL);
17269  }
17270 
17271  /* create constraint */
17272  SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
17273  local, modifiable, dynamic, removable, stickingatnode) );
17274 
17275  if( needEvents(scip) )
17276  {
17277  /* catch bound change events of variables */
17278  SCIP_CALL( consCatchAllEvents(scip, *cons, conshdlrdata->eventhdlr) );
17279  assert(consdata->eventdata != NULL);
17280  }
17281 
17282  return SCIP_OKAY;
17283 }
17284 
17285 /** creates and captures a linear constraint
17286  * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
17287  * method SCIPcreateConsLinear(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
17288  *
17289  * @see SCIPcreateConsLinear() for information about the basic constraint flag configuration
17290  *
17291  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
17292  */
17294  SCIP* scip, /**< SCIP data structure */
17295  SCIP_CONS** cons, /**< pointer to hold the created constraint */
17296  const char* name, /**< name of constraint */
17297  int nvars, /**< number of nonzeros in the constraint */
17298  SCIP_VAR** vars, /**< array with variables of constraint entries */
17299  SCIP_Real* vals, /**< array with coefficients of constraint entries */
17300  SCIP_Real lhs, /**< left hand side of constraint */
17301  SCIP_Real rhs /**< right hand side of constraint */
17302  )
17303 {
17304  assert(scip != NULL);
17305 
17306  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, vals, lhs, rhs,
17307  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
17308 
17309  return SCIP_OKAY;
17311 
17312 /** creates by copying and captures a linear constraint */
17314  SCIP* scip, /**< target SCIP data structure */
17315  SCIP_CONS** cons, /**< pointer to store the created target constraint */
17316  SCIP* sourcescip, /**< source SCIP data structure */
17317  const char* name, /**< name of constraint */
17318  int nvars, /**< number of variables in source variable array */
17319  SCIP_VAR** sourcevars, /**< source variables of the linear constraints */
17320  SCIP_Real* sourcecoefs, /**< coefficient array of the linear constraint, or NULL if all coefficients are one */
17321  SCIP_Real lhs, /**< left hand side of the linear constraint */
17322  SCIP_Real rhs, /**< right hand side of the linear constraint */
17323  SCIP_HASHMAP* varmap, /**< a SCIP_HASHMAP mapping variables of the source SCIP to corresponding
17324  * variables of the target SCIP */
17325  SCIP_HASHMAP* consmap, /**< a hashmap to store the mapping of source constraints to the corresponding
17326  * target constraints */
17327  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP? */
17328  SCIP_Bool separate, /**< should the constraint be separated during LP processing? */
17329  SCIP_Bool enforce, /**< should the constraint be enforced during node processing? */
17330  SCIP_Bool check, /**< should the constraint be checked for feasibility? */
17331  SCIP_Bool propagate, /**< should the constraint be propagated during node processing? */
17332  SCIP_Bool local, /**< is constraint only valid locally? */
17333  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)? */
17334  SCIP_Bool dynamic, /**< is constraint subject to aging? */
17335  SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup? */
17336  SCIP_Bool stickingatnode, /**< should the constraint always be kept at the node where it was added, even
17337  * if it may be moved to a more global node? */
17338  SCIP_Bool global, /**< create a global or a local copy? */
17339  SCIP_Bool* valid /**< pointer to store if the copying was valid */
17340  )
17341 {
17342  SCIP_VAR** vars;
17343  SCIP_Real* coefs;
17344 
17345  SCIP_Real constant;
17346  int requiredsize;
17347  int v;
17348  SCIP_Bool success;
17349 
17350  if( SCIPisGT(scip, lhs, rhs) )
17351  {
17352  *valid = FALSE;
17353  return SCIP_OKAY;
17354  }
17355 
17356  (*valid) = TRUE;
17357 
17358  if( nvars == 0 )
17359  {
17360  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, 0, NULL, NULL, lhs, rhs,
17361  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
17362  return SCIP_OKAY;
17363  }
17364 
17365  /* duplicate variable array */
17366  SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, sourcevars, nvars) );
17367 
17368  /* duplicate coefficient array */
17369  if( sourcecoefs != NULL )
17370  {
17371  SCIP_CALL( SCIPduplicateBufferArray(scip, &coefs, sourcecoefs, nvars) );
17372  }
17373  else
17374  {
17375  SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
17376  for( v = 0; v < nvars; ++v )
17377  coefs[v] = 1.0;
17378  }
17379 
17380  constant = 0.0;
17381 
17382  /* transform source variable to active variables of the source SCIP since only these can be mapped to variables of
17383  * the target SCIP
17384  */
17385  if( !SCIPvarIsOriginal(vars[0]) )
17386  {
17387  SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, nvars, &constant, &requiredsize, TRUE) );
17388 
17389  if( requiredsize > nvars )
17390  {
17391  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requiredsize) );
17392  SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, requiredsize) );
17393 
17394  SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, requiredsize, &constant, &requiredsize, TRUE) );
17395  assert(requiredsize <= nvars);
17396  }
17397  }
17398  else
17399  {
17400  for( v = 0; v < nvars; ++v )
17401  {
17402  assert(SCIPvarIsOriginal(vars[v]));
17403  SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &coefs[v], &constant) );
17404  assert(vars[v] != NULL);
17405  }
17406  }
17407 
17408 
17409  success = TRUE;
17410  /* map variables of the source constraint to variables of the target SCIP */
17411  for( v = 0; v < nvars && success; ++v )
17412  {
17413  SCIP_VAR* var;
17414  var = vars[v];
17415 
17416  SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, var, &vars[v], varmap, consmap, global, &success) );
17417  assert(!(success) || vars[v] != NULL);
17418  }
17419 
17420  /* only create the target constraint, if all variables could be copied */
17421  if( success )
17422  {
17423  if( !SCIPisInfinity(scip, -lhs) )
17424  lhs -= constant;
17425 
17426  if( !SCIPisInfinity(scip, rhs) )
17427  rhs -= constant;
17428 
17429  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
17430  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
17431  }
17432  else
17433  *valid = FALSE;
17434 
17435  /* free buffer array */
17436  SCIPfreeBufferArray(scip, &coefs);
17437  SCIPfreeBufferArray(scip, &vars);
17438 
17439  return SCIP_OKAY;
17440 }
17441 
17442 /** adds coefficient to linear constraint (if it is not zero) */
17444  SCIP* scip, /**< SCIP data structure */
17445  SCIP_CONS* cons, /**< constraint data */
17446  SCIP_VAR* var, /**< variable of constraint entry */
17447  SCIP_Real val /**< coefficient of constraint entry */
17448  )
17449 {
17450  assert(scip != NULL);
17451  assert(cons != NULL);
17452  assert(var != NULL);
17453 
17454  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
17455  {
17456  SCIPerrorMessage("constraint is not linear\n");
17457  return SCIP_INVALIDDATA;
17458  }
17459 
17460  /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
17461  * constraint after presolving we have to ensure that it holds active variables
17462  */
17463  if( SCIPgetStage(scip) >= SCIP_STAGE_EXITPRESOLVE )
17464  {
17465  SCIP_CONSDATA* consdata;
17466  SCIP_VAR** consvars;
17467  SCIP_Real* consvals;
17468  SCIP_Real constant = 0.0;
17469  SCIP_Real rhs;
17470  SCIP_Real lhs;
17471  int nconsvars;
17472  int requiredsize;
17473  int v;
17474 
17475  nconsvars = 1;
17476  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nconsvars) );
17477  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
17478  consvars[0] = var;
17479  consvals[0] = val;
17480 
17481  /* get active variables for new constraint */
17482  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, nconsvars, &constant, &requiredsize, TRUE) );
17483 
17484  /* if space was not enough we need to resize the buffers */
17485  if( requiredsize > nconsvars )
17486  {
17487  SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
17488  SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
17489 
17490  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize, TRUE) );
17491  assert(requiredsize <= nconsvars);
17492  }
17493 
17494  consdata = SCIPconsGetData(cons);
17495  assert(consdata != NULL);
17496 
17497  lhs = consdata->lhs;
17498  rhs = consdata->rhs;
17499 
17500  /* adjust sides and check that we do not subtract infinity values */
17501  /* constant is infinite */
17502  if( SCIPisInfinity(scip, REALABS(constant)) )
17503  {
17504  if( constant < 0.0 )
17505  {
17506  if( SCIPisInfinity(scip, lhs) )
17507  {
17508  SCIPfreeBufferArray(scip, &consvals);
17509  SCIPfreeBufferArray(scip, &consvars);
17510 
17511  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));
17512 
17513  SCIPABORT();
17514  return SCIP_INVALIDDATA; /*lint !e527*/
17515  }
17516  if( SCIPisInfinity(scip, rhs) )
17517  {
17518  SCIPfreeBufferArray(scip, &consvals);
17519  SCIPfreeBufferArray(scip, &consvars);
17520 
17521  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));
17522 
17523  SCIPABORT();
17524  return SCIP_INVALIDDATA; /*lint !e527*/
17525  }
17526 
17527  lhs = -SCIPinfinity(scip);
17528  rhs = -SCIPinfinity(scip);
17529  }
17530  else
17531  {
17532  if( SCIPisInfinity(scip, -lhs) )
17533  {
17534  SCIPfreeBufferArray(scip, &consvals);
17535  SCIPfreeBufferArray(scip, &consvars);
17536 
17537  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));
17538 
17539  SCIPABORT();
17540  return SCIP_INVALIDDATA; /*lint !e527*/
17541  }
17542  if( SCIPisInfinity(scip, -rhs) )
17543  {
17544  SCIPfreeBufferArray(scip, &consvals);
17545  SCIPfreeBufferArray(scip, &consvars);
17546 
17547  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));
17548 
17549  SCIPABORT();
17550  return SCIP_INVALIDDATA; /*lint !e527*/
17551  }
17552 
17553  lhs = SCIPinfinity(scip);
17554  rhs = SCIPinfinity(scip);
17555  }
17556  }
17557  /* constant is not infinite */
17558  else
17559  {
17560  if( !SCIPisInfinity(scip, REALABS(lhs)) )
17561  lhs -= constant;
17562  if( !SCIPisInfinity(scip, REALABS(rhs)) )
17563  rhs -= constant;
17564 
17565  if( SCIPisInfinity(scip, -lhs) )
17566  lhs = -SCIPinfinity(scip);
17567  else if( SCIPisInfinity(scip, lhs) )
17568  lhs = SCIPinfinity(scip);
17569 
17570  if( SCIPisInfinity(scip, rhs) )
17571  rhs = SCIPinfinity(scip);
17572  else if( SCIPisInfinity(scip, -rhs) )
17573  rhs = -SCIPinfinity(scip);
17574  }
17575 
17576  /* add all active variables to constraint */
17577  for( v = nconsvars - 1; v >= 0; --v )
17578  {
17579  SCIP_CALL( addCoef(scip, cons, consvars[v], consvals[v]) );
17580  }
17581 
17582  /* update left and right hand sides */
17583  SCIP_CALL( chgLhs(scip, cons, lhs));
17584  SCIP_CALL( chgRhs(scip, cons, rhs));
17585 
17586  SCIPfreeBufferArray(scip, &consvals);
17587  SCIPfreeBufferArray(scip, &consvars);
17588  }
17589  else
17590  {
17591  SCIP_CALL( addCoef(scip, cons, var, val) );
17592  }
17593 
17594  return SCIP_OKAY;
17595 }
17596 
17597 /** changes coefficient of variable in linear constraint; deletes the variable if coefficient is zero; adds variable if
17598  * not yet contained in the constraint
17599  *
17600  * @note This method may only be called during problem creation stage for an original constraint and variable.
17601  *
17602  * @note This method requires linear time to search for occurences of the variable in the constraint data.
17603  */
17605  SCIP* scip, /**< SCIP data structure */
17606  SCIP_CONS* cons, /**< constraint data */
17607  SCIP_VAR* var, /**< variable of constraint entry */
17608  SCIP_Real val /**< new coefficient of constraint entry */
17609  )
17610 {
17611  SCIP_CONSDATA* consdata;
17612  SCIP_VAR** vars;
17613  SCIP_Bool found;
17614  int i;
17615 
17616  assert(scip != NULL);
17617  assert(cons != NULL);
17618  assert(var != NULL);
17619 
17620  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
17621  {
17622  SCIPerrorMessage("constraint is not linear\n");
17623  return SCIP_INVALIDDATA;
17624  }
17625 
17626  if( SCIPgetStage(scip) > SCIP_STAGE_PROBLEM || !SCIPconsIsOriginal(cons) || !SCIPvarIsOriginal(var) )
17627  {
17628  SCIPerrorMessage("method may only be called during problem creation stage for original constraints and variables\n");
17629  return SCIP_INVALIDDATA;
17630  }
17631 
17632  consdata = SCIPconsGetData(cons);
17633  assert(consdata != NULL);
17634 
17635  vars = consdata->vars;
17636  found = FALSE;
17637  i = 0;
17638  while( i < consdata->nvars )
17639  {
17640  if( vars[i] == var )
17641  {
17642  if( found || SCIPisZero(scip, val) )
17643  {
17644  SCIP_CALL( delCoefPos(scip, cons, i) );
17645 
17646  /* decrease i by one since otherwise we would skip the coefficient which has been switched to position i */
17647  i--;
17648  }
17649  else
17650  {
17651  SCIP_CALL( chgCoefPos(scip, cons, i, val) );
17652  }
17653  found = TRUE;
17654  }
17655  i++;
17656  }
17657 
17658  if( !found && !SCIPisZero(scip, val) )
17659  {
17660  SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val) );
17661  }
17662 
17663  return SCIP_OKAY;
17664 }
17665 
17666 /** deletes variable from linear constraint
17667  *
17668  * @note This method may only be called during problem creation stage for an original constraint and variable.
17669  *
17670  * @note This method requires linear time to search for occurences of the variable in the constraint data.
17671  */
17673  SCIP* scip, /**< SCIP data structure */
17674  SCIP_CONS* cons, /**< constraint data */
17675  SCIP_VAR* var /**< variable of constraint entry */
17676  )
17677 {
17678  assert(scip != NULL);
17679  assert(cons != NULL);
17680  assert(var != NULL);
17681 
17682  SCIP_CALL( SCIPchgCoefLinear(scip, cons, var, 0.0) );
17683 
17684  return SCIP_OKAY;
17685 }
17686 
17687 /** gets left hand side of linear constraint */
17689  SCIP* scip, /**< SCIP data structure */
17690  SCIP_CONS* cons /**< constraint data */
17691  )
17692 {
17693  SCIP_CONSDATA* consdata;
17694 
17695  assert(cons != NULL);
17696 
17697  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
17698  {
17699  SCIPerrorMessage("constraint is not linear\n");
17700  SCIPABORT();
17701  return SCIP_INVALID; /*lint !e527*/
17702  }
17703 
17704  consdata = SCIPconsGetData(cons);
17705  assert(consdata != NULL);
17706 
17707  return consdata->lhs;
17708 }
17709 
17710 /** gets right hand side of linear constraint */
17712  SCIP* scip, /**< SCIP data structure */
17713  SCIP_CONS* cons /**< constraint data */
17714  )
17715 {
17716  SCIP_CONSDATA* consdata;
17717 
17718  assert(cons != NULL);
17719 
17720  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
17721  {
17722  SCIPerrorMessage("constraint is not linear\n");
17723  SCIPABORT();
17724  return SCIP_INVALID; /*lint !e527*/
17725  }
17726 
17727  consdata = SCIPconsGetData(cons);
17728  assert(consdata != NULL);
17729 
17730  return consdata->rhs;
17731 }
17732 
17733 /** changes left hand side of linear constraint */
17735  SCIP* scip, /**< SCIP data structure */
17736  SCIP_CONS* cons, /**< constraint data */
17737  SCIP_Real lhs /**< new left hand side */
17738  )
17739 {
17740  assert(scip != NULL);
17741  assert(cons != NULL);
17742 
17743  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
17744  {
17745  SCIPerrorMessage("constraint is not linear\n");
17746  return SCIP_INVALIDDATA;
17747  }
17748 
17749  SCIP_CALL( chgLhs(scip, cons, lhs) );
17750 
17751  return SCIP_OKAY;
17752 }
17753 
17754 /** changes right hand side of linear constraint */
17756  SCIP* scip, /**< SCIP data structure */
17757  SCIP_CONS* cons, /**< constraint data */
17758  SCIP_Real rhs /**< new right hand side */
17759  )
17760 {
17761  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
17762  {
17763  SCIPerrorMessage("constraint is not linear\n");
17764  return SCIP_INVALIDDATA;
17765  }
17766 
17767  SCIP_CALL( chgRhs(scip, cons, rhs) );
17768 
17769  return SCIP_OKAY;
17770 }
17771 
17772 /** gets the number of variables in the linear constraint */
17773 int SCIPgetNVarsLinear(
17774  SCIP* scip, /**< SCIP data structure */
17775  SCIP_CONS* cons /**< constraint data */
17776  )
17777 {
17778  SCIP_CONSDATA* consdata;
17779 
17780  assert(cons != NULL);
17781 
17782  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
17783  {
17784  SCIPerrorMessage("constraint is not linear\n");
17785  SCIPABORT();
17786  return -1; /*lint !e527*/
17787  }
17788 
17789  consdata = SCIPconsGetData(cons);
17790  assert(consdata != NULL);
17791 
17792  return consdata->nvars;
17793 }
17794 
17795 /** gets the array of variables in the linear constraint; the user must not modify this array! */
17797  SCIP* scip, /**< SCIP data structure */
17798  SCIP_CONS* cons /**< constraint data */
17799  )
17800 {
17801  SCIP_CONSDATA* consdata;
17802 
17803  assert(cons != NULL);
17804 
17805  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
17806  {
17807  SCIPerrorMessage("constraint is not linear\n");
17808  SCIPABORT();
17809  return NULL; /*lint !e527*/
17810  }
17811 
17812  consdata = SCIPconsGetData(cons);
17813  assert(consdata != NULL);
17814 
17815  return consdata->vars;
17816 }
17817 
17818 /** gets the array of coefficient values in the linear constraint; the user must not modify this array! */
17820  SCIP* scip, /**< SCIP data structure */
17821  SCIP_CONS* cons /**< constraint data */
17822  )
17823 {
17824  SCIP_CONSDATA* consdata;
17825 
17826  assert(cons != NULL);
17827 
17828  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
17829  {
17830  SCIPerrorMessage("constraint is not linear\n");
17831  SCIPABORT();
17832  return NULL; /*lint !e527*/
17833  }
17834 
17835  consdata = SCIPconsGetData(cons);
17836  assert(consdata != NULL);
17837 
17838  return consdata->vals;
17839 }
17840 
17841 /** gets the activity of the linear constraint in the given solution
17842  *
17843  * @note if the solution contains values at infinity, this method will return SCIP_INVALID in case the activity
17844  * comprises positive and negative infinity contributions
17845  */
17847  SCIP* scip, /**< SCIP data structure */
17848  SCIP_CONS* cons, /**< constraint data */
17849  SCIP_SOL* sol /**< solution, or NULL to use current node's solution */
17850  )
17851 {
17852  SCIP_CONSDATA* consdata;
17853 
17854  assert(cons != NULL);
17855 
17856  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
17857  {
17858  SCIPerrorMessage("constraint is not linear\n");
17859  SCIPABORT();
17860  return SCIP_INVALID; /*lint !e527*/
17861  }
17862 
17863  consdata = SCIPconsGetData(cons);
17864  assert(consdata != NULL);
17865 
17866  if( consdata->row != NULL )
17867  return SCIPgetRowSolActivity(scip, consdata->row, sol);
17868  else
17869  return consdataGetActivity(scip, consdata, sol);
17870 }
17871 
17872 /** gets the feasibility of the linear constraint in the given solution */
17874  SCIP* scip, /**< SCIP data structure */
17875  SCIP_CONS* cons, /**< constraint data */
17876  SCIP_SOL* sol /**< solution, or NULL to use current node's solution */
17877  )
17878 {
17879  SCIP_CONSDATA* consdata;
17880 
17881  assert(cons != NULL);
17882 
17883  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
17884  {
17885  SCIPerrorMessage("constraint is not linear\n");
17886  SCIPABORT();
17887  return SCIP_INVALID; /*lint !e527*/
17888  }
17889 
17890  consdata = SCIPconsGetData(cons);
17891  assert(consdata != NULL);
17892 
17893  if( consdata->row != NULL )
17894  return SCIPgetRowSolFeasibility(scip, consdata->row, sol);
17895  else
17896  return consdataGetFeasibility(scip, consdata, sol);
17897 }
17898 
17899 /** gets the dual solution of the linear constraint in the current LP */
17901  SCIP* scip, /**< SCIP data structure */
17902  SCIP_CONS* cons /**< constraint data */
17903  )
17904 {
17905  SCIP_CONSDATA* consdata;
17906 
17907  assert(cons != NULL);
17908  assert(!SCIPconsIsOriginal(cons)); /* original constraints would always return 0 */
17909 
17910  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
17911  {
17912  SCIPerrorMessage("constraint is not linear\n");
17913  SCIPABORT();
17914  return SCIP_INVALID; /*lint !e527*/
17915  }
17916 
17917  consdata = SCIPconsGetData(cons);
17918  assert(consdata != NULL);
17919 
17920  if( consdata->row != NULL )
17921  return SCIProwGetDualsol(consdata->row);
17922  else
17923  return 0.0;
17924 }
17925 
17926 /** gets the dual Farkas value of the linear constraint in the current infeasible LP */
17928  SCIP* scip, /**< SCIP data structure */
17929  SCIP_CONS* cons /**< constraint data */
17930  )
17931 {
17932  SCIP_CONSDATA* consdata;
17933 
17934  assert(cons != NULL);
17935  assert(!SCIPconsIsOriginal(cons)); /* original constraints would always return 0 */
17936 
17937  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
17938  {
17939  SCIPerrorMessage("constraint is not linear\n");
17940  SCIPABORT();
17941  return SCIP_INVALID; /*lint !e527*/
17942  }
17943 
17944  consdata = SCIPconsGetData(cons);
17945  assert(consdata != NULL);
17946 
17947  if( consdata->row != NULL )
17948  return SCIProwGetDualfarkas(consdata->row);
17949  else
17950  return 0.0;
17951 }
17952 
17953 /** returns the linear relaxation of the given linear constraint; may return NULL if no LP row was yet created;
17954  * the user must not modify the row!
17955  */
17957  SCIP* scip, /**< SCIP data structure */
17958  SCIP_CONS* cons /**< constraint data */
17959  )
17960 {
17961  SCIP_CONSDATA* consdata;
17962 
17963  assert(cons != NULL);
17964 
17965  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
17966  {
17967  SCIPerrorMessage("constraint is not linear\n");
17968  SCIPABORT();
17969  return NULL; /*lint !e527*/
17970  }
17971 
17972  consdata = SCIPconsGetData(cons);
17973  assert(consdata != NULL);
17974 
17975  return consdata->row;
17976 }
17977 
17978 /** tries to automatically convert a linear constraint into a more specific and more specialized constraint */
17980  SCIP* scip, /**< SCIP data structure */
17981  SCIP_CONS* cons, /**< source constraint to try to convert */
17982  SCIP_CONS** upgdcons /**< pointer to store upgraded constraint, or NULL if not successful */
17983  )
17984 {
17985  SCIP_CONSHDLR* conshdlr;
17986  SCIP_CONSHDLRDATA* conshdlrdata;
17987  SCIP_CONSDATA* consdata;
17988  SCIP_VAR* var;
17989  SCIP_Real val;
17990  SCIP_Real lb;
17991  SCIP_Real ub;
17992  SCIP_Real poscoeffsum;
17993  SCIP_Real negcoeffsum;
17994  SCIP_Bool integral;
17995  int nposbin;
17996  int nnegbin;
17997  int nposint;
17998  int nnegint;
17999  int nposimpl;
18000  int nnegimpl;
18001  int nposimplbin;
18002  int nnegimplbin;
18003  int nposcont;
18004  int nnegcont;
18005  int ncoeffspone;
18006  int ncoeffsnone;
18007  int ncoeffspint;
18008  int ncoeffsnint;
18009  int ncoeffspfrac;
18010  int ncoeffsnfrac;
18011  int i;
18012 
18013  assert(scip != NULL);
18014  assert(cons != NULL);
18015  assert(upgdcons != NULL);
18016 
18017  *upgdcons = NULL;
18018 
18019  /* we cannot upgrade a modifiable linear constraint, since we don't know what additional coefficients to expect */
18020  if( SCIPconsIsModifiable(cons) )
18021  return SCIP_OKAY;
18022 
18023  /* check for upgradability */
18024  if( SCIPconsGetNUpgradeLocks(cons) > 0 )
18025  return SCIP_OKAY;
18026 
18027  /* get the constraint handler and check, if it's really a linear constraint */
18028  conshdlr = SCIPconsGetHdlr(cons);
18029  if( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) != 0 )
18030  {
18031  SCIPerrorMessage("constraint is not linear\n");
18032  return SCIP_INVALIDDATA;
18033  }
18034 
18035  /* get constraint handler data and constraint data */
18036  conshdlrdata = SCIPconshdlrGetData(conshdlr);
18037  assert(conshdlrdata != NULL);
18038  consdata = SCIPconsGetData(cons);
18039  assert(consdata != NULL);
18040 
18041  /* check, if the constraint was already upgraded and will be deleted anyway after preprocessing */
18042  if( consdata->upgraded )
18043  return SCIP_OKAY;
18044 
18045  /* check, if the constraint is already stored as LP row */
18046  if( consdata->row != NULL )
18047  {
18048  if( SCIProwIsInLP(consdata->row) )
18049  {
18050  SCIPerrorMessage("cannot upgrade linear constraint that is already stored as row in the LP\n");
18051  return SCIP_INVALIDDATA;
18052  }
18053  else
18054  {
18055  SCIP_CALL( SCIPreleaseRow(scip, &consdata->row) );
18056  }
18057  }
18058 
18059  /* normalize constraint */
18060  SCIP_CALL( normalizeCons(scip, cons) );
18061 
18062 
18063  /*
18064  * calculate some statistics on linear constraint
18065  */
18066 
18067  nposbin = 0;
18068  nnegbin = 0;
18069  nposint = 0;
18070  nnegint = 0;
18071  nposimpl = 0;
18072  nnegimpl = 0;
18073  nposimplbin = 0;
18074  nnegimplbin = 0;
18075  nposcont = 0;
18076  nnegcont = 0;
18077  ncoeffspone = 0;
18078  ncoeffsnone = 0;
18079  ncoeffspint = 0;
18080  ncoeffsnint = 0;
18081  ncoeffspfrac = 0;
18082  ncoeffsnfrac = 0;
18083  integral = TRUE;
18084  poscoeffsum = 0.0;
18085  negcoeffsum = 0.0;
18086 
18087  for( i = 0; i < consdata->nvars; ++i )
18088  {
18089  var = consdata->vars[i];
18090  val = consdata->vals[i];
18091  lb = SCIPvarGetLbLocal(var);
18092  ub = SCIPvarGetUbLocal(var);
18093  assert(!SCIPisZero(scip, val));
18094 
18095  switch( SCIPvarGetType(var) )
18096  {
18097  case SCIP_VARTYPE_BINARY:
18098  if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
18099  integral = integral && SCIPisIntegral(scip, val);
18100  if( val >= 0.0 )
18101  nposbin++;
18102  else
18103  nnegbin++;
18104  break;
18105  case SCIP_VARTYPE_INTEGER:
18106  if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
18107  integral = integral && SCIPisIntegral(scip, val);
18108  if( val >= 0.0 )
18109  nposint++;
18110  else
18111  nnegint++;
18112  break;
18113  case SCIP_VARTYPE_IMPLINT:
18114  if( SCIPvarIsBinary(var) )
18115  {
18116  if( val >= 0.0 )
18117  nposimplbin++;
18118  else
18119  nnegimplbin++;
18120  }
18121  if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
18122  integral = integral && SCIPisIntegral(scip, val);
18123  if( val >= 0.0 )
18124  nposimpl++;
18125  else
18126  nnegimpl++;
18127  break;
18129  integral = integral && SCIPisEQ(scip, lb, ub) && SCIPisIntegral(scip, val * lb);
18130  if( val >= 0.0 )
18131  nposcont++;
18132  else
18133  nnegcont++;
18134  break;
18135  default:
18136  SCIPerrorMessage("unknown variable type\n");
18137  return SCIP_INVALIDDATA;
18138  }
18139  if( SCIPisEQ(scip, val, 1.0) )
18140  ncoeffspone++;
18141  else if( SCIPisEQ(scip, val, -1.0) )
18142  ncoeffsnone++;
18143  else if( SCIPisIntegral(scip, val) )
18144  {
18145  if( SCIPisPositive(scip, val) )
18146  ncoeffspint++;
18147  else
18148  ncoeffsnint++;
18149  }
18150  else
18151  {
18152  if( SCIPisPositive(scip, val) )
18153  ncoeffspfrac++;
18154  else
18155  ncoeffsnfrac++;
18156  }
18157  if( SCIPisPositive(scip, val) )
18158  poscoeffsum += val;
18159  else
18160  negcoeffsum += val;
18161  }
18162 
18163 
18164  /*
18165  * call the upgrading methods
18166  */
18167 
18168  SCIPdebugMsg(scip, "upgrading linear constraint <%s> (%d upgrade methods):\n",
18169  SCIPconsGetName(cons), conshdlrdata->nlinconsupgrades);
18170  SCIPdebugMsg(scip, " +bin=%d -bin=%d +int=%d -int=%d +impl=%d -impl=%d +cont=%d -cont=%d +1=%d -1=%d +I=%d -I=%d +F=%d -F=%d possum=%.15g negsum=%.15g integral=%u\n",
18171  nposbin, nnegbin, nposint, nnegint, nposimpl, nnegimpl, nposcont, nnegcont,
18172  ncoeffspone, ncoeffsnone, ncoeffspint, ncoeffsnint, ncoeffspfrac, ncoeffsnfrac,
18173  poscoeffsum, negcoeffsum, integral);
18174 
18175  /* try all upgrading methods in priority order in case the upgrading step is enable */
18176  for( i = 0; i < conshdlrdata->nlinconsupgrades && *upgdcons == NULL; ++i )
18177  {
18178  if( conshdlrdata->linconsupgrades[i]->active )
18179  {
18180  SCIP_CALL( conshdlrdata->linconsupgrades[i]->linconsupgd(scip, cons, consdata->nvars,
18181  consdata->vars, consdata->vals, consdata->lhs, consdata->rhs,
18182  nposbin, nnegbin, nposint, nnegint, nposimpl, nnegimpl, nposimplbin, nnegimplbin, nposcont, nnegcont,
18183  ncoeffspone, ncoeffsnone, ncoeffspint, ncoeffsnint, ncoeffspfrac, ncoeffsnfrac,
18184  poscoeffsum, negcoeffsum, integral,
18185  upgdcons) );
18186  }
18187  }
18188 
18189 #ifdef SCIP_DEBUG
18190  if( *upgdcons != NULL )
18191  {
18192  SCIPdebugPrintCons(scip, cons, NULL);
18193  SCIPdebugMsg(scip, " -> upgraded to constraint type <%s>\n", SCIPconshdlrGetName(SCIPconsGetHdlr(*upgdcons)));
18194  SCIPdebugPrintCons(scip, *upgdcons, NULL);
18195  }
18196 #endif
18197 
18198  return SCIP_OKAY;
18199 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
#define EVENTHDLR_DESC
Definition: cons_linear.c:80
#define CONSHDLR_DELAYSEPA
Definition: cons_linear.c:72
void SCIPsortRealInt(SCIP_Real *realarray, int *intarray, int len)
SCIP_VAR ** SCIPgetLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip.h:21975
#define SCIP_DECL_LINCONSUPGD(x)
Definition: cons_linear.h:104
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
Definition: cons.c:4143
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
Definition: scip.c:46385
struct InferInfo INFERINFO
SCIP_RETCODE SCIPincConsAge(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:28028
SCIP_Real SCIPgetActivityLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip.h:21964
SCIP_RETCODE SCIPflattenVarAggregationGraph(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:18906
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
Definition: scip.c:6263
SCIP_Bool SCIPinRepropagation(SCIP *scip)
Definition: scip.c:40735
static SCIP_RETCODE tightenVarBounds(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool force)
Definition: cons_linear.c:6631
static void consdataCalcMinAbsval(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1361
SCIP_RETCODE SCIPincludeNonlinconsUpgrade(SCIP *scip, SCIP_DECL_NONLINCONSUPGD((*nonlinconsupgd)), SCIP_DECL_EXPRGRAPHNODEREFORM((*nodereform)), int priority, SCIP_Bool active, const char *conshdlrname)
SCIP_Real SCIPfeastol(SCIP *scip)
Definition: scip.c:45508
SCIP_RETCODE SCIPincludeConshdlrLinear(SCIP *scip)
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:860
static int inferInfoGetPos(INFERINFO inferinfo)
Definition: cons_linear.c:402
static SCIP_RETCODE consCatchEvent(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
Definition: cons_linear.c:715
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip.h:21958
static SCIP_RETCODE chgCoefPos(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Real newval)
Definition: cons_linear.c:3890
static SCIP_RETCODE simplifyInequalities(SCIP *scip, SCIP_CONS *cons, int *nchgcoefs, int *nchgsides)
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip.c:22212
static SCIP_Real consdataGetFeasibility(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol)
Definition: cons_linear.c:3072
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip.c:19346
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46320
#define DEFAULT_MAXAGGRNORMSCALE
Definition: cons_linear.c:103
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip.c:814
#define DEFAULT_PRESOLPAIRWISE
Definition: cons_linear.c:91
#define SCIP_EVENTTYPE_VARFIXED
Definition: type_event.h:58
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:8140
SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
Definition: var.c:16961
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
Definition: scip.c:6286
SCIP_RETCODE SCIPcreateConsBasicLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs)
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46333
#define CONSHDLR_NAME
Definition: cons_linear.c:61
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip.c:19206
#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:3093
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2253
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:1528
#define DEFAULT_RANGEDROWFREQ
Definition: cons_linear.c:138
static void consdataRecomputeMaxActivityDelta(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1466
#define MAXSCALEDCOEF
Definition: cons_linear.c:145
SCIP_RETCODE SCIPcatchVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: scip.c:40502
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip.c:6576
static SCIP_Bool checkEqualObjective(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real *scale, SCIP_Real *offset)
Definition: cons_linear.c:9899
#define DEFAULT_CHECKRELMAXABS
Definition: cons_linear.c:100
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
Definition: scip.c:42726
static SCIP_RETCODE fixVariables(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars)
Definition: cons_linear.c:7576
SCIP_VAR * SCIPbdchginfoGetVar(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17791
SCIP_Bool SCIPisUbBetter(SCIP *scip, SCIP_Real newub, SCIP_Real oldlb, SCIP_Real oldub)
Definition: scip.c:46683
#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:9187
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:5271
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17169
SCIP_RETCODE SCIPincludeQuadconsUpgrade(SCIP *scip, SCIP_DECL_QUADCONSUPGD((*quadconsupgd)), int priority, SCIP_Bool active, const char *conshdlrname)
SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETVARS((*consgetvars)))
Definition: scip.c:6516
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)
static SCIP_RETCODE findOperators(const char *str, char **firstoperator, char **secondoperator, SCIP_Bool *success)
SCIP_RETCODE SCIPupdateCutoffbound(SCIP *scip, SCIP_Real cutoffbound)
Definition: scip.c:42754
#define SCIP_MAXSTRLEN
Definition: def.h:225
#define SCIP_DECL_CONSINITPRE(x)
Definition: type_cons.h:114
SCIP_Bool SCIPvarIsInitial(SCIP_VAR *var)
Definition: var.c:16756
SCIP_Bool SCIPparseReal(SCIP *scip, const char *str, SCIP_Real *value, char **endptr)
Definition: scip.c:45705
SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
Definition: scip.c:6008
SCIP_RETCODE SCIPresetConsAge(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:28056
static SCIP_RETCODE consDropAllEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linear.c:818
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:12530
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip.c:45835
SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
Definition: var.c:16949
static long bound
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
Definition: scip.c:30418
SCIP_RETCODE SCIPsetConsPropagated(SCIP *scip, SCIP_CONS *cons, SCIP_Bool propagate)
Definition: scip.c:27615
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
Definition: scip.c:46110
SCIP_Bool SCIPisSumRelEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46761
static void consdataUpdateActivitiesGlbUb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real oldub, SCIP_Real newub, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:1986
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17225
SCIP_Bool SCIPisUpdateUnreliable(SCIP *scip, SCIP_Real newvalue, SCIP_Real oldvalue)
Definition: scip.c:46868
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46037
SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: scip.c:8561
static SCIP_Real consdataGetMaxAbsval(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:2216
static SCIP_RETCODE linconsupgradeCreate(SCIP *scip, SCIP_LINCONSUPGRADE **linconsupgrade, SCIP_DECL_LINCONSUPGD((*linconsupgd)), int priority)
Definition: cons_linear.c:505
void SCIPsortDownRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
#define DEFAULT_MAXSEPACUTS
Definition: cons_linear.c:89
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip.c:18652
SCIP_RETCODE SCIPupdateConsFlags(SCIP *scip, SCIP_CONS *cons0, SCIP_CONS *cons1)
Definition: scip.c:27768
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip.c:18461
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:16735
SCIP_RETCODE SCIPsetConshdlrInitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITPRE((*consinitpre)))
Definition: scip.c:6177
static void consdataRecomputeMinactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1231
SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
Definition: scip.c:46409
#define DEFAULT_DETECTPARTIALOBJECTIVE
Definition: cons_linear.c:132
SCIP_RETCODE SCIPconvertCutsToConss(SCIP *scip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, int *ncutsadded)
Definition: scip.c:2997
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46372
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:2790
static void permSortConsdata(SCIP_CONSDATA *consdata, int *perm, int nvars)
Definition: cons_linear.c:3151
#define DEFAULT_AGGREGATEVARIABLES
Definition: cons_linear.c:115
#define FALSE
Definition: def.h:64
SCIP_Real SCIPadjustedVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real ub)
Definition: scip.c:21674
static SCIP_DECL_HASHGETKEY(hashGetKeyLinearcons)
static SCIP_DECL_CONSEXITSOL(consExitsolLinear)
static void consdataInvalidateActivities(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1132
int SCIPconsGetPos(SCIP_CONS *cons)
Definition: cons.c:7891
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:278
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:5866
SCIP_Real * SCIPgetLinearCoefsNonlinear(SCIP *scip, SCIP_CONS *cons)
static SCIP_DECL_CONSCOPY(consCopyLinear)
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:46050
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:9340
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
Definition: scip.c:46122
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:2852
static SCIP_Bool conshdlrdataHasUpgrade(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_DECL_LINCONSUPGD((*linconsupgd)), const char *conshdlrname)
Definition: cons_linear.c:586
#define TRUE
Definition: def.h:63
#define SCIPdebug(x)
Definition: pub_message.h:74
#define DEFAULT_MAXCARDBOUNDDIST
Definition: cons_linear.c:109
SCIP_RETCODE SCIPunmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:28286
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_Real SCIPgetLocalLowerbound(SCIP *scip)
Definition: scip.c:13271
SCIP_Real SCIPvarGetNegationConstant(SCIP_VAR *var)
Definition: var.c:17006
enum Proprule PROPRULE
#define DEFAULT_NMINCOMPARISONS
Definition: cons_linear.c:93
#define SCIPstatisticMessage
Definition: pub_message.h:104
SCIP_ROW * SCIPgetRowLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPaddConflictUb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
Definition: scip.c:26907
static SCIP_DECL_CONSINITLP(consInitlpLinear)
SCIP_RETCODE SCIPaddVarLocks(SCIP *scip, SCIP_VAR *var, int nlocksdown, int nlocksup)
Definition: scip.c:21349
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition: cons.c:8160
#define SCIP_PRESOLTIMING_EXHAUSTIVE
Definition: type_timing.h:45
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:7360
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)
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:16862
#define SCIP_EVENTTYPE_GLBCHANGED
Definition: type_event.h:61
static SCIP_DECL_CONSENFOPS(consEnfopsLinear)
SCIP_Real SCIPvarGetAggrScalar(SCIP_VAR *var)
Definition: var.c:16915
SCIP_Real SCIPgetRhsNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:8190
static GRAPHNODE ** active
SCIP_RETCODE SCIPinitConflictAnalysis(SCIP *scip, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
Definition: scip.c:26811
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip.c:22328
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip.h:21973
static SCIP_RETCODE tightenSides(SCIP *scip, SCIP_CONS *cons, int *nchgsides)
Definition: cons_linear.c:8677
#define SCIPdebugMessage
Definition: pub_message.h:77
#define DEFAULT_MINGAINPERNMINCOMP
Definition: cons_linear.c:94
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:5920
SCIP_Real SCIPselectSimpleValue(SCIP_Real lb, SCIP_Real ub, SCIP_Longint maxdnom)
Definition: misc.c:8482
int SCIPconsGetNLocksNeg(SCIP_CONS *cons)
Definition: cons.c:8240
SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
Definition: scip.c:1228
static SCIP_DECL_CONSEXITPRE(consExitpreLinear)
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip.h:21999
void SCIPsortDownRealInt(SCIP_Real *realarray, int *intarray, int len)
enum Proprule PROPRULE
Definition: cons_linear.c:352
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:45985
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)
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:22003
static INFERINFO getInferInfo(PROPRULE proprule, int pos)
Definition: cons_linear.c:411
static SCIP_RETCODE rangedRowPropagation(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *nchgbds, int *naddconss)
Definition: cons_linear.c:5658
SCIP_Real SCIPadjustedVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real lb)
Definition: scip.c:21642
SCIP_Bool SCIPvarIsRemovable(SCIP_VAR *var)
Definition: var.c:16766
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:6660
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip.h:21956
#define SCIPdebugPrintCons(x, y, z)
Definition: pub_message.h:83
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip.c:1010
SCIP_RETCODE SCIPdelCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
int SCIPgetNLPBranchCands(SCIP *scip)
Definition: scip.c:36334
static SCIP_RETCODE consDropEvent(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
Definition: cons_linear.c:752
SCIP_RETCODE SCIPsetConshdlrDelvars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELVARS((*consdelvars)))
Definition: scip.c:6447
#define checkMaxActivityDelta(scip, consdata)
Definition: cons_linear.c:1461
SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:16995
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:8150
#define SCIP_EVENTTYPE_BOUNDCHANGED
Definition: type_event.h:108
static SCIP_DECL_SORTINDCOMP(consdataCompVar)
Definition: cons_linear.c:3138
SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
Definition: scip.c:6309
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
Definition: lp.c:16411
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip.c:1260
#define SCIPdebugMsgPrint
Definition: scip.h:452
#define SCIPdebugMsg
Definition: scip.h:451
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:4237
static SCIP_Real consdataGetMinAbsval(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:2232
SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip.c:18693
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
Definition: scip.c:6493
SCIP_Real SCIPgetLhsQuadratic(SCIP *scip, SCIP_CONS *cons)
#define DEFAULT_SEPARATEALL
Definition: cons_linear.c:112
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition: cons.c:7942
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip.c:1336
#define DEFAULT_MAXSEPACUTSROOT
Definition: cons_linear.c:90
int SCIPgetNContVars(SCIP *scip)
Definition: scip.c:11860
static SCIP_RETCODE addConflictFixedVars(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *infervar, SCIP_BDCHGIDX *bdchgidx, int inferpos)
Definition: cons_linear.c:4940
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:27240
SCIP_Real SCIPepsilon(SCIP *scip)
Definition: scip.c:45480
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:17909
#define CONSHDLR_PRESOLTIMING
Definition: cons_linear.c:76
SCIP_RETCODE SCIPaddConflictLb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
Definition: scip.c:26840
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
Definition: scip.c:46457
#define CONSHDLR_PROP_TIMING
Definition: cons_linear.c:77
#define MAXMULTIAGGRQUOTIENT
Definition: cons_linear.c:9347
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:2014
int SCIPgetNQuadVarTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
Definition: scip.c:46445
SCIP_Bool SCIPconsIsOriginal(SCIP_CONS *cons)
Definition: cons.c:8180
#define SCIP_EVENTTYPE_LBCHANGED
Definition: type_event.h:104
static SCIP_DECL_CONSFREE(consFreeLinear)
#define CONSHDLR_SEPAFREQ
Definition: cons_linear.c:66
SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
Definition: var.c:16985
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:16602
#define MAXCONSPRESOLROUNDS
SCIP_Bool SCIPisConflictAnalysisApplicable(SCIP *scip)
Definition: scip.c:26789
static SCIP_DECL_EVENTEXEC(eventExecLinear)
SCIP_Bool SCIPrealToRational(SCIP_Real val, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Longint *nominator, SCIP_Longint *denominator)
Definition: misc.c:8077
SCIP_Bool SCIPisLbBetter(SCIP *scip, SCIP_Real newlb, SCIP_Real oldlb, SCIP_Real oldub)
Definition: scip.c:46668
static void linconsupgradeFree(SCIP *scip, SCIP_LINCONSUPGRADE **linconsupgrade)
Definition: cons_linear.c:526
SCIP_RETCODE SCIPsetConsSeparated(SCIP *scip, SCIP_CONS *cons, SCIP_Bool separate)
Definition: scip.c:27540
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip.c:25139
static SCIP_RETCODE analyzeConflict(SCIP *scip, SCIP_CONS *cons, SCIP_Bool reasonisrhs)
Definition: cons_linear.c:5149
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:7070
SCIP_RETCODE SCIPaddClique(SCIP *scip, SCIP_VAR **vars, SCIP_Bool *values, int nvars, SCIP_Bool isequation, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip.c:23909
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17179
static SCIP_RETCODE checkParallelObjective(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata)
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip.h:21970
#define CONFLICTHDLR_NAME
Definition: cons_linear.c:82
static SCIP_RETCODE aggregateConstraints(SCIP *scip, SCIP_CONS *cons0, SCIP_CONS *cons1, int *commonidx0, int *commonidx1, int *diffidx0minus1, int *diffidx1minus0, int nvarscommon, int commonidxweight, int diffidx0minus1weight, int diffidx1minus0weight, SCIP_Real maxaggrnormscale, int *nchgcoefs, SCIP_Bool *aggregated)
SCIP_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:25478
Constraint handler for knapsack constraints of the form , x binary and .
#define DEFAULT_DETECTCUTOFFBOUND
Definition: cons_linear.c:122
static SCIP_RETCODE updateCutoffbound(SCIP *scip, SCIP_CONS *cons, SCIP_Real primalbound)
SCIP_Real SCIPeventGetNewbound(SCIP_EVENT *event)
Definition: event.c:1162
SCIP_Bool SCIPisPresolveFinished(SCIP *scip)
Definition: scip.c:1047
SCIP_Bool SCIPconsIsLocked(SCIP_CONS *cons)
Definition: cons.c:8220
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:7311
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
Definition: scip.c:6032
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:5202
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:2413
#define SCIPhashFour(a, b, c, d)
Definition: pub_misc.h:474
SCIP_Bool SCIPisSumRelLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46787
#define SCIPerrorMessage
Definition: pub_message.h:45
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4113
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:12459
#define CONSHDLR_PROPFREQ
Definition: cons_linear.c:67
SCIP_Real SCIPgetDualsolLinear(SCIP *scip, SCIP_CONS *cons)
static SCIP_DECL_QUADCONSUPGD(upgradeConsQuadratic)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:45998
SCIP_RETCODE SCIPaddConsLocal(SCIP *scip, SCIP_CONS *cons, SCIP_NODE *validnode)
Definition: scip.c:13079
static SCIP_DECL_CONSENFOLP(consEnfolpLinear)
SCIP_Bool SCIPdoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:25528
SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:13160
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:2512
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:22439
SCIP_RETCODE SCIPupgradeConsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **upgdcons)
static SCIP_DECL_CONSSEPALP(consSepalpLinear)
SCIP_RETCODE SCIPgetProbvarSum(SCIP *scip, SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: scip.c:19006
SCIP_Real * SCIPgetCoefsLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
static void consdataCalcMaxAbsval(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1337
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:23781
static INLINE uint32_t SCIPrealHashCode(double x)
Definition: pub_misc.h:488
#define DEFAULT_MULTAGGRREMOVE
Definition: cons_linear.c:140
static SCIP_RETCODE chgRhs(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
Definition: cons_linear.c:3493
static SCIP_RETCODE conshdlrdataEnsureLinconsupgradesSize(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, int num)
Definition: cons_linear.c:445
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip.c:45753
static void consdataUpdateDelCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:2059
static SCIP_RETCODE consdataSort(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:3224
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip.c:21477
static void consdataUpdateAddCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:2009
static int inferInfoGetProprule(INFERINFO inferinfo)
Definition: cons_linear.c:393
static SCIP_RETCODE consdataTightenCoefs(SCIP *scip, SCIP_CONS *cons, int *nchgcoefs, int *nchgsides)
Definition: cons_linear.c:8760
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:7881
SCIP_Real SCIPvarGetAggrConstant(SCIP_VAR *var)
Definition: var.c:16926
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:8100
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:155
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16555
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
Definition: scip.c:6057
constraint handler for quadratic constraints
SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4133
static SCIP_RETCODE addConflictReasonVars(SCIP *scip, SCIP_VAR **vars, int nvars, SCIP_VAR *var, SCIP_Real bound)
Definition: cons_linear.c:5005
#define NULL
Definition: lpi_spx1.cpp:137
SCIP_RETCODE SCIPmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:28258
static SCIP_RETCODE delCoefPos(SCIP *scip, SCIP_CONS *cons, int pos)
Definition: cons_linear.c:3769
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:5056
static int getInferInt(PROPRULE proprule, int pos)
Definition: cons_linear.c:430
#define REALABS(x)
Definition: def.h:169
SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
Definition: scip.c:4423
static SCIP_RETCODE checkPartialObjective(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata)
Definition: cons_linear.c:9977
static SCIP_RETCODE conshdlrdataIncludeUpgrade(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_LINCONSUPGRADE *linconsupgrade)
Definition: cons_linear.c:616
#define CONSHDLR_DELAYPROP
Definition: cons_linear.c:73
int SCIPconsGetNLocksPos(SCIP_CONS *cons)
Definition: cons.c:8230
int SCIPconshdlrGetPropFreq(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:5009
#define SCIP_CALL(x)
Definition: def.h:316
SCIP_Real SCIPgetLowerbound(SCIP *scip)
Definition: scip.c:42550
#define SCIP_EVENTTYPE_LBTIGHTENED
Definition: type_event.h:63
static SCIP_Bool canTightenBounds(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:5173
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46359
#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:5340
#define SCIPhashSignature64(a)
Definition: pub_misc.h:471
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:18950
SCIP_Real SCIPvarGetMultaggrConstant(SCIP_VAR *var)
Definition: var.c:16973
SCIP_RETCODE SCIPhashtableRemove(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2383
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46346
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:2312
SCIP_RETCODE SCIPanalyzeConflictCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
Definition: scip.c:27191
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip.c:1353
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8120
static SCIP_RETCODE scaleCons(SCIP *scip, SCIP_CONS *cons, SCIP_Real scalar)
Definition: cons_linear.c:3957
static SCIP_DECL_CONSINIT(consInitLinear)
SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
Definition: scip.c:6332
#define SCIPdebugGetSolVal(scip, var, val)
Definition: debug.h:265
SCIP_RETCODE SCIPaddCut(SCIP *scip, SCIP_SOL *sol, SCIP_ROW *cut, SCIP_Bool forcecut, SCIP_Bool *infeasible)
Definition: scip.c:33999
struct SCIP_ConsData SCIP_CONSDATA
Definition: type_cons.h:50
static SCIP_DECL_CONSTRANS(consTransLinear)
#define SCIP_EVENTTYPE_BOUNDTIGHTENED
Definition: type_event.h:106
static SCIP_DECL_HASHKEYVAL(hashKeyValLinearcons)
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition: scip.c:28863
#define SCIP_EVENTTYPE_UBCHANGED
Definition: type_event.h:105
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:7450
SCIP_Real SCIPgetDualfarkasLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisHugeValue(SCIP *scip, SCIP_Real val)
Definition: scip.c:46073
static void consdataUpdateChgCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real oldval, SCIP_Real newval, SCIP_Bool checkreliability)
Definition: cons_linear.c:2116
#define DEFAULT_DETECTLOWERBOUND
Definition: cons_linear.c:127
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip.c:21542
SCIP_Real SCIPgetRhsQuadratic(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE consdataPrint(SCIP *scip, SCIP_CONSDATA *consdata, FILE *file)
Definition: cons_linear.c:1093
SCIP_Bool SCIPvarIsOriginal(SCIP_VAR *var)
Definition: var.c:16684
void SCIPhashtablePrintStatistics(SCIP_HASHTABLE *hashtable, SCIP_MESSAGEHDLR *messagehdlr)
Definition: misc.c:2493
#define QUADCONSUPGD_PRIORITY
Definition: cons_linear.c:157
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:21991
public data structures and miscellaneous methods
static SCIP_RETCODE chgLhs(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
Definition: cons_linear.c:3372
SCIP_Bool SCIPisSumGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46258
SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
Definition: event.c:982
#define SCIP_Bool
Definition: def.h:61
SCIP_RETCODE SCIPchgRowRhs(SCIP *scip, SCIP_ROW *row, SCIP_Real rhs)
Definition: scip.c:30335
#define CONSHDLR_NEEDSCONS
Definition: cons_linear.c:74
#define CONSHDLR_EAGERFREQ
Definition: cons_linear.c:68
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:959
static SCIP_RETCODE performVarDeletions(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss)
Definition: cons_linear.c:4041
static const char * paramname[]
Definition: lpi_msk.c:4271
static void consdataRecomputeGlbMaxactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1311
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:30152
SCIP_Real SCIPgetLhsNonlinear(SCIP *scip, SCIP_CONS *cons)
static SCIP_Real consdataGetActivity(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol)
Definition: cons_linear.c:3004
int SCIPgetDepth(SCIP *scip)
Definition: scip.c:42321
#define MAXTIGHTENROUNDS
Definition: cons_linear.c:6899
constraint handler for nonlinear constraints
static void conshdlrdataFree(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata)
Definition: cons_linear.c:564
#define DEFAULT_SINGLEVARSTUFFING
Definition: cons_linear.c:119
static SCIP_DECL_CONSPROP(consPropLinear)
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip.c:28746
int SCIPvarGetNLocksUp(SCIP_VAR *var)
Definition: var.c:3217
#define DEFAULT_DUALPRESOLVING
Definition: cons_linear.c:117
#define MAX(x, y)
Definition: tclique_def.h:75
static SCIP_RETCODE mergeMultiples(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:4446
static SCIP_DECL_CONSDELVARS(consDelvarsLinear)
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:7901
int SCIPvarCompare(SCIP_VAR *var1, SCIP_VAR *var2)
Definition: var.c:11249
methods for debugging
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition: cons.c:8010
static SCIP_RETCODE presolStuffing(SCIP *scip, SCIP_CONS *cons, SCIP_Bool singletonstuffing, SCIP_Bool singlevarstuffing, SCIP_Bool *cutoff, int *nfixedvars, int *nchgbds)
SCIP_RETCODE SCIPchgRowLhs(SCIP *scip, SCIP_ROW *row, SCIP_Real lhs)
Definition: scip.c:30311
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8080
static void consdataUpdateActivitiesGlbLb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real oldlb, SCIP_Real newlb, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:1963
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:8050
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17017
static SCIP_Real consdataComputePseudoActivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1178
SCIP_RETCODE SCIPdropVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: scip.c:40548
SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17781
static void consdataCalcActivities(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:2250
#define NONLINCONSUPGD_PRIORITY
Definition: cons_linear.c:158
SCIP_VAR * SCIPvarGetAggrVar(SCIP_VAR *var)
Definition: var.c:16904
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:17314
static int getVarWeight(SCIP_VAR *var)
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip.c:25235
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:93
int SCIPgetNRuns(SCIP *scip)
Definition: scip.c:41326
SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
Definition: lp.c:16424
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip.c:21403
#define MAXDNOM
Definition: cons_linear.c:144
SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
Definition: scip.c:6470
#define SCIP_EVENTTYPE_UBTIGHTENED
Definition: type_event.h:65
Constraint handler for linear constraints in their most general form, .
int SCIPgetNObjVars(SCIP *scip)
Definition: scip.c:11908
SCIP_Longint SCIPgetNConflictConssApplied(SCIP *scip)
Definition: scip.c:42295
void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
Definition: misc.c:2314
SCIP_RETCODE SCIPchgRhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
Definition: var.c:16937
SCIP_Bool SCIPisSumRelGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46813
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
Definition: scip.c:46061
SCIP_Real SCIPgetRowSolActivity(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
Definition: scip.c:30843
#define DEFAULT_MAXROUNDSROOT
Definition: cons_linear.c:88
#define SCIP_EVENTTYPE_GBDCHANGED
Definition: type_event.h:103
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12080
SCIP_Real SCIPgetFeasibilityLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
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:22508
Proprule
#define DEFAULT_TIGHTENBOUNDSFREQ
Definition: cons_linear.c:86
#define SCIP_MAXTREEDEPTH
Definition: def.h:252
static SCIP_Bool needEvents(SCIP *scip)
Definition: cons_linear.c:849
int SCIPgetNBinVars(SCIP *scip)
Definition: scip.c:11725
static SCIP_RETCODE aggregateVariables(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *naggrvars, int *ndelconss)
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip.c:35163
#define DEFAULT_SIMPLIFYINEQUALITIES
Definition: cons_linear.c:116
static SCIP_RETCODE createRow(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:7287
#define MINVALRECOMP
Definition: cons_linear.c:154
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:2064
SCIP_RETCODE SCIPincludeLinconsUpgrade(SCIP *scip, SCIP_DECL_LINCONSUPGD((*linconsupgd)), int priority, const char *conshdlrname)
#define CONSHDLR_SEPAPRIORITY
Definition: cons_linear.c:63
int SCIPgetNVars(SCIP *scip)
Definition: scip.c:11680
int SCIPconsGetNUpgradeLocks(SCIP_CONS *cons)
Definition: cons.c:8272
#define SCIP_REAL_MAX
Definition: def.h:146
static void consdataGetReliableResidualActivity(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *cancelvar, SCIP_Real *resactivity, SCIP_Bool isminresact, SCIP_Bool useglobalbounds)
Definition: cons_linear.c:2558
static void consdataRecomputeMaxactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1258
SCIP_RETCODE SCIPwriteVarsLinearsum(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Bool type)
Definition: scip.c:17543
SCIP_RETCODE SCIPupdateLocalLowerbound(SCIP *scip, SCIP_Real newbound)
Definition: scip.c:13382
static SCIP_DECL_CONSENFORELAX(consEnforelaxLinear)
#define MAXSCALEDCOEFINTEGER
Definition: cons_linear.c:146
static SCIP_DECL_CONSCHECK(consCheckLinear)
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPsetConshdlrExitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITPRE((*consexitpre)))
Definition: scip.c:6201
static SCIP_RETCODE conshdlrdataCreate(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linear.c:540
static void consdataCalcSignatures(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:3118
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition: scip.c:30290
int SCIPgetNLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
static SCIP_DECL_CONSPARSE(consParseLinear)
static SCIP_RETCODE analyzeConflictRangedRow(SCIP *scip, SCIP_CONS *cons, SCIP_VAR **vars, int nvars, SCIP_VAR *var, SCIP_Real bound)
Definition: cons_linear.c:5600
static SCIP_RETCODE lockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
Definition: cons_linear.c:648
static SCIP_DECL_CONSGETVARS(consGetVarsLinear)
int SCIPvarGetNLocksDown(SCIP_VAR *var)
Definition: var.c:3162
void SCIPsort(int *perm, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
Definition: misc.c:4652
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46024
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:2639
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
Definition: scip.c:46134
static SCIP_RETCODE fullDualPresolve(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool *cutoff, int *nchgbds)
int SCIPgetNLinearVarsNonlinear(SCIP *scip, SCIP_CONS *cons)
static const SCIP_Real scalars[]
Definition: lp.c:5573
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:1912
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:11360
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition: cons.c:7911
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:22621
SCIP_RETCODE SCIPsetConshdlrInit(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINIT((*consinit)))
Definition: scip.c:6081
#define CONTWEIGHT
SCIP_Real SCIPgetHugeValue(SCIP *scip)
Definition: scip.c:46087
static SCIP_DECL_CONSLOCK(consLockLinear)
SCIP_RETCODE SCIPsetConsEnforced(SCIP *scip, SCIP_CONS *cons, SCIP_Bool enforce)
Definition: scip.c:27565
static void consdataCheckNonbinvar(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1390
static SCIP_RETCODE consCatchAllEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linear.c:786
SCIP_RETCODE SCIPsetConshdlrExit(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXIT((*consexit)))
Definition: scip.c:6105
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:7711
SCIP_Bool SCIPisConsCompressionEnabled(SCIP *scip)
Definition: scip.c:1862
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip.c:27417
static SCIP_DECL_CONSPRINT(consPrintLinear)
static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinear)
SCIP_Bool SCIPallowDualReds(SCIP *scip)
Definition: scip.c:25541
const char * SCIPconflicthdlrGetName(SCIP_CONFLICTHDLR *conflicthdlr)
Definition: conflict.c:714
SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
Definition: scip.c:6225
SCIP_Real SCIPeventGetOldbound(SCIP_EVENT *event)
Definition: event.c:1138
SCIP_Bool SCIPisFeasPositive(SCIP *scip, SCIP_Real val)
Definition: scip.c:46397
static SCIP_RETCODE convertBinaryEquality(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *naggrvars, int *ndelconss)
Definition: cons_linear.c:9243
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip.c:11635
static SCIP_DECL_HASHKEYEQ(hashKeyEqLinearcons)
#define CONFLICTHDLR_DESC
Definition: cons_linear.c:83
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16674
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:25344
static SCIP_RETCODE normalizeCons(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:4100
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:18427
#define SCIP_Real
Definition: def.h:145
static SCIP_RETCODE tightenBounds(SCIP *scip, SCIP_CONS *cons, SCIP_Real maxeasyactivitydelta, SCIP_Bool sortvars, SCIP_Bool *cutoff, int *nchgbds)
Definition: cons_linear.c:6903
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8130
SCIP_RETCODE SCIPaddVarsToRow(SCIP *scip, SCIP_ROW *row, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip.c:30444
SCIP_VAR ** SCIPgetLinearVarsNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip.c:1138
#define SCIP_EVENTTYPE_VARUNLOCKED
Definition: type_event.h:59
static void getNewSidesAfterAggregation(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *slackvar, SCIP_Real slackcoef, SCIP_Real *newlhs, SCIP_Real *newrhs)
Definition: cons_linear.c:9301
#define DEFAULT_SINGLETONSTUFFING
Definition: cons_linear.c:118
#define MIN(x, y)
Definition: memory.c:75
SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETNVARS((*consgetnvars)))
Definition: scip.c:6539
#define EVENTHDLR_NAME
Definition: cons_linear.c:79
SCIP_Bool SCIPisScalingIntegral(SCIP *scip, SCIP_Real val, SCIP_Real scalar)
Definition: scip.c:46146
#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:4517
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:8070
SCIP_Bool SCIPdoNotAggr(SCIP *scip)
Definition: scip.c:25508
#define SCIP_INVALID
Definition: def.h:165
#define DEFAULT_RANGEDROWPROPAGATION
Definition: cons_linear.c:135
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8060
SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
Definition: scip.c:30892
static SCIP_RETCODE addCoef(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
Definition: cons_linear.c:3615
static SCIP_DECL_CONFLICTEXEC(conflictExecLinear)
#define CONSHDLR_DESC
Definition: cons_linear.c:62
SCIP_Real SCIPcutoffbounddelta(SCIP *scip)
Definition: scip.c:45564
#define SCIP_Longint
Definition: def.h:130
SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
Definition: var.c:17281
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:16852
SCIP_Real SCIPgetRowSolFeasibility(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
Definition: scip.c:30866
static SCIP_RETCODE consdataEnsureVarsSize(SCIP *scip, SCIP_CONSDATA *consdata, int num)
Definition: cons_linear.c:470
#define SCIPdebugAddSolVal(scip, var, val)
Definition: debug.h:264
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:16720
static SCIP_DECL_NONLINCONSUPGD(upgradeConsNonlinear)
#define MAX_CLIQUE_NONZEROS_PER_CONS
Definition: cons_linear.c:7644
static void consdataRecomputeGlbMinactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1285
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
Definition: scip.c:46098
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46011
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:60
static SCIP_RETCODE convertLongEquality(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_CONS *cons, SCIP_Bool *cutoff, int *naggrvars, int *ndelconss)
Definition: cons_linear.c:9357
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition: type_cons.h:49
SCIP_RETCODE SCIPchgLhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17235
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip.h:21976
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
Definition: scip.c:46421
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:16697
static int inferInfoToInt(INFERINFO inferinfo)
Definition: cons_linear.c:384
SCIP_Bool SCIPconsIsMarkedPropagate(SCIP_CONS *cons)
Definition: cons.c:8090
#define MAXVALRECOMP
Definition: cons_linear.c:153
static SCIP_RETCODE unlockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
Definition: cons_linear.c:681
static SCIP_DECL_CONSPRESOL(consPresolLinear)
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:89
#define DEFAULT_MAXEASYACTIVITYDELTA
Definition: cons_linear.c:106
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:396
SCIP_EXPRGRAPHNODE * SCIPgetExprgraphNodeNonlinear(SCIP *scip, SCIP_CONS *cons)
#define SCIP_EVENTTYPE_GUBCHANGED
Definition: type_event.h:62
SCIP_RETCODE SCIPaddConflict(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons, SCIP_NODE *validnode, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
Definition: scip.c:12915
static SCIP_RETCODE enforceConstraint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss, int nusefulconss, SCIP_SOL *sol, SCIP_RESULT *result)
static SCIP_DECL_CONSGETNVARS(consGetNVarsLinear)
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
Definition: scip.c:46183
static SCIP_DECL_CONSEXIT(consExitLinear)
#define DEFAULT_RANGEDROWMAXDEPTH
Definition: cons_linear.c:137
SCIP_RETCODE SCIPsetConshdlrExitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITSOL((*consexitsol)))
Definition: scip.c:6153
#define SCIPcombineTwoInt(a, b)
Definition: pub_misc.h:478
#define SCIPABORT()
Definition: def.h:288
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:16746
SCIP_Longint SCIPcalcGreComDiv(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:7945
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip.c:38182
SCIP_Bool SCIPvarIsDeleted(SCIP_VAR *var)
Definition: var.c:16776
static INFERINFO intToInferInfo(int i)
Definition: cons_linear.c:371
SCIP_RETCODE SCIPaddObjoffset(SCIP *scip, SCIP_Real addval)
Definition: scip.c:10960
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
#define INTWEIGHT
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
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:4293
static SCIP_RETCODE addConflictBounds(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *infervar, SCIP_BDCHGIDX *bdchgidx, int inferpos, SCIP_Bool reasonisrhs)
Definition: cons_linear.c:4758
SCIP_Longint SCIPcalcSmaComMul(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:8056
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
Definition: scip.c:46171
#define SCIP_EVENTTYPE_VARDELETED
Definition: type_event.h:57
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:1913
SCIP_RETCODE SCIPseparateRelaxedKnapsack(SCIP *scip, SCIP_CONS *cons, SCIP_SEPA *sepa, int nknapvars, SCIP_VAR **knapvars, SCIP_Real *knapvals, SCIP_Real valscale, SCIP_Real rhs, SCIP_SOL *sol, SCIP_Bool *cutoff, int *ncuts)
SCIP_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:4211
int SCIPgetNSepaRounds(SCIP *scip)
Definition: scip.c:42160
#define DEFAULT_PRESOLUSEHASHING
Definition: cons_linear.c:92
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:16842
#define HASHSIZE_LINEARCONS
Definition: cons_linear.c:152
SCIP_RETCODE SCIPchgCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:16710
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:1938
static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata)
Definition: cons_linear.c:1058
uint64_t SCIP_EVENTTYPE
Definition: type_event.h:134
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip.h:21995
SCIP_RETCODE SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
Definition: scip.c:5966
SCIP_RETCODE SCIPsetConsInitial(SCIP *scip, SCIP_CONS *cons, SCIP_Bool initial)
Definition: scip.c:27515
#define SCIP_EVENTTYPE_BOUNDRELAXED
Definition: type_event.h:107
#define DEFAULT_RANGEDROWARTCONS
Definition: cons_linear.c:136
static SCIP_RETCODE dualPresolve(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *naggrvars, int *ndelconss)