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 2002-2022 Zuse Institute Berlin */
7 /* */
8 /* Licensed under the Apache License, Version 2.0 (the "License"); */
9 /* you may not use this file except in compliance with the License. */
10 /* You may obtain a copy of the License at */
11 /* */
12 /* http://www.apache.org/licenses/LICENSE-2.0 */
13 /* */
14 /* Unless required by applicable law or agreed to in writing, software */
15 /* distributed under the License is distributed on an "AS IS" BASIS, */
16 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17 /* See the License for the specific language governing permissions and */
18 /* limitations under the License. */
19 /* */
20 /* You should have received a copy of the Apache-2.0 license */
21 /* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22 /* */
23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24 
25 /**@file cons_linear.c
26  * @ingroup DEFPLUGINS_CONS
27  * @brief Constraint handler for linear constraints in their most general form, \f$lhs <= a^T x <= rhs\f$.
28  * @author Tobias Achterberg
29  * @author Timo Berthold
30  * @author Marc Pfetsch
31  * @author Kati Wolter
32  * @author Michael Winkler
33  * @author Gerald Gamrath
34  * @author Domenico Salvagnin
35  *
36  * Linear constraints are separated with a high priority, because they are easy
37  * to separate. Instead of using the global cut pool, the same effect can be
38  * implemented by adding linear constraints to the root node, such that they are
39  * separated each time, the linear constraints are separated. A constraint
40  * handler, which generates linear constraints in this way should have a lower
41  * separation priority than the linear constraint handler, and it should have a
42  * separation frequency that is a multiple of the frequency of the linear
43  * constraint handler. In this way, it can be avoided to separate the same cut
44  * twice, because if a separation run of the handler is always preceded by a
45  * separation of the linear constraints, the priorily added constraints are
46  * always satisfied.
47  *
48  * Linear constraints are enforced and checked with a very low priority. Checking
49  * of (many) linear constraints is much more involved than checking the solution
50  * values for integrality. Because we are separating the linear constraints quite
51  * often, it is only necessary to enforce them for integral solutions. A constraint
52  * handler which generates pool cuts in its enforcing method should have an
53  * enforcing priority smaller than that of the linear constraint handler to avoid
54  * regenerating constraints which already exist.
55  */
56 
57 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
58 
59 #include "blockmemshell/memory.h"
60 #include "scip/cons_nonlinear.h"
61 #include "scip/cons_knapsack.h"
62 #include "scip/cons_linear.h"
63 #include "scip/debug.h"
64 #include "scip/pub_conflict.h"
65 #include "scip/pub_cons.h"
66 #include "scip/pub_event.h"
67 #include "scip/pub_expr.h"
68 #include "scip/pub_lp.h"
69 #include "scip/pub_message.h"
70 #include "scip/pub_misc.h"
71 #include "scip/pub_misc_sort.h"
72 #include "scip/pub_var.h"
73 #include "scip/scip_branch.h"
74 #include "scip/scip_conflict.h"
75 #include "scip/scip_cons.h"
76 #include "scip/scip_copy.h"
77 #include "scip/scip_cut.h"
78 #include "scip/scip_event.h"
79 #include "scip/scip_general.h"
80 #include "scip/scip_lp.h"
81 #include "scip/scip_mem.h"
82 #include "scip/scip_message.h"
83 #include "scip/scip_numerics.h"
84 #include "scip/scip_param.h"
85 #include "scip/scip_prob.h"
86 #include "scip/scip_probing.h"
87 #include "scip/scip_sol.h"
88 #include "scip/scip_solvingstats.h"
89 #include "scip/scip_tree.h"
90 #include "scip/scip_var.h"
91 #include <ctype.h>
92 #include <string.h>
93 #if defined(_WIN32) || defined(_WIN64)
94 #else
95 #include <strings.h> /*lint --e{766}*/
96 #endif
97 
98 
99 #define CONSHDLR_NAME "linear"
100 #define CONSHDLR_DESC "linear constraints of the form lhs <= a^T x <= rhs"
101 #define CONSHDLR_SEPAPRIORITY +100000 /**< priority of the constraint handler for separation */
102 #define CONSHDLR_ENFOPRIORITY -1000000 /**< priority of the constraint handler for constraint enforcing */
103 #define CONSHDLR_CHECKPRIORITY -1000000 /**< priority of the constraint handler for checking feasibility */
104 #define CONSHDLR_SEPAFREQ 0 /**< frequency for separating cuts; zero means to separate only in the root node */
105 #define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
106 #define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
107  * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
108 #define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
109 #define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
110 #define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
111 #define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
113 #define CONSHDLR_PRESOLTIMING (SCIP_PRESOLTIMING_FAST | SCIP_PRESOLTIMING_EXHAUSTIVE) /**< presolving timing of the constraint handler (fast, medium, or exhaustive) */
114 #define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP
116 #define EVENTHDLR_NAME "linear"
117 #define EVENTHDLR_DESC "bound change event handler for linear constraints"
119 #define CONFLICTHDLR_NAME "linear"
120 #define CONFLICTHDLR_DESC "conflict handler creating linear constraints"
121 #define CONFLICTHDLR_PRIORITY -1000000
123 #define DEFAULT_TIGHTENBOUNDSFREQ 1 /**< multiplier on propagation frequency, how often the bounds are tightened */
124 #define DEFAULT_MAXROUNDS 5 /**< maximal number of separation rounds per node (-1: unlimited) */
125 #define DEFAULT_MAXROUNDSROOT -1 /**< maximal number of separation rounds in the root node (-1: unlimited) */
126 #define DEFAULT_MAXSEPACUTS 50 /**< maximal number of cuts separated per separation round */
127 #define DEFAULT_MAXSEPACUTSROOT 200 /**< maximal number of cuts separated per separation round in root node */
128 #define DEFAULT_PRESOLPAIRWISE TRUE /**< should pairwise constraint comparison be performed in presolving? */
129 #define DEFAULT_PRESOLUSEHASHING TRUE /**< should hash table be used for detecting redundant constraints in advance */
130 #define DEFAULT_NMINCOMPARISONS 200000 /**< number for minimal pairwise presolving comparisons */
131 #define DEFAULT_MINGAINPERNMINCOMP 1e-06 /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise
132  * comparison round */
133 #define DEFAULT_SORTVARS TRUE /**< should variables be sorted after presolve w.r.t their coefficient absolute for faster
134  * propagation? */
135 #define DEFAULT_CHECKRELMAXABS FALSE /**< should the violation for a constraint with side 0.0 be checked relative
136  * to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
137 #define DEFAULT_MAXAGGRNORMSCALE 0.0 /**< maximal allowed relative gain in maximum norm for constraint aggregation
138  * (0.0: disable constraint aggregation) */
139 #define DEFAULT_MAXEASYACTIVITYDELTA 1e6 /**< maximum activity delta to run easy propagation on linear constraint
140  * (faster, but numerically less stable) */
141 #define DEFAULT_MAXCARDBOUNDDIST 0.0 /**< maximal relative distance from current node's dual bound to primal bound compared
142  * to best node's dual bound for separating knapsack cardinality cuts */
143 #define DEFAULT_SEPARATEALL FALSE /**< should all constraints be subject to cardinality cut generation instead of only
144  * the ones with non-zero dual value? */
145 #define DEFAULT_AGGREGATEVARIABLES TRUE /**< should presolving search for redundant variables in equations */
146 #define DEFAULT_SIMPLIFYINEQUALITIES TRUE /**< should presolving try to simplify inequalities */
147 #define DEFAULT_DUALPRESOLVING TRUE /**< should dual presolving steps be performed? */
148 #define DEFAULT_SINGLETONSTUFFING TRUE /**< should stuffing of singleton continuous variables be performed? */
149 #define DEFAULT_SINGLEVARSTUFFING FALSE /**< should single variable stuffing be performed, which tries to fulfill
150  * constraints using the cheapest variable? */
151 #define DEFAULT_DETECTCUTOFFBOUND TRUE /**< should presolving try to detect constraints parallel to the objective
152  * function defining an upper bound and prevent these constraints from
153  * entering the LP */
154 #define DEFAULT_DETECTLOWERBOUND TRUE /**< should presolving try to detect constraints parallel to the objective
155  * function defining a lower bound and prevent these constraints from
156  * entering the LP */
157 #define DEFAULT_DETECTPARTIALOBJECTIVE TRUE/**< should presolving try to detect subsets of constraints parallel to the
158  * objective function */
159 #define DEFAULT_RANGEDROWPROPAGATION TRUE /**< should we perform ranged row propagation */
160 #define DEFAULT_RANGEDROWARTCONS TRUE /**< should presolving and propagation extract sub-constraints from ranged rows and equations? */
161 #define DEFAULT_RANGEDROWMAXDEPTH INT_MAX /**< maximum depth to apply ranged row propagation */
162 #define DEFAULT_RANGEDROWFREQ 1 /**< frequency for applying ranged row propagation */
163 
164 #define DEFAULT_MULTAGGRREMOVE FALSE /**< should multi-aggregations only be performed if the constraint can be
165  * removed afterwards? */
166 #define DEFAULT_MAXMULTAGGRQUOT 1e+03 /**< maximum coefficient dynamism (ie. maxabsval / minabsval) for multiaggregation */
167 #define DEFAULT_MAXDUALMULTAGGRQUOT 1e+20 /**< maximum coefficient dynamism (ie. maxabsval / minabsval) for multiaggregation */
168 #define DEFAULT_EXTRACTCLIQUES TRUE /**< should cliques be extracted? */
169 
170 #define MAXDNOM 10000LL /**< maximal denominator for simple rational fixed values */
171 #define MAXSCALEDCOEF 0 /**< maximal coefficient value after scaling */
172 #define MAXSCALEDCOEFINTEGER 0 /**< maximal coefficient value after scaling if all variables are of integral
173  * type
174  */
175 #define MAXACTVAL 1e+09 /**< maximal absolute value of full and partial activities such that
176  * redundancy-based simplifications are allowed to be applied
177  */
179 #define MAXVALRECOMP 1e+06 /**< maximal abolsute value we trust without recomputing the activity */
180 #define MINVALRECOMP 1e-05 /**< minimal abolsute value we trust without recomputing the activity */
183 #define NONLINCONSUPGD_PRIORITY 1000000 /**< priority of the constraint handler for upgrading of expressions constraints */
184 
185 /* @todo add multi-aggregation of variables that are in exactly two equations (, if not numerically an issue),
186  * maybe in fullDualPresolve(), see convertLongEquality()
187  */
188 
189 
190 /** constraint data for linear constraints */
191 struct SCIP_ConsData
192 {
193  SCIP_Real lhs; /**< left hand side of row (for ranged rows) */
194  SCIP_Real rhs; /**< right hand side of row */
195  SCIP_Real maxabsval; /**< maximum absolute value of all coefficients */
196  SCIP_Real minabsval; /**< minimal absolute value of all coefficients */
197  SCIP_Real minactivity; /**< minimal value w.r.t. the variable's local bounds for the constraint's
198  * activity, ignoring the coefficients contributing with infinite value */
199  SCIP_Real maxactivity; /**< maximal value w.r.t. the variable's local bounds for the constraint's
200  * activity, ignoring the coefficients contributing with infinite value */
201  SCIP_Real lastminactivity; /**< last minimal activity which was computed by complete summation
202  * over all contributing values */
203  SCIP_Real lastmaxactivity; /**< last maximal activity which was computed by complete summation
204  * over all contributing values */
205  SCIP_Real glbminactivity; /**< minimal value w.r.t. the variable's global bounds for the constraint's
206  * activity, ignoring the coefficients contributing with infinite value */
207  SCIP_Real glbmaxactivity; /**< maximal value w.r.t. the variable's global bounds for the constraint's
208  * activity, ignoring the coefficients contributing with infinite value */
209  SCIP_Real lastglbminactivity; /**< last global minimal activity which was computed by complete summation
210  * over all contributing values */
211  SCIP_Real lastglbmaxactivity; /**< last global maximal activity which was computed by complete summation
212  * over all contributing values */
213  SCIP_Real maxactdelta; /**< maximal activity contribution of a single variable, or SCIP_INVALID if invalid */
214  SCIP_VAR* maxactdeltavar; /**< variable with maximal activity contribution, or NULL if invalid */
215  uint64_t possignature; /**< bit signature of coefficients that may take a positive value */
216  uint64_t negsignature; /**< bit signature of coefficients that may take a negative value */
217  SCIP_ROW* row; /**< LP row, if constraint is already stored in LP row format */
218  SCIP_NLROW* nlrow; /**< NLP row, if constraint has been added to NLP relaxation */
219  SCIP_VAR** vars; /**< variables of constraint entries */
220  SCIP_Real* vals; /**< coefficients of constraint entries */
221  SCIP_EVENTDATA** eventdata; /**< event data for bound change events of the variables */
222  int minactivityneginf; /**< number of coefficients contributing with neg. infinite value to minactivity */
223  int minactivityposinf; /**< number of coefficients contributing with pos. infinite value to minactivity */
224  int maxactivityneginf; /**< number of coefficients contributing with neg. infinite value to maxactivity */
225  int maxactivityposinf; /**< number of coefficients contributing with pos. infinite value to maxactivity */
226  int minactivityneghuge; /**< number of coefficients contributing with huge neg. value to minactivity */
227  int minactivityposhuge; /**< number of coefficients contributing with huge pos. value to minactivity */
228  int maxactivityneghuge; /**< number of coefficients contributing with huge neg. value to maxactivity */
229  int maxactivityposhuge; /**< number of coefficients contributing with huge pos. value to maxactivity */
230  int glbminactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbminactivity */
231  int glbminactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbminactivity */
232  int glbmaxactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbmaxactivity */
233  int glbmaxactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbmaxactivity */
234  int glbminactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbminactivity */
235  int glbminactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbminactivity */
236  int glbmaxactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbmaxactivity */
237  int glbmaxactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbmaxactivity */
238  int varssize; /**< size of the vars- and vals-arrays */
239  int nvars; /**< number of nonzeros in constraint */
240  int nbinvars; /**< the number of binary variables in the constraint, only valid after
241  * sorting in stage >= SCIP_STAGE_INITSOLVE
242  */
243  unsigned int boundstightened:2; /**< is constraint already propagated with bound tightening? */
244  unsigned int rangedrowpropagated:2; /**< did we perform ranged row propagation on this constraint?
245  * (0: no, 1: yes, 2: with potentially adding artificial constraint */
246  unsigned int validmaxabsval:1; /**< is the maximum absolute value valid? */
247  unsigned int validminabsval:1; /**< is the minimum absolute value valid? */
248  unsigned int validactivities:1; /**< are the activity bounds (local and global) valid? */
249  unsigned int validminact:1; /**< is the local minactivity valid? */
250  unsigned int validmaxact:1; /**< is the local maxactivity valid? */
251  unsigned int validglbminact:1; /**< is the global minactivity valid? */
252  unsigned int validglbmaxact:1; /**< is the global maxactivity valid? */
253  unsigned int presolved:1; /**< is constraint already presolved? */
254  unsigned int removedfixings:1; /**< are all fixed variables removed from the constraint? */
255  unsigned int validsignature:1; /**< is the bit signature valid? */
256  unsigned int changed:1; /**< was constraint changed since last aggregation round in preprocessing? */
257  unsigned int normalized:1; /**< is the constraint in normalized form? */
258  unsigned int upgradetried:1; /**< was the constraint already tried to be upgraded? */
259  unsigned int upgraded:1; /**< is the constraint upgraded and will it be removed after preprocessing? */
260  unsigned int indexsorted:1; /**< are the constraint's variables sorted by type and index? */
261  unsigned int merged:1; /**< are the constraint's equal variables already merged? */
262  unsigned int cliquesadded:1; /**< were the cliques of the constraint already extracted? */
263  unsigned int implsadded:1; /**< were the implications of the constraint already extracted? */
264  unsigned int coefsorted:1; /**< are variables sorted by type and their absolute activity delta? */
265  unsigned int varsdeleted:1; /**< were variables deleted after last cleanup? */
266  unsigned int hascontvar:1; /**< does the constraint contain at least one continuous variable? */
267  unsigned int hasnonbinvar:1; /**< does the constraint contain at least one non-binary variable? */
268  unsigned int hasnonbinvalid:1; /**< is the information stored in hasnonbinvar and hascontvar valid? */
269  unsigned int checkabsolute:1; /**< should the constraint be checked w.r.t. an absolute feasibilty tolerance? */
270 };
271 
272 /** event data for bound change event */
273 struct SCIP_EventData
274 {
275  SCIP_CONS* cons; /**< linear constraint to process the bound change for */
276  int varpos; /**< position of variable in vars array */
277  int filterpos; /**< position of event in variable's event filter */
278 };
279 
280 /** constraint handler data */
281 struct SCIP_ConshdlrData
282 {
283  SCIP_EVENTHDLR* eventhdlr; /**< event handler for bound change events */
284  SCIP_LINCONSUPGRADE** linconsupgrades; /**< linear constraint upgrade methods for specializing linear constraints */
285  SCIP_Real maxaggrnormscale; /**< maximal allowed relative gain in maximum norm for constraint aggregation
286  * (0.0: disable constraint aggregation) */
287  SCIP_Real maxcardbounddist; /**< maximal relative distance from current node's dual bound to primal bound compared
288  * to best node's dual bound for separating knapsack cardinality cuts */
289  SCIP_Real mingainpernmincomp; /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise comparison round */
290  SCIP_Real maxeasyactivitydelta;/**< maximum activity delta to run easy propagation on linear constraint
291  * (faster, but numerically less stable) */
292  int linconsupgradessize;/**< size of linconsupgrade array */
293  int nlinconsupgrades; /**< number of linear constraint upgrade methods */
294  int tightenboundsfreq; /**< multiplier on propagation frequency, how often the bounds are tightened */
295  int maxrounds; /**< maximal number of separation rounds per node (-1: unlimited) */
296  int maxroundsroot; /**< maximal number of separation rounds in the root node (-1: unlimited) */
297  int maxsepacuts; /**< maximal number of cuts separated per separation round */
298  int maxsepacutsroot; /**< maximal number of cuts separated per separation round in root node */
299  int nmincomparisons; /**< number for minimal pairwise presolving comparisons */
300  int naddconss; /**< number of added constraints */
301  SCIP_Bool presolpairwise; /**< should pairwise constraint comparison be performed in presolving? */
302  SCIP_Bool presolusehashing; /**< should hash table be used for detecting redundant constraints in advance */
303  SCIP_Bool separateall; /**< should all constraints be subject to cardinality cut generation instead of only
304  * the ones with non-zero dual value? */
305  SCIP_Bool aggregatevariables; /**< should presolving search for redundant variables in equations */
306  SCIP_Bool simplifyinequalities;/**< should presolving try to cancel down or delete coefficients in inequalities */
307  SCIP_Bool dualpresolving; /**< should dual presolving steps be performed? */
308  SCIP_Bool singletonstuffing; /**< should stuffing of singleton continuous variables be performed? */
309  SCIP_Bool singlevarstuffing; /**< should single variable stuffing be performed, which tries to fulfill
310  * constraints using the cheapest variable? */
311  SCIP_Bool sortvars; /**< should binary variables be sorted for faster propagation? */
312  SCIP_Bool checkrelmaxabs; /**< should the violation for a constraint with side 0.0 be checked relative
313  * to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
314  SCIP_Bool detectcutoffbound; /**< should presolving try to detect constraints parallel to the objective
315  * function defining an upper bound and prevent these constraints from
316  * entering the LP */
317  SCIP_Bool detectlowerbound; /**< should presolving try to detect constraints parallel to the objective
318  * function defining a lower bound and prevent these constraints from
319  * entering the LP */
320  SCIP_Bool detectpartialobjective;/**< should presolving try to detect subsets of constraints parallel to
321  * the objective function */
322  SCIP_Bool rangedrowpropagation;/**< should presolving and propagation try to improve bounds, detect
323  * infeasibility, and extract sub-constraints from ranged rows and
324  * equations */
325  SCIP_Bool rangedrowartcons; /**< should presolving and propagation extract sub-constraints from ranged rows and equations?*/
326  int rangedrowmaxdepth; /**< maximum depth to apply ranged row propagation */
327  int rangedrowfreq; /**< frequency for applying ranged row propagation */
328  SCIP_Bool multaggrremove; /**< should multi-aggregations only be performed if the constraint can be
329  * removed afterwards? */
330  SCIP_Real maxmultaggrquot; /**< maximum coefficient dynamism (ie. maxabsval / minabsval) for primal multiaggregation */
331  SCIP_Real maxdualmultaggrquot;/**< maximum coefficient dynamism (ie. maxabsval / minabsval) for dual multiaggregation */
332  SCIP_Bool extractcliques; /**< should cliques be extracted? */
333 };
334 
335 /** linear constraint update method */
336 struct SCIP_LinConsUpgrade
337 {
338  SCIP_DECL_LINCONSUPGD((*linconsupgd)); /**< method to call for upgrading linear constraint */
339  int priority; /**< priority of upgrading method */
340  SCIP_Bool active; /**< is upgrading enabled */
341 };
342 
343 
344 /*
345  * Propagation rules
346  */
347 
348 enum Proprule
349 {
350  PROPRULE_1_RHS = 1, /**< activity residuals of all other variables tighten bounds of single
351  * variable due to the right hand side of the inequality */
352  PROPRULE_1_LHS = 2, /**< activity residuals of all other variables tighten bounds of single
353  * variable due to the left hand side of the inequality */
354  PROPRULE_1_RANGEDROW = 3, /**< fixed variables and gcd of all left variables tighten bounds of a
355  * single variable in this reanged row */
356  PROPRULE_INVALID = 0 /**< propagation was applied without a specific propagation rule */
357 };
358 typedef enum Proprule PROPRULE;
360 /** inference information */
361 struct InferInfo
362 {
363  union
364  {
365  struct
366  {
367  unsigned int proprule:8; /**< propagation rule that was applied */
368  unsigned int pos:24; /**< variable position, the propagation rule was applied at */
369  } asbits;
370  int asint; /**< inference information as a single int value */
371  } val;
372 };
373 typedef struct InferInfo INFERINFO;
374 
375 /** converts an integer into an inference information */
376 static
378  int i /**< integer to convert */
379  )
380 {
381  INFERINFO inferinfo;
382 
383  inferinfo.val.asint = i;
384 
385  return inferinfo;
386 }
387 
388 /** converts an inference information into an int */
389 static
390 int inferInfoToInt(
391  INFERINFO inferinfo /**< inference information to convert */
392  )
393 {
394  return inferinfo.val.asint;
395 }
397 /** returns the propagation rule stored in the inference information */
398 static
400  INFERINFO inferinfo /**< inference information to convert */
401  )
402 {
403  return (int) inferinfo.val.asbits.proprule;
404 }
405 
406 /** returns the position stored in the inference information */
407 static
408 int inferInfoGetPos(
409  INFERINFO inferinfo /**< inference information to convert */
410  )
411 {
412  return (int) inferinfo.val.asbits.pos;
413 }
414 
415 /** constructs an inference information out of a propagation rule and a position number */
416 static
418  PROPRULE proprule, /**< propagation rule that deduced the value */
419  int pos /**< variable position, the propagation rule was applied at */
420  )
421 {
422  INFERINFO inferinfo;
423 
424  assert(pos >= 0);
425  /* in the inferinfo struct only 24 bits for 'pos' are reserved */
426  assert(pos < (1<<24));
428  inferinfo.val.asbits.proprule = (unsigned int) proprule; /*lint !e641*/
429  inferinfo.val.asbits.pos = (unsigned int) pos; /*lint !e732*/
430 
431  return inferinfo;
432 }
433 
434 /** constructs an inference information out of a propagation rule and a position number, returns info as int */
435 static
437  PROPRULE proprule, /**< propagation rule that deduced the value */
438  int pos /**< variable position, the propagation rule was applied at */
439  )
440 {
441  return inferInfoToInt(getInferInfo(proprule, pos));
442 }
443 
444 
445 /*
446  * memory growing methods for dynamically allocated arrays
447  */
448 
449 /** ensures, that linconsupgrades array can store at least num entries */
450 static
452  SCIP* scip, /**< SCIP data structure */
453  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
454  int num /**< minimum number of entries to store */
455  )
456 {
457  assert(scip != NULL);
458  assert(conshdlrdata != NULL);
459  assert(conshdlrdata->nlinconsupgrades <= conshdlrdata->linconsupgradessize);
460 
461  if( num > conshdlrdata->linconsupgradessize )
462  {
463  int newsize;
464 
465  newsize = SCIPcalcMemGrowSize(scip, num);
466  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &conshdlrdata->linconsupgrades, conshdlrdata->linconsupgradessize, newsize) );
467  conshdlrdata->linconsupgradessize = newsize;
468  }
469  assert(num <= conshdlrdata->linconsupgradessize);
471  return SCIP_OKAY;
472 }
473 
474 /** ensures, that vars and vals arrays can store at least num entries */
475 static
477  SCIP* scip, /**< SCIP data structure */
478  SCIP_CONSDATA* consdata, /**< linear constraint data */
479  int num /**< minimum number of entries to store */
480  )
481 {
482  assert(scip != NULL);
483  assert(consdata != NULL);
484  assert(consdata->nvars <= consdata->varssize);
485 
486  if( num > consdata->varssize )
487  {
488  int newsize;
489 
490  newsize = SCIPcalcMemGrowSize(scip, num);
491  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vars, consdata->varssize, newsize) );
492  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vals, consdata->varssize, newsize) );
493  if( consdata->eventdata != NULL )
494  {
495  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize, newsize) );
496  }
497  consdata->varssize = newsize;
498  }
499  assert(num <= consdata->varssize);
500 
501  return SCIP_OKAY;
502 }
503 
504 
505 /*
506  * local methods for managing linear constraint update methods
507  */
508 
509 /** creates a linear constraint upgrade data object */
510 static
512  SCIP* scip, /**< SCIP data structure */
513  SCIP_LINCONSUPGRADE** linconsupgrade, /**< pointer to store the linear constraint upgrade */
514  SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
515  int priority /**< priority of upgrading method */
516  )
517 {
518  assert(scip != NULL);
519  assert(linconsupgrade != NULL);
520  assert(linconsupgd != NULL);
521 
522  SCIP_CALL( SCIPallocBlockMemory(scip, linconsupgrade) );
523  (*linconsupgrade)->linconsupgd = linconsupgd;
524  (*linconsupgrade)->priority = priority;
525  (*linconsupgrade)->active = TRUE;
526 
527  return SCIP_OKAY;
528 }
529 
530 /** frees a linear constraint upgrade data object */
531 static
532 void linconsupgradeFree(
533  SCIP* scip, /**< SCIP data structure */
534  SCIP_LINCONSUPGRADE** linconsupgrade /**< pointer to the linear constraint upgrade */
535  )
536 {
537  assert(scip != NULL);
538  assert(linconsupgrade != NULL);
539  assert(*linconsupgrade != NULL);
540 
541  SCIPfreeBlockMemory(scip, linconsupgrade);
542 }
543 
544 /** creates constraint handler data for linear constraint handler */
545 static
547  SCIP* scip, /**< SCIP data structure */
548  SCIP_CONSHDLRDATA** conshdlrdata, /**< pointer to store the constraint handler data */
549  SCIP_EVENTHDLR* eventhdlr /**< event handler */
550  )
551 {
552  assert(scip != NULL);
553  assert(conshdlrdata != NULL);
554  assert(eventhdlr != NULL);
555 
556  SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
557  (*conshdlrdata)->linconsupgrades = NULL;
558  (*conshdlrdata)->linconsupgradessize = 0;
559  (*conshdlrdata)->nlinconsupgrades = 0;
560  (*conshdlrdata)->naddconss = 0;
561 
562  /* set event handler for updating linear constraint activity bounds */
563  (*conshdlrdata)->eventhdlr = eventhdlr;
564 
565  return SCIP_OKAY;
566 }
567 
568 /** frees constraint handler data for linear constraint handler */
569 static
570 void conshdlrdataFree(
571  SCIP* scip, /**< SCIP data structure */
572  SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to the constraint handler data */
573  )
574 {
575  int i;
576 
577  assert(scip != NULL);
578  assert(conshdlrdata != NULL);
579  assert(*conshdlrdata != NULL);
580 
581  for( i = 0; i < (*conshdlrdata)->nlinconsupgrades; ++i )
582  {
583  linconsupgradeFree(scip, &(*conshdlrdata)->linconsupgrades[i]);
584  }
585  SCIPfreeBlockMemoryArrayNull(scip, &(*conshdlrdata)->linconsupgrades, (*conshdlrdata)->linconsupgradessize);
586 
587  SCIPfreeBlockMemory(scip, conshdlrdata);
588 }
590 /** creates a linear constraint upgrade data object */
591 static
593  SCIP* scip, /**< SCIP data structure */
594  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
595  SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
596  const char* conshdlrname /**< name of the constraint handler */
597  )
598 {
599  int i;
600 
601  assert(scip != NULL);
602  assert(conshdlrdata != NULL);
603  assert(linconsupgd != NULL);
604  assert(conshdlrname != NULL);
605 
606  for( i = conshdlrdata->nlinconsupgrades - 1; i >= 0; --i )
607  {
608  if( conshdlrdata->linconsupgrades[i]->linconsupgd == linconsupgd )
609  {
610 #ifdef SCIP_DEBUG
611  SCIPwarningMessage(scip, "Try to add already known upgrade message for constraint handler %s.\n", conshdlrname);
612 #endif
613  return TRUE;
614  }
615  }
616 
617  return FALSE;
618 }
619 
620 /** adds a linear constraint update method to the constraint handler's data */
621 static
623  SCIP* scip, /**< SCIP data structure */
624  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
625  SCIP_LINCONSUPGRADE* linconsupgrade /**< linear constraint upgrade method */
626  )
627 {
628  int i;
629 
630  assert(scip != NULL);
631  assert(conshdlrdata != NULL);
632  assert(linconsupgrade != NULL);
633 
634  SCIP_CALL( conshdlrdataEnsureLinconsupgradesSize(scip, conshdlrdata, conshdlrdata->nlinconsupgrades+1) );
635 
636  for( i = conshdlrdata->nlinconsupgrades;
637  i > 0 && conshdlrdata->linconsupgrades[i-1]->priority < linconsupgrade->priority; --i )
638  {
639  conshdlrdata->linconsupgrades[i] = conshdlrdata->linconsupgrades[i-1];
640  }
641  assert(0 <= i && i <= conshdlrdata->nlinconsupgrades);
642  conshdlrdata->linconsupgrades[i] = linconsupgrade;
643  conshdlrdata->nlinconsupgrades++;
644 
645  return SCIP_OKAY;
646 }
647 
648 /*
649  * local methods
650  */
651 
652 /** installs rounding locks for the given variable associated to the given coefficient in the linear constraint */
653 static
655  SCIP* scip, /**< SCIP data structure */
656  SCIP_CONS* cons, /**< linear constraint */
657  SCIP_VAR* var, /**< variable of constraint entry */
658  SCIP_Real val /**< coefficient of constraint entry */
659  )
660 {
661  SCIP_CONSDATA* consdata;
662 
663  assert(scip != NULL);
664  assert(cons != NULL);
665  assert(var != NULL);
666 
667  consdata = SCIPconsGetData(cons);
668  assert(consdata != NULL);
669  assert(!SCIPisZero(scip, val));
670 
671  if( SCIPisPositive(scip, val) )
672  {
673  SCIP_CALL( SCIPlockVarCons(scip, var, cons,
674  !SCIPisInfinity(scip, -consdata->lhs), !SCIPisInfinity(scip, consdata->rhs)) );
675  }
676  else
677  {
678  SCIP_CALL( SCIPlockVarCons(scip, var, cons,
679  !SCIPisInfinity(scip, consdata->rhs), !SCIPisInfinity(scip, -consdata->lhs)) );
680  }
681 
682  return SCIP_OKAY;
683 }
684 
685 /** removes rounding locks for the given variable associated to the given coefficient in the linear constraint */
686 static
688  SCIP* scip, /**< SCIP data structure */
689  SCIP_CONS* cons, /**< linear constraint */
690  SCIP_VAR* var, /**< variable of constraint entry */
691  SCIP_Real val /**< coefficient of constraint entry */
692  )
693 {
694  SCIP_CONSDATA* consdata;
695 
696  assert(scip != NULL);
697  assert(cons != NULL);
698  assert(var != NULL);
699 
700  consdata = SCIPconsGetData(cons);
701  assert(consdata != NULL);
702  assert(!SCIPisZero(scip, val));
703 
704  if( SCIPisPositive(scip, val) )
705  {
706  SCIP_CALL( SCIPunlockVarCons(scip, var, cons, !SCIPisInfinity(scip, -consdata->lhs),
707  !SCIPisInfinity(scip, consdata->rhs)) );
708  }
709  else
710  {
711  SCIP_CALL( SCIPunlockVarCons(scip, var, cons, !SCIPisInfinity(scip, consdata->rhs),
712  !SCIPisInfinity(scip, -consdata->lhs)) );
713  }
714 
715  return SCIP_OKAY;
716 }
717 
718 /** creates event data for variable at given position, and catches events */
719 /**! [SnippetDebugAssertions] */
720 static
722  SCIP* scip, /**< SCIP data structure */
723  SCIP_CONS* cons, /**< linear constraint */
724  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
725  int pos /**< array position of variable to catch bound change events for */
726  )
727 {
728  SCIP_CONSDATA* consdata;
729  assert(scip != NULL);
730  assert(cons != NULL);
731  assert(eventhdlr != NULL);
732 
733  consdata = SCIPconsGetData(cons);
734  assert(consdata != NULL);
735 
736  assert(0 <= pos && pos < consdata->nvars);
737  assert(consdata->vars != NULL);
738  assert(consdata->vars[pos] != NULL);
739  assert(SCIPvarIsTransformed(consdata->vars[pos]));
740  assert(consdata->eventdata != NULL);
741  assert(consdata->eventdata[pos] == NULL);
742 
743  SCIP_CALL( SCIPallocBlockMemory(scip, &(consdata->eventdata[pos])) ); /*lint !e866*/
744  consdata->eventdata[pos]->cons = cons;
745  consdata->eventdata[pos]->varpos = pos;
746 
747  SCIP_CALL( SCIPcatchVarEvent(scip, consdata->vars[pos],
750  eventhdlr, consdata->eventdata[pos], &consdata->eventdata[pos]->filterpos) );
751 
752  consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(consdata->vars[pos]);
753 
754  return SCIP_OKAY;
755 }
756 /**! [SnippetDebugAssertions] */
757 
758 /** deletes event data for variable at given position, and drops events */
759 static
761  SCIP* scip, /**< SCIP data structure */
762  SCIP_CONS* cons, /**< linear constraint */
763  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
764  int pos /**< array position of variable to catch bound change events for */
765  )
766 {
767  SCIP_CONSDATA* consdata;
768  assert(scip != NULL);
769  assert(cons != NULL);
770  assert(eventhdlr != NULL);
771 
772  consdata = SCIPconsGetData(cons);
773  assert(consdata != NULL);
774 
775  assert(0 <= pos && pos < consdata->nvars);
776  assert(consdata->vars[pos] != NULL);
777  assert(consdata->eventdata != NULL);
778  assert(consdata->eventdata[pos] != NULL);
779  assert(consdata->eventdata[pos]->cons == cons);
780  assert(consdata->eventdata[pos]->varpos == pos);
781 
782  SCIP_CALL( SCIPdropVarEvent(scip, consdata->vars[pos],
785  eventhdlr, consdata->eventdata[pos], consdata->eventdata[pos]->filterpos) );
786 
787  SCIPfreeBlockMemory(scip, &consdata->eventdata[pos]); /*lint !e866*/
788 
789  return SCIP_OKAY;
790 }
791 
792 /** catches bound change events for all variables in transformed linear constraint */
793 static
795  SCIP* scip, /**< SCIP data structure */
796  SCIP_CONS* cons, /**< linear constraint */
797  SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
798  )
799 {
800  SCIP_CONSDATA* consdata;
801  int i;
802 
803  assert(scip != NULL);
804  assert(cons != NULL);
805 
806  consdata = SCIPconsGetData(cons);
807  assert(consdata != NULL);
808  assert(consdata->eventdata == NULL);
809 
810  /* allocate eventdata array */
811  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize) );
812  assert(consdata->eventdata != NULL);
813  BMSclearMemoryArray(consdata->eventdata, consdata->nvars);
814 
815  /* catch event for every single variable */
816  for( i = 0; i < consdata->nvars; ++i )
817  {
818  SCIP_CALL( consCatchEvent(scip, cons, eventhdlr, i) );
819  }
820 
821  return SCIP_OKAY;
822 }
823 
824 /** drops bound change events for all variables in transformed linear constraint */
825 static
827  SCIP* scip, /**< SCIP data structure */
828  SCIP_CONS* cons, /**< linear constraint */
829  SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
830  )
831 {
832  SCIP_CONSDATA* consdata;
833  int i;
834 
835  assert(scip != NULL);
836  assert(cons != NULL);
837 
838  consdata = SCIPconsGetData(cons);
839  assert(consdata != NULL);
840  assert(consdata->eventdata != NULL);
841 
842  /* drop event of every single variable */
843  for( i = consdata->nvars - 1; i >= 0; --i )
844  {
845  SCIP_CALL( consDropEvent(scip, cons, eventhdlr, i) );
846  }
847 
848  /* free eventdata array */
849  SCIPfreeBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize);
850  assert(consdata->eventdata == NULL);
851 
852  return SCIP_OKAY;
853 }
854 
855 /** creates a linear constraint data */
856 static
858  SCIP* scip, /**< SCIP data structure */
859  SCIP_CONSDATA** consdata, /**< pointer to linear constraint data */
860  int nvars, /**< number of nonzeros in the constraint */
861  SCIP_VAR** vars, /**< array with variables of constraint entries */
862  SCIP_Real* vals, /**< array with coefficients of constraint entries */
863  SCIP_Real lhs, /**< left hand side of row */
864  SCIP_Real rhs /**< right hand side of row */
865  )
866 {
867  int v;
868  SCIP_Real constant;
869 
870  assert(scip != NULL);
871  assert(consdata != NULL);
872  assert(nvars == 0 || vars != NULL);
873  assert(nvars == 0 || vals != NULL);
874 
875  if( SCIPisInfinity(scip, rhs) )
876  rhs = SCIPinfinity(scip);
877  else if( SCIPisInfinity(scip, -rhs) )
878  rhs = -SCIPinfinity(scip);
879 
880  if( SCIPisInfinity(scip, -lhs) )
881  lhs = -SCIPinfinity(scip);
882  else if( SCIPisInfinity(scip, lhs) )
883  lhs = SCIPinfinity(scip);
884 
885  if( SCIPisGT(scip, lhs, rhs) )
886  {
887  SCIPwarningMessage(scip, "left hand side of linear constraint greater than right hand side\n");
888  SCIPwarningMessage(scip, " -> lhs=%g, rhs=%g\n", lhs, rhs);
889  }
890 
891  SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
892 
893  (*consdata)->varssize = 0;
894  (*consdata)->nvars = nvars;
895  (*consdata)->hascontvar = FALSE;
896  (*consdata)->hasnonbinvar = FALSE;
897  (*consdata)->hasnonbinvalid = TRUE;
898  (*consdata)->vars = NULL;
899  (*consdata)->vals = NULL;
900 
901  constant = 0.0;
902  if( nvars > 0 )
903  {
904  int k;
905 
906  SCIP_VAR** varsbuffer;
907  SCIP_Real* valsbuffer;
908 
909  /* copy variables into temporary buffer */
910  SCIP_CALL( SCIPallocBufferArray(scip, &varsbuffer, nvars) );
911  SCIP_CALL( SCIPallocBufferArray(scip, &valsbuffer, nvars) );
912  k = 0;
913 
914  /* loop over variables and sort out fixed ones */
915  for( v = 0; v < nvars; ++v )
916  {
917  SCIP_VAR* var;
918  SCIP_Real val;
919 
920  var = vars[v];
921  val = vals[v];
922 
923  assert(var != NULL);
924  if( !SCIPisZero(scip, val) )
925  {
926  /* treat fixed variable as a constant if problem compression is enabled */
928  {
929  constant += SCIPvarGetLbGlobal(var) * val;
930  }
931  else
932  {
933  varsbuffer[k] = var;
934  valsbuffer[k] = val;
935  k++;
936 
937  /* update hascontvar and hasnonbinvar flags */
938  if( !(*consdata)->hascontvar )
939  {
940  SCIP_VARTYPE vartype = SCIPvarGetType(var);
941 
942  if( vartype != SCIP_VARTYPE_BINARY )
943  {
944  (*consdata)->hasnonbinvar = TRUE;
945 
946  if( vartype == SCIP_VARTYPE_CONTINUOUS )
947  (*consdata)->hascontvar = TRUE;
948  }
949  }
950  }
951  }
952  }
953  (*consdata)->nvars = k;
954 
955  if( k > 0 )
956  {
957  /* copy the possibly reduced buffer arrays into block */
958  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, varsbuffer, k) );
959  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vals, valsbuffer, k) );
960  (*consdata)->varssize = k;
961  }
962  /* free temporary buffer */
963  SCIPfreeBufferArray(scip, &valsbuffer);
964  SCIPfreeBufferArray(scip, &varsbuffer);
965  }
966 
967  (*consdata)->eventdata = NULL;
968 
969  /* due to compressed copying, we may have fixed variables contributing to the left and right hand side */
970  if( !SCIPisZero(scip, constant) )
971  {
972  if( !SCIPisInfinity(scip, REALABS(lhs)) )
973  lhs -= constant;
974 
975  if( !SCIPisInfinity(scip, REALABS(rhs)) )
976  rhs -= constant;
977  }
978 
979  (*consdata)->row = NULL;
980  (*consdata)->nlrow = NULL;
981  (*consdata)->lhs = lhs;
982  (*consdata)->rhs = rhs;
983  (*consdata)->maxabsval = SCIP_INVALID;
984  (*consdata)->minabsval = SCIP_INVALID;
985  (*consdata)->minactivity = SCIP_INVALID;
986  (*consdata)->maxactivity = SCIP_INVALID;
987  (*consdata)->lastminactivity = SCIP_INVALID;
988  (*consdata)->lastmaxactivity = SCIP_INVALID;
989  (*consdata)->maxactdelta = SCIP_INVALID;
990  (*consdata)->maxactdeltavar = NULL;
991  (*consdata)->minactivityneginf = -1;
992  (*consdata)->minactivityposinf = -1;
993  (*consdata)->maxactivityneginf = -1;
994  (*consdata)->maxactivityposinf = -1;
995  (*consdata)->minactivityneghuge = -1;
996  (*consdata)->minactivityposhuge = -1;
997  (*consdata)->maxactivityneghuge = -1;
998  (*consdata)->maxactivityposhuge = -1;
999  (*consdata)->glbminactivity = SCIP_INVALID;
1000  (*consdata)->glbmaxactivity = SCIP_INVALID;
1001  (*consdata)->lastglbminactivity = SCIP_INVALID;
1002  (*consdata)->lastglbmaxactivity = SCIP_INVALID;
1003  (*consdata)->glbminactivityneginf = -1;
1004  (*consdata)->glbminactivityposinf = -1;
1005  (*consdata)->glbmaxactivityneginf = -1;
1006  (*consdata)->glbmaxactivityposinf = -1;
1007  (*consdata)->glbminactivityneghuge = -1;
1008  (*consdata)->glbminactivityposhuge = -1;
1009  (*consdata)->glbmaxactivityneghuge = -1;
1010  (*consdata)->glbmaxactivityposhuge = -1;
1011  (*consdata)->possignature = 0;
1012  (*consdata)->negsignature = 0;
1013  (*consdata)->validmaxabsval = FALSE;
1014  (*consdata)->validminabsval = FALSE;
1015  (*consdata)->validactivities = FALSE;
1016  (*consdata)->validminact = FALSE;
1017  (*consdata)->validmaxact = FALSE;
1018  (*consdata)->validglbminact = FALSE;
1019  (*consdata)->validglbmaxact = FALSE;
1020  (*consdata)->boundstightened = 0;
1021  (*consdata)->presolved = FALSE;
1022  (*consdata)->removedfixings = FALSE;
1023  (*consdata)->validsignature = FALSE;
1024  (*consdata)->changed = TRUE;
1025  (*consdata)->normalized = FALSE;
1026  (*consdata)->upgradetried = FALSE;
1027  (*consdata)->upgraded = FALSE;
1028  (*consdata)->indexsorted = (nvars <= 1);
1029  (*consdata)->merged = (nvars <= 1);
1030  (*consdata)->cliquesadded = FALSE;
1031  (*consdata)->implsadded = FALSE;
1032  (*consdata)->coefsorted = FALSE;
1033  (*consdata)->nbinvars = -1;
1034  (*consdata)->varsdeleted = FALSE;
1035  (*consdata)->rangedrowpropagated = 0;
1036  (*consdata)->checkabsolute = FALSE;
1037 
1038  if( SCIPisTransformed(scip) )
1039  {
1040  /* get transformed variables */
1041  SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
1042  }
1043 
1044  /* capture variables */
1045  for( v = 0; v < (*consdata)->nvars; v++ )
1046  {
1047  /* likely implies a deleted variable */
1048  if( (*consdata)->vars[v] == NULL )
1049  {
1050  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vars, (*consdata)->varssize);
1051  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vals, (*consdata)->varssize);
1052  SCIPfreeBlockMemory(scip, consdata);
1053  return SCIP_INVALIDDATA;
1054  }
1055 
1056  assert(!SCIPisZero(scip, (*consdata)->vals[v]));
1057  SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->vars[v]) );
1058  }
1059 
1060  return SCIP_OKAY;
1061 }
1062 
1063 /** frees a linear constraint data */
1064 static
1066  SCIP* scip, /**< SCIP data structure */
1067  SCIP_CONSDATA** consdata /**< pointer to linear constraint data */
1068  )
1069 {
1070  int v;
1071 
1072  assert(scip != NULL);
1073  assert(consdata != NULL);
1074  assert(*consdata != NULL);
1075  assert((*consdata)->varssize >= 0);
1076 
1077  /* release the row */
1078  if( (*consdata)->row != NULL )
1079  {
1080  SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->row) );
1081  }
1082 
1083  /* release the nlrow */
1084  if( (*consdata)->nlrow != NULL )
1085  {
1086  SCIP_CALL( SCIPreleaseNlRow(scip, &(*consdata)->nlrow) );
1087  }
1088 
1089  /* release variables */
1090  for( v = 0; v < (*consdata)->nvars; v++ )
1091  {
1092  assert((*consdata)->vars[v] != NULL);
1093  assert(!SCIPisZero(scip, (*consdata)->vals[v]));
1094  SCIP_CALL( SCIPreleaseVar(scip, &((*consdata)->vars[v])) );
1095  }
1096 
1097  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vars, (*consdata)->varssize);
1098  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vals, (*consdata)->varssize);
1099  SCIPfreeBlockMemory(scip, consdata);
1100 
1101  return SCIP_OKAY;
1102 }
1103 
1104 /** prints linear constraint in CIP format to file stream */
1105 static
1107  SCIP* scip, /**< SCIP data structure */
1108  SCIP_CONSDATA* consdata, /**< linear constraint data */
1109  FILE* file /**< output file (or NULL for standard output) */
1110  )
1111 {
1112  assert(scip != NULL);
1113  assert(consdata != NULL);
1114 
1115  /* print left hand side for ranged rows */
1116  if( !SCIPisInfinity(scip, -consdata->lhs)
1117  && !SCIPisInfinity(scip, consdata->rhs)
1118  && !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1119  SCIPinfoMessage(scip, file, "%.15g <= ", consdata->lhs);
1120 
1121  /* print coefficients and variables */
1122  if( consdata->nvars == 0 )
1123  SCIPinfoMessage(scip, file, "0");
1124  else
1125  {
1126  /* post linear sum of the linear constraint */
1127  SCIP_CALL( SCIPwriteVarsLinearsum(scip, file, consdata->vars, consdata->vals, consdata->nvars, TRUE) );
1128  }
1129 
1130  /* print right hand side */
1131  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1132  SCIPinfoMessage(scip, file, " == %.15g", consdata->rhs);
1133  else if( !SCIPisInfinity(scip, consdata->rhs) )
1134  SCIPinfoMessage(scip, file, " <= %.15g", consdata->rhs);
1135  else if( !SCIPisInfinity(scip, -consdata->lhs) )
1136  SCIPinfoMessage(scip, file, " >= %.15g", consdata->lhs);
1137  else
1138  SCIPinfoMessage(scip, file, " [free]");
1139 
1140  return SCIP_OKAY;
1141 }
1142 
1143 /** prints linear constraint and contained solution values of variables to file stream */
1144 static
1146  SCIP* scip, /**< SCIP data structure */
1147  SCIP_CONS* cons, /**< linear constraint */
1148  SCIP_SOL* sol, /**< solution to print */
1149  FILE* file /**< output file (or NULL for standard output) */
1150  )
1151 {
1152  SCIP_CONSDATA* consdata;
1153 
1154  assert(scip != NULL);
1155  assert(cons != NULL);
1156 
1157  consdata = SCIPconsGetData(cons);
1158  assert(consdata != NULL);
1159 
1161 
1162  /* print left hand side for ranged rows */
1163  if( !SCIPisInfinity(scip, -consdata->lhs)
1164  && !SCIPisInfinity(scip, consdata->rhs)
1165  && !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1166  SCIPinfoMessage(scip, file, "%.15g <= ", consdata->lhs);
1167 
1168  /* print coefficients and variables */
1169  if( consdata->nvars == 0 )
1170  SCIPinfoMessage(scip, file, "0");
1171  else
1172  {
1173  int v;
1174 
1175  /* post linear sum of the linear constraint */
1176  for( v = 0; v < consdata->nvars; ++v )
1177  {
1178  if( consdata->vals != NULL )
1179  {
1180  if( consdata->vals[v] == 1.0 )
1181  {
1182  if( v > 0 )
1183  SCIPinfoMessage(scip, file, " +");
1184  }
1185  else if( consdata->vals[v] == -1.0 )
1186  SCIPinfoMessage(scip, file, " -");
1187  else
1188  SCIPinfoMessage(scip, file, " %+.9g", consdata->vals[v]);
1189  }
1190  else if( consdata->nvars > 0 )
1191  SCIPinfoMessage(scip, file, " +");
1192 
1193  /* print variable name */
1194  SCIP_CALL( SCIPwriteVarName(scip, file, consdata->vars[v], TRUE) );
1195 
1196  SCIPinfoMessage(scip, file, " (%+.9g)", SCIPgetSolVal(scip, sol, consdata->vars[v]));
1197  }
1198  }
1199 
1200  /* print right hand side */
1201  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1202  SCIPinfoMessage(scip, file, " == %.15g", consdata->rhs);
1203  else if( !SCIPisInfinity(scip, consdata->rhs) )
1204  SCIPinfoMessage(scip, file, " <= %.15g", consdata->rhs);
1205  else if( !SCIPisInfinity(scip, -consdata->lhs) )
1206  SCIPinfoMessage(scip, file, " >= %.15g", consdata->lhs);
1207  else
1208  SCIPinfoMessage(scip, file, " [free]");
1209 
1210  SCIPinfoMessage(scip, file, ";\n");
1211 
1212  return SCIP_OKAY;
1213 }
1214 
1215 /** invalidates activity bounds, such that they are recalculated in next get */
1216 static
1218  SCIP_CONSDATA* consdata /**< linear constraint */
1219  )
1220 {
1221  assert(consdata != NULL);
1222 
1223  consdata->validactivities = FALSE;
1224  consdata->validminact = FALSE;
1225  consdata->validmaxact = FALSE;
1226  consdata->validglbminact = FALSE;
1227  consdata->validglbmaxact = FALSE;
1228  consdata->validmaxabsval = FALSE;
1229  consdata->validminabsval = FALSE;
1230  consdata->hasnonbinvalid = FALSE;
1231  consdata->minactivity = SCIP_INVALID;
1232  consdata->maxactivity = SCIP_INVALID;
1233  consdata->lastminactivity = SCIP_INVALID;
1234  consdata->lastmaxactivity = SCIP_INVALID;
1235  consdata->maxabsval = SCIP_INVALID;
1236  consdata->minabsval = SCIP_INVALID;
1237  consdata->maxactdelta = SCIP_INVALID;
1238  consdata->maxactdeltavar = NULL;
1239  consdata->minactivityneginf = -1;
1240  consdata->minactivityposinf = -1;
1241  consdata->maxactivityneginf = -1;
1242  consdata->maxactivityposinf = -1;
1243  consdata->minactivityneghuge = -1;
1244  consdata->minactivityposhuge = -1;
1245  consdata->maxactivityneghuge = -1;
1246  consdata->maxactivityposhuge = -1;
1247  consdata->glbminactivity = SCIP_INVALID;
1248  consdata->glbmaxactivity = SCIP_INVALID;
1249  consdata->lastglbminactivity = SCIP_INVALID;
1250  consdata->lastglbmaxactivity = SCIP_INVALID;
1251  consdata->glbminactivityneginf = -1;
1252  consdata->glbminactivityposinf = -1;
1253  consdata->glbmaxactivityneginf = -1;
1254  consdata->glbmaxactivityposinf = -1;
1255  consdata->glbminactivityneghuge = -1;
1256  consdata->glbminactivityposhuge = -1;
1257  consdata->glbmaxactivityneghuge = -1;
1258  consdata->glbmaxactivityposhuge = -1;
1259 }
1260 
1261 /** compute the pseudo activity of a constraint */
1262 static
1264  SCIP* scip, /**< SCIP data structure */
1265  SCIP_CONSDATA* consdata /**< linear constraint data */
1266  )
1267 {
1268  int i;
1269  int pseudoactivityposinf;
1270  int pseudoactivityneginf;
1271  SCIP_Real pseudoactivity;
1272  SCIP_Real bound;
1273  SCIP_Real val;
1274 
1275  pseudoactivity = 0;
1276  pseudoactivityposinf = 0;
1277  pseudoactivityneginf = 0;
1278 
1279  for( i = consdata->nvars - 1; i >= 0; --i )
1280  {
1281  val = consdata->vals[i];
1282  bound = (SCIPvarGetBestBoundType(consdata->vars[i]) == SCIP_BOUNDTYPE_LOWER) ? SCIPvarGetLbLocal(consdata->vars[i]) : SCIPvarGetUbLocal(consdata->vars[i]);
1283  if( SCIPisInfinity(scip, bound) )
1284  {
1285  if( val > 0.0 )
1286  pseudoactivityposinf++;
1287  else
1288  pseudoactivityneginf++;
1289  }
1290  else
1291  {
1292  if( SCIPisInfinity(scip, -bound) )
1293  {
1294  if( val > 0.0 )
1295  pseudoactivityneginf++;
1296  else
1297  pseudoactivityposinf++;
1298  }
1299  else
1300  pseudoactivity += val * bound;
1301  }
1302  }
1303 
1304  if( pseudoactivityneginf > 0 && pseudoactivityposinf > 0 )
1305  return SCIP_INVALID;
1306  else if( pseudoactivityneginf > 0 )
1307  return -SCIPinfinity(scip);
1308  else if( pseudoactivityposinf > 0 )
1309  return SCIPinfinity(scip);
1310 
1311  return pseudoactivity;
1312 }
1313 
1314 /** recompute the minactivity of a constraint */
1315 static
1317  SCIP* scip, /**< SCIP data structure */
1318  SCIP_CONSDATA* consdata /**< linear constraint data */
1319  )
1320 {
1321  int i;
1322  SCIP_Real bound;
1323 
1324  consdata->minactivity = 0;
1325 
1326  for( i = consdata->nvars - 1; i >= 0; --i )
1327  {
1328  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetLbLocal(consdata->vars[i]) : SCIPvarGetUbLocal(consdata->vars[i]);
1329  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1330  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1331  consdata->minactivity += consdata->vals[i] * bound;
1332  }
1333 
1334  /* the activity was just computed from scratch and is valid now */
1335  consdata->validminact = TRUE;
1336 
1337  /* the activity was just computed from scratch, mark it to be reliable */
1338  consdata->lastminactivity = consdata->minactivity;
1339 }
1340 
1341 /** recompute the maxactivity of a constraint */
1342 static
1344  SCIP* scip, /**< SCIP data structure */
1345  SCIP_CONSDATA* consdata /**< linear constraint data */
1346  )
1347 {
1348  int i;
1349  SCIP_Real bound;
1350 
1351  consdata->maxactivity = 0;
1352 
1353  for( i = consdata->nvars - 1; i >= 0; --i )
1354  {
1355  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetUbLocal(consdata->vars[i]) : SCIPvarGetLbLocal(consdata->vars[i]);
1356  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1357  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1358  consdata->maxactivity += consdata->vals[i] * bound;
1359  }
1360 
1361  /* the activity was just computed from scratch and is valid now */
1362  consdata->validmaxact = TRUE;
1363 
1364  /* the activity was just computed from scratch, mark it to be reliable */
1365  consdata->lastmaxactivity = consdata->maxactivity;
1366 }
1367 
1368 /** recompute the global minactivity of a constraint */
1369 static
1371  SCIP* scip, /**< SCIP data structure */
1372  SCIP_CONSDATA* consdata /**< linear constraint data */
1373  )
1374 {
1375  int i;
1376  SCIP_Real bound;
1377 
1378  consdata->glbminactivity = 0;
1379 
1380  for( i = consdata->nvars - 1; i >= 0; --i )
1381  {
1382  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetLbGlobal(consdata->vars[i]) : SCIPvarGetUbGlobal(consdata->vars[i]);
1383  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1384  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1385  consdata->glbminactivity += consdata->vals[i] * bound;
1386  }
1387 
1388  /* the activity was just computed from scratch and is valid now */
1389  consdata->validglbminact = TRUE;
1390 
1391  /* the activity was just computed from scratch, mark it to be reliable */
1392  consdata->lastglbminactivity = consdata->glbminactivity;
1393 }
1394 
1395 /** recompute the global maxactivity of a constraint */
1396 static
1398  SCIP* scip, /**< SCIP data structure */
1399  SCIP_CONSDATA* consdata /**< linear constraint data */
1400  )
1401 {
1402  int i;
1403  SCIP_Real bound;
1404 
1405  consdata->glbmaxactivity = 0;
1406 
1407  for( i = consdata->nvars - 1; i >= 0; --i )
1408  {
1409  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetUbGlobal(consdata->vars[i]) : SCIPvarGetLbGlobal(consdata->vars[i]);
1410  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1411  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1412  consdata->glbmaxactivity += consdata->vals[i] * bound;
1413  }
1414 
1415  /* the activity was just computed from scratch and is valid now */
1416  consdata->validglbmaxact = TRUE;
1417 
1418  /* the activity was just computed from scratch, mark it to be reliable */
1419  consdata->lastglbmaxactivity = consdata->glbmaxactivity;
1420 }
1421 
1422 /** calculates maximum absolute value of coefficients */
1423 static
1425  SCIP_CONSDATA* consdata /**< linear constraint data */
1426  )
1427 {
1428  SCIP_Real absval;
1429  int i;
1430 
1431  assert(consdata != NULL);
1432  assert(!consdata->validmaxabsval);
1433  assert(consdata->maxabsval >= SCIP_INVALID);
1434 
1435  consdata->validmaxabsval = TRUE;
1436  consdata->maxabsval = 0.0;
1437  for( i = 0; i < consdata->nvars; ++i )
1438  {
1439  absval = consdata->vals[i];
1440  absval = REALABS(absval);
1441  if( absval > consdata->maxabsval )
1442  consdata->maxabsval = absval;
1443  }
1444 }
1445 
1446 /** calculates minimum absolute value of coefficients */
1447 static
1449  SCIP_CONSDATA* consdata /**< linear constraint data */
1450  )
1451 {
1452  SCIP_Real absval;
1453  int i;
1454 
1455  assert(consdata != NULL);
1456  assert(!consdata->validminabsval);
1457  assert(consdata->minabsval >= SCIP_INVALID);
1458 
1459  consdata->validminabsval = TRUE;
1460 
1461  if( consdata->nvars > 0 )
1462  consdata->minabsval = REALABS(consdata->vals[0]);
1463  else
1464  consdata->minabsval = 0.0;
1465 
1466  for( i = 1; i < consdata->nvars; ++i )
1467  {
1468  absval = consdata->vals[i];
1469  absval = REALABS(absval);
1470  if( absval < consdata->minabsval )
1471  consdata->minabsval = absval;
1472  }
1473 }
1474 
1475 /** checks the type of all variables of the constraint and sets hasnonbinvar and hascontvar flags accordingly */
1476 static
1478  SCIP_CONSDATA* consdata /**< linear constraint data */
1479  )
1480 {
1481  int v;
1482 
1483  assert(!consdata->hasnonbinvalid);
1484  consdata->hasnonbinvar = FALSE;
1485  consdata->hascontvar = FALSE;
1486 
1487  for( v = consdata->nvars - 1; v >= 0; --v )
1488  {
1489  SCIP_VARTYPE vartype = SCIPvarGetType(consdata->vars[v]);
1490 
1491  if( vartype != SCIP_VARTYPE_BINARY )
1492  {
1493  consdata->hasnonbinvar = TRUE;
1494 
1495  if( vartype == SCIP_VARTYPE_CONTINUOUS )
1496  {
1497  consdata->hascontvar = TRUE;
1498  break;
1499  }
1500  }
1501  }
1502  assert(consdata->hascontvar || v < 0);
1503 
1504  consdata->hasnonbinvalid = TRUE;
1505 }
1506 
1507 
1508 #ifdef CHECKMAXACTDELTA
1509 /** checks that the stored maximal activity delta (if not invalid) is correct */
1510 static
1512  SCIP* scip, /**< SCIP data structure */
1513  SCIP_CONSDATA* consdata /**< linear constraint data */
1514  )
1515 {
1516  if( consdata->maxactdelta != SCIP_INVALID )
1517  {
1518  SCIP_Real maxactdelta = 0.0;
1519  SCIP_Real domain;
1520  SCIP_Real delta;
1521  SCIP_Real lb;
1522  SCIP_Real ub;
1523  int v;
1524 
1525  for( v = consdata->nvars - 1; v >= 0; --v )
1526  {
1527  lb = SCIPvarGetLbLocal(consdata->vars[v]);
1528  ub = SCIPvarGetUbLocal(consdata->vars[v]);
1529 
1530  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
1531  {
1532  maxactdelta = SCIPinfinity(scip);
1533  break;
1534  }
1535 
1536  domain = ub - lb;
1537  delta = REALABS(consdata->vals[v]) * domain;
1538 
1539  if( delta > maxactdelta )
1540  {
1541  maxactdelta = delta;
1542  }
1543  }
1544  assert(SCIPisFeasEQ(scip, maxactdelta, consdata->maxactdelta));
1545  }
1546 }
1547 #else
1548 #define checkMaxActivityDelta(scip, consdata) /**/
1549 #endif
1550 
1551 /** recompute maximal activity contribution for a single variable */
1552 static
1554  SCIP* scip, /**< SCIP data structure */
1555  SCIP_CONSDATA* consdata /**< linear constraint data */
1556  )
1557 {
1558  SCIP_Real delta;
1559  int v;
1560 
1561  consdata->maxactdelta = 0.0;
1562 
1563  if( !consdata->hasnonbinvalid )
1564  consdataCheckNonbinvar(consdata);
1565 
1566  /* easy case, the problem consists only of binary variables */
1567  if( !consdata->hasnonbinvar )
1568  {
1569  for( v = consdata->nvars - 1; v >= 0; --v )
1570  {
1571  if( SCIPvarGetLbLocal(consdata->vars[v]) < 0.5 && SCIPvarGetUbLocal(consdata->vars[v]) > 0.5 )
1572  {
1573  delta = REALABS(consdata->vals[v]);
1574 
1575  if( delta > consdata->maxactdelta )
1576  {
1577  consdata->maxactdelta = delta;
1578  consdata->maxactdeltavar = consdata->vars[v];
1579  }
1580  }
1581  }
1582  return;
1583  }
1584 
1585  for( v = consdata->nvars - 1; v >= 0; --v )
1586  {
1587  SCIP_Real domain;
1588  SCIP_Real lb;
1589  SCIP_Real ub;
1590 
1591  lb = SCIPvarGetLbLocal(consdata->vars[v]);
1592  ub = SCIPvarGetUbLocal(consdata->vars[v]);
1593 
1594  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
1595  {
1596  consdata->maxactdelta = SCIPinfinity(scip);
1597  consdata->maxactdeltavar = consdata->vars[v];
1598  break;
1599  }
1600 
1601  domain = ub - lb;
1602  delta = REALABS(consdata->vals[v]) * domain;
1603 
1604  if( delta > consdata->maxactdelta )
1605  {
1606  consdata->maxactdelta = delta;
1607  consdata->maxactdeltavar = consdata->vars[v];
1608  }
1609  }
1610 }
1611 
1612 
1613 /** updates activities for a change in a bound */
1614 static
1616  SCIP* scip, /**< SCIP data structure */
1617  SCIP_CONSDATA* consdata, /**< linear constraint data */
1618  SCIP_VAR* var, /**< variable that has been changed; can be NULL for global bound changes */
1619  SCIP_Real oldbound, /**< old bound of variable */
1620  SCIP_Real newbound, /**< new bound of variable */
1621  SCIP_Real val, /**< coefficient of constraint entry */
1622  SCIP_BOUNDTYPE boundtype, /**< type of the bound change */
1623  SCIP_Bool global, /**< is it a global or a local bound change? */
1624  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1625  )
1626 {
1627  SCIP_Real* activity;
1628  SCIP_Real* lastactivity;
1629  int* activityposinf;
1630  int* activityneginf;
1631  int* activityposhuge;
1632  int* activityneghuge;
1633  SCIP_Real oldcontribution;
1634  SCIP_Real newcontribution;
1635  SCIP_Real delta;
1636  SCIP_Bool validact;
1637  SCIP_Bool finitenewbound;
1638  SCIP_Bool hugevalnewcont;
1639 
1640  assert(scip != NULL);
1641  assert(consdata != NULL);
1642  assert(global || (var != NULL));
1643  assert(consdata->validactivities);
1644  assert(consdata->minactivity < SCIP_INVALID);
1645  assert(consdata->maxactivity < SCIP_INVALID);
1646  assert(consdata->lastminactivity < SCIP_INVALID);
1647  assert(consdata->lastmaxactivity < SCIP_INVALID);
1648  assert(consdata->minactivityneginf >= 0);
1649  assert(consdata->minactivityposinf >= 0);
1650  assert(consdata->maxactivityneginf >= 0);
1651  assert(consdata->maxactivityposinf >= 0);
1652  assert(consdata->minactivityneghuge >= 0);
1653  assert(consdata->minactivityposhuge >= 0);
1654  assert(consdata->maxactivityneghuge >= 0);
1655  assert(consdata->maxactivityposhuge >= 0);
1656  assert(consdata->glbminactivity < SCIP_INVALID);
1657  assert(consdata->glbmaxactivity < SCIP_INVALID);
1658  assert(consdata->lastglbminactivity < SCIP_INVALID);
1659  assert(consdata->lastglbmaxactivity < SCIP_INVALID);
1660  assert(consdata->glbminactivityneginf >= 0);
1661  assert(consdata->glbminactivityposinf >= 0);
1662  assert(consdata->glbmaxactivityneginf >= 0);
1663  assert(consdata->glbmaxactivityposinf >= 0);
1664  assert(consdata->glbminactivityneghuge >= 0);
1665  assert(consdata->glbminactivityposhuge >= 0);
1666  assert(consdata->glbmaxactivityneghuge >= 0);
1667  assert(consdata->glbmaxactivityposhuge >= 0);
1668 
1669  delta = 0.0;
1670 
1671  /* we are updating global activities */
1672  if( global )
1673  {
1674  /* depending on the boundtype and the coefficient, we choose the activity to be updated:
1675  * lower bound + pos. coef: update minactivity
1676  * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
1677  * upper bound + pos. coef: update maxactivity
1678  * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
1679  */
1680  if( boundtype == SCIP_BOUNDTYPE_LOWER )
1681  {
1682  if( val > 0.0 )
1683  {
1684  activity = &(consdata->glbminactivity);
1685  lastactivity = &(consdata->lastglbminactivity);
1686  activityposinf = &(consdata->glbminactivityposinf);
1687  activityneginf = &(consdata->glbminactivityneginf);
1688  activityposhuge = &(consdata->glbminactivityposhuge);
1689  activityneghuge = &(consdata->glbminactivityneghuge);
1690  validact = consdata->validglbminact;
1691  }
1692  else
1693  {
1694  activity = &(consdata->glbmaxactivity);
1695  lastactivity = &(consdata->lastglbmaxactivity);
1696  activityposinf = &(consdata->glbmaxactivityneginf);
1697  activityneginf = &(consdata->glbmaxactivityposinf);
1698  activityposhuge = &(consdata->glbmaxactivityposhuge);
1699  activityneghuge = &(consdata->glbmaxactivityneghuge);
1700  validact = consdata->validglbmaxact;
1701  }
1702  }
1703  else
1704  {
1705  if( val > 0.0 )
1706  {
1707  activity = &(consdata->glbmaxactivity);
1708  lastactivity = &(consdata->lastglbmaxactivity);
1709  activityposinf = &(consdata->glbmaxactivityposinf);
1710  activityneginf = &(consdata->glbmaxactivityneginf);
1711  activityposhuge = &(consdata->glbmaxactivityposhuge);
1712  activityneghuge = &(consdata->glbmaxactivityneghuge);
1713  validact = consdata->validglbmaxact;
1714  }
1715  else
1716  {
1717  activity = &(consdata->glbminactivity);
1718  lastactivity = &(consdata->lastglbminactivity);
1719  activityposinf = &(consdata->glbminactivityneginf);
1720  activityneginf = &(consdata->glbminactivityposinf);
1721  activityposhuge = &(consdata->glbminactivityposhuge);
1722  activityneghuge = &(consdata->glbminactivityneghuge);
1723  validact = consdata->validglbminact;
1724  }
1725  }
1726  }
1727  /* we are updating local activities */
1728  else
1729  {
1730  /* depending on the boundtype and the coefficient, we choose the activity to be updated:
1731  * lower bound + pos. coef: update minactivity
1732  * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
1733  * upper bound + pos. coef: update maxactivity
1734  * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
1735  */
1736  if( boundtype == SCIP_BOUNDTYPE_LOWER )
1737  {
1738  if( val > 0.0 )
1739  {
1740  activity = &(consdata->minactivity);
1741  lastactivity = &(consdata->lastminactivity);
1742  activityposinf = &(consdata->minactivityposinf);
1743  activityneginf = &(consdata->minactivityneginf);
1744  activityposhuge = &(consdata->minactivityposhuge);
1745  activityneghuge = &(consdata->minactivityneghuge);
1746  validact = consdata->validminact;
1747  }
1748  else
1749  {
1750  activity = &(consdata->maxactivity);
1751  lastactivity = &(consdata->lastmaxactivity);
1752  activityposinf = &(consdata->maxactivityneginf);
1753  activityneginf = &(consdata->maxactivityposinf);
1754  activityposhuge = &(consdata->maxactivityposhuge);
1755  activityneghuge = &(consdata->maxactivityneghuge);
1756  validact = consdata->validmaxact;
1757  }
1758  }
1759  else
1760  {
1761  if( val > 0.0 )
1762  {
1763  activity = &(consdata->maxactivity);
1764  lastactivity = &(consdata->lastmaxactivity);
1765  activityposinf = &(consdata->maxactivityposinf);
1766  activityneginf = &(consdata->maxactivityneginf);
1767  activityposhuge = &(consdata->maxactivityposhuge);
1768  activityneghuge = &(consdata->maxactivityneghuge);
1769  validact = consdata->validmaxact;
1770  }
1771  else
1772  {
1773  activity = &(consdata->minactivity);
1774  lastactivity = &(consdata->lastminactivity);
1775  activityposinf = &(consdata->minactivityneginf);
1776  activityneginf = &(consdata->minactivityposinf);
1777  activityposhuge = &(consdata->minactivityposhuge);
1778  activityneghuge = &(consdata->minactivityneghuge);
1779  validact = consdata->validminact;
1780  }
1781  }
1782  }
1783 
1784  oldcontribution = val * oldbound;
1785  newcontribution = val * newbound;
1786  hugevalnewcont = SCIPisHugeValue(scip, REALABS(newcontribution));
1787  finitenewbound = !SCIPisInfinity(scip, REALABS(newbound));
1788 
1789  if( SCIPisInfinity(scip, REALABS(oldbound)) )
1790  {
1791  /* old bound was +infinity */
1792  if( oldbound > 0.0 )
1793  {
1794  assert((*activityposinf) >= 1);
1795 
1796  /* we only have to do something if the new bound is not again +infinity */
1797  if( finitenewbound || newbound < 0.0 )
1798  {
1799  /* decrease the counter for positive infinite contributions */
1800  (*activityposinf)--;
1801 
1802  /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1803  if( !finitenewbound && newbound < 0.0 )
1804  (*activityneginf)++;
1805  else if( hugevalnewcont )
1806  {
1807  /* if the contribution of this variable is too large, increase the counter for huge values */
1808  if( newcontribution > 0.0 )
1809  (*activityposhuge)++;
1810  else
1811  (*activityneghuge)++;
1812  }
1813  /* "normal case": just add the contribution to the activity */
1814  else
1815  delta = newcontribution;
1816  }
1817  }
1818  /* old bound was -infinity */
1819  else
1820  {
1821  assert(oldbound < 0.0);
1822  assert((*activityneginf) >= 1);
1823 
1824  /* we only have to do something ig the new bound is not again -infinity */
1825  if( finitenewbound || newbound > 0.0 )
1826  {
1827  /* decrease the counter for negative infinite contributions */
1828  (*activityneginf)--;
1829 
1830  /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1831  if( !finitenewbound && newbound > 0.0 )
1832  (*activityposinf)++;
1833  else if( hugevalnewcont )
1834  {
1835  /* if the contribution of this variable is too large, increase the counter for huge values */
1836  if( newcontribution > 0.0 )
1837  (*activityposhuge)++;
1838  else
1839  (*activityneghuge)++;
1840  }
1841  /* "normal case": just add the contribution to the activity */
1842  else
1843  delta = newcontribution;
1844  }
1845  }
1846  }
1847  else if( SCIPisHugeValue(scip, REALABS(oldcontribution)) )
1848  {
1849  /* old contribution was too large and positive */
1850  if( oldcontribution > 0.0 )
1851  {
1852  assert((*activityposhuge) >= 1);
1853 
1854  /* decrease the counter for huge positive contributions; it might be increased again later,
1855  * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
1856  */
1857  (*activityposhuge)--;
1858 
1859  if( !finitenewbound )
1860  {
1861  /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1862  if( newbound > 0.0 )
1863  (*activityposinf)++;
1864  /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1865  else
1866  (*activityneginf)++;
1867  }
1868  else if( hugevalnewcont )
1869  {
1870  /* if the contribution of this variable is too large and positive, increase the corresponding counter */
1871  if( newcontribution > 0.0 )
1872  (*activityposhuge)++;
1873  /* if the contribution of this variable is too large and negative, increase the corresponding counter */
1874  else
1875  (*activityneghuge)++;
1876  }
1877  /* "normal case": just add the contribution to the activity */
1878  else
1879  delta = newcontribution;
1880  }
1881  /* old contribution was too large and negative */
1882  else
1883  {
1884  assert(oldcontribution < 0.0);
1885  assert((*activityneghuge) >= 1);
1886 
1887  /* decrease the counter for huge negative contributions; it might be increased again later,
1888  * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
1889  */
1890  (*activityneghuge)--;
1891 
1892  if( !finitenewbound )
1893  {
1894  /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1895  if( newbound > 0.0 )
1896  (*activityposinf)++;
1897  /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1898  else
1899  (*activityneginf)++;
1900  }
1901  else if( hugevalnewcont )
1902  {
1903  /* if the contribution of this variable is too large and positive, increase the corresponding counter */
1904  if( newcontribution > 0.0 )
1905  (*activityposhuge)++;
1906  /* if the contribution of this variable is too large and negative, increase the corresponding counter */
1907  else
1908  (*activityneghuge)++;
1909  }
1910  /* "normal case": just add the contribution to the activity */
1911  else
1912  delta = newcontribution;
1913  }
1914  }
1915  /* old bound was finite and not too large */
1916  else
1917  {
1918  if( !finitenewbound )
1919  {
1920  /* if the new bound is +infinity, the old contribution has to be subtracted
1921  * and the counter for positive infinite contributions has to be increased
1922  */
1923  if( newbound > 0.0 )
1924  {
1925  (*activityposinf)++;
1926  delta = -oldcontribution;
1927  }
1928  /* if the new bound is -infinity, the old contribution has to be subtracted
1929  * and the counter for negative infinite contributions has to be increased
1930  */
1931  else
1932  {
1933  assert(newbound < 0.0 );
1934 
1935  (*activityneginf)++;
1936  delta = -oldcontribution;
1937  }
1938  }
1939  /* if the contribution of this variable is too large, increase the counter for huge values */
1940  else if( hugevalnewcont )
1941  {
1942  if( newcontribution > 0.0 )
1943  {
1944  (*activityposhuge)++;
1945  delta = -oldcontribution;
1946  }
1947  else
1948  {
1949  (*activityneghuge)++;
1950  delta = -oldcontribution;
1951  }
1952  }
1953  /* "normal case": just update the activity */
1954  else
1955  delta = newcontribution - oldcontribution;
1956  }
1957 
1958  /* update the activity, if the current value is valid and there was a change in the finite part */
1959  if( validact && (delta != 0.0) )
1960  {
1961  /* if the absolute value of the activity is increased, this is regarded as reliable,
1962  * otherwise, we check whether we can still trust the updated value
1963  */
1964  (*activity) = (*activity) + delta;
1965  assert(!SCIPisInfinity(scip, -(*activity)) && !SCIPisInfinity(scip, *activity));
1966 
1967  if( REALABS((*lastactivity)) < REALABS(*activity) )
1968  {
1969  (*lastactivity) = (*activity);
1970  }
1971  else
1972  {
1973  if( checkreliability && SCIPisUpdateUnreliable(scip, (*activity), (*lastactivity)) )
1974  {
1975  SCIPdebugMsg(scip, "%s activity of linear constraint unreliable after update: %16.9g\n",
1976  (global ? "global " : ""), (*activity));
1977 
1978  /* mark the activity that was just changed and is not reliable anymore to be invalid */
1979  if( global )
1980  {
1981  if( (boundtype == SCIP_BOUNDTYPE_LOWER) == (val > 0.0) )
1982  consdata->validglbminact = FALSE;
1983  else
1984  consdata->validglbmaxact = FALSE;
1985  }
1986  else
1987  {
1988  if( (boundtype == SCIP_BOUNDTYPE_LOWER) == (val > 0.0) )
1989  consdata->validminact = FALSE;
1990  else
1991  consdata->validmaxact = FALSE;
1992  }
1993  }
1994  }
1995  }
1996 }
1997 
1998 /** updates minimum and maximum activity for a change in lower bound */
1999 static
2001  SCIP* scip, /**< SCIP data structure */
2002  SCIP_CONSDATA* consdata, /**< linear constraint data */
2003  SCIP_VAR* var, /**< variable that has been changed */
2004  SCIP_Real oldlb, /**< old lower bound of variable */
2005  SCIP_Real newlb, /**< new lower bound of variable */
2006  SCIP_Real val, /**< coefficient of constraint entry */
2007  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2008  )
2009 {
2010  assert(scip != NULL);
2011  assert(consdata != NULL);
2012  assert(var != NULL);
2013 
2014  if( consdata->validactivities )
2015  {
2016  consdataUpdateActivities(scip, consdata, var, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, FALSE, checkreliability);
2017 
2018  assert(!SCIPisInfinity(scip, -consdata->minactivity) && !SCIPisInfinity(scip, consdata->minactivity));
2019  assert(!SCIPisInfinity(scip, -consdata->maxactivity) && !SCIPisInfinity(scip, consdata->maxactivity));
2020  }
2021 }
2022 
2023 /** updates minimum and maximum activity for a change in upper bound */
2024 static
2026  SCIP* scip, /**< SCIP data structure */
2027  SCIP_CONSDATA* consdata, /**< linear constraint data */
2028  SCIP_VAR* var, /**< variable that has been changed */
2029  SCIP_Real oldub, /**< old upper bound of variable */
2030  SCIP_Real newub, /**< new upper bound of variable */
2031  SCIP_Real val, /**< coefficient of constraint entry */
2032  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2033  )
2034 {
2035  assert(scip != NULL);
2036  assert(consdata != NULL);
2037  assert(var != NULL);
2038 
2039  if( consdata->validactivities )
2040  {
2041  consdataUpdateActivities(scip, consdata, var, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, FALSE, checkreliability);
2042 
2043  assert(!SCIPisInfinity(scip, -consdata->minactivity) && !SCIPisInfinity(scip, consdata->minactivity));
2044  assert(!SCIPisInfinity(scip, -consdata->maxactivity) && !SCIPisInfinity(scip, consdata->maxactivity));
2045  }
2046 }
2047 
2048 /** updates minimum and maximum global activity for a change in the global lower bound */
2049 static
2051  SCIP* scip, /**< SCIP data structure */
2052  SCIP_CONSDATA* consdata, /**< linear constraint data */
2053  SCIP_Real oldlb, /**< old lower bound of variable */
2054  SCIP_Real newlb, /**< new lower bound of variable */
2055  SCIP_Real val, /**< coefficient of constraint entry */
2056  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2057  )
2058 {
2059  assert(scip != NULL);
2060  assert(consdata != NULL);
2061 
2062  if( consdata->validactivities )
2063  {
2064  consdataUpdateActivities(scip, consdata, NULL, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, TRUE, checkreliability);
2065 
2066  assert(!SCIPisInfinity(scip, -consdata->glbminactivity) && !SCIPisInfinity(scip, consdata->glbminactivity));
2067  assert(!SCIPisInfinity(scip, -consdata->glbmaxactivity) && !SCIPisInfinity(scip, consdata->glbmaxactivity));
2068  }
2070 
2071 /** updates minimum and maximum global activity for a change in global upper bound */
2072 static
2074  SCIP* scip, /**< SCIP data structure */
2075  SCIP_CONSDATA* consdata, /**< linear constraint data */
2076  SCIP_Real oldub, /**< old upper bound of variable */
2077  SCIP_Real newub, /**< new upper bound of variable */
2078  SCIP_Real val, /**< coefficient of constraint entry */
2079  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2080  )
2081 {
2082  assert(scip != NULL);
2083  assert(consdata != NULL);
2084 
2085  if( consdata->validactivities )
2086  {
2087  consdataUpdateActivities(scip, consdata, NULL, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, TRUE, checkreliability);
2088 
2089  assert(!SCIPisInfinity(scip, -consdata->glbminactivity) && !SCIPisInfinity(scip, consdata->glbminactivity));
2090  assert(!SCIPisInfinity(scip, -consdata->glbmaxactivity) && !SCIPisInfinity(scip, consdata->glbmaxactivity));
2091  }
2093 
2094 /** updates minimum and maximum activity and maximum absolute value for coefficient addition */
2095 static
2097  SCIP* scip, /**< SCIP data structure */
2098  SCIP_CONSDATA* consdata, /**< linear constraint data */
2099  SCIP_VAR* var, /**< variable of constraint entry */
2100  SCIP_Real val, /**< coefficient of constraint entry */
2101  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2102  )
2103 {
2104  assert(scip != NULL);
2105  assert(consdata != NULL);
2106  assert(var != NULL);
2107 
2108  /* update maximum absolute value */
2109  if( consdata->validmaxabsval )
2110  {
2111  SCIP_Real absval;
2112 
2113  assert(consdata->maxabsval < SCIP_INVALID);
2114 
2115  absval = REALABS(val);
2116  consdata->maxabsval = MAX(consdata->maxabsval, absval);
2117  }
2118 
2119  if( consdata->validminabsval )
2120  {
2121  SCIP_Real absval;
2122 
2123  assert(consdata->minabsval < SCIP_INVALID);
2124 
2125  absval = REALABS(val);
2126  consdata->minabsval = MIN(consdata->minabsval, absval);
2127  }
2128 
2129  /* update minimal and maximal activity */
2130  if( consdata->validactivities )
2131  {
2132  assert(consdata->minactivity < SCIP_INVALID);
2133  assert(consdata->maxactivity < SCIP_INVALID);
2134  assert(consdata->glbminactivity < SCIP_INVALID);
2135  assert(consdata->glbmaxactivity < SCIP_INVALID);
2136 
2137  consdataUpdateActivitiesLb(scip, consdata, var, 0.0, SCIPvarGetLbLocal(var), val, checkreliability);
2138  consdataUpdateActivitiesUb(scip, consdata, var, 0.0, SCIPvarGetUbLocal(var), val, checkreliability);
2139  consdataUpdateActivitiesGlbLb(scip, consdata, 0.0, SCIPvarGetLbGlobal(var), val, checkreliability);
2140  consdataUpdateActivitiesGlbUb(scip, consdata, 0.0, SCIPvarGetUbGlobal(var), val, checkreliability);
2141  }
2142 }
2143 
2144 /** updates minimum and maximum activity for coefficient deletion, invalidates maximum absolute value if necessary */
2145 static
2147  SCIP* scip, /**< SCIP data structure */
2148  SCIP_CONSDATA* consdata, /**< linear constraint data */
2149  SCIP_VAR* var, /**< variable of constraint entry */
2150  SCIP_Real val, /**< coefficient of constraint entry */
2151  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2152  )
2153 {
2154  assert(scip != NULL);
2155  assert(consdata != NULL);
2156  assert(var != NULL);
2157 
2158  /* invalidate maximum absolute value, if this coefficient was the maximum */
2159  if( consdata->validmaxabsval )
2160  {
2161  SCIP_Real absval;
2162 
2163  absval = REALABS(val);
2164 
2165  if( SCIPisEQ(scip, absval, consdata->maxabsval) )
2166  {
2167  consdata->validmaxabsval = FALSE;
2168  consdata->maxabsval = SCIP_INVALID;
2169  }
2170  }
2171 
2172  /* invalidate minimum absolute value, if this coefficient was the minimum */
2173  if( consdata->validminabsval )
2174  {
2175  SCIP_Real absval;
2176 
2177  absval = REALABS(val);
2178 
2179  if( SCIPisEQ(scip, absval, consdata->minabsval) )
2180  {
2181  consdata->validminabsval = FALSE;
2182  consdata->minabsval = SCIP_INVALID;
2183  }
2184  }
2185 
2186  /* update minimal and maximal activity */
2187  if( consdata->validactivities )
2188  {
2189  assert(consdata->minactivity < SCIP_INVALID);
2190  assert(consdata->maxactivity < SCIP_INVALID);
2191  assert(consdata->glbminactivity < SCIP_INVALID);
2192  assert(consdata->glbmaxactivity < SCIP_INVALID);
2193 
2194  consdataUpdateActivitiesLb(scip, consdata, var, SCIPvarGetLbLocal(var), 0.0, val, checkreliability);
2195  consdataUpdateActivitiesUb(scip, consdata, var, SCIPvarGetUbLocal(var), 0.0, val, checkreliability);
2196  consdataUpdateActivitiesGlbLb(scip, consdata, SCIPvarGetLbGlobal(var), 0.0, val, checkreliability);
2197  consdataUpdateActivitiesGlbUb(scip, consdata, SCIPvarGetUbGlobal(var), 0.0, val, checkreliability);
2198  }
2199 }
2200 
2201 /** updates minimum and maximum activity for coefficient change, invalidates maximum absolute value if necessary */
2202 static
2204  SCIP* scip, /**< SCIP data structure */
2205  SCIP_CONSDATA* consdata, /**< linear constraint data */
2206  SCIP_VAR* var, /**< variable of constraint entry */
2207  SCIP_Real oldval, /**< old coefficient of constraint entry */
2208  SCIP_Real newval, /**< new coefficient of constraint entry */
2209  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2210  )
2211 {
2212  assert(scip != NULL);
2213  assert(consdata != NULL);
2214  assert(var != NULL);
2215 
2216  /* old zero coefficients should be handled by consdataUpdateAddCoef() */
2217  assert(!SCIPisZero(scip, oldval));
2218 
2219  /* new zero coefficients should be handled by consdataUpdateDelCoef() */
2220  assert(!SCIPisZero(scip, newval));
2221 
2222  /* update maximum absolute value */
2223  if( consdata->validmaxabsval )
2224  {
2225  SCIP_Real absval;
2226 
2227  absval = REALABS(newval);
2228 
2229  if( SCIPisGE(scip, absval, consdata->maxabsval) )
2230  {
2231  consdata->maxabsval = absval;
2232  }
2233  else
2234  {
2235  absval = REALABS(oldval);
2236 
2237  /* invalidate maximum absolute value */
2238  if( SCIPisEQ(scip, absval, consdata->maxabsval) )
2239  {
2240  consdata->validmaxabsval = FALSE;
2241  consdata->maxabsval = SCIP_INVALID;
2242  }
2243  }
2244  }
2245 
2246  /* update minimum absolute value */
2247  if( consdata->validminabsval )
2248  {
2249  SCIP_Real absval;
2250 
2251  absval = REALABS(newval);
2252 
2253  if( SCIPisLE(scip, absval, consdata->minabsval) )
2254  {
2255  consdata->minabsval = absval;
2256  }
2257  else
2258  {
2259  absval = REALABS(oldval);
2260 
2261  /* invalidate minimum absolute value */
2262  if( SCIPisEQ(scip, absval, consdata->minabsval) )
2263  {
2264  consdata->validminabsval = FALSE;
2265  consdata->minabsval = SCIP_INVALID;
2266  }
2267  }
2268  }
2269 
2270  /* update maximum activity delta */
2271  if( !SCIPisInfinity(scip, consdata->maxactdelta ) )
2272  {
2273  SCIP_Real domain;
2274  SCIP_Real delta;
2275 
2276  assert(!SCIPisInfinity(scip, SCIPvarGetLbLocal(var)));
2277  assert(!SCIPisInfinity(scip, SCIPvarGetUbLocal(var)));
2278 
2279  domain = SCIPvarGetUbLocal(var) - SCIPvarGetLbLocal(var);
2280  delta = REALABS(newval) * domain;
2281 
2282  if( delta > consdata->maxactdelta )
2283  {
2284  consdata->maxactdelta = delta;
2285  consdata->maxactdeltavar = var;
2286  }
2287  else
2288  {
2289  /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
2290  if( consdata->maxactdeltavar == var )
2291  consdata->maxactdelta = SCIP_INVALID;
2292  }
2293  }
2294 
2295  /* @todo do something more clever here, e.g. if oldval * newval >= 0, do the update directly */
2296  consdataUpdateDelCoef(scip, consdata, var, oldval, checkreliability);
2297  consdataUpdateAddCoef(scip, consdata, var, newval, checkreliability);
2298 }
2299 
2300 /** returns the maximum absolute value of all coefficients in the constraint */
2301 static
2303  SCIP_CONSDATA* consdata /**< linear constraint data */
2304  )
2305 {
2306  assert(consdata != NULL);
2307 
2308  if( !consdata->validmaxabsval )
2309  consdataCalcMaxAbsval(consdata);
2310  assert(consdata->validmaxabsval);
2311  assert(consdata->maxabsval < SCIP_INVALID);
2312 
2313  return consdata->maxabsval;
2314 }
2315 
2316 /** returns the minimum absolute value of all coefficients in the constraint */
2317 static
2319  SCIP_CONSDATA* consdata /**< linear constraint data */
2320  )
2322  assert(consdata != NULL);
2323 
2324  if( !consdata->validminabsval )
2325  consdataCalcMinAbsval(consdata);
2326  assert(consdata->validminabsval);
2327  assert(consdata->minabsval < SCIP_INVALID);
2328 
2329  return consdata->minabsval;
2330 }
2331 
2332 /** calculates minimum and maximum local and global activity for constraint from scratch;
2333  * additionally recalculates maximum absolute value of coefficients
2334  */
2335 static
2337  SCIP* scip, /**< SCIP data structure */
2338  SCIP_CONSDATA* consdata /**< linear constraint data */
2339  )
2340 {
2341  int i;
2342 
2343  assert(scip != NULL);
2344  assert(consdata != NULL);
2345  assert(!consdata->validactivities);
2346  assert(consdata->minactivity >= SCIP_INVALID || consdata->validminact);
2347  assert(consdata->maxactivity >= SCIP_INVALID || consdata->validmaxact);
2348  assert(consdata->glbminactivity >= SCIP_INVALID || consdata->validglbminact);
2349  assert(consdata->glbmaxactivity >= SCIP_INVALID || consdata->validglbmaxact);
2350 
2351  consdata->validmaxabsval = TRUE;
2352  consdata->validminabsval = TRUE;
2353  consdata->validactivities = TRUE;
2354  consdata->validminact = TRUE;
2355  consdata->validmaxact = TRUE;
2356  consdata->validglbminact = TRUE;
2357  consdata->validglbmaxact = TRUE;
2358  consdata->maxabsval = 0.0;
2359  consdata->minabsval = (consdata->nvars == 0 ? 0.0 : REALABS(consdata->vals[0]));
2360  consdata->minactivity = 0.0;
2361  consdata->maxactivity = 0.0;
2362  consdata->lastminactivity = 0.0;
2363  consdata->lastmaxactivity = 0.0;
2364  consdata->minactivityneginf = 0;
2365  consdata->minactivityposinf = 0;
2366  consdata->maxactivityneginf = 0;
2367  consdata->maxactivityposinf = 0;
2368  consdata->minactivityneghuge = 0;
2369  consdata->minactivityposhuge = 0;
2370  consdata->maxactivityneghuge = 0;
2371  consdata->maxactivityposhuge = 0;
2372  consdata->glbminactivity = 0.0;
2373  consdata->glbmaxactivity = 0.0;
2374  consdata->lastglbminactivity = 0.0;
2375  consdata->lastglbmaxactivity = 0.0;
2376  consdata->glbminactivityneginf = 0;
2377  consdata->glbminactivityposinf = 0;
2378  consdata->glbmaxactivityneginf = 0;
2379  consdata->glbmaxactivityposinf = 0;
2380  consdata->glbminactivityneghuge = 0;
2381  consdata->glbminactivityposhuge = 0;
2382  consdata->glbmaxactivityneghuge = 0;
2383  consdata->glbmaxactivityposhuge = 0;
2384 
2385  for( i = 0; i < consdata->nvars; ++i )
2386  consdataUpdateAddCoef(scip, consdata, consdata->vars[i], consdata->vals[i], FALSE);
2387 
2388  consdata->lastminactivity = consdata->minactivity;
2389  consdata->lastmaxactivity = consdata->maxactivity;
2390  consdata->lastglbminactivity = consdata->glbminactivity;
2391  consdata->lastglbmaxactivity = consdata->glbmaxactivity;
2392 }
2393 
2394 /** gets minimal activity for constraint and given values of counters for infinite and huge contributions
2395  * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
2396  */
2397 static
2398 void getMinActivity(
2399  SCIP* scip, /**< SCIP data structure */
2400  SCIP_CONSDATA* consdata, /**< linear constraint */
2401  int posinf, /**< number of coefficients contributing pos. infinite value */
2402  int neginf, /**< number of coefficients contributing neg. infinite value */
2403  int poshuge, /**< number of coefficients contributing huge pos. value */
2404  int neghuge, /**< number of coefficients contributing huge neg. value */
2405  SCIP_Real delta, /**< value to subtract from stored minactivity
2406  * (contribution of the variable set to zero when getting residual activity) */
2407  SCIP_Bool global, /**< should the global or local minimal activity be returned? */
2408  SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
2409  SCIP_Real* minactivity, /**< pointer to store the minimal activity */
2410  SCIP_Bool* isrelax, /**< pointer to store whether the activity is a relaxation,
2411  * i.e. is <= the exact minactivity (in case of huge contributing values) */
2412  SCIP_Bool* issettoinfinity /**< pointer to store whether minactivity was set to infinity or calculated */
2413  )
2414 {
2415  assert(scip != NULL);
2416  assert(consdata != NULL);
2417  assert(posinf >= 0);
2418  assert(neginf >= 0);
2419  assert(poshuge >= 0);
2420  assert(neghuge >= 0);
2421  assert(minactivity != NULL);
2422  assert(isrelax != NULL);
2423  assert(issettoinfinity != NULL);
2424 
2425  /* if we have pos. infinite contributions, the minactivity is +infty */
2426  if( posinf > 0 )
2427  {
2428  *minactivity = SCIPinfinity(scip);
2429  *issettoinfinity = TRUE;
2430  *isrelax = FALSE;
2431  }
2432  /* if we have neg. (and no pos.) infinite contributions, the minactivity is -infty */
2433  else if( neginf > 0 )
2434  {
2435  *minactivity = -SCIPinfinity(scip);
2436  *issettoinfinity = TRUE;
2437  *isrelax = FALSE;
2438  }
2439  /* if we have neg. huge contributions, we only know that -infty is a relaxation of the minactivity */
2440  else if( neghuge > 0 )
2441  {
2442  *minactivity = -SCIPinfinity(scip);
2443  *issettoinfinity = TRUE;
2444  *isrelax = TRUE;
2445  }
2446  /* we do not need a good relaxation and we have positive huge contributions, so we just return -infty as activity */
2447  else if( !goodrelax && poshuge > 0 )
2448  {
2449  *minactivity = -SCIPinfinity(scip);
2450  *issettoinfinity = TRUE;
2451  *isrelax = TRUE;
2452  }
2453  else
2454  {
2455  SCIP_Real tmpactivity;
2456 
2457  /* recompute minactivity if it is not valid */
2458  if( global )
2459  {
2460  if( !consdata->validglbminact )
2461  consdataRecomputeGlbMinactivity(scip, consdata);
2462  assert(consdata->validglbminact);
2463 
2464  tmpactivity = consdata->glbminactivity;
2465  }
2466  else
2467  {
2468  if( !consdata->validminact )
2469  consdataRecomputeMinactivity(scip, consdata);
2470  assert(consdata->validminact);
2471 
2472  tmpactivity = consdata->minactivity;
2473  }
2474 
2475  /* we have no infinite and no neg. huge contributions, but pos. huge contributions;
2476  * a feasible relaxation of the minactivity is the number of positive huge contributions
2477  * times the minimum value counting as "huge" plus finite (and non-huge) part of minactivity - delta
2478  */
2479  if( poshuge > 0 )
2480  {
2481  *minactivity = 1.0 * poshuge * SCIPgetHugeValue(scip) + (tmpactivity - delta);
2482  *issettoinfinity = FALSE;
2483  *isrelax = TRUE;
2484  }
2485  /* all counters are zero, so the minactivity is just stored and we subtract the delta */
2486  else
2487  {
2488  *minactivity = tmpactivity - delta;
2489  *issettoinfinity = FALSE;
2490  *isrelax = FALSE;
2491  }
2492  }
2493 }
2494 
2495 /** gets maximal activity for constraint and given values of counters for infinite and huge contributions
2496  * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
2497  */
2498 static
2499 void getMaxActivity(
2500  SCIP* scip, /**< SCIP data structure */
2501  SCIP_CONSDATA* consdata, /**< linear constraint */
2502  int posinf, /**< number of coefficients contributing pos. infinite value */
2503  int neginf, /**< number of coefficients contributing neg. infinite value */
2504  int poshuge, /**< number of coefficients contributing huge pos. value */
2505  int neghuge, /**< number of coefficients contributing huge neg. value */
2506  SCIP_Real delta, /**< value to subtract from stored maxactivity
2507  * (contribution of the variable set to zero when getting residual activity) */
2508  SCIP_Bool global, /**< should the global or local maximal activity be returned? */
2509  SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
2510  SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
2511  SCIP_Bool* isrelax, /**< pointer to store whether the activity is a relaxation,
2512  * i.e. is >= the exact maxactivity (in case of huge contributing values) */
2513  SCIP_Bool* issettoinfinity /**< pointer to store whether maxactivity was set to infinity or calculated */
2514  )
2515 {
2516  assert(scip != NULL);
2517  assert(consdata != NULL);
2518  assert(posinf >= 0);
2519  assert(neginf >= 0);
2520  assert(poshuge >= 0);
2521  assert(neghuge >= 0);
2522  assert(maxactivity != NULL);
2523  assert(isrelax != NULL);
2524  assert(issettoinfinity != NULL);
2525 
2526  /* if we have neg. infinite contributions, the maxactivity is -infty */
2527  if( neginf > 0 )
2528  {
2529  *maxactivity = -SCIPinfinity(scip);
2530  *issettoinfinity = TRUE;
2531  *isrelax = FALSE;
2532  }
2533  /* if we have pos. (and no neg.) infinite contributions, the maxactivity is +infty */
2534  else if( posinf > 0 )
2535  {
2536  *maxactivity = SCIPinfinity(scip);
2537  *issettoinfinity = TRUE;
2538  *isrelax = FALSE;
2539  }
2540  /* if we have pos. huge contributions, we only know that +infty is a relaxation of the maxactivity */
2541  else if( poshuge > 0 )
2542  {
2543  *maxactivity = SCIPinfinity(scip);
2544  *issettoinfinity = TRUE;
2545  *isrelax = TRUE;
2546  }
2547  /* we do not need a good relaxation and we have positve huge contributions, so we just return +infty as activity */
2548  else if( !goodrelax && neghuge > 0 )
2549  {
2550  *maxactivity = SCIPinfinity(scip);
2551  *issettoinfinity = TRUE;
2552  *isrelax = TRUE;
2553  }
2554  else
2555  {
2556  SCIP_Real tmpactivity;
2557 
2558  /* recompute maxactivity if it is not valid */
2559  if( global )
2560  {
2561  if( !consdata->validglbmaxact )
2562  consdataRecomputeGlbMaxactivity(scip, consdata);
2563  assert(consdata->validglbmaxact);
2564 
2565  tmpactivity = consdata->glbmaxactivity;
2566  }
2567  else
2568  {
2569  if( !consdata->validmaxact )
2570  consdataRecomputeMaxactivity(scip, consdata);
2571  assert(consdata->validmaxact);
2572 
2573  tmpactivity = consdata->maxactivity;
2574  }
2575 
2576  /* we have no infinite, and no pos. huge contributions, but neg. huge contributions;
2577  * a feasible relaxation of the maxactivity is minus the number of negative huge contributions
2578  * times the minimum value counting as "huge" plus the finite (and non-huge) part of maxactivity minus delta
2579  */
2580  if( neghuge > 0 )
2581  {
2582  *maxactivity = -1.0 * neghuge * SCIPgetHugeValue(scip) + tmpactivity - delta;
2583  *issettoinfinity = FALSE;
2584  *isrelax = TRUE;
2585  }
2586  /* all counters are zero, so the maxactivity is just stored and we subtract the delta */
2587  else
2588  {
2589  *maxactivity = tmpactivity - delta;
2590  *issettoinfinity = FALSE;
2591  *isrelax = FALSE;
2592  }
2593  }
2594 }
2595 
2596 /** gets activity bounds for constraint */
2597 static
2599  SCIP* scip, /**< SCIP data structure */
2600  SCIP_CONSDATA* consdata, /**< linear constraint */
2601  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2602  * relaxed activities ignored, anyway? */
2603  SCIP_Real* minactivity, /**< pointer to store the minimal activity */
2604  SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
2605  SCIP_Bool* minisrelax, /**< pointer to store whether the returned minactivity is just a relaxation,
2606  * i.e. <= the exact minactivity (in case of huge contributions),
2607  * or equal to the exact minimal activity */
2608  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned maxactivity is just a relaxation,
2609  * i.e. >= the exact maxactivity (in case of huge contributions),
2610  * or equal to the exact maximal activity */
2611  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minactivity was set to infinity or calculated */
2612  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxactivity was set to infinity or calculated */
2613 
2614  )
2615 {
2616  assert(scip != NULL);
2617  assert(consdata != NULL);
2618  assert(minactivity != NULL);
2619  assert(maxactivity != NULL);
2620  assert(isminsettoinfinity != NULL);
2621  assert(ismaxsettoinfinity != NULL);
2622 
2623  if( !consdata->validactivities )
2624  {
2625  consdataCalcActivities(scip, consdata);
2626  assert(consdata->validminact);
2627  assert(consdata->validmaxact);
2628  }
2629  assert(consdata->minactivity < SCIP_INVALID);
2630  assert(consdata->maxactivity < SCIP_INVALID);
2631  assert(consdata->minactivityneginf >= 0);
2632  assert(consdata->minactivityposinf >= 0);
2633  assert(consdata->maxactivityneginf >= 0);
2634  assert(consdata->maxactivityposinf >= 0);
2635 
2636  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2637  consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2638  minactivity, minisrelax, isminsettoinfinity);
2639 
2640  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2641  consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2642  maxactivity, maxisrelax, ismaxsettoinfinity);
2643 }
2644 
2645 /** calculates activity bounds for constraint after setting variable to zero */
2646 static
2648  SCIP* scip, /**< SCIP data structure */
2649  SCIP_CONSDATA* consdata, /**< linear constraint */
2650  SCIP_VAR* cancelvar, /**< variable to calculate activity residual for */
2651  SCIP_Real* resactivity, /**< pointer to store the residual activity */
2652  SCIP_Bool isminresact, /**< should minimal or maximal residual activity be calculated? */
2653  SCIP_Bool useglobalbounds /**< should global or local bounds be used? */
2654  )
2655 {
2656  SCIP_VAR* var;
2657  SCIP_Real val;
2658  SCIP_Real lb;
2659  SCIP_Real ub;
2660  int v;
2661 
2662  assert(scip != NULL);
2663  assert(consdata != NULL);
2664  assert(cancelvar != NULL);
2665  assert(resactivity != NULL);
2667  *resactivity = 0.0;
2668 
2669  for( v = 0; v < consdata->nvars; ++v )
2670  {
2671  var = consdata->vars[v];
2672  assert(var != NULL);
2673  if( var == cancelvar )
2674  continue;
2675 
2676  val = consdata->vals[v];
2677 
2678  if( useglobalbounds )
2679  {
2680  lb = SCIPvarGetLbGlobal(var);
2681  ub = SCIPvarGetUbGlobal(var);
2682  }
2683  else
2684  {
2685  lb = SCIPvarGetLbLocal(var);
2686  ub = SCIPvarGetUbLocal(var);
2687  }
2688 
2689  assert(!SCIPisZero(scip, val));
2690  assert(SCIPisLE(scip, lb, ub));
2691 
2692  if( val > 0.0 )
2693  {
2694  if( isminresact )
2695  {
2696  assert(!SCIPisInfinity(scip, -lb));
2697  assert(!SCIPisHugeValue(scip, REALABS(val*lb)));
2698  *resactivity += val*lb;
2699  }
2700  else
2701  {
2702  assert(!SCIPisInfinity(scip, ub));
2703  assert(!SCIPisHugeValue(scip, REALABS(val*ub)));
2704  *resactivity += val*ub;
2705  }
2706  }
2707  else
2708  {
2709  if( isminresact)
2710  {
2711  assert(!SCIPisInfinity(scip, ub));
2712  assert(!SCIPisHugeValue(scip, REALABS(val*ub)));
2713  *resactivity += val*ub;
2714  }
2715  else
2716  {
2717  assert(!SCIPisInfinity(scip, -lb));
2718  assert(!SCIPisHugeValue(scip, REALABS(val*lb)));
2719  *resactivity += val*lb;
2720  }
2721  }
2722  }
2723  assert(!SCIPisInfinity(scip, *resactivity) && !SCIPisInfinity(scip, -(*resactivity)));
2724 }
2725 
2726 /** gets activity bounds for constraint after setting variable to zero */
2727 static
2729  SCIP* scip, /**< SCIP data structure */
2730  SCIP_CONSDATA* consdata, /**< linear constraint */
2731  SCIP_VAR* var, /**< variable to calculate activity residual for */
2732  SCIP_Real val, /**< coefficient value of variable in linear constraint */
2733  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2734  * relaxed acticities ignored, anyway? */
2735  SCIP_Real* minresactivity, /**< pointer to store the minimal residual activity */
2736  SCIP_Real* maxresactivity, /**< pointer to store the maximal residual activity */
2737  SCIP_Bool* minisrelax, /**< pointer to store whether the returned residual minactivity is just a
2738  * relaxation, i.e. <= the exact residual minactivity (in case of huge
2739  * contributions), or equal to the exact residual minactivity */
2740  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned residual maxactivity is just a
2741  * relaxation, i.e. <= the exact residual maxactivity (in case of huge
2742  * contributions), or equal to the exact residual minactivity */
2743  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2744  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
2745  )
2746 {
2747  SCIP_Real minactbound;
2748  SCIP_Real maxactbound;
2749  SCIP_Real absval;
2750 
2751  assert(scip != NULL);
2752  assert(consdata != NULL);
2753  assert(var != NULL);
2754  assert(minresactivity != NULL);
2755  assert(maxresactivity != NULL);
2756  assert(minisrelax != NULL);
2757  assert(maxisrelax != NULL);
2758  assert(isminsettoinfinity != NULL);
2759  assert(ismaxsettoinfinity != NULL);
2760 
2761  /* get activity bounds of linear constraint */
2762  if( !consdata->validactivities )
2763  {
2764  consdataCalcActivities(scip, consdata);
2765  assert(consdata->validminact);
2766  assert(consdata->validmaxact);
2767  }
2768  assert(consdata->minactivity < SCIP_INVALID);
2769  assert(consdata->maxactivity < SCIP_INVALID);
2770  assert(consdata->minactivityneginf >= 0);
2771  assert(consdata->minactivityposinf >= 0);
2772  assert(consdata->maxactivityneginf >= 0);
2773  assert(consdata->maxactivityposinf >= 0);
2774  assert(consdata->minactivityneghuge >= 0);
2775  assert(consdata->minactivityposhuge >= 0);
2776  assert(consdata->maxactivityneghuge >= 0);
2777  assert(consdata->maxactivityposhuge >= 0);
2778 
2779  if( val > 0.0 )
2780  {
2781  minactbound = SCIPvarGetLbLocal(var);
2782  maxactbound = SCIPvarGetUbLocal(var);
2783  absval = val;
2784  }
2785  else
2786  {
2787  minactbound = -SCIPvarGetUbLocal(var);
2788  maxactbound = -SCIPvarGetLbLocal(var);
2789  absval = -val;
2790  }
2791 
2792  /* get/compute minactivity by calling getMinActivity() with updated counters for infinite and huge values
2793  * and contribution of variable set to zero that has to be subtracted from finite part of activity
2794  */
2795  if( SCIPisInfinity(scip, minactbound) )
2796  {
2797  assert(consdata->minactivityposinf >= 1);
2798 
2799  getMinActivity(scip, consdata, consdata->minactivityposinf - 1, consdata->minactivityneginf,
2800  consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2801  minresactivity, minisrelax, isminsettoinfinity);
2802  }
2803  else if( SCIPisInfinity(scip, -minactbound) )
2804  {
2805  assert(consdata->minactivityneginf >= 1);
2806 
2807  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf - 1,
2808  consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2809  minresactivity, minisrelax, isminsettoinfinity);
2810  }
2811  else if( SCIPisHugeValue(scip, minactbound * absval) )
2812  {
2813  assert(consdata->minactivityposhuge >= 1);
2814 
2815  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2816  consdata->minactivityposhuge - 1, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2817  minresactivity, minisrelax, isminsettoinfinity);
2818  }
2819  else if( SCIPisHugeValue(scip, -minactbound * absval) )
2820  {
2821  assert(consdata->minactivityneghuge >= 1);
2822 
2823  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2824  consdata->minactivityposhuge, consdata->minactivityneghuge - 1, 0.0, FALSE, goodrelax,
2825  minresactivity, minisrelax, isminsettoinfinity);
2826  }
2827  else
2828  {
2829  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2830  consdata->minactivityposhuge, consdata->minactivityneghuge, absval * minactbound, FALSE, goodrelax,
2831  minresactivity, minisrelax, isminsettoinfinity);
2832  }
2833 
2834  /* get/compute maxactivity by calling getMaxActivity() with updated counters for infinite and huge values
2835  * and contribution of variable set to zero that has to be subtracted from finite part of activity
2836  */
2837  if( SCIPisInfinity(scip, -maxactbound) )
2838  {
2839  assert(consdata->maxactivityneginf >= 1);
2840 
2841  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf - 1,
2842  consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2843  maxresactivity, maxisrelax, ismaxsettoinfinity);
2844  }
2845  else if( SCIPisInfinity(scip, maxactbound) )
2846  {
2847  assert(consdata->maxactivityposinf >= 1);
2848 
2849  getMaxActivity(scip, consdata, consdata->maxactivityposinf - 1, consdata->maxactivityneginf,
2850  consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2851  maxresactivity, maxisrelax, ismaxsettoinfinity);
2852  }
2853  else if( SCIPisHugeValue(scip, absval * maxactbound) )
2854  {
2855  assert(consdata->maxactivityposhuge >= 1);
2856 
2857  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2858  consdata->maxactivityposhuge - 1, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2859  maxresactivity, maxisrelax, ismaxsettoinfinity);
2860  }
2861  else if( SCIPisHugeValue(scip, -absval * maxactbound) )
2862  {
2863  assert(consdata->maxactivityneghuge >= 1);
2864 
2865  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2866  consdata->maxactivityposhuge, consdata->maxactivityneghuge - 1, 0.0, FALSE, goodrelax,
2867  maxresactivity, maxisrelax, ismaxsettoinfinity);
2868  }
2869  else
2870  {
2871  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2872  consdata->maxactivityposhuge, consdata->maxactivityneghuge, absval * maxactbound, FALSE, goodrelax,
2873  maxresactivity, maxisrelax, ismaxsettoinfinity);
2874  }
2875 }
2876 
2877 /** gets global activity bounds for constraint */
2878 static
2880  SCIP* scip, /**< SCIP data structure */
2881  SCIP_CONSDATA* consdata, /**< linear constraint */
2882  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2883  * relaxed acticities ignored, anyway? */
2884  SCIP_Real* glbminactivity, /**< pointer to store the minimal activity, or NULL, if not needed */
2885  SCIP_Real* glbmaxactivity, /**< pointer to store the maximal activity, or NULL, if not needed */
2886  SCIP_Bool* minisrelax, /**< pointer to store whether the returned minactivity is just a relaxation,
2887  * i.e. <= the exact minactivity (in case of huge contributions),
2888  * or equal to the exact minimal activity */
2889  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned maxactivity is just a relaxation,
2890  * i.e. >= the exact maxactivity (in case of huge contributions),
2891  * or equal to the exact maximal activity */
2892  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2893  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
2894  )
2895 {
2896  assert(scip != NULL);
2897  assert(consdata != NULL);
2898  assert((glbminactivity != NULL && minisrelax != NULL && isminsettoinfinity != NULL)
2899  || (glbmaxactivity != NULL && maxisrelax != NULL && ismaxsettoinfinity != NULL));
2900 
2901  if( !consdata->validactivities )
2902  {
2903  consdataCalcActivities(scip, consdata);
2904  assert(consdata->validglbminact);
2905  assert(consdata->validglbmaxact);
2906  }
2907  assert(consdata->glbminactivity < SCIP_INVALID);
2908  assert(consdata->glbmaxactivity < SCIP_INVALID);
2909  assert(consdata->glbminactivityneginf >= 0);
2910  assert(consdata->glbminactivityposinf >= 0);
2911  assert(consdata->glbmaxactivityneginf >= 0);
2912  assert(consdata->glbmaxactivityposinf >= 0);
2913  assert(consdata->glbminactivityneghuge >= 0);
2914  assert(consdata->glbminactivityposhuge >= 0);
2915  assert(consdata->glbmaxactivityneghuge >= 0);
2916  assert(consdata->glbmaxactivityposhuge >= 0);
2917 
2918  if( glbminactivity != NULL )
2919  {
2920  assert(isminsettoinfinity != NULL);
2921  assert(minisrelax != NULL);
2922 
2923  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
2924  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
2925  glbminactivity, minisrelax, isminsettoinfinity);
2926  }
2927 
2928  if( glbmaxactivity != NULL )
2929  {
2930  assert(ismaxsettoinfinity != NULL);
2931  assert(maxisrelax != NULL);
2932 
2933  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
2934  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
2935  glbmaxactivity, maxisrelax, ismaxsettoinfinity);
2936  }
2937 }
2938 
2939 /** gets global activity bounds for constraint after setting variable to zero */
2940 static
2942  SCIP* scip, /**< SCIP data structure */
2943  SCIP_CONSDATA* consdata, /**< linear constraint */
2944  SCIP_VAR* var, /**< variable to calculate activity residual for */
2945  SCIP_Real val, /**< coefficient value of variable in linear constraint */
2946  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2947  * relaxed acticities ignored, anyway? */
2948  SCIP_Real* minresactivity, /**< pointer to store the minimal residual activity, or NULL, if not needed */
2949  SCIP_Real* maxresactivity, /**< pointer to store the maximal residual activity, or NULL, if not needed */
2950  SCIP_Bool* minisrelax, /**< pointer to store whether the returned residual minactivity is just a
2951  * relaxation, i.e. <= the exact residual minactivity (in case of huge
2952  * contributions), or equal to the exact residual minactivity */
2953  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned residual maxactivity is just a
2954  * relaxation, i.e. <= the exact residual maxactivity (in case of huge
2955  * contributions), or equal to the exact residual minactivity */
2956  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2957  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
2958  )
2959 {
2960  SCIP_Real minactbound;
2961  SCIP_Real maxactbound;
2962  SCIP_Real absval;
2963 
2964  assert(scip != NULL);
2965  assert(consdata != NULL);
2966  assert(var != NULL);
2967  assert((minresactivity != NULL && minisrelax != NULL && isminsettoinfinity != NULL )
2968  || (maxresactivity != NULL && maxisrelax != NULL && ismaxsettoinfinity != NULL));
2969 
2970  /* get activity bounds of linear constraint */
2971  if( !consdata->validactivities )
2972  consdataCalcActivities(scip, consdata);
2973 
2974  assert(consdata->glbminactivity < SCIP_INVALID);
2975  assert(consdata->glbmaxactivity < SCIP_INVALID);
2976  assert(consdata->glbminactivityneginf >= 0);
2977  assert(consdata->glbminactivityposinf >= 0);
2978  assert(consdata->glbmaxactivityneginf >= 0);
2979  assert(consdata->glbmaxactivityposinf >= 0);
2980 
2981  if( val > 0.0 )
2982  {
2983  minactbound = SCIPvarGetLbGlobal(var);
2984  maxactbound = SCIPvarGetUbGlobal(var);
2985  absval = val;
2986  }
2987  else
2988  {
2989  minactbound = -SCIPvarGetUbGlobal(var);
2990  maxactbound = -SCIPvarGetLbGlobal(var);
2991  absval = -val;
2992  }
2993 
2994  if( minresactivity != NULL )
2995  {
2996  assert(isminsettoinfinity != NULL);
2997  assert(minisrelax != NULL);
2998 
2999  /* get/compute minactivity by calling getMinActivity() with updated counters for infinite and huge values
3000  * and contribution of variable set to zero that has to be subtracted from finite part of activity
3001  */
3002  if( SCIPisInfinity(scip, minactbound) )
3003  {
3004  assert(consdata->glbminactivityposinf >= 1);
3005 
3006  getMinActivity(scip, consdata, consdata->glbminactivityposinf - 1, consdata->glbminactivityneginf,
3007  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
3008  minresactivity, minisrelax, isminsettoinfinity);
3009  }
3010  else if( SCIPisInfinity(scip, -minactbound) )
3011  {
3012  assert(consdata->glbminactivityneginf >= 1);
3013 
3014  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf - 1,
3015  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
3016  minresactivity, minisrelax, isminsettoinfinity);
3017  }
3018  else if( SCIPisHugeValue(scip, minactbound * absval) )
3019  {
3020  assert(consdata->glbminactivityposhuge >= 1);
3021 
3022  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
3023  consdata->glbminactivityposhuge - 1, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
3024  minresactivity, minisrelax, isminsettoinfinity);
3025  }
3026  else if( SCIPisHugeValue(scip, -minactbound * absval) )
3027  {
3028  assert(consdata->glbminactivityneghuge >= 1);
3029 
3030  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
3031  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge - 1, 0.0, TRUE, goodrelax,
3032  minresactivity, minisrelax, isminsettoinfinity);
3033  }
3034  else
3035  {
3036  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
3037  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, absval * minactbound, TRUE,
3038  goodrelax, minresactivity, minisrelax, isminsettoinfinity);
3039  }
3040  }
3041 
3042  if( maxresactivity != NULL )
3043  {
3044  assert(ismaxsettoinfinity != NULL);
3045  assert(maxisrelax != NULL);
3046 
3047  /* get/compute maxactivity by calling getMaxActivity() with updated counters for infinite and huge values
3048  * and contribution of variable set to zero that has to be subtracted from finite part of activity
3049  */
3050  if( SCIPisInfinity(scip, -maxactbound) )
3051  {
3052  assert(consdata->glbmaxactivityneginf >= 1);
3053 
3054  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf - 1,
3055  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
3056  maxresactivity, maxisrelax, ismaxsettoinfinity);
3057  }
3058  else if( SCIPisInfinity(scip, maxactbound) )
3059  {
3060  assert(consdata->glbmaxactivityposinf >= 1);
3061 
3062  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf - 1, consdata->glbmaxactivityneginf,
3063  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
3064  maxresactivity, maxisrelax, ismaxsettoinfinity);
3065  }
3066  else if( SCIPisHugeValue(scip, absval * maxactbound) )
3067  {
3068  assert(consdata->glbmaxactivityposhuge >= 1);
3069 
3070  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
3071  consdata->glbmaxactivityposhuge - 1, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
3072  maxresactivity, maxisrelax, ismaxsettoinfinity);
3073  }
3074  else if( SCIPisHugeValue(scip, -absval * maxactbound) )
3075  {
3076  assert(consdata->glbmaxactivityneghuge >= 1);
3077 
3078  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
3079  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge - 1, 0.0, TRUE, goodrelax,
3080  maxresactivity, maxisrelax, ismaxsettoinfinity);
3081  }
3082  else
3083  {
3084  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
3085  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, absval * maxactbound, TRUE,
3086  goodrelax, maxresactivity, maxisrelax, ismaxsettoinfinity);
3087  }
3088  }
3089 }
3090 
3091 /** calculates the activity of the linear constraint for given solution */
3092 static
3094  SCIP* scip, /**< SCIP data structure */
3095  SCIP_CONSDATA* consdata, /**< linear constraint data */
3096  SCIP_SOL* sol /**< solution to get activity for, NULL to current solution */
3097  )
3098 {
3099  SCIP_Real activity;
3100 
3101  assert(scip != NULL);
3102  assert(consdata != NULL);
3103 
3104  if( sol == NULL && !SCIPhasCurrentNodeLP(scip) )
3105  activity = consdataComputePseudoActivity(scip, consdata);
3106  else
3107  {
3108  SCIP_Real solval;
3109  int nposinf;
3110  int nneginf;
3111  SCIP_Bool negsign;
3112  int v;
3113 
3114  activity = 0.0;
3115  nposinf = 0;
3116  nneginf = 0;
3117 
3118  for( v = 0; v < consdata->nvars; ++v )
3119  {
3120  solval = SCIPgetSolVal(scip, sol, consdata->vars[v]);
3121 
3122  if( consdata->vals[v] < 0 )
3123  negsign = TRUE;
3124  else
3125  negsign = FALSE;
3126 
3127  if( (SCIPisInfinity(scip, solval) && !negsign) || (SCIPisInfinity(scip, -solval) && negsign) )
3128  ++nposinf;
3129  else if( (SCIPisInfinity(scip, solval) && negsign) || (SCIPisInfinity(scip, -solval) && !negsign) )
3130  ++nneginf;
3131  else
3132  activity += consdata->vals[v] * solval;
3133  }
3134  assert(nneginf >= 0 && nposinf >= 0);
3135 
3136  SCIPdebugMsg(scip, "activity of linear constraint: %.15g, %d positive infinity values, %d negative infinity values \n", activity, nposinf, nneginf);
3137 
3138  /* check for amount of infinity values and correct the activity */
3139  if( nposinf > 0 && nneginf > 0 )
3140  activity = (consdata->rhs + consdata->lhs) / 2;
3141  else if( nposinf > 0 )
3142  activity = SCIPinfinity(scip);
3143  else if( nneginf > 0 )
3144  activity = -SCIPinfinity(scip);
3145 
3146  SCIPdebugMsg(scip, "corrected activity of linear constraint: %.15g\n", activity);
3147  }
3148 
3149  if( activity == SCIP_INVALID ) /*lint !e777*/
3150  return activity;
3151  else if( activity < 0 )
3152  activity = MAX(activity, -SCIPinfinity(scip)); /*lint !e666*/
3153  else
3154  activity = MIN(activity, SCIPinfinity(scip)); /*lint !e666*/
3155 
3156  return activity;
3157 }
3158 
3159 /** calculates the feasibility of the linear constraint for given solution */
3160 static
3162  SCIP* scip, /**< SCIP data structure */
3163  SCIP_CONSDATA* consdata, /**< linear constraint data */
3164  SCIP_SOL* sol /**< solution to get feasibility for, NULL to current solution */
3165  )
3166 {
3167  SCIP_Real activity;
3168 
3169  assert(scip != NULL);
3170  assert(consdata != NULL);
3171 
3172  activity = consdataGetActivity(scip, consdata, sol);
3173 
3174  if( activity == SCIP_INVALID ) /*lint !e777*/
3175  return -SCIPinfinity(scip);
3176 
3177  return MIN(consdata->rhs - activity, activity - consdata->lhs);
3178 }
3179 
3180 /** updates bit signatures after adding a single coefficient */
3181 static
3183  SCIP_CONSDATA* consdata, /**< linear constraint data */
3184  int pos /**< position of coefficient to update signatures for */
3185  )
3186 {
3187  uint64_t varsignature;
3188  SCIP_Real lb;
3189  SCIP_Real ub;
3190  SCIP_Real val;
3191 
3192  assert(consdata != NULL);
3193  assert(consdata->validsignature);
3194 
3195  varsignature = SCIPhashSignature64(SCIPvarGetIndex(consdata->vars[pos]));
3196  lb = SCIPvarGetLbGlobal(consdata->vars[pos]);
3197  ub = SCIPvarGetUbGlobal(consdata->vars[pos]);
3198  val = consdata->vals[pos];
3199  if( (val > 0.0 && ub > 0.0) || (val < 0.0 && lb < 0.0) )
3200  consdata->possignature |= varsignature;
3201  if( (val > 0.0 && lb < 0.0) || (val < 0.0 && ub > 0.0) )
3202  consdata->negsignature |= varsignature;
3203 }
3204 
3205 /** calculates the bit signatures of the given constraint data */
3206 static
3208  SCIP_CONSDATA* consdata /**< linear constraint data */
3209  )
3210 {
3211  assert(consdata != NULL);
3212 
3213  if( !consdata->validsignature )
3214  {
3215  int i;
3216 
3217  consdata->validsignature = TRUE;
3218  consdata->possignature = 0;
3219  consdata->negsignature = 0;
3220  for( i = 0; i < consdata->nvars; ++i )
3221  consdataUpdateSignatures(consdata, i);
3222  }
3223 }
3224 
3225 /** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
3226 static
3227 SCIP_DECL_SORTINDCOMP(consdataCompVar)
3228 { /*lint --e{715}*/
3229  SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
3230  SCIP_VAR* var1;
3231  SCIP_VAR* var2;
3232 
3233  assert(consdata != NULL);
3234  assert(0 <= ind1 && ind1 < consdata->nvars);
3235  assert(0 <= ind2 && ind2 < consdata->nvars);
3236 
3237  var1 = consdata->vars[ind1];
3238  var2 = consdata->vars[ind2];
3239 
3240  /* exactly one variable is binary */
3241  if( SCIPvarIsBinary(var1) != SCIPvarIsBinary(var2) )
3242  {
3243  return (SCIPvarIsBinary(var1) ? -1 : +1);
3244  }
3245  /* both variables are binary */
3246  else if( SCIPvarIsBinary(var1) )
3247  {
3248  return SCIPvarCompare(var1, var2);
3249  }
3250  else
3251  {
3252  SCIP_VARTYPE vartype1 = SCIPvarGetType(var1);
3253  SCIP_VARTYPE vartype2 = SCIPvarGetType(var2);
3254 
3255  if( vartype1 < vartype2 )
3256  return -1;
3257  else if( vartype1 > vartype2 )
3258  return +1;
3259  else
3260  return SCIPvarCompare(var1, var2);
3261  }
3262 }
3263 
3264 /** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
3265 static
3266 SCIP_DECL_SORTINDCOMP(consdataCompVarProp)
3267 { /*lint --e{715}*/
3268  SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
3269  SCIP_VAR* var1;
3270  SCIP_VAR* var2;
3271 
3272  assert(consdata != NULL);
3273  assert(0 <= ind1 && ind1 < consdata->nvars);
3274  assert(0 <= ind2 && ind2 < consdata->nvars);
3275 
3276  var1 = consdata->vars[ind1];
3277  var2 = consdata->vars[ind2];
3278 
3279  /* exactly one variable is binary */
3280  if( SCIPvarIsBinary(var1) != SCIPvarIsBinary(var2) )
3281  {
3282  return (SCIPvarIsBinary(var1) ? -1 : +1);
3283  }
3284  /* both variables are binary */
3285  else if( SCIPvarIsBinary(var1) )
3286  {
3287  SCIP_Real abscoef1 = REALABS(consdata->vals[ind1]);
3288  SCIP_Real abscoef2 = REALABS(consdata->vals[ind2]);
3289 
3290  if( EPSGT(abscoef1, abscoef2, 1e-9) )
3291  return -1;
3292  else if( EPSGT(abscoef2, abscoef1, 1e-9) )
3293  return +1;
3294  else
3295  return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
3296  }
3297  else
3298  {
3299  SCIP_VARTYPE vartype1 = SCIPvarGetType(var1);
3300  SCIP_VARTYPE vartype2 = SCIPvarGetType(var2);
3301 
3302  if( vartype1 < vartype2 )
3303  {
3304  return -1;
3305  }
3306  else if( vartype1 > vartype2 )
3307  {
3308  return +1;
3309  }
3310  else
3311  {
3312  /* both variables are continuous */
3313  if( !SCIPvarIsIntegral(var1) )
3314  {
3315  assert(!SCIPvarIsIntegral(var2));
3316  return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
3317  }
3318  else
3319  {
3320  SCIP_Real abscont1 = REALABS(consdata->vals[ind1] * (SCIPvarGetUbGlobal(var1) - SCIPvarGetLbGlobal(var1)));
3321  SCIP_Real abscont2 = REALABS(consdata->vals[ind2] * (SCIPvarGetUbGlobal(var2) - SCIPvarGetLbGlobal(var2)));
3322 
3323  if( EPSGT(abscont1, abscont2, 1e-9) )
3324  return -1;
3325  else if( EPSGT(abscont2, abscont1, 1e-9) )
3326  return +1;
3327  else
3328  return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
3329  }
3330  }
3331  }
3332 }
3333 
3334 /** permutes the constraint's variables according to a given permutation. */
3335 static
3336 void permSortConsdata(
3337  SCIP_CONSDATA* consdata, /**< the constraint data */
3338  int* perm, /**< the target permutation */
3339  int nvars /**< the number of variables */
3340  )
3341 { /*lint --e{715}*/
3342  SCIP_VAR* varv;
3343  SCIP_EVENTDATA* eventdatav;
3344  SCIP_Real valv;
3345  int v;
3346  int i;
3347  int nexti;
3348 
3349  assert(perm != NULL);
3350  assert(consdata != NULL);
3351 
3352  /* permute the variables in the linear constraint according to the target permutation */
3353  eventdatav = NULL;
3354  for( v = 0; v < nvars; ++v )
3355  {
3356  if( perm[v] != v )
3357  {
3358  varv = consdata->vars[v];
3359  valv = consdata->vals[v];
3360  if( consdata->eventdata != NULL )
3361  eventdatav = consdata->eventdata[v];
3362  i = v;
3363  do
3364  {
3365  assert(0 <= perm[i] && perm[i] < nvars);
3366  assert(perm[i] != i);
3367  consdata->vars[i] = consdata->vars[perm[i]];
3368  consdata->vals[i] = consdata->vals[perm[i]];
3369  if( consdata->eventdata != NULL )
3370  {
3371  consdata->eventdata[i] = consdata->eventdata[perm[i]];
3372  consdata->eventdata[i]->varpos = i;
3373  }
3374  nexti = perm[i];
3375  perm[i] = i;
3376  i = nexti;
3377  }
3378  while( perm[i] != v );
3379  consdata->vars[i] = varv;
3380  consdata->vals[i] = valv;
3381  if( consdata->eventdata != NULL )
3382  {
3383  consdata->eventdata[i] = eventdatav;
3384  consdata->eventdata[i]->varpos = i;
3385  }
3386  perm[i] = i;
3387  }
3388  }
3389 #ifdef SCIP_DEBUG
3390  /* check sorting */
3391  for( v = 0; v < nvars; ++v )
3392  {
3393  assert(perm[v] == v);
3394  assert(consdata->eventdata == NULL || consdata->eventdata[v]->varpos == v);
3395  }
3396 #endif
3397 }
3398 
3399 /** sorts linear constraint's variables depending on the stage of the solving process:
3400  * - during PRESOLVING
3401  * sorts variables by binaries, integers, implicit integers, and continuous variables,
3402  * and the variables of the same type by non-decreasing variable index
3403  *
3404  * - during SOLVING
3405  * sorts variables of the remaining problem by binaries, integers, implicit integers, and continuous variables,
3406  * and binary and integer variables by their global max activity delta (within each group),
3407  * ties within a group are broken by problem index of the variable.
3408  *
3409  * This fastens the propagation time of the constraint handler.
3410  */
3411 static
3413  SCIP* scip, /**< SCIP data structure */
3414  SCIP_CONSDATA* consdata /**< linear constraint data */
3415  )
3416 {
3417  assert(scip != NULL);
3418  assert(consdata != NULL);
3419 
3420  /* check if there are variables for sorting */
3421  if( consdata->nvars <= 1 )
3422  {
3423  consdata->indexsorted = TRUE;
3424  consdata->coefsorted = TRUE;
3425  consdata->nbinvars = (consdata->nvars == 1 ? (int)SCIPvarIsBinary(consdata->vars[0]) : 0);
3426  }
3427  else if( (!consdata->indexsorted && SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE)
3428  || (!consdata->coefsorted && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE) )
3429  {
3430  int* perm;
3431  int v;
3432 
3433  /* get temporary memory to store the sorted permutation */
3434  SCIP_CALL( SCIPallocBufferArray(scip, &perm, consdata->nvars) );
3435 
3436  /* call sorting method */
3437  if( SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE )
3438  SCIPsort(perm, consdataCompVar, (void*)consdata, consdata->nvars);
3439  else
3440  SCIPsort(perm, consdataCompVarProp, (void*)consdata, consdata->nvars);
3441 
3442  permSortConsdata(consdata, perm, consdata->nvars);
3443 
3444  /* free temporary memory */
3445  SCIPfreeBufferArray(scip, &perm);
3446 
3447  if( SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE )
3448  {
3449  consdata->indexsorted = FALSE;
3450  consdata->coefsorted = TRUE;
3451 
3452  /* count binary variables in the sorted vars array */
3453  consdata->nbinvars = 0;
3454  for( v = 0; v < consdata->nvars; ++v )
3455  {
3456  if( SCIPvarIsBinary(consdata->vars[v]) )
3457  ++consdata->nbinvars;
3458  else
3459  break;
3460  }
3461  }
3462  else
3463  {
3464  consdata->indexsorted = TRUE;
3465  consdata->coefsorted = FALSE;
3466  }
3467  }
3468 
3469  return SCIP_OKAY;
3470 }
3471 
3472 
3473 /*
3474  * local linear constraint handler methods
3475  */
3476 
3477 /** sets left hand side of linear constraint */
3478 static
3480  SCIP* scip, /**< SCIP data structure */
3481  SCIP_CONS* cons, /**< linear constraint */
3482  SCIP_Real lhs /**< new left hand side */
3483  )
3484 {
3485  SCIP_CONSDATA* consdata;
3486  SCIP_Bool locked;
3487  int i;
3488 
3489  assert(scip != NULL);
3490  assert(cons != NULL);
3491  assert(!SCIPisInfinity(scip, lhs));
3492 
3493  /* adjust value to not be smaller than -inf */
3494  if ( SCIPisInfinity(scip, -lhs) )
3495  lhs = -SCIPinfinity(scip);
3496 
3497  consdata = SCIPconsGetData(cons);
3498  assert(consdata != NULL);
3499  assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
3500  assert(!SCIPisInfinity(scip, consdata->lhs));
3501 
3502  /* check whether the side is not changed */
3503  if( SCIPisEQ(scip, consdata->lhs, lhs) )
3504  return SCIP_OKAY;
3505 
3506  /* ensure that rhs >= lhs is satisfied without numerical tolerance */
3507  if( SCIPisEQ(scip, lhs, consdata->rhs) )
3508  {
3509  consdata->rhs = lhs;
3510  assert(consdata->row == NULL);
3511  }
3512 
3513  locked = FALSE;
3514  for( i = 0; i < NLOCKTYPES && !locked; i++ )
3515  locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
3516 
3517  /* if necessary, update the rounding locks of variables */
3518  if( locked )
3519  {
3520  if( SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, -lhs) )
3521  {
3522  SCIP_VAR** vars;
3523  SCIP_Real* vals;
3524  int v;
3525 
3526  /* the left hand side switched from -infinity to a non-infinite value -> install rounding locks */
3527  vars = consdata->vars;
3528  vals = consdata->vals;
3529 
3530  for( v = 0; v < consdata->nvars; ++v )
3531  {
3532  assert(vars[v] != NULL);
3533  assert(!SCIPisZero(scip, vals[v]));
3534 
3535  if( SCIPisPositive(scip, vals[v]) )
3536  {
3537  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3538  }
3539  else
3540  {
3541  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3542  }
3543  }
3544  }
3545  else if( !SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, -lhs) )
3546  {
3547  SCIP_VAR** vars;
3548  SCIP_Real* vals;
3549  int v;
3550 
3551  /* the left hand side switched from a non-infinite value to -infinity -> remove rounding locks */
3552  vars = consdata->vars;
3553  vals = consdata->vals;
3554 
3555  for( v = 0; v < consdata->nvars; ++v )
3556  {
3557  assert(vars[v] != NULL);
3558  assert(!SCIPisZero(scip, vals[v]));
3559 
3560  if( SCIPisPositive(scip, vals[v]) )
3561  {
3562  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3563  }
3564  else
3565  {
3566  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3567  }
3568  }
3569  }
3570  }
3571 
3572  /* 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 */
3573  if( !SCIPisInfinity(scip, -lhs) && SCIPisGT(scip, lhs, consdata->lhs) )
3574  {
3575  consdata->boundstightened = 0;
3576  consdata->presolved = FALSE;
3577  consdata->cliquesadded = FALSE;
3578  consdata->implsadded = FALSE;
3579 
3580  /* mark the constraint for propagation */
3581  if( SCIPconsIsTransformed(cons) )
3582  {
3583  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3584  }
3585  }
3586 
3587  /* set new left hand side and update constraint data */
3588  consdata->lhs = lhs;
3589  consdata->changed = TRUE;
3590  consdata->normalized = FALSE;
3591  consdata->upgradetried = FALSE;
3592  consdata->rangedrowpropagated = 0;
3593 
3594  /* update the lhs of the LP row */
3595  if( consdata->row != NULL )
3596  {
3597  SCIP_CALL( SCIPchgRowLhs(scip, consdata->row, lhs) );
3598  }
3599 
3600  return SCIP_OKAY;
3601 }
3602 
3603 /** sets right hand side of linear constraint */
3604 static
3606  SCIP* scip, /**< SCIP data structure */
3607  SCIP_CONS* cons, /**< linear constraint */
3608  SCIP_Real rhs /**< new right hand side */
3609  )
3610 {
3611  SCIP_CONSDATA* consdata;
3612  SCIP_Bool locked;
3613  int i;
3614 
3615  assert(scip != NULL);
3616  assert(cons != NULL);
3617  assert(!SCIPisInfinity(scip, -rhs));
3618 
3619  /* adjust value to not be larger than inf */
3620  if ( SCIPisInfinity(scip, rhs) )
3621  rhs = SCIPinfinity(scip);
3622 
3623  consdata = SCIPconsGetData(cons);
3624  assert(consdata != NULL);
3625  assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
3626  assert(!SCIPisInfinity(scip, -consdata->rhs));
3627 
3628  /* check whether the side is not changed */
3629  if( SCIPisEQ(scip, consdata->rhs, rhs) )
3630  return SCIP_OKAY;
3631 
3632  /* ensure that rhs >= lhs is satisfied without numerical tolerance */
3633  if( SCIPisEQ(scip, rhs, consdata->lhs) )
3634  {
3635  consdata->lhs = rhs;
3636  assert(consdata->row == NULL);
3637  }
3638 
3639  locked = FALSE;
3640  for( i = 0; i < NLOCKTYPES && !locked; i++ )
3641  locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
3642 
3643  /* if necessary, update the rounding locks of variables */
3644  if( locked )
3645  {
3646  assert(SCIPconsIsTransformed(cons));
3647 
3648  if( SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, rhs) )
3649  {
3650  SCIP_VAR** vars;
3651  SCIP_Real* vals;
3652  int v;
3653 
3654  /* the right hand side switched from infinity to a non-infinite value -> install rounding locks */
3655  vars = consdata->vars;
3656  vals = consdata->vals;
3657 
3658  for( v = 0; v < consdata->nvars; ++v )
3659  {
3660  assert(vars[v] != NULL);
3661  assert(!SCIPisZero(scip, vals[v]));
3662 
3663  if( SCIPisPositive(scip, vals[v]) )
3664  {
3665  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3666  }
3667  else
3668  {
3669  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3670  }
3671  }
3672  }
3673  else if( !SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, rhs) )
3674  {
3675  SCIP_VAR** vars;
3676  SCIP_Real* vals;
3677  int v;
3678 
3679  /* the right hand side switched from a non-infinite value to infinity -> remove rounding locks */
3680  vars = consdata->vars;
3681  vals = consdata->vals;
3682 
3683  for( v = 0; v < consdata->nvars; ++v )
3684  {
3685  assert(vars[v] != NULL);
3686  assert(!SCIPisZero(scip, vals[v]));
3687 
3688  if( SCIPisPositive(scip, vals[v]) )
3689  {
3690  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3691  }
3692  else
3693  {
3694  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3695  }
3696  }
3697  }
3698  }
3699 
3700  /* 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 */
3701  if( !SCIPisInfinity(scip, rhs) && SCIPisLT(scip, rhs, consdata->rhs) )
3702  {
3703  consdata->boundstightened = 0;
3704  consdata->presolved = FALSE;
3705  consdata->cliquesadded = FALSE;
3706  consdata->implsadded = FALSE;
3707 
3708  /* mark the constraint for propagation */
3709  if( SCIPconsIsTransformed(cons) )
3710  {
3711  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3712  }
3713  }
3714 
3715  /* set new right hand side and update constraint data */
3716  consdata->rhs = rhs;
3717  consdata->changed = TRUE;
3718  consdata->normalized = FALSE;
3719  consdata->upgradetried = FALSE;
3720  consdata->rangedrowpropagated = 0;
3721 
3722  /* update the rhs of the LP row */
3723  if( consdata->row != NULL )
3724  {
3725  SCIP_CALL( SCIPchgRowRhs(scip, consdata->row, rhs) );
3726  }
3727 
3728  return SCIP_OKAY;
3729 }
3730 
3731 /** adds coefficient in linear constraint */
3732 static
3734  SCIP* scip, /**< SCIP data structure */
3735  SCIP_CONS* cons, /**< linear constraint */
3736  SCIP_VAR* var, /**< variable of constraint entry */
3737  SCIP_Real val /**< coefficient of constraint entry */
3738  )
3739 {
3740  SCIP_CONSDATA* consdata;
3741  SCIP_Bool transformed;
3742 
3743  assert(scip != NULL);
3744  assert(cons != NULL);
3745  assert(var != NULL);
3746 
3747  /* relaxation-only variables must not be used in checked or enforced constraints */
3748  assert(!SCIPvarIsRelaxationOnly(var) || (!SCIPconsIsChecked(cons) && !SCIPconsIsEnforced(cons)));
3749 
3750  /* ignore coefficient if it is nearly zero */
3751  if( SCIPisZero(scip, val) )
3752  return SCIP_OKAY;
3753 
3754  consdata = SCIPconsGetData(cons);
3755  assert(consdata != NULL);
3756 
3757  /* are we in the transformed problem? */
3758  transformed = SCIPconsIsTransformed(cons);
3759 
3760  /* always use transformed variables in transformed constraints */
3761  if( transformed )
3762  {
3763  SCIP_CALL( SCIPgetTransformedVar(scip, var, &var) );
3764  }
3765  assert(var != NULL);
3766  assert(transformed == SCIPvarIsTransformed(var));
3767 
3768  SCIP_CALL( consdataEnsureVarsSize(scip, consdata, consdata->nvars+1) );
3769  consdata->vars[consdata->nvars] = var;
3770  consdata->vals[consdata->nvars] = val;
3771  consdata->nvars++;
3772 
3773  /* capture variable */
3774  SCIP_CALL( SCIPcaptureVar(scip, var) );
3775 
3776  /* if we are in transformed problem, the variable needs an additional event data */
3777  if( transformed )
3778  {
3779  if( consdata->eventdata != NULL )
3780  {
3781  SCIP_CONSHDLR* conshdlr;
3782  SCIP_CONSHDLRDATA* conshdlrdata;
3783 
3784  /* check for event handler */
3785  conshdlr = SCIPconsGetHdlr(cons);
3786  conshdlrdata = SCIPconshdlrGetData(conshdlr);
3787  assert(conshdlrdata != NULL);
3788  assert(conshdlrdata->eventhdlr != NULL);
3789 
3790  /* initialize eventdata array */
3791  consdata->eventdata[consdata->nvars-1] = NULL;
3792 
3793  /* catch bound change events of variable */
3794  SCIP_CALL( consCatchEvent(scip, cons, conshdlrdata->eventhdlr, consdata->nvars-1) );
3795  }
3796 
3797  /* update minimum and maximum activities */
3798  consdataUpdateAddCoef(scip, consdata, var, val, FALSE);
3799 
3800  /* update maximum activity delta */
3801  if( !SCIPisInfinity(scip, consdata->maxactdelta ) )
3802  {
3803  SCIP_Real lb;
3804  SCIP_Real ub;
3805 
3806  lb = SCIPvarGetLbLocal(var);
3807  ub = SCIPvarGetUbLocal(var);
3808 
3809  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
3810  {
3811  consdata->maxactdelta = SCIPinfinity(scip);
3812  consdata->maxactdeltavar = var;
3813  }
3814  else
3815  {
3816  SCIP_Real domain = ub - lb;
3817  SCIP_Real delta = REALABS(val) * domain;
3818 
3819  if( delta > consdata->maxactdelta )
3820  {
3821  consdata->maxactdelta = delta;
3822  consdata->maxactdeltavar = var;
3823  }
3824  }
3825  }
3826  }
3827 
3828  /* install rounding locks for new variable */
3829  SCIP_CALL( lockRounding(scip, cons, var, val) );
3830 
3831  /* mark the constraint for propagation */
3832  if( transformed )
3833  {
3834  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3835  }
3836 
3837  consdata->boundstightened = 0;
3838  consdata->presolved = FALSE;
3839  consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(var);
3840 
3841  if( consdata->validsignature )
3842  consdataUpdateSignatures(consdata, consdata->nvars-1);
3843 
3844  consdata->changed = TRUE;
3845  consdata->normalized = FALSE;
3846  consdata->upgradetried = FALSE;
3847  consdata->cliquesadded = FALSE;
3848  consdata->implsadded = FALSE;
3849  consdata->rangedrowpropagated = 0;
3850 
3851  if( consdata->nvars == 1 )
3852  {
3853  consdata->indexsorted = TRUE;
3854  consdata->coefsorted = TRUE;
3855  consdata->merged = TRUE;
3856  }
3857  else
3858  {
3859  consdata->merged = FALSE;
3860 
3861  if( SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE )
3862  {
3863  consdata->indexsorted = consdata->indexsorted && (consdataCompVar((void*)consdata, consdata->nvars-2, consdata->nvars-1) <= 0);
3864  consdata->coefsorted = FALSE;
3865  }
3866  else
3867  {
3868  consdata->indexsorted = FALSE;
3869  consdata->coefsorted = consdata->coefsorted && (consdataCompVarProp((void*)consdata, consdata->nvars-2, consdata->nvars-1) <= 0);
3870  }
3871  }
3872 
3873  /* update hascontvar and hasnonbinvar flags */
3874  if( consdata->hasnonbinvalid && !consdata->hascontvar )
3875  {
3876  SCIP_VARTYPE vartype = SCIPvarGetType(var);
3877 
3878  if( vartype != SCIP_VARTYPE_BINARY )
3879  {
3880  consdata->hasnonbinvar = TRUE;
3881 
3882  if( vartype == SCIP_VARTYPE_CONTINUOUS )
3883  consdata->hascontvar = TRUE;
3884  }
3885  }
3886 
3887  /* add the new coefficient to the LP row */
3888  if( consdata->row != NULL )
3889  {
3890  SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, var, val) );
3891  }
3892 
3893  return SCIP_OKAY;
3894 }
3895 
3896 /** deletes coefficient at given position from linear constraint data */
3897 static
3899  SCIP* scip, /**< SCIP data structure */
3900  SCIP_CONS* cons, /**< linear constraint */
3901  int pos /**< position of coefficient to delete */
3902  )
3903 {
3904  SCIP_CONSDATA* consdata;
3905  SCIP_VAR* var;
3906  SCIP_Real val;
3907 
3908  assert(scip != NULL);
3909  assert(cons != NULL);
3910 
3911  consdata = SCIPconsGetData(cons);
3912  assert(consdata != NULL);
3913  assert(0 <= pos && pos < consdata->nvars);
3914 
3915  var = consdata->vars[pos];
3916  val = consdata->vals[pos];
3917  assert(var != NULL);
3918 
3919  /* remove rounding locks for deleted variable */
3920  SCIP_CALL( unlockRounding(scip, cons, var, val) );
3921 
3922  /* if we are in transformed problem, delete the event data of the variable */
3923  if( SCIPconsIsTransformed(cons) )
3924  {
3925  SCIP_CONSHDLR* conshdlr;
3926  SCIP_CONSHDLRDATA* conshdlrdata;
3927 
3928  /* check for event handler */
3929  conshdlr = SCIPconsGetHdlr(cons);
3930  conshdlrdata = SCIPconshdlrGetData(conshdlr);
3931  assert(conshdlrdata != NULL);
3932  assert(conshdlrdata->eventhdlr != NULL);
3933 
3934  /* drop bound change events of variable */
3935  if( consdata->eventdata != NULL )
3936  {
3937  SCIP_CALL( consDropEvent(scip, cons, conshdlrdata->eventhdlr, pos) );
3938  assert(consdata->eventdata[pos] == NULL);
3939  }
3940  }
3941 
3942  /* move the last variable to the free slot */
3943  if( pos != consdata->nvars - 1 )
3944  {
3945  consdata->vars[pos] = consdata->vars[consdata->nvars-1];
3946  consdata->vals[pos] = consdata->vals[consdata->nvars-1];
3947 
3948  if( consdata->eventdata != NULL )
3949  {
3950  consdata->eventdata[pos] = consdata->eventdata[consdata->nvars-1];
3951  assert(consdata->eventdata[pos] != NULL);
3952  consdata->eventdata[pos]->varpos = pos;
3953  }
3954 
3955  consdata->indexsorted = consdata->indexsorted && (pos + 2 >= consdata->nvars);
3956  consdata->coefsorted = consdata->coefsorted && (pos + 2 >= consdata->nvars);
3957  }
3958  consdata->nvars--;
3959 
3960  /* if at most one variable is left, the activities should be recalculated (to correspond exactly to the bounds
3961  * of the remaining variable, or give exactly 0.0)
3962  */
3963  if( consdata->nvars <= 1 )
3964  consdataInvalidateActivities(consdata);
3965  else
3966  {
3967  if( SCIPconsIsTransformed(cons) )
3968  {
3969  /* if we are in transformed problem, update minimum and maximum activities */
3970  consdataUpdateDelCoef(scip, consdata, var, val, TRUE);
3971 
3972  /* if the variable defining the maximal activity delta was removed from the constraint, the maximal activity
3973  * delta needs to be recalculated on the next real propagation
3974  */
3975  if( consdata->maxactdeltavar == var )
3976  {
3977  consdata->maxactdelta = SCIP_INVALID;
3978  consdata->maxactdeltavar = NULL;
3979  }
3980  }
3981  }
3982 
3983  /* mark the constraint for propagation */
3984  if( SCIPconsIsTransformed(cons) )
3985  {
3986  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3987  }
3988 
3989  consdata->boundstightened = 0;
3990  consdata->presolved = FALSE;
3991  consdata->validsignature = FALSE;
3992  consdata->changed = TRUE;
3993  consdata->normalized = FALSE;
3994  consdata->upgradetried = FALSE;
3995  consdata->cliquesadded = FALSE;
3996  consdata->implsadded = FALSE;
3997  consdata->rangedrowpropagated = 0;
3998 
3999  /* check if hasnonbinvar flag might be incorrect now */
4000  if( consdata->hasnonbinvar && SCIPvarGetType(var) != SCIP_VARTYPE_BINARY )
4001  {
4002  consdata->hasnonbinvalid = FALSE;
4003  }
4004 
4005  /* delete coefficient from the LP row */
4006  if( consdata->row != NULL )
4007  {
4008  SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, var, -val) );
4009  }
4010 
4011  /* release variable */
4012  SCIP_CALL( SCIPreleaseVar(scip, &var) );
4013 
4014  return SCIP_OKAY;
4015 }
4016 
4017 /** changes coefficient value at given position of linear constraint data */
4018 static
4020  SCIP* scip, /**< SCIP data structure */
4021  SCIP_CONS* cons, /**< linear constraint */
4022  int pos, /**< position of coefficient to delete */
4023  SCIP_Real newval /**< new value of coefficient */
4024  )
4025 {
4026  SCIP_CONSDATA* consdata;
4027  SCIP_VAR* var;
4028  SCIP_Real val;
4029  SCIP_Bool locked;
4030  int i;
4031 
4032  assert(scip != NULL);
4033  assert(cons != NULL);
4034  assert(!SCIPisZero(scip, newval));
4035 
4036  consdata = SCIPconsGetData(cons);
4037  assert(consdata != NULL);
4038  assert(0 <= pos && pos < consdata->nvars);
4039  assert(!SCIPisZero(scip, newval));
4040 
4041  var = consdata->vars[pos];
4042  val = consdata->vals[pos];
4043  assert(var != NULL);
4044  assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(var));
4045 
4046  locked = FALSE;
4047  for( i = 0; i < NLOCKTYPES && !locked; i++ )
4048  locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
4049 
4050  /* if necessary, update the rounding locks of the variable */
4051  if( locked && newval * val < 0.0 )
4052  {
4053  assert(SCIPconsIsTransformed(cons));
4054 
4055  /* remove rounding locks for variable with old coefficient */
4056  SCIP_CALL( unlockRounding(scip, cons, var, val) );
4057 
4058  /* install rounding locks for variable with new coefficient */
4059  SCIP_CALL( lockRounding(scip, cons, var, newval) );
4060  }
4061 
4062  /* change the value */
4063  consdata->vals[pos] = newval;
4064 
4065  if( consdata->coefsorted )
4066  {
4067  if( pos > 0 )
4068  consdata->coefsorted = (consdataCompVarProp((void*)consdata, pos - 1, pos) <= 0);
4069  if( consdata->coefsorted && pos < consdata->nvars - 1 )
4070  consdata->coefsorted = (consdataCompVarProp((void*)consdata, pos, pos + 1) <= 0);
4071  }
4072 
4073  /* update minimum and maximum activities */
4074  if( SCIPconsIsTransformed(cons) )
4075  consdataUpdateChgCoef(scip, consdata, var, val, newval, TRUE);
4076 
4077  /* mark the constraint for propagation */
4078  if( SCIPconsIsTransformed(cons) )
4079  {
4080  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
4081  }
4082 
4083  consdata->boundstightened = 0;
4084  consdata->presolved = FALSE;
4085  consdata->validsignature = consdata->validsignature && (newval * val > 0.0);
4086  consdata->changed = TRUE;
4087  consdata->normalized = FALSE;
4088  consdata->upgradetried = FALSE;
4089  consdata->cliquesadded = FALSE;
4090  consdata->implsadded = FALSE;
4091  consdata->rangedrowpropagated = 0;
4092 
4093  return SCIP_OKAY;
4094 }
4095 
4096 /** scales a linear constraint with a constant scalar */
4097 static
4099  SCIP* scip, /**< SCIP data structure */
4100  SCIP_CONS* cons, /**< linear constraint to scale */
4101  SCIP_Real scalar /**< value to scale constraint with */
4102  )
4103 {
4104  SCIP_CONSDATA* consdata;
4105  SCIP_Real newval;
4106  SCIP_Real absscalar;
4107  int i;
4108 
4109  assert(scip != NULL);
4110  assert(cons != NULL);
4111 
4112  consdata = SCIPconsGetData(cons);
4113  assert(consdata != NULL);
4114  assert(consdata->row == NULL);
4115  assert(!SCIPisEQ(scip, scalar, 1.0));
4116 
4117  if( (!SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, -consdata->lhs * scalar))
4118  || (!SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, consdata->rhs * scalar)) )
4119  {
4120  SCIPwarningMessage(scip, "skipped scaling for linear constraint <%s> to avoid numerical troubles (scalar: %.15g)\n",
4121  SCIPconsGetName(cons), scalar);
4122 
4123  return SCIP_OKAY;
4124  }
4125 
4126  /* scale the coefficients */
4127  for( i = consdata->nvars - 1; i >= 0; --i )
4128  {
4129  newval = scalar * consdata->vals[i];
4130 
4131  /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasFloor, we add an additional 0.5 before
4132  * flooring down our new value
4133  */
4134  if( SCIPisScalingIntegral(scip, consdata->vals[i], scalar) )
4135  newval = SCIPfeasFloor(scip, newval + 0.5);
4136 
4137  if( SCIPisZero(scip, newval) )
4138  {
4139  SCIPwarningMessage(scip, "coefficient %.15g of variable <%s> in linear constraint <%s> scaled to zero (scalar: %.15g)\n",
4140  consdata->vals[i], SCIPvarGetName(consdata->vars[i]), SCIPconsGetName(cons), scalar);
4141  SCIP_CALL( delCoefPos(scip, cons, i) );
4142  }
4143  else
4144  consdata->vals[i] = newval;
4145  }
4146 
4147  /* scale the sides */
4148  if( scalar < 0.0 )
4149  {
4150  SCIP_Real lhs;
4151 
4152  lhs = consdata->lhs;
4153  consdata->lhs = -consdata->rhs;
4154  consdata->rhs = -lhs;
4155  }
4156  absscalar = REALABS(scalar);
4157  if( !SCIPisInfinity(scip, -consdata->lhs) )
4158  {
4159  newval = absscalar * consdata->lhs;
4160 
4161  /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasFloor, we add an additional 0.5 before
4162  * flooring down our new value
4163  */
4164  if( SCIPisScalingIntegral(scip, consdata->lhs, absscalar) )
4165  consdata->lhs = SCIPfeasFloor(scip, newval + 0.5);
4166  else
4167  consdata->lhs = newval;
4168  }
4169  if( !SCIPisInfinity(scip, consdata->rhs) )
4170  {
4171  newval = absscalar * consdata->rhs;
4172 
4173  /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasCeil, we subtract 0.5 before ceiling up
4174  * our new value
4175  */
4176  if( SCIPisScalingIntegral(scip, consdata->rhs, absscalar) )
4177  consdata->rhs = SCIPfeasCeil(scip, newval - 0.5);
4178  else
4179  consdata->rhs = newval;
4180  }
4181 
4182  consdataInvalidateActivities(consdata);
4183  consdata->cliquesadded = FALSE;
4184  consdata->implsadded = FALSE;
4185 
4186  return SCIP_OKAY;
4187 }
4188 
4189 /** perform deletion of variables in all constraints of the constraint handler */
4190 static
4192  SCIP* scip, /**< SCIP data structure */
4193  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4194  SCIP_CONS** conss, /**< array of constraints */
4195  int nconss /**< number of constraints */
4196  )
4197 {
4198  SCIP_CONSDATA* consdata;
4199  int i;
4200  int v;
4201 
4202  assert(scip != NULL);
4203  assert(conshdlr != NULL);
4204  assert(conss != NULL);
4205  assert(nconss >= 0);
4206  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
4207 
4208  /* iterate over all constraints */
4209  for( i = 0; i < nconss; i++ )
4210  {
4211  consdata = SCIPconsGetData(conss[i]);
4212 
4213  /* constraint is marked, that some of its variables were deleted */
4214  if( consdata->varsdeleted )
4215  {
4216  /* iterate over all variables of the constraint and delete them from the constraint */
4217  for( v = consdata->nvars - 1; v >= 0; --v )
4218  {
4219  if( SCIPvarIsDeleted(consdata->vars[v]) )
4220  {
4221  SCIP_CALL( delCoefPos(scip, conss[i], v) );
4222  }
4223  }
4224  consdata->varsdeleted = FALSE;
4225  }
4226  }
4227 
4228  return SCIP_OKAY;
4229 }
4230 
4231 
4232 /** normalizes a linear constraint with the following rules:
4233  * - if all coefficients have them same absolute value, change them to (-)1.0
4234  * - multiplication with +1 or -1:
4235  * Apply the following rules in the given order, until the sign of the factor is determined. Later rules only apply,
4236  * if the current rule doesn't determine the sign):
4237  * 1. the right hand side must not be negative
4238  * 2. the right hand side must not be infinite
4239  * 3. the absolute value of the right hand side must be greater than that of the left hand side
4240  * 4. the number of positive coefficients must not be smaller than the number of negative coefficients
4241  * 5. multiply with +1
4242  * - rationals to integrals
4243  * Try to identify a rational representation of the fractional coefficients, and multiply all coefficients
4244  * by the smallest common multiple of all denominators to get integral coefficients.
4245  * Forbid large denominators due to numerical stability.
4246  * - division by greatest common divisor
4247  * If all coefficients are integral, divide them by the greatest common divisor.
4248  */
4249 static
4251  SCIP* scip, /**< SCIP data structure */
4252  SCIP_CONS* cons, /**< linear constraint to normalize */
4253  SCIP_Bool* infeasible /**< pointer to store whether infeasibility was detected */
4254  )
4255 {
4256  SCIP_CONSDATA* consdata;
4257  SCIP_Real* vals;
4258  SCIP_Longint scm;
4259  SCIP_Longint nominator;
4260  SCIP_Longint denominator;
4261  SCIP_Longint gcd;
4262  SCIP_Longint maxmult;
4263  SCIP_Real epsilon;
4264  SCIP_Real feastol;
4265  SCIP_Real maxabsval;
4266  SCIP_Real minabsval;
4267  SCIP_Bool success;
4268  SCIP_Bool onlyintegral;
4269  int nvars;
4270  int mult;
4271  int nposcoeffs;
4272  int nnegcoeffs;
4273  int i;
4274  int v;
4275 
4276  assert(scip != NULL);
4277  assert(cons != NULL);
4278  assert(infeasible != NULL);
4279 
4280  *infeasible = FALSE;
4281 
4282  /* we must not change a modifiable constraint in any way */
4283  if( SCIPconsIsModifiable(cons) )
4284  return SCIP_OKAY;
4285 
4286  /* get constraint data */
4287  consdata = SCIPconsGetData(cons);
4288  assert(consdata != NULL);
4289 
4290  /* check, if the constraint is already normalized */
4291  if( consdata->normalized )
4292  return SCIP_OKAY;
4293 
4294  /* get coefficient arrays */
4295  vals = consdata->vals;
4296  nvars = consdata->nvars;
4297  assert(nvars == 0 || vals != NULL);
4298 
4299  if( nvars == 0 )
4300  {
4301  consdata->normalized = TRUE;
4302  return SCIP_OKAY;
4303  }
4304 
4305  assert(vals != NULL);
4306 
4307  /* get maximal and minimal absolute coefficient */
4308  maxabsval = consdataGetMaxAbsval(consdata);
4309  minabsval = consdataGetMinAbsval(consdata);
4310 
4311  /* return if scaling by maxval will eliminate coefficients */
4312  if( SCIPisZero(scip, minabsval/maxabsval) )
4313  return SCIP_OKAY;
4314 
4315  /* check if all coefficients are in absolute value equal, and not 1.0 */
4316  if( !SCIPisEQ(scip, maxabsval, 1.0) )
4317  {
4318  SCIP_Bool abscoefsequ;
4319 
4320  abscoefsequ = TRUE;
4321 
4322  for( v = nvars - 1; v >= 0; --v )
4323  {
4324  if( !SCIPisEQ(scip, REALABS(vals[v]), maxabsval) )
4325  {
4326  abscoefsequ = FALSE;
4327  break;
4328  }
4329  }
4330 
4331  /* all coefficients are in absolute value equal, so change them to (-)1.0 */
4332  if( abscoefsequ )
4333  {
4334  SCIPdebugMsg(scip, "divide linear constraint with %g, because all coefficients are in absolute value the same\n", maxabsval);
4335  SCIPdebugPrintCons(scip, cons, NULL);
4336  SCIP_CALL( scaleCons(scip, cons, 1/maxabsval) );
4337 
4338  if( consdata->validmaxabsval )
4339  {
4340  if( !SCIPisEQ(scip, consdata->maxabsval, 1.0) )
4341  consdata->maxabsval = 1.0;
4342  if( !SCIPisEQ(scip, consdata->minabsval, 1.0) )
4343  consdata->minabsval = 1.0;
4344 
4345  maxabsval = 1.0;
4346  }
4347  else
4348  {
4349  /* get maximal absolute coefficient */
4350  maxabsval = consdataGetMaxAbsval(consdata);
4351  }
4352 
4353  /* get new consdata information, because scaleCons() might have deleted variables */
4354  vals = consdata->vals;
4355  nvars = consdata->nvars;
4356 
4357  assert(nvars == 0 || vals != NULL);
4358  }
4359  }
4360 
4361  /* nvars might have changed */
4362  if( nvars == 0 )
4363  {
4364  consdata->normalized = TRUE;
4365  return SCIP_OKAY;
4366  }
4367 
4368  assert(vals != NULL);
4369 
4370  /* calculate the maximal multiplier for common divisor calculation:
4371  * |p/q - val| < epsilon and q < feastol/epsilon => |p - q*val| < feastol
4372  * which means, a value of feastol/epsilon should be used as maximal multiplier;
4373  * additionally, we don't want to scale the constraint if this would lead to too
4374  * large coefficients
4375  */
4376  epsilon = SCIPepsilon(scip) * 0.9; /* slightly decrease epsilon to be safe in rational conversion below */
4377  feastol = SCIPfeastol(scip);
4378  maxmult = (SCIP_Longint)(feastol/epsilon + feastol);
4379 
4380  if( !consdata->hasnonbinvalid )
4381  consdataCheckNonbinvar(consdata);
4382 
4383  /* if all variables are of integral type we will allow a greater multiplier */
4384  if( !consdata->hascontvar )
4385  maxmult = MIN(maxmult, (SCIP_Longint) (MAXSCALEDCOEFINTEGER / MAX(maxabsval, 1.0))); /*lint !e835*/
4386  else
4387  maxmult = MIN(maxmult, (SCIP_Longint) (MAXSCALEDCOEF / MAX(maxabsval, 1.0))); /*lint !e835*/
4388 
4389  /*
4390  * multiplication with +1 or -1
4391  */
4392  mult = 0;
4393 
4394  /* 1. the right hand side must not be negative */
4395  if( SCIPisPositive(scip, consdata->lhs) )
4396  mult = +1;
4397  else if( SCIPisNegative(scip, consdata->rhs) )
4398  mult = -1;
4399 
4400  if( mult == 0 )
4401  {
4402  /* 2. the right hand side must not be infinite */
4403  if( SCIPisInfinity(scip, -consdata->lhs) )
4404  mult = +1;
4405  else if( SCIPisInfinity(scip, consdata->rhs) )
4406  mult = -1;
4407  }
4408 
4409  if( mult == 0 )
4410  {
4411  /* 3. the absolute value of the right hand side must be greater than that of the left hand side */
4412  if( SCIPisGT(scip, REALABS(consdata->rhs), REALABS(consdata->lhs)) )
4413  mult = +1;
4414  else if( SCIPisLT(scip, REALABS(consdata->rhs), REALABS(consdata->lhs)) )
4415  mult = -1;
4416  }
4417 
4418  if( mult == 0 )
4419  {
4420  /* 4. the number of positive coefficients must not be smaller than the number of negative coefficients */
4421  nposcoeffs = 0;
4422  nnegcoeffs = 0;
4423  for( i = 0; i < nvars; ++i )
4424  {
4425  if( vals[i] > 0.0 )
4426  nposcoeffs++;
4427  else
4428  nnegcoeffs++;
4429  }
4430  if( nposcoeffs > nnegcoeffs )
4431  mult = +1;
4432  else if( nposcoeffs < nnegcoeffs )
4433  mult = -1;
4434  }
4435 
4436  if( mult == 0 )
4437  {
4438  /* 5. multiply with +1 */
4439  mult = +1;
4440  }
4441 
4442  assert(mult == +1 || mult == -1);
4443  if( mult == -1 )
4444  {
4445  /* scale the constraint with -1 */
4446  SCIPdebugMsg(scip, "multiply linear constraint with -1.0\n");
4447  SCIPdebugPrintCons(scip, cons, NULL);
4448  SCIP_CALL( scaleCons(scip, cons, -1.0) );
4449 
4450  /* scalecons() can delete variables, but scaling with -1 should not do that */
4451  assert(nvars == consdata->nvars);
4452  }
4453 
4454  /*
4455  * rationals to integrals
4456  *
4457  * @todo try scaling only on behalf of non-continuous variables
4458  */
4459  success = TRUE;
4460  scm = 1;
4461  for( i = 0; i < nvars && success && scm <= maxmult; ++i )
4462  {
4463  if( !SCIPisIntegral(scip, vals[i]) )
4464  {
4465  /* epsilon has been slightly decreased above - to be on the safe side */
4466  success = SCIPrealToRational(vals[i], -epsilon, epsilon , maxmult, &nominator, &denominator);
4467  if( success )
4468  scm = SCIPcalcSmaComMul(scm, denominator);
4469  }
4470  }
4471  assert(scm >= 1);
4472 
4473  /* it might be that we have really big coefficients, but all are integral, in that case we want to divide them by
4474  * their greatest common divisor
4475  */
4476  onlyintegral = TRUE;
4477  if( scm == 1 )
4478  {
4479  for( i = nvars - 1; i >= 0; --i )
4480  {
4481  if( !SCIPisIntegral(scip, vals[i]) )
4482  {
4483  onlyintegral = FALSE;
4484  break;
4485  }
4486  }
4487  }
4488 
4489  success = success && (scm <= maxmult || (scm == 1 && onlyintegral));
4490  if( success && scm != 1 )
4491  {
4492  /* scale the constraint with the smallest common multiple of all denominators */
4493  SCIPdebugMsg(scip, "scale linear constraint with %" SCIP_LONGINT_FORMAT " to make coefficients integral\n", scm);
4494  SCIPdebugPrintCons(scip, cons, NULL);
4495  SCIP_CALL( scaleCons(scip, cons, (SCIP_Real)scm) );
4496 
4497  if( consdata->validmaxabsval )
4498  {
4499  consdata->maxabsval *= REALABS((SCIP_Real)scm);
4500  if( !SCIPisIntegral(scip, consdata->maxabsval) )
4501  {
4502  consdata->validmaxabsval = FALSE;
4503  consdata->maxabsval = SCIP_INVALID;
4504  consdataCalcMaxAbsval(consdata);
4505  }
4506  }
4507 
4508  if( consdata->validminabsval )
4509  {
4510  consdata->minabsval *= REALABS((SCIP_Real)scm);
4511  if( !SCIPisIntegral(scip, consdata->minabsval) )
4512  {
4513  consdata->validminabsval = FALSE;
4514  consdata->minabsval = SCIP_INVALID;
4515  consdataCalcMinAbsval(consdata);
4516  }
4517  }
4518 
4519  /* get new consdata information, because scalecons() might have deleted variables */
4520  vals = consdata->vals;
4521  nvars = consdata->nvars;
4522  assert(nvars == 0 || vals != NULL);
4523  }
4524 
4525  /*
4526  * division by greatest common divisor
4527  */
4528  if( success && nvars >= 1 )
4529  {
4530  /* all coefficients are integral: divide them by their greatest common divisor */
4531  assert(SCIPisIntegral(scip, vals[0]));
4532 
4533  gcd = (SCIP_Longint)(REALABS(vals[0]) + feastol);
4534  for( i = 1; i < nvars && gcd > 1; ++i )
4535  {
4536  assert(SCIPisIntegral(scip, vals[i]));
4537  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[i]) + feastol));
4538  }
4539 
4540  if( gcd > 1 )
4541  {
4542  /* since the lhs/rhs is not respected for gcd calculation it can happen that we detect infeasibility */
4543  if( !consdata->hascontvar && onlyintegral )
4544  {
4545  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) && !SCIPisFeasIntegral(scip, consdata->rhs / gcd) )
4546  {
4547  *infeasible = TRUE;
4548 
4549  SCIPdebugMsg(scip, "detected infeasibility of constraint after scaling with gcd=%" SCIP_LONGINT_FORMAT ":\n", gcd);
4550  SCIPdebugPrintCons(scip, cons, NULL);
4551 
4552  return SCIP_OKAY;
4553  }
4554  }
4555 
4556  /* divide the constraint by the greatest common divisor of the coefficients */
4557  SCIPdebugMsg(scip, "divide linear constraint by greatest common divisor %" SCIP_LONGINT_FORMAT "\n", gcd);
4558  SCIPdebugPrintCons(scip, cons, NULL);
4559  SCIP_CALL( scaleCons(scip, cons, 1.0/(SCIP_Real)gcd) );
4560 
4561  if( consdata->validmaxabsval )
4562  {
4563  consdata->maxabsval /= REALABS((SCIP_Real)gcd);
4564  }
4565  if( consdata->validminabsval )
4566  {
4567  consdata->minabsval /= REALABS((SCIP_Real)gcd);
4568  }
4569  }
4570  }
4571 
4572  /* mark constraint to be normalized */
4573  consdata->normalized = TRUE;
4574 
4575  SCIPdebugMsg(scip, "normalized constraint:\n");
4576  SCIPdebugPrintCons(scip, cons, NULL);
4577 
4578  return SCIP_OKAY;
4579 }
4580 
4581 /** replaces multiple occurrences of a variable by a single coefficient */
4582 static
4584  SCIP* scip, /**< SCIP data structure */
4585  SCIP_CONS* cons /**< linear constraint */
4586  )
4587 {
4588  SCIP_CONSDATA* consdata;
4589  SCIP_VAR* var;
4590  SCIP_Real valsum;
4591  int v;
4592 
4593  assert(scip != NULL);
4594  assert(cons != NULL);
4595 
4596  consdata = SCIPconsGetData(cons);
4597  assert(consdata != NULL);
4598 
4599  if( consdata->merged )
4600  return SCIP_OKAY;
4601 
4602  /* sort the constraint */
4603  SCIP_CALL( consdataSort(scip, consdata) );
4604 
4605  /* go backwards through the constraint looking for multiple occurrences of the same variable;
4606  * backward direction is necessary, since delCoefPos() modifies the given position and
4607  * the subsequent ones
4608  */
4609  v = consdata->nvars-1;
4610  while( v >= 1 )
4611  {
4612  var = consdata->vars[v];
4613  if( consdata->vars[v-1] == var )
4614  {
4615  valsum = consdata->vals[v];
4616  do
4617  {
4618  SCIP_CALL( delCoefPos(scip, cons, v) );
4619  --v;
4620  valsum += consdata->vals[v];
4621  }
4622  while( v >= 1 && consdata->vars[v-1] == var );
4623 
4624  /* modify the last existing occurrence of the variable */
4625  assert(consdata->vars[v] == var);
4626  if( SCIPisZero(scip, valsum) )
4627  {
4628  SCIP_CALL( delCoefPos(scip, cons, v) );
4629 
4630  /* if the variable defining the maximal activity delta was removed from the constraint, the maximal activity
4631  * delta needs to be recalculated on the next real propagation
4632  */
4633  if( consdata->maxactdeltavar == var )
4634  {
4635  consdata->maxactdelta = SCIP_INVALID;
4636  consdata->maxactdeltavar = NULL;
4637  }
4638  }
4639  else
4640  {
4641  SCIP_CALL( chgCoefPos(scip, cons, v, valsum) );
4642  }
4643  }
4644  --v;
4645  }
4646 
4647  consdata->merged = TRUE;
4648 
4649  return SCIP_OKAY;
4650 }
4651 
4652 /** replaces all fixed and aggregated variables by their non-fixed counterparts */
4653 static
4655  SCIP* scip, /**< SCIP data structure */
4656  SCIP_CONS* cons, /**< linear constraint */
4657  SCIP_Bool* infeasible /**< pointer to store if infeasibility is detected; or NULL if this
4658  * information is not needed; in this case, we apply all fixings
4659  * instead of stopping after the first infeasible one */
4660  )
4661 {
4662  SCIP_CONSDATA* consdata;
4663  SCIP_VAR* var;
4664  SCIP_VAR** aggrvars;
4665  SCIP_Real val;
4666  SCIP_Real* aggrscalars;
4667  SCIP_Real fixedval;
4668  SCIP_Real aggrconst;
4669  int v;
4670  int naggrvars;
4671  int i;
4672 
4673  assert(scip != NULL);
4674  assert(cons != NULL);
4675 
4676  if( infeasible != NULL )
4677  *infeasible = FALSE;
4678 
4679  consdata = SCIPconsGetData(cons);
4680  assert(consdata != NULL);
4681 
4682  if( consdata->eventdata == NULL )
4683  {
4684  SCIP_CONSHDLR* conshdlr;
4685  SCIP_CONSHDLRDATA* conshdlrdata;
4686 
4687  conshdlr = SCIPconsGetHdlr(cons);
4688  assert(conshdlr != NULL);
4689 
4690  conshdlrdata = SCIPconshdlrGetData(conshdlr);
4691  assert(conshdlrdata != NULL);
4692 
4693  /* catch bound change events of variables */
4694  SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
4695  assert(consdata->eventdata != NULL);
4696  }
4697 
4698  if( !consdata->removedfixings )
4699  {
4700  SCIP_Real lhssubtrahend;
4701  SCIP_Real rhssubtrahend;
4702 
4703  /* if an unmodifiable row has been added to the LP, then we cannot apply fixing anymore (cannot change a row)
4704  * this should not happen, as applyFixings is called in addRelaxation() before creating and adding a row
4705  */
4706  assert(consdata->row == NULL || !SCIProwIsInLP(consdata->row) || SCIProwIsModifiable(consdata->row));
4707 
4708  lhssubtrahend = 0.0;
4709  rhssubtrahend = 0.0;
4710 
4711  SCIPdebugMsg(scip, "applying fixings:\n");
4712  SCIPdebugPrintCons(scip, cons, NULL);
4713 
4714  v = 0;
4715  while( v < consdata->nvars )
4716  {
4717  var = consdata->vars[v];
4718  val = consdata->vals[v];
4719  assert(SCIPvarIsTransformed(var));
4720 
4721  switch( SCIPvarGetStatus(var) )
4722  {
4724  SCIPerrorMessage("original variable in transformed linear constraint\n");
4725  return SCIP_INVALIDDATA;
4726 
4727  case SCIP_VARSTATUS_LOOSE:
4728  case SCIP_VARSTATUS_COLUMN:
4729  ++v;
4730  break;
4731 
4732  case SCIP_VARSTATUS_FIXED:
4733  assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)));
4734  fixedval = SCIPvarGetLbGlobal(var);
4735  if( !SCIPisInfinity(scip, -consdata->lhs) )
4736  {
4737  if( SCIPisInfinity(scip, ABS(fixedval)) )
4738  {
4739  if( val * fixedval > 0.0 )
4740  {
4741  SCIP_CALL( chgLhs(scip, cons, -SCIPinfinity(scip)) );
4742  }
4743  else
4744  {
4745  if( infeasible != NULL )
4746  {
4747  /* if lhs gets infinity it means that the problem is infeasible */
4748  *infeasible = TRUE;
4749  return SCIP_OKAY;
4750  }
4751  else
4752  {
4753  SCIP_CALL( chgLhs(scip, cons, SCIPinfinity(scip)) );
4754  }
4755  }
4756  }
4757  else
4758  lhssubtrahend += val * fixedval;
4759  }
4760  if( !SCIPisInfinity(scip, consdata->rhs) )
4761  {
4762  if( SCIPisInfinity(scip, ABS(fixedval)) )
4763  {
4764  if( val * fixedval > 0.0 )
4765  {
4766  if( infeasible != NULL )
4767  {
4768  /* if rhs gets -infinity it means that the problem is infeasible */
4769  *infeasible = TRUE;
4770  return SCIP_OKAY;
4771  }
4772  else
4773  {
4774  SCIP_CALL( chgRhs(scip, cons, -SCIPinfinity(scip)) );
4775  }
4776  }
4777  else
4778  {
4779  SCIP_CALL( chgRhs(scip, cons, SCIPinfinity(scip)) );
4780  }
4781  }
4782  else
4783  rhssubtrahend += val * fixedval;
4784  }
4785  SCIP_CALL( delCoefPos(scip, cons, v) );
4786  break;
4787 
4789  {
4790  SCIP_VAR* activevar = SCIPvarGetAggrVar(var);
4791  SCIP_Real activescalar = val * SCIPvarGetAggrScalar(var);
4792  SCIP_Real activeconstant = val * SCIPvarGetAggrConstant(var);
4793 
4794  assert(activevar != NULL);
4795  SCIP_CALL( SCIPgetProbvarSum(scip, &activevar, &activescalar, &activeconstant) );
4796  assert(activevar != NULL);
4797 
4798  if( !SCIPisZero(scip, activescalar) )
4799  {
4800  SCIP_CALL( addCoef(scip, cons, activevar, activescalar) );
4801  }
4802 
4803  if( !SCIPisZero(scip, activeconstant) )
4804  {
4805  if( !SCIPisInfinity(scip, -consdata->lhs) )
4806  lhssubtrahend += activeconstant;
4807  if( !SCIPisInfinity(scip, consdata->rhs) )
4808  rhssubtrahend += activeconstant;
4809  }
4810 
4811  SCIP_CALL( delCoefPos(scip, cons, v) );
4812  break;
4813  }
4816  naggrvars = SCIPvarGetMultaggrNVars(var);
4817  aggrvars = SCIPvarGetMultaggrVars(var);
4818  aggrscalars = SCIPvarGetMultaggrScalars(var);
4819  for( i = 0; i < naggrvars; ++i )
4820  {
4821  SCIP_CALL( addCoef(scip, cons, aggrvars[i], val * aggrscalars[i]) );
4822  }
4823  aggrconst = SCIPvarGetMultaggrConstant(var);
4824 
4825  if( !SCIPisInfinity(scip, -consdata->lhs) )
4826  lhssubtrahend += val * aggrconst;
4827  if( !SCIPisInfinity(scip, consdata->rhs) )
4828  rhssubtrahend += val * aggrconst;
4829 
4830  SCIP_CALL( delCoefPos(scip, cons, v) );
4831  break;
4832 
4834  SCIP_CALL( addCoef(scip, cons, SCIPvarGetNegationVar(var), -val) );
4835  aggrconst = SCIPvarGetNegationConstant(var);
4836 
4837  if( !SCIPisInfinity(scip, -consdata->lhs) )
4838  lhssubtrahend += val * aggrconst;
4839  if( !SCIPisInfinity(scip, consdata->rhs) )
4840  rhssubtrahend += val * aggrconst;
4841 
4842  SCIP_CALL( delCoefPos(scip, cons, v) );
4843  break;
4844 
4845  default:
4846  SCIPerrorMessage("unknown variable status\n");
4847  SCIPABORT();
4848  return SCIP_INVALIDDATA; /*lint !e527*/
4849  }
4850  }
4851 
4852  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->lhs) )
4853  {
4854  /* for large numbers that are relatively equal, substraction can lead to cancellation,
4855  * causing wrong fixings of other variables --> better use a real zero here;
4856  * for small numbers, polishing the difference might lead to wrong results -->
4857  * better use the exact difference in this case
4858  */
4859  if( SCIPisEQ(scip, lhssubtrahend, consdata->lhs) && SCIPisFeasGE(scip, REALABS(lhssubtrahend), 1.0) )
4860  {
4861  SCIP_CALL( chgLhs(scip, cons, 0.0) );
4862  }
4863  else
4864  {
4865  SCIP_CALL( chgLhs(scip, cons, consdata->lhs - lhssubtrahend) );
4866  }
4867  }
4868  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, -consdata->rhs))
4869  {
4870  /* for large numbers that are relatively equal, substraction can lead to cancellation,
4871  * causing wrong fixings of other variables --> better use a real zero here;
4872  * for small numbers, polishing the difference might lead to wrong results -->
4873  * better use the exact difference in this case
4874  */
4875  if( SCIPisEQ(scip, rhssubtrahend, consdata->rhs ) && SCIPisFeasGE(scip, REALABS(rhssubtrahend), 1.0) )
4876  {
4877  SCIP_CALL( chgRhs(scip, cons, 0.0) );
4878  }
4879  else
4880  {
4881  SCIP_CALL( chgRhs(scip, cons, consdata->rhs - rhssubtrahend) );
4882  }
4883  }
4884  consdata->removedfixings = TRUE;
4885 
4886  SCIPdebugMsg(scip, "after fixings:\n");
4887  SCIPdebugPrintCons(scip, cons, NULL);
4888 
4889  /* if aggregated variables have been replaced, multiple entries of the same variable are possible and we have
4890  * to clean up the constraint
4891  */
4892  SCIP_CALL( mergeMultiples(scip, cons) );
4893 
4894  SCIPdebugMsg(scip, "after merging:\n");
4895  SCIPdebugPrintCons(scip, cons, NULL);
4896  }
4897  assert(consdata->removedfixings);
4898 
4899 #ifndef NDEBUG
4900  /* check, if all fixings are applied */
4901  for( v = 0; v < consdata->nvars; ++v )
4902  assert(SCIPvarIsActive(consdata->vars[v]));
4903 #endif
4904 
4905  return SCIP_OKAY;
4906 }
4907 
4908 /** for each variable in the linear constraint, except the inferred variable, adds one bound to the conflict analysis'
4909  * candidate store (bound depends on sign of coefficient and whether the left or right hand side was the reason for the
4910  * inference variable's bound change); the conflict analysis can be initialized with the linear constraint being the
4911  * conflict detecting constraint by using NULL as inferred variable
4912  */
4913 static
4915  SCIP* scip, /**< SCIP data structure */
4916  SCIP_CONS* cons, /**< constraint that inferred the bound change */
4917  SCIP_VAR* infervar, /**< variable that was deduced, or NULL */
4918  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
4919  int inferpos, /**< position of the inferred variable in the vars array */
4920  SCIP_Bool reasonisrhs /**< is the right hand side responsible for the bound change? */
4921  )
4922 {
4923  SCIP_CONSDATA* consdata;
4924  SCIP_VAR** vars;
4925  SCIP_Real* vals;
4926  int nvars;
4927  int i;
4928 
4929  assert(scip != NULL);
4930  assert(cons != NULL);
4931 
4932  consdata = SCIPconsGetData(cons);
4934  assert(consdata != NULL);
4935 
4936  vars = consdata->vars;
4937  vals = consdata->vals;
4938  nvars = consdata->nvars;
4939 
4940  assert(vars != NULL || nvars == 0);
4941  assert(vals != NULL || nvars == 0);
4942 
4943  assert(-1 <= inferpos && inferpos < nvars);
4944  assert((infervar == NULL) == (inferpos == -1));
4945  assert(inferpos == -1 || vars[inferpos] == infervar); /*lint !e613*/
4946 
4947  /* for each variable, add the bound to the conflict queue, that is responsible for the minimal or maximal
4948  * residual value, depending on whether the left or right hand side is responsible for the bound change:
4949  * - if the right hand side is the reason, the minimal residual activity is responsible
4950  * - if the left hand side is the reason, the maximal residual activity is responsible
4951  */
4952 
4953  /* if the variable is integral we only need to add reason bounds until the propagation could be applied */
4954  if( infervar == NULL || SCIPvarIsIntegral(infervar) )
4955  {
4956  SCIP_Real minresactivity;
4957  SCIP_Real maxresactivity;
4958  SCIP_Bool minisrelax;
4959  SCIP_Bool maxisrelax;
4960  SCIP_Bool isminsettoinfinity;
4961  SCIP_Bool ismaxsettoinfinity;
4962 
4963  minresactivity = -SCIPinfinity(scip);
4964  maxresactivity = SCIPinfinity(scip);
4965 
4966  /* calculate the minimal and maximal global activity of all other variables involved in the constraint */
4967  if( infervar != NULL )
4968  {
4969  assert(vals != NULL); /* for flexelint */
4970  if( reasonisrhs )
4971  consdataGetGlbActivityResiduals(scip, consdata, infervar, vals[inferpos], FALSE, &minresactivity, NULL,
4972  &minisrelax, NULL, &isminsettoinfinity, NULL);
4973  else
4974  consdataGetGlbActivityResiduals(scip, consdata, infervar, vals[inferpos], FALSE, NULL, &maxresactivity,
4975  NULL, &maxisrelax, NULL, &ismaxsettoinfinity);
4976  }
4977  else
4978  {
4979  if( reasonisrhs )
4980  consdataGetGlbActivityBounds(scip, consdata, FALSE, &minresactivity, NULL,
4981  &minisrelax, NULL, &isminsettoinfinity, NULL);
4982  else
4983  consdataGetGlbActivityBounds(scip, consdata, FALSE, NULL, &maxresactivity,
4984  NULL, &maxisrelax, NULL, &ismaxsettoinfinity);
4985  }
4986 
4987  /* we can only do something clever, if the residual activity is finite and not relaxed */
4988  if( (reasonisrhs && !isminsettoinfinity && !minisrelax) || (!reasonisrhs && !ismaxsettoinfinity && !maxisrelax) ) /*lint !e644*/
4989  {
4990  SCIP_Real rescap;
4991  SCIP_Bool resactisinf;
4992 
4993  resactisinf = FALSE;
4994 
4995  /* calculate the residual capacity that would be left, if the variable would be set to one more / one less
4996  * than its inferred bound
4997  */
4998  if( infervar != NULL )
4999  {
5000  assert(vals != NULL); /* for flexelint */
5001 
5002  if( reasonisrhs )
5003  {
5004  if( SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastglbminactivity) )
5005  {
5006  consdataGetReliableResidualActivity(scip, consdata, infervar, &minresactivity, TRUE, TRUE);
5007  if( SCIPisInfinity(scip, -minresactivity) )
5008  resactisinf = TRUE;
5009  }
5010  rescap = consdata->rhs - minresactivity;
5011  }
5012  else
5013  {
5014  if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastglbmaxactivity) )
5015  {
5016  consdataGetReliableResidualActivity(scip, consdata, infervar, &maxresactivity, FALSE, TRUE);
5017  if( SCIPisInfinity(scip, maxresactivity) )
5018  resactisinf = TRUE;
5019  }
5020  rescap = consdata->lhs - maxresactivity;
5021  }
5022 
5023  if( reasonisrhs == (vals[inferpos] > 0.0) )
5024  rescap -= vals[inferpos] * (SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) + 1.0);
5025  else
5026  rescap -= vals[inferpos] * (SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) - 1.0);
5027  }
5028  else
5029  rescap = (reasonisrhs ? consdata->rhs - minresactivity : consdata->lhs - maxresactivity);
5030 
5031  if( !resactisinf )
5032  {
5033  /* now add bounds as reasons until the residual capacity is exceeded */
5034  for( i = 0; i < nvars; ++i )
5035  {
5036  assert( vars != NULL && vals != NULL ); /* for lint */
5037 
5038  /* zero coefficients and the infered variable can be ignored */
5039  if( vars[i] == infervar || SCIPisZero(scip, vals[i]) )
5040  continue;
5041 
5042  /* check if the residual capacity is exceeded */
5043  if( (reasonisrhs && SCIPisFeasNegative(scip, rescap))
5044  || (!reasonisrhs && SCIPisFeasPositive(scip, rescap)) )
5045  break;
5046 
5047  /* update the residual capacity due to the local bound of this variable */
5048  if( reasonisrhs == (vals[i] > 0.0) )
5049  {
5050  /* rhs is reason and coeff is positive, or lhs is reason and coeff is negative -> lower bound */
5051  SCIP_CALL( SCIPaddConflictLb(scip, vars[i], bdchgidx) );
5052  rescap -= vals[i] * (SCIPgetVarLbAtIndex(scip, vars[i], bdchgidx, FALSE) - SCIPvarGetLbGlobal(vars[i]));
5053  }
5054  else
5055  {
5056  /* lhs is reason and coeff is positive, or rhs is reason and coeff is negative -> upper bound */
5057  SCIP_CALL( SCIPaddConflictUb(scip, vars[i], bdchgidx) );
5058  rescap -= vals[i] * (SCIPgetVarUbAtIndex(scip, vars[i], bdchgidx, FALSE) - SCIPvarGetUbGlobal(vars[i]));
5059  }
5060  }
5061  return SCIP_OKAY;
5062  }
5063  }
5064  }
5065 
5066  /* for a bound change on a continuous variable, all locally changed bounds are responsible */
5067  for( i = 0; i < nvars; ++i )
5068  {
5069  assert(vars != NULL); /* for flexelint */
5070  assert(vals != NULL); /* for flexelint */
5071 
5072  /* zero coefficients and the infered variable can be ignored */
5073  if( vars[i] == infervar || SCIPisZero(scip, vals[i]) )
5074  continue;
5075 
5076  if( reasonisrhs == (vals[i] > 0.0) )
5077  {
5078  /* rhs is reason and coeff is positive, or lhs is reason and coeff is negative -> lower bound is responsible */
5079  SCIP_CALL( SCIPaddConflictLb(scip, vars[i], bdchgidx) );
5080  }
5081  else
5082  {
5083  /* lhs is reason and coeff is positive, or rhs is reason and coeff is negative -> upper bound is responsible */
5084  SCIP_CALL( SCIPaddConflictUb(scip, vars[i], bdchgidx) );
5085  }
5086  }
5087 
5088  return SCIP_OKAY;
5089 }
5090 
5091 /** for each variable in the linear ranged row constraint, except the inferred variable, adds the bounds of all fixed
5092  * variables to the conflict analysis' candidate store; the conflict analysis can be initialized
5093  * with the linear constraint being the conflict detecting constraint by using NULL as inferred variable
5094  */
5095 static
5097  SCIP* scip, /**< SCIP data structure */
5098  SCIP_CONS* cons, /**< constraint that inferred the bound change */
5099  SCIP_VAR* infervar, /**< variable that was deduced, or NULL */
5100  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
5101  int inferpos /**< position of the inferred variable in the vars array, or -1 */
5102  )
5103 {
5104  SCIP_CONSDATA* consdata;
5105  SCIP_VAR** vars;
5106  int nvars;
5107  int v;
5108 
5109  assert(scip != NULL);
5110  assert(cons != NULL);
5111 
5112  consdata = SCIPconsGetData(cons);
5113  assert(consdata != NULL);
5114  vars = consdata->vars;
5115  nvars = consdata->nvars;
5116  assert(vars != NULL || nvars == 0);
5117  assert(-1 <= inferpos && inferpos < nvars);
5118  assert((infervar == NULL) == (inferpos == -1));
5119  assert(inferpos == -1 || vars != NULL);
5120  assert(inferpos == -1 || vars[inferpos] == infervar); /*lint !e613*/
5121 
5122  /* collect all fixed variables */
5123  for( v = nvars - 1; v >= 0; --v )
5124  {
5125  assert(vars != NULL); /* for flexelint */
5126 
5127  /* need to add old bounds before propagation of inferrence variable */
5128  if( vars[v] == infervar )
5129  {
5130  assert(vars[v] != NULL);
5131 
5132  if( !SCIPisEQ(scip, SCIPgetVarLbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPvarGetLbGlobal(vars[v])) )
5133  {
5134  /* @todo get boundchange index before this last boundchange and correct the index */
5135  SCIP_CALL( SCIPaddConflictLb(scip, vars[v], bdchgidx) );
5136  }
5137 
5138  if( !SCIPisEQ(scip, SCIPgetVarUbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPvarGetUbGlobal(vars[v])) )
5139  {
5140  /* @todo get boundchange index before this last boundchange and correct the index */
5141  SCIP_CALL( SCIPaddConflictUb(scip, vars[v], bdchgidx) );
5142  }
5143 
5144  continue;
5145  }
5146 
5147  /* check for fixed variables */
5148  if( SCIPisEQ(scip, SCIPgetVarLbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPgetVarUbAtIndex(scip, vars[v], bdchgidx, FALSE)) )
5149  {
5150  /* add all bounds of fixed variables which lead to the boundchange of the given inference variable */
5151  SCIP_CALL( SCIPaddConflictLb(scip, vars[v], bdchgidx) );
5152  SCIP_CALL( SCIPaddConflictUb(scip, vars[v], bdchgidx) );
5153  }
5154  }
5155 
5156  return SCIP_OKAY;
5157 }
5158 
5159 /** add reasoning variables to conflict candidate queue which led to the conflict */
5160 static
5162  SCIP* scip, /**< SCIP data structure */
5163  SCIP_VAR** vars, /**< variables reasoning the infeasibility */
5164  int nvars, /**< number of variables reasoning the infeasibility */
5165  SCIP_VAR* var, /**< variable which was tried to fix/tighten, or NULL */
5166  SCIP_Real bound /**< bound of variable which was tried to apply, or SCIP_INVALID */
5167  )
5168 {
5169  int v;
5170 
5171  assert(scip != NULL);
5172 
5173  /* collect all variables for which the local bounds differ from their global bounds */
5174  for( v = nvars - 1; v >= 0; --v )
5175  {
5176  assert(vars != NULL);
5177 
5178  /* check for local bound changes variables */
5179  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(vars[v]), SCIPvarGetLbGlobal(vars[v])) )
5180  {
5181  /* add conflict bound */
5182  SCIP_CALL( SCIPaddConflictLb(scip, vars[v], 0) );
5183  }
5184 
5185  if( !SCIPisEQ(scip, SCIPvarGetUbLocal(vars[v]), SCIPvarGetUbGlobal(vars[v])) )
5186  {
5187  SCIP_CALL( SCIPaddConflictUb(scip, vars[v], 0) );
5188  }
5189  }
5190 
5191  if( var != NULL )
5192  {
5193  if( bound < SCIPvarGetLbLocal(var) )
5194  {
5195  SCIP_CALL( SCIPaddConflictLb(scip, var, 0) );
5196  }
5197 
5198  if( bound > SCIPvarGetUbLocal(var) )
5199  {
5200  SCIP_CALL( SCIPaddConflictUb(scip, var, 0) );
5201  }
5202  }
5203 
5204  return SCIP_OKAY;
5205 }
5206 
5207 /** resolves a propagation on the given variable by supplying the variables needed for applying the corresponding
5208  * propagation rule (see propagateCons()):
5209  * (1) activity residuals of all other variables tighten bounds of single variable
5210  */
5211 static
5213  SCIP* scip, /**< SCIP data structure */
5214  SCIP_CONS* cons, /**< constraint that inferred the bound change */
5215  SCIP_VAR* infervar, /**< variable that was deduced */
5216  INFERINFO inferinfo, /**< inference information */
5217  SCIP_BOUNDTYPE boundtype, /**< the type of the changed bound (lower or upper bound) */
5218  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
5219  SCIP_RESULT* result /**< pointer to store the result of the propagation conflict resolving call */
5220  )
5221 {
5222  SCIP_CONSDATA* consdata;
5223  SCIP_VAR** vars;
5224 #ifndef NDEBUG
5225  SCIP_Real* vals;
5226 #endif
5227  int nvars;
5228  int inferpos;
5229 
5230  assert(scip != NULL);
5231  assert(cons != NULL);
5232  assert(result != NULL);
5233 
5234  consdata = SCIPconsGetData(cons);
5235  assert(consdata != NULL);
5236  vars = consdata->vars;
5237  nvars = consdata->nvars;
5238 #ifndef NDEBUG
5239  vals = consdata->vals;
5240  assert(vars != NULL);
5241  assert(vals != NULL);
5242 #endif
5243 
5244  /* get the position of the inferred variable in the vars array */
5245  inferpos = inferInfoGetPos(inferinfo);
5246  if( inferpos >= nvars || vars[inferpos] != infervar )
5247  {
5248  /* find inference variable in constraint */
5249  /**@todo use a binary search here; the variables can be sorted by variable index */
5250  for( inferpos = 0; inferpos < nvars && vars[inferpos] != infervar; ++inferpos )
5251  {}
5252  }
5253  assert(inferpos < nvars);
5254  assert(vars[inferpos] == infervar);
5255  assert(!SCIPisZero(scip, vals[inferpos]));
5256 
5257  switch( inferInfoGetProprule(inferinfo) )
5258  {
5259  case PROPRULE_1_RHS:
5260  /* the bound of the variable was tightened, because the minimal or maximal residual activity of the linear
5261  * constraint (only taking the other variables into account) didn't leave enough space for a larger
5262  * domain in order to not exceed the right hand side of the inequality
5263  */
5264  assert((vals[inferpos] > 0.0) == (boundtype == SCIP_BOUNDTYPE_UPPER));
5265  SCIP_CALL( addConflictBounds(scip, cons, infervar, bdchgidx, inferpos, TRUE) );
5266  *result = SCIP_SUCCESS;
5267  break;
5268 
5269  case PROPRULE_1_LHS:
5270  /* the bound of the variable was tightened, because the minimal or maximal residual activity of the linear
5271  * constraint (only taking the other variables into account) didn't leave enough space for a larger
5272  * domain in order to not fall below the left hand side of the inequality
5273  */
5274  assert((vals[inferpos] > 0.0) == (boundtype == SCIP_BOUNDTYPE_LOWER));
5275  SCIP_CALL( addConflictBounds(scip, cons, infervar, bdchgidx, inferpos, FALSE) );
5276  *result = SCIP_SUCCESS;
5277  break;
5278 
5279  case PROPRULE_1_RANGEDROW:
5280  /* the bound of the variable was tightened, because some variables were already fixed and the leftover only allow
5281  * the given inference variable to their bounds in this given ranged row
5282  */
5283 
5284  /* check that we really have a ranged row here */
5285  assert(!SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->rhs));
5286  SCIP_CALL( addConflictFixedVars(scip, cons, infervar, bdchgidx, inferpos) );
5287  *result = SCIP_SUCCESS;
5288  break;
5289 
5290  case PROPRULE_INVALID:
5291  default:
5292  SCIPerrorMessage("invalid inference information %d in linear constraint <%s> at position %d for %s bound of variable <%s>\n",
5293  inferInfoGetProprule(inferinfo), SCIPconsGetName(cons), inferInfoGetPos(inferinfo),
5294  boundtype == SCIP_BOUNDTYPE_LOWER ? "lower" : "upper", SCIPvarGetName(infervar));
5295  SCIP_CALL( SCIPprintCons(scip, cons, NULL) );
5296  SCIPinfoMessage(scip, NULL, ";\n");
5297  return SCIP_INVALIDDATA;
5298  }
5299 
5300  return SCIP_OKAY;
5301 }
5302 
5303 /** analyzes conflicting bounds on given constraint, and adds conflict constraint to problem */
5304 static
5306  SCIP* scip, /**< SCIP data structure */
5307  SCIP_CONS* cons, /**< conflict detecting constraint */
5308  SCIP_Bool reasonisrhs /**< is the right hand side responsible for the conflict? */
5309  )
5310 {
5311  /* conflict analysis can only be applied in solving stage and if it is turned on */
5313  return SCIP_OKAY;
5314 
5315  /* initialize conflict analysis */
5317 
5318  /* add the conflicting bound for each variable of infeasible constraint to conflict candidate queue */
5319  SCIP_CALL( addConflictBounds(scip, cons, NULL, NULL, -1, reasonisrhs) );
5320 
5321  /* analyze the conflict */
5322  SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
5323 
5324  return SCIP_OKAY;
5325 }
5326 
5327 /** check if there is any hope of tightening some bounds */
5328 static
5330  SCIP_CONS* cons /**< linear constraint */
5331  )
5332 {
5333  SCIP_CONSDATA* consdata;
5334  int infcountmin;
5335  int infcountmax;
5336 
5337  consdata = SCIPconsGetData(cons);
5338  assert(consdata != NULL);
5339 
5340  infcountmin = consdata->minactivityneginf
5341  + consdata->minactivityposinf
5342  + consdata->minactivityneghuge
5343  + consdata->minactivityposhuge;
5344  infcountmax = consdata->maxactivityneginf
5345  + consdata->maxactivityposinf
5346  + consdata->maxactivityneghuge
5347  + consdata->maxactivityposhuge;
5349  if( infcountmin > 1 && infcountmax > 1 )
5350  return FALSE;
5351 
5352  return TRUE;
5353 }
5354 
5355 /** tighten upper bound */
5356 static
5358  SCIP* scip, /**< SCIP data structure */
5359  SCIP_CONS* cons, /**< linear constraint */
5360  int pos, /**< variable position */
5361  PROPRULE proprule, /**< propagation rule that deduced the value */
5362  SCIP_Real newub, /**< new upper bound */
5363  SCIP_Real oldub, /**< old upper bound */
5364  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
5365  int* nchgbds, /**< pointer to count the total number of tightened bounds */
5366  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
5367  )
5368 {
5369  SCIP_CONSDATA* consdata;
5370  SCIP_VAR* var;
5371  SCIP_Real lb;
5372  SCIP_Bool infeasible;
5373  SCIP_Bool tightened;
5374 
5375  assert(cons != NULL);
5376  assert(!SCIPisInfinity(scip, newub));
5377 
5378  consdata = SCIPconsGetData(cons);
5379  assert(consdata != NULL);
5380  var = consdata->vars[pos];
5381  assert(var != NULL);
5382 
5383  lb = SCIPvarGetLbLocal(var);
5384  newub = SCIPadjustedVarUb(scip, var, newub);
5385 
5386  if( force || SCIPisUbBetter(scip, newub, lb, oldub) )
5387  {
5388  SCIP_VARTYPE vartype;
5389 
5390  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, activity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newub=%.15g\n",
5391  SCIPconsGetName(cons), SCIPvarGetName(var), lb, oldub, consdata->vals[pos], consdata->minactivity, consdata->maxactivity, consdata->lhs, consdata->rhs, newub);
5392 
5393  vartype = SCIPvarGetType(var);
5394 
5395  /* tighten upper bound */
5396  SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(proprule, pos), force, &infeasible, &tightened) );
5397 
5398  if( infeasible )
5399  {
5400  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5401  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5402 
5403  /* analyze conflict */
5404  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
5405 
5406  *cutoff = TRUE;
5407  }
5408  else if( tightened )
5409  {
5410  assert(SCIPisFeasLE(scip, SCIPvarGetUbLocal(var), oldub));
5411  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
5412  SCIPconsGetName(cons), SCIPvarGetName(var), lb, SCIPvarGetUbLocal(var));
5413 
5414  (*nchgbds)++;
5415 
5416  /* if variable type was changed we might be able to upgrade the constraint */
5417  if( vartype != SCIPvarGetType(var) )
5418  consdata->upgradetried = FALSE;
5419  }
5420  }
5421  return SCIP_OKAY;
5422 }
5423 
5424 /** tighten lower bound */
5425 static
5427  SCIP* scip, /**< SCIP data structure */
5428  SCIP_CONS* cons, /**< linear constraint */
5429  int pos, /**< variable position */
5430  PROPRULE proprule, /**< propagation rule that deduced the value */
5431  SCIP_Real newlb, /**< new lower bound */
5432  SCIP_Real oldlb, /**< old lower bound */
5433  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
5434  int* nchgbds, /**< pointer to count the total number of tightened bounds */
5435  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
5436  )
5437 {
5438  SCIP_CONSDATA* consdata;
5439  SCIP_VAR* var;
5440  SCIP_Real ub;
5441  SCIP_Bool infeasible;
5442  SCIP_Bool tightened;
5443 
5444  assert(cons != NULL);
5445  assert(!SCIPisInfinity(scip, newlb));
5446 
5447  consdata = SCIPconsGetData(cons);
5448  assert(consdata != NULL);
5449  var = consdata->vars[pos];
5450  assert(var != NULL);
5451 
5452  ub = SCIPvarGetUbLocal(var);
5453  newlb = SCIPadjustedVarLb(scip, var, newlb);
5454 
5455  if( force || SCIPisLbBetter(scip, newlb, oldlb, ub) )
5456  {
5457  SCIP_VARTYPE vartype;
5458 
5459  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, activity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
5460  SCIPconsGetName(cons), SCIPvarGetName(var), oldlb, ub, consdata->vals[pos], consdata->minactivity, consdata->maxactivity, consdata->lhs, consdata->rhs, newlb);
5461 
5462  vartype = SCIPvarGetType(var);
5463 
5464  /* tighten lower bound */
5465  SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(proprule, pos), force, &infeasible, &tightened) );
5466 
5467  if( infeasible )
5468  {
5469  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5470  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5471 
5472  /* analyze conflict */
5473  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
5474 
5475  *cutoff = TRUE;
5476  }
5477  else if( tightened )
5478  {
5479  assert(SCIPisFeasGE(scip, SCIPvarGetLbLocal(var), oldlb));
5480  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
5481  SCIPconsGetName(cons), SCIPvarGetName(var), SCIPvarGetLbLocal(var), ub);
5482 
5483  (*nchgbds)++;
5484 
5485  /* if variable type was changed we might be able to upgrade the constraint */
5486  if( vartype != SCIPvarGetType(var) )
5487  consdata->upgradetried = FALSE;
5488  }
5489  }
5490  return SCIP_OKAY;
5491 }
5492 
5493 /** tightens bounds of a single variable due to activity bounds (easy case) */
5494 static
5496  SCIP* scip, /**< SCIP data structure */
5497  SCIP_CONS* cons, /**< linear constraint */
5498  int pos, /**< position of the variable in the vars array */
5499  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
5500  int* nchgbds, /**< pointer to count the total number of tightened bounds */
5501  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
5502  )
5503 {
5504  SCIP_CONSDATA* consdata;
5505  SCIP_VAR* var;
5506  SCIP_Real val;
5507  SCIP_Real lb;
5508  SCIP_Real ub;
5509  SCIP_Real lhs;
5510  SCIP_Real rhs;
5511 
5512  assert(scip != NULL);
5513  assert(cons != NULL);
5514  assert(cutoff != NULL);
5515  assert(nchgbds != NULL);
5516 
5517  /* we cannot tighten variables' bounds, if the constraint may be not complete */
5518  if( SCIPconsIsModifiable(cons) )
5519  return SCIP_OKAY;
5520 
5521  consdata = SCIPconsGetData(cons);
5522  assert(consdata != NULL);
5523  assert(0 <= pos && pos < consdata->nvars);
5524 
5525  *cutoff = FALSE;
5526 
5527  var = consdata->vars[pos];
5528  assert(var != NULL);
5529 
5530  /* we cannot tighten bounds of multi-aggregated variables */
5532  return SCIP_OKAY;
5533 
5534  val = consdata->vals[pos];
5535  lhs = consdata->lhs;
5536  rhs = consdata->rhs;
5537  assert(!SCIPisZero(scip, val));
5538  assert(!SCIPisInfinity(scip, lhs));
5539  assert(!SCIPisInfinity(scip, -rhs));
5540 
5541  lb = SCIPvarGetLbLocal(var);
5542  ub = SCIPvarGetUbLocal(var);
5543  assert(SCIPisLE(scip, lb, ub));
5544 
5545  /* recompute activities if needed */
5546  if( !consdata->validactivities )
5547  consdataCalcActivities(scip, consdata);
5548  assert(consdata->validactivities);
5549  if( !consdata->validminact )
5550  consdataRecomputeMinactivity(scip, consdata);
5551  assert(consdata->validminact);
5552 
5553  if( val > 0.0 )
5554  {
5555  /* check, if we can tighten the variable's upper bound */
5556  if( !SCIPisInfinity(scip, rhs) )
5557  {
5558  SCIP_Real slack;
5559  SCIP_Real alpha;
5560 
5561  /* min activity should be valid at this point (if this is not true, then some decisions might be wrong!) */
5562  assert(consdata->validminact);
5563 
5564  /* if the minactivity is larger than the right hand side by feasibility epsilon, the constraint is infeasible */
5565  if( SCIPisFeasLT(scip, rhs, consdata->minactivity) )
5566  {
5567  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, minactivity=%.15g > rhs=%.15g\n",
5568  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->minactivity, rhs);
5569 
5570  *cutoff = TRUE;
5571  return SCIP_OKAY;
5572  }
5573 
5574  slack = rhs - consdata->minactivity;
5575 
5576  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5577  * it to zero
5578  */
5579  if( !SCIPisPositive(scip, slack) )
5580  slack = 0.0;
5581 
5582  alpha = val * (ub - lb);
5583  assert(!SCIPisNegative(scip, alpha));
5584 
5585  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5586  {
5587  SCIP_Real newub;
5588 
5589  /* compute new upper bound */
5590  newub = lb + (slack / val);
5591 
5592  SCIP_CALL( tightenVarUb(scip, cons, pos, PROPRULE_1_RHS, newub, ub, cutoff, nchgbds, force) );
5593 
5594  if( *cutoff )
5595  {
5596  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5597  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5598 
5599  return SCIP_OKAY;
5600  }
5601 
5602  /* collect the new upper bound which is needed for the lower bound computation */
5603  ub = SCIPvarGetUbLocal(var);
5604  }
5605  }
5606 
5607  /* check, if we can tighten the variable's lower bound */
5608  if( !SCIPisInfinity(scip, -lhs) )
5609  {
5610  SCIP_Real slack;
5611  SCIP_Real alpha;
5612 
5613  /* make sure the max activity is reliable */
5614  if( !consdata->validmaxact )
5615  {
5616  consdataRecomputeMaxactivity(scip, consdata);
5617  }
5618  assert(consdata->validmaxact);
5619 
5620  /* if the maxactivity is smaller than the left hand side by feasibility epsilon, the constraint is infeasible */
5621  if( SCIPisFeasLT(scip, consdata->maxactivity, lhs) )
5622  {
5623  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, maxactivity=%.15g < lhs=%.15g\n",
5624  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->maxactivity, lhs);
5625  *cutoff = TRUE;
5626  return SCIP_OKAY;
5627  }
5628 
5629  slack = consdata->maxactivity - lhs;
5630 
5631  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5632  * it to zero
5633  */
5634  if( !SCIPisPositive(scip, slack) )
5635  slack = 0.0;
5636 
5637  alpha = val * (ub - lb);
5638  assert(!SCIPisNegative(scip, alpha));
5639 
5640  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5641  {
5642  SCIP_Real newlb;
5643 
5644  /* compute new lower bound */
5645  newlb = ub - (slack / val);
5646 
5647  SCIP_CALL( tightenVarLb(scip, cons, pos, PROPRULE_1_LHS, newlb, lb, cutoff, nchgbds, force) );
5648 
5649  if( *cutoff )
5650  {
5651  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5652  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5653 
5654  return SCIP_OKAY;
5655  }
5656  }
5657  }
5658  }
5659  else
5660  {
5661  /* check, if we can tighten the variable's lower bound */
5662  if( !SCIPisInfinity(scip, rhs) )
5663  {
5664  SCIP_Real slack;
5665  SCIP_Real alpha;
5666 
5667  /* min activity should be valid at this point (if this is not true, then some decisions might be wrong!) */
5668  assert(consdata->validminact);
5669 
5670  /* if the minactivity is larger than the right hand side by feasibility epsilon, the constraint is infeasible */
5671  if( SCIPisFeasLT(scip, rhs, consdata->minactivity) )
5672  {
5673  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, minactivity=%.15g > rhs=%.15g\n",
5674  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->minactivity, rhs);
5675 
5676  *cutoff = TRUE;
5677  return SCIP_OKAY;
5678  }
5679 
5680  slack = rhs - consdata->minactivity;
5681 
5682  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5683  * it to zero
5684  */
5685  if( !SCIPisPositive(scip, slack) )
5686  slack = 0.0;
5687 
5688  alpha = val * (lb - ub);
5689  assert(!SCIPisNegative(scip, alpha));
5690 
5691  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5692  {
5693  SCIP_Real newlb;
5694 
5695  /* compute new lower bound */
5696  newlb = ub + slack / val;
5697 
5698  SCIP_CALL( tightenVarLb(scip, cons, pos, PROPRULE_1_RHS, newlb, lb, cutoff, nchgbds, force) );
5699 
5700  if( *cutoff )
5701  {
5702  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5703  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5704 
5705  return SCIP_OKAY;
5706  }
5707  /* collect the new lower bound which is needed for the upper bound computation */
5708  lb = SCIPvarGetLbLocal(var);
5709  }
5710  }
5711 
5712  /* check, if we can tighten the variable's upper bound */
5713  if( !SCIPisInfinity(scip, -lhs) )
5714  {
5715  SCIP_Real slack;
5716  SCIP_Real alpha;
5717 
5718  /* make sure the max activity is reliable */
5719  if( !consdata->validmaxact )
5720  {
5721  consdataRecomputeMaxactivity(scip, consdata);
5722  }
5723  assert(consdata->validmaxact);
5724 
5725  /* if the maxactivity is smaller than the left hand side by feasibility epsilon, the constraint is infeasible */
5726  if( SCIPisFeasLT(scip, consdata->maxactivity, lhs) )
5727  {
5728  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, maxactivity=%.15g < lhs=%.15g\n",
5729  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->maxactivity, lhs);
5730 
5731  *cutoff = TRUE;
5732  return SCIP_OKAY;
5733  }
5734 
5735  slack = consdata->maxactivity - lhs;
5736 
5737  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5738  * it to zero
5739  */
5740  if( !SCIPisPositive(scip, slack) )
5741  slack = 0.0;
5742 
5743  alpha = val * (lb - ub);
5744  assert(!SCIPisNegative(scip, alpha));
5745 
5746  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5747  {
5748  SCIP_Real newub;
5749 
5750  /* compute new upper bound */
5751  newub = lb - (slack / val);
5752 
5753  SCIP_CALL( tightenVarUb(scip, cons, pos, PROPRULE_1_LHS, newub, ub, cutoff, nchgbds, force) );
5754 
5755  if( *cutoff )
5756  {
5757  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5758  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5759 
5760  return SCIP_OKAY;
5761  }
5762  }
5763  }
5764  }
5765 
5766  return SCIP_OKAY;
5767 }
5768 
5769 /** analyzes conflicting bounds on given ranged row constraint, and adds conflict constraint to problem */
5770 static
5772  SCIP* scip, /**< SCIP data structure */
5773  SCIP_CONS* cons, /**< conflict detecting constraint */
5774  SCIP_VAR** vars, /**< variables reasoning the infeasibility */
5775  int nvars, /**< number of variables reasoning the infeasibility */
5776  SCIP_VAR* var, /**< variable which was tried to fix/tighten, or NULL */
5777  SCIP_Real bound /**< bound of variable which was tried to apply, or SCIP_INVALID */
5778  )
5779 {
5780 #ifndef NDEBUG
5781  SCIP_CONSDATA* consdata;
5782 
5783  assert(scip != NULL);
5784  assert(cons != NULL);
5785 
5786  consdata = SCIPconsGetData(cons);
5787  assert(consdata != NULL);
5788  assert(!SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->rhs));
5789 #endif
5791  /* conflict analysis can only be applied in solving stage and if it is turned on */
5793  return SCIP_OKAY;
5794 
5795  /* initialize conflict analysis */
5797 
5798  /* add the conflicting fixed variables of this ranged row constraint to conflict candidate queue */
5799  SCIP_CALL( addConflictFixedVars(scip, cons, NULL, NULL, -1) );
5800 
5801  /* add reasoning variables to conflict candidate queue which led to the conflict */
5802  SCIP_CALL( addConflictReasonVars(scip, vars, nvars, var, bound) );
5803 
5804  /* analyze the conflict */
5805  SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
5806 
5807  return SCIP_OKAY;
5808 }
5809 
5810 /** propagate ranged rows
5811  *
5812  * Check ranged rows for possible solutions, possibly detect infeasibility, fix variables due to having only one possible
5813  * solution, tighten bounds if having only two possible solutions or add constraints which propagate a subset of
5814  * variables better.
5815  *
5816  * Example:
5817  * c1: 12 x1 + 9 x2 - x3 = 0 with x1, x2 free and 1 <= x3 <= 2
5818  *
5819  * x3 needs to be a multiple of 3, so the instance is infeasible.
5820  *
5821  * Example:
5822  * c1: 12 x1 + 9 x2 - x3 = 1 with x1, x2 free and 1 <= x3 <= 2
5823  *
5824  * The only possible value for x3 is 2, so the variable will be fixed.
5825  *
5826  * @todo add holes if possible
5827  */
5828 static
5830  SCIP* scip, /**< SCIP data structure */
5831  SCIP_CONS* cons, /**< linear constraint */
5832  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
5833  int* nfixedvars, /**< pointer to count number of fixed variables */
5834  int* nchgbds, /**< pointer to count the number of bound changes */
5835  int* naddconss /**< pointer to count number of added constraints */
5836  )
5837 {
5838  SCIP_CONSHDLRDATA* conshdlrdata;
5839  SCIP_CONSHDLR* conshdlr;
5840  SCIP_CONSDATA* consdata;
5841  SCIP_VAR** infcheckvars;
5842  SCIP_Real* infcheckvals;
5843  SCIP_Real minactinfvars;
5844  SCIP_Real maxactinfvars;
5845  SCIP_Real lb;
5846  SCIP_Real ub;
5847  SCIP_Real feastol;
5848  SCIP_Real fixedact;
5849  SCIP_Real lhs;
5850  SCIP_Real rhs;
5851  SCIP_Real absminbincoef;
5852  SCIP_Longint gcd;
5853  SCIP_Longint gcdtmp;
5854  SCIP_Bool minactinfvarsinvalid;
5855  SCIP_Bool maxactinfvarsinvalid;
5856  SCIP_Bool possiblegcd;
5857  SCIP_Bool gcdisone;
5858  SCIP_Bool addartconss;
5859  int ninfcheckvars;
5860  int nunfixedvars;
5861  int nfixedconsvars;
5862  int ncontvars;
5863  int pos;
5864  int v;
5865 
5866  assert(scip != NULL);
5867  assert(cons != NULL);
5868  assert(cutoff != NULL);
5869  assert(nfixedvars != NULL);
5870  assert(nchgbds != NULL);
5871  assert(naddconss != NULL);
5872 
5873  /* modifiable constraint can be changed so we do not have all necessary information */
5874  if( SCIPconsIsModifiable(cons) )
5875  return SCIP_OKAY;
5876 
5877  consdata = SCIPconsGetData(cons);
5878  assert(consdata != NULL);
5879 
5880  /* we already did full ranged row propagation */
5881  if( consdata->rangedrowpropagated == 2 )
5882  return SCIP_OKAY;
5883 
5884  /* at least three variables are needed */
5885  if( consdata->nvars < 3 )
5886  return SCIP_OKAY;
5887 
5888  /* do nothing on normal inequalities */
5889  if( SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, consdata->rhs) )
5890  return SCIP_OKAY;
5891 
5892  /* get constraint handler data */
5893  conshdlr = SCIPconsGetHdlr(cons);
5894  assert(conshdlr != NULL);
5895  conshdlrdata = SCIPconshdlrGetData(conshdlr);
5896  assert(conshdlrdata != NULL);
5897 
5898  addartconss = conshdlrdata->rangedrowartcons && SCIPgetDepth(scip) < 1 && !SCIPinProbing(scip) && !SCIPinRepropagation(scip);
5899 
5900  /* we may add artificial constraints */
5901  if( addartconss )
5902  consdata->rangedrowpropagated = 2;
5903  /* we are not allowed to add artificial constraints during propagation; if nothing changed on this constraint since
5904  * the last rangedrowpropagation, we can stop; otherwise, we mark this constraint to be rangedrowpropagated without
5905  * artificial constraints
5906  */
5907  else
5908  {
5909  if( consdata->rangedrowpropagated > 0 )
5910  return SCIP_OKAY;
5911 
5912  consdata->rangedrowpropagated = 1;
5913  }
5914  fixedact = 0;
5915  nfixedconsvars = 0;
5916  /* calculate fixed activity and number of fixed variables */
5917  for( v = consdata->nvars - 1; v >= 0; --v )
5918  {
5919  /* all zero coefficients should be eliminated */
5920  assert(!SCIPisZero(scip, consdata->vals[v]));
5921 
5922  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5923  {
5924  fixedact += SCIPvarGetLbLocal(consdata->vars[v]) * consdata->vals[v];
5925  ++nfixedconsvars;
5926  }
5927  }
5928 
5929  /* do not work with huge fixed activities */
5930  if( SCIPisHugeValue(scip, REALABS(fixedact)) )
5931  return SCIP_OKAY;
5932 
5933  /* compute lhs and rhs for unfixed variables only and get number of unfixed variables */
5934  assert(!SCIPisInfinity(scip, -fixedact) && !SCIPisInfinity(scip, fixedact));
5935  lhs = consdata->lhs - fixedact;
5936  rhs = consdata->rhs - fixedact;
5937  nunfixedvars = consdata->nvars - nfixedconsvars;
5938 
5939  /* allocate temporary memory for variables and coefficients which may lead to infeasibility */
5940  SCIP_CALL( SCIPallocBufferArray(scip, &infcheckvars, nunfixedvars) );
5941  SCIP_CALL( SCIPallocBufferArray(scip, &infcheckvals, nunfixedvars) );
5942 
5943  absminbincoef = SCIP_REAL_MAX;
5944  ncontvars = 0;
5945  gcdisone = TRUE;
5946  possiblegcd = TRUE;
5947 
5948  /* we now partition all unfixed variables in two groups:
5949  *
5950  * the first one contains all integral variable with integral
5951  * coefficient so that all variables in this group will have a gcd greater than 1, this group will be implicitly
5952  * given
5953  *
5954  * the second group will contain all left unfixed variables and will be saved as infcheckvars with corresponding
5955  * coefficients as infcheckvals, the order of these variables should be the same as in the consdata object
5956  */
5957 
5958  /* find first integral variables with integral coefficient greater than 1, thereby collecting all other unfixed
5959  * variables
5960  */
5961  ninfcheckvars = 0;
5962  v = -1;
5963  pos = -1;
5964  do
5965  {
5966  ++v;
5967 
5968  /* partition the variables, do not change the order of collection, because it might be used later on */
5969  while( v < consdata->nvars && (SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS ||
5970  !SCIPisIntegral(scip, consdata->vals[v]) || SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0)) )
5971  {
5972  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5973  {
5974  if( SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS )
5975  {
5976  ++ncontvars;
5977  }
5978  else if( SCIPvarIsBinary(consdata->vars[v]) )
5979  {
5980  SCIP_Real absval;
5981 
5982  absval = REALABS(consdata->vals[v]);
5983 
5984  if( absminbincoef > absval )
5985  absminbincoef = absval;
5986  }
5987 
5988  gcdisone = gcdisone && SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0);
5989  possiblegcd = FALSE;
5990  infcheckvars[ninfcheckvars] = consdata->vars[v];
5991  infcheckvals[ninfcheckvars] = consdata->vals[v];
5992  ++ninfcheckvars;
5993 
5994  if( pos == -1 )
5995  pos = v;
5996  }
5997  ++v;
5998  }
5999  }
6000  while( v < consdata->nvars && SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) );
6001 
6002  /* if the first group of variables is empty, we stop */
6003  /* @todo try to propagate/split up a constraint of the form:
6004  * x_1 + ... + x_m + a_1*y_1 + ... + a_n*y_n = k + c,
6005  * 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]
6006  */
6007  if( v == consdata->nvars )
6008  goto TERMINATE;
6009 
6010  /* we need a