Scippy

SCIP

Solving Constraint Integer Programs

cons_linear.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright (C) 2002-2022 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not visit scipopt.org. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file cons_linear.c
17  * @ingroup DEFPLUGINS_CONS
18  * @brief Constraint handler for linear constraints in their most general form, \f$lhs <= a^T x <= rhs\f$.
19  * @author Tobias Achterberg
20  * @author Timo Berthold
21  * @author Marc Pfetsch
22  * @author Kati Wolter
23  * @author Michael Winkler
24  * @author Gerald Gamrath
25  * @author Domenico Salvagnin
26  *
27  * Linear constraints are separated with a high priority, because they are easy
28  * to separate. Instead of using the global cut pool, the same effect can be
29  * implemented by adding linear constraints to the root node, such that they are
30  * separated each time, the linear constraints are separated. A constraint
31  * handler, which generates linear constraints in this way should have a lower
32  * separation priority than the linear constraint handler, and it should have a
33  * separation frequency that is a multiple of the frequency of the linear
34  * constraint handler. In this way, it can be avoided to separate the same cut
35  * twice, because if a separation run of the handler is always preceded by a
36  * separation of the linear constraints, the priorily added constraints are
37  * always satisfied.
38  *
39  * Linear constraints are enforced and checked with a very low priority. Checking
40  * of (many) linear constraints is much more involved than checking the solution
41  * values for integrality. Because we are separating the linear constraints quite
42  * often, it is only necessary to enforce them for integral solutions. A constraint
43  * handler which generates pool cuts in its enforcing method should have an
44  * enforcing priority smaller than that of the linear constraint handler to avoid
45  * regenerating constraints which already exist.
46  */
47 
48 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
49 
50 #include "blockmemshell/memory.h"
51 #include "scip/cons_nonlinear.h"
52 #include "scip/cons_knapsack.h"
53 #include "scip/cons_linear.h"
54 #include "scip/debug.h"
55 #include "scip/pub_conflict.h"
56 #include "scip/pub_cons.h"
57 #include "scip/pub_event.h"
58 #include "scip/pub_expr.h"
59 #include "scip/pub_lp.h"
60 #include "scip/pub_message.h"
61 #include "scip/pub_misc.h"
62 #include "scip/pub_misc_sort.h"
63 #include "scip/pub_var.h"
64 #include "scip/scip_branch.h"
65 #include "scip/scip_conflict.h"
66 #include "scip/scip_cons.h"
67 #include "scip/scip_copy.h"
68 #include "scip/scip_cut.h"
69 #include "scip/scip_event.h"
70 #include "scip/scip_general.h"
71 #include "scip/scip_lp.h"
72 #include "scip/scip_mem.h"
73 #include "scip/scip_message.h"
74 #include "scip/scip_numerics.h"
75 #include "scip/scip_param.h"
76 #include "scip/scip_prob.h"
77 #include "scip/scip_probing.h"
78 #include "scip/scip_sol.h"
79 #include "scip/scip_solvingstats.h"
80 #include "scip/scip_tree.h"
81 #include "scip/scip_var.h"
82 #include <ctype.h>
83 #include <string.h>
84 #if defined(_WIN32) || defined(_WIN64)
85 #else
86 #include <strings.h> /*lint --e{766}*/
87 #endif
88 
89 
90 #define CONSHDLR_NAME "linear"
91 #define CONSHDLR_DESC "linear constraints of the form lhs <= a^T x <= rhs"
92 #define CONSHDLR_SEPAPRIORITY +100000 /**< priority of the constraint handler for separation */
93 #define CONSHDLR_ENFOPRIORITY -1000000 /**< priority of the constraint handler for constraint enforcing */
94 #define CONSHDLR_CHECKPRIORITY -1000000 /**< priority of the constraint handler for checking feasibility */
95 #define CONSHDLR_SEPAFREQ 0 /**< frequency for separating cuts; zero means to separate only in the root node */
96 #define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
97 #define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
98  * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
99 #define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
100 #define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
101 #define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
102 #define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
104 #define CONSHDLR_PRESOLTIMING (SCIP_PRESOLTIMING_FAST | SCIP_PRESOLTIMING_EXHAUSTIVE) /**< presolving timing of the constraint handler (fast, medium, or exhaustive) */
105 #define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP
107 #define EVENTHDLR_NAME "linear"
108 #define EVENTHDLR_DESC "bound change event handler for linear constraints"
110 #define CONFLICTHDLR_NAME "linear"
111 #define CONFLICTHDLR_DESC "conflict handler creating linear constraints"
112 #define CONFLICTHDLR_PRIORITY -1000000
114 #define DEFAULT_TIGHTENBOUNDSFREQ 1 /**< multiplier on propagation frequency, how often the bounds are tightened */
115 #define DEFAULT_MAXROUNDS 5 /**< maximal number of separation rounds per node (-1: unlimited) */
116 #define DEFAULT_MAXROUNDSROOT -1 /**< maximal number of separation rounds in the root node (-1: unlimited) */
117 #define DEFAULT_MAXSEPACUTS 50 /**< maximal number of cuts separated per separation round */
118 #define DEFAULT_MAXSEPACUTSROOT 200 /**< maximal number of cuts separated per separation round in root node */
119 #define DEFAULT_PRESOLPAIRWISE TRUE /**< should pairwise constraint comparison be performed in presolving? */
120 #define DEFAULT_PRESOLUSEHASHING TRUE /**< should hash table be used for detecting redundant constraints in advance */
121 #define DEFAULT_NMINCOMPARISONS 200000 /**< number for minimal pairwise presolving comparisons */
122 #define DEFAULT_MINGAINPERNMINCOMP 1e-06 /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise
123  * comparison round */
124 #define DEFAULT_SORTVARS TRUE /**< should variables be sorted after presolve w.r.t their coefficient absolute for faster
125  * propagation? */
126 #define DEFAULT_CHECKRELMAXABS FALSE /**< should the violation for a constraint with side 0.0 be checked relative
127  * to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
128 #define DEFAULT_MAXAGGRNORMSCALE 0.0 /**< maximal allowed relative gain in maximum norm for constraint aggregation
129  * (0.0: disable constraint aggregation) */
130 #define DEFAULT_MAXEASYACTIVITYDELTA 1e6 /**< maximum activity delta to run easy propagation on linear constraint
131  * (faster, but numerically less stable) */
132 #define DEFAULT_MAXCARDBOUNDDIST 0.0 /**< maximal relative distance from current node's dual bound to primal bound compared
133  * to best node's dual bound for separating knapsack cardinality cuts */
134 #define DEFAULT_SEPARATEALL FALSE /**< should all constraints be subject to cardinality cut generation instead of only
135  * the ones with non-zero dual value? */
136 #define DEFAULT_AGGREGATEVARIABLES TRUE /**< should presolving search for redundant variables in equations */
137 #define DEFAULT_SIMPLIFYINEQUALITIES TRUE /**< should presolving try to simplify inequalities */
138 #define DEFAULT_DUALPRESOLVING TRUE /**< should dual presolving steps be performed? */
139 #define DEFAULT_SINGLETONSTUFFING TRUE /**< should stuffing of singleton continuous variables be performed? */
140 #define DEFAULT_SINGLEVARSTUFFING FALSE /**< should single variable stuffing be performed, which tries to fulfill
141  * constraints using the cheapest variable? */
142 #define DEFAULT_DETECTCUTOFFBOUND TRUE /**< should presolving try to detect constraints parallel to the objective
143  * function defining an upper bound and prevent these constraints from
144  * entering the LP */
145 #define DEFAULT_DETECTLOWERBOUND TRUE /**< should presolving try to detect constraints parallel to the objective
146  * function defining a lower bound and prevent these constraints from
147  * entering the LP */
148 #define DEFAULT_DETECTPARTIALOBJECTIVE TRUE/**< should presolving try to detect subsets of constraints parallel to the
149  * objective function */
150 #define DEFAULT_RANGEDROWPROPAGATION TRUE /**< should we perform ranged row propagation */
151 #define DEFAULT_RANGEDROWARTCONS TRUE /**< should presolving and propagation extract sub-constraints from ranged rows and equations? */
152 #define DEFAULT_RANGEDROWMAXDEPTH INT_MAX /**< maximum depth to apply ranged row propagation */
153 #define DEFAULT_RANGEDROWFREQ 1 /**< frequency for applying ranged row propagation */
154 
155 #define DEFAULT_MULTAGGRREMOVE FALSE /**< should multi-aggregations only be performed if the constraint can be
156  * removed afterwards? */
157 #define DEFAULT_MAXMULTAGGRQUOT 1e+03 /**< maximum coefficient dynamism (ie. maxabsval / minabsval) for multiaggregation */
158 #define DEFAULT_MAXDUALMULTAGGRQUOT 1e+20 /**< maximum coefficient dynamism (ie. maxabsval / minabsval) for multiaggregation */
159 #define DEFAULT_EXTRACTCLIQUES TRUE /**< should cliques be extracted? */
160 
161 #define MAXDNOM 10000LL /**< maximal denominator for simple rational fixed values */
162 #define MAXSCALEDCOEF 0 /**< maximal coefficient value after scaling */
163 #define MAXSCALEDCOEFINTEGER 0 /**< maximal coefficient value after scaling if all variables are of integral
164  * type
165  */
166 #define MAXACTVAL 1e+09 /**< maximal absolute value of full and partial activities such that
167  * redundancy-based simplifications are allowed to be applied
168  */
170 #define MAXVALRECOMP 1e+06 /**< maximal abolsute value we trust without recomputing the activity */
171 #define MINVALRECOMP 1e-05 /**< minimal abolsute value we trust without recomputing the activity */
174 #define NONLINCONSUPGD_PRIORITY 1000000 /**< priority of the constraint handler for upgrading of expressions constraints */
175 
176 /* @todo add multi-aggregation of variables that are in exactly two equations (, if not numerically an issue),
177  * maybe in fullDualPresolve(), see convertLongEquality()
178  */
179 
180 
181 /** constraint data for linear constraints */
182 struct SCIP_ConsData
183 {
184  SCIP_Real lhs; /**< left hand side of row (for ranged rows) */
185  SCIP_Real rhs; /**< right hand side of row */
186  SCIP_Real maxabsval; /**< maximum absolute value of all coefficients */
187  SCIP_Real minabsval; /**< minimal absolute value of all coefficients */
188  SCIP_Real minactivity; /**< minimal value w.r.t. the variable's local bounds for the constraint's
189  * activity, ignoring the coefficients contributing with infinite value */
190  SCIP_Real maxactivity; /**< maximal value w.r.t. the variable's local bounds for the constraint's
191  * activity, ignoring the coefficients contributing with infinite value */
192  SCIP_Real lastminactivity; /**< last minimal activity which was computed by complete summation
193  * over all contributing values */
194  SCIP_Real lastmaxactivity; /**< last maximal activity which was computed by complete summation
195  * over all contributing values */
196  SCIP_Real glbminactivity; /**< minimal value w.r.t. the variable's global bounds for the constraint's
197  * activity, ignoring the coefficients contributing with infinite value */
198  SCIP_Real glbmaxactivity; /**< maximal value w.r.t. the variable's global bounds for the constraint's
199  * activity, ignoring the coefficients contributing with infinite value */
200  SCIP_Real lastglbminactivity; /**< last global minimal activity which was computed by complete summation
201  * over all contributing values */
202  SCIP_Real lastglbmaxactivity; /**< last global maximal activity which was computed by complete summation
203  * over all contributing values */
204  SCIP_Real maxactdelta; /**< maximal activity contribution of a single variable, or SCIP_INVALID if invalid */
205  SCIP_VAR* maxactdeltavar; /**< variable with maximal activity contribution, or NULL if invalid */
206  uint64_t possignature; /**< bit signature of coefficients that may take a positive value */
207  uint64_t negsignature; /**< bit signature of coefficients that may take a negative value */
208  SCIP_ROW* row; /**< LP row, if constraint is already stored in LP row format */
209  SCIP_NLROW* nlrow; /**< NLP row, if constraint has been added to NLP relaxation */
210  SCIP_VAR** vars; /**< variables of constraint entries */
211  SCIP_Real* vals; /**< coefficients of constraint entries */
212  SCIP_EVENTDATA** eventdata; /**< event data for bound change events of the variables */
213  int minactivityneginf; /**< number of coefficients contributing with neg. infinite value to minactivity */
214  int minactivityposinf; /**< number of coefficients contributing with pos. infinite value to minactivity */
215  int maxactivityneginf; /**< number of coefficients contributing with neg. infinite value to maxactivity */
216  int maxactivityposinf; /**< number of coefficients contributing with pos. infinite value to maxactivity */
217  int minactivityneghuge; /**< number of coefficients contributing with huge neg. value to minactivity */
218  int minactivityposhuge; /**< number of coefficients contributing with huge pos. value to minactivity */
219  int maxactivityneghuge; /**< number of coefficients contributing with huge neg. value to maxactivity */
220  int maxactivityposhuge; /**< number of coefficients contributing with huge pos. value to maxactivity */
221  int glbminactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbminactivity */
222  int glbminactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbminactivity */
223  int glbmaxactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbmaxactivity */
224  int glbmaxactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbmaxactivity */
225  int glbminactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbminactivity */
226  int glbminactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbminactivity */
227  int glbmaxactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbmaxactivity */
228  int glbmaxactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbmaxactivity */
229  int varssize; /**< size of the vars- and vals-arrays */
230  int nvars; /**< number of nonzeros in constraint */
231  int nbinvars; /**< the number of binary variables in the constraint, only valid after
232  * sorting in stage >= SCIP_STAGE_INITSOLVE
233  */
234  unsigned int boundstightened:2; /**< is constraint already propagated with bound tightening? */
235  unsigned int rangedrowpropagated:2; /**< did we perform ranged row propagation on this constraint?
236  * (0: no, 1: yes, 2: with potentially adding artificial constraint */
237  unsigned int validmaxabsval:1; /**< is the maximum absolute value valid? */
238  unsigned int validminabsval:1; /**< is the minimum absolute value valid? */
239  unsigned int validactivities:1; /**< are the activity bounds (local and global) valid? */
240  unsigned int validminact:1; /**< is the local minactivity valid? */
241  unsigned int validmaxact:1; /**< is the local maxactivity valid? */
242  unsigned int validglbminact:1; /**< is the global minactivity valid? */
243  unsigned int validglbmaxact:1; /**< is the global maxactivity valid? */
244  unsigned int presolved:1; /**< is constraint already presolved? */
245  unsigned int removedfixings:1; /**< are all fixed variables removed from the constraint? */
246  unsigned int validsignature:1; /**< is the bit signature valid? */
247  unsigned int changed:1; /**< was constraint changed since last aggregation round in preprocessing? */
248  unsigned int normalized:1; /**< is the constraint in normalized form? */
249  unsigned int upgradetried:1; /**< was the constraint already tried to be upgraded? */
250  unsigned int upgraded:1; /**< is the constraint upgraded and will it be removed after preprocessing? */
251  unsigned int indexsorted:1; /**< are the constraint's variables sorted by type and index? */
252  unsigned int merged:1; /**< are the constraint's equal variables already merged? */
253  unsigned int cliquesadded:1; /**< were the cliques of the constraint already extracted? */
254  unsigned int implsadded:1; /**< were the implications of the constraint already extracted? */
255  unsigned int coefsorted:1; /**< are variables sorted by type and their absolute activity delta? */
256  unsigned int varsdeleted:1; /**< were variables deleted after last cleanup? */
257  unsigned int hascontvar:1; /**< does the constraint contain at least one continuous variable? */
258  unsigned int hasnonbinvar:1; /**< does the constraint contain at least one non-binary variable? */
259  unsigned int hasnonbinvalid:1; /**< is the information stored in hasnonbinvar and hascontvar valid? */
260  unsigned int checkabsolute:1; /**< should the constraint be checked w.r.t. an absolute feasibilty tolerance? */
261 };
262 
263 /** event data for bound change event */
264 struct SCIP_EventData
265 {
266  SCIP_CONS* cons; /**< linear constraint to process the bound change for */
267  int varpos; /**< position of variable in vars array */
268  int filterpos; /**< position of event in variable's event filter */
269 };
270 
271 /** constraint handler data */
272 struct SCIP_ConshdlrData
273 {
274  SCIP_EVENTHDLR* eventhdlr; /**< event handler for bound change events */
275  SCIP_LINCONSUPGRADE** linconsupgrades; /**< linear constraint upgrade methods for specializing linear constraints */
276  SCIP_Real maxaggrnormscale; /**< maximal allowed relative gain in maximum norm for constraint aggregation
277  * (0.0: disable constraint aggregation) */
278  SCIP_Real maxcardbounddist; /**< maximal relative distance from current node's dual bound to primal bound compared
279  * to best node's dual bound for separating knapsack cardinality cuts */
280  SCIP_Real mingainpernmincomp; /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise comparison round */
281  SCIP_Real maxeasyactivitydelta;/**< maximum activity delta to run easy propagation on linear constraint
282  * (faster, but numerically less stable) */
283  int linconsupgradessize;/**< size of linconsupgrade array */
284  int nlinconsupgrades; /**< number of linear constraint upgrade methods */
285  int tightenboundsfreq; /**< multiplier on propagation frequency, how often the bounds are tightened */
286  int maxrounds; /**< maximal number of separation rounds per node (-1: unlimited) */
287  int maxroundsroot; /**< maximal number of separation rounds in the root node (-1: unlimited) */
288  int maxsepacuts; /**< maximal number of cuts separated per separation round */
289  int maxsepacutsroot; /**< maximal number of cuts separated per separation round in root node */
290  int nmincomparisons; /**< number for minimal pairwise presolving comparisons */
291  int naddconss; /**< number of added constraints */
292  SCIP_Bool presolpairwise; /**< should pairwise constraint comparison be performed in presolving? */
293  SCIP_Bool presolusehashing; /**< should hash table be used for detecting redundant constraints in advance */
294  SCIP_Bool separateall; /**< should all constraints be subject to cardinality cut generation instead of only
295  * the ones with non-zero dual value? */
296  SCIP_Bool aggregatevariables; /**< should presolving search for redundant variables in equations */
297  SCIP_Bool simplifyinequalities;/**< should presolving try to cancel down or delete coefficients in inequalities */
298  SCIP_Bool dualpresolving; /**< should dual presolving steps be performed? */
299  SCIP_Bool singletonstuffing; /**< should stuffing of singleton continuous variables be performed? */
300  SCIP_Bool singlevarstuffing; /**< should single variable stuffing be performed, which tries to fulfill
301  * constraints using the cheapest variable? */
302  SCIP_Bool sortvars; /**< should binary variables be sorted for faster propagation? */
303  SCIP_Bool checkrelmaxabs; /**< should the violation for a constraint with side 0.0 be checked relative
304  * to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
305  SCIP_Bool detectcutoffbound; /**< should presolving try to detect constraints parallel to the objective
306  * function defining an upper bound and prevent these constraints from
307  * entering the LP */
308  SCIP_Bool detectlowerbound; /**< should presolving try to detect constraints parallel to the objective
309  * function defining a lower bound and prevent these constraints from
310  * entering the LP */
311  SCIP_Bool detectpartialobjective;/**< should presolving try to detect subsets of constraints parallel to
312  * the objective function */
313  SCIP_Bool rangedrowpropagation;/**< should presolving and propagation try to improve bounds, detect
314  * infeasibility, and extract sub-constraints from ranged rows and
315  * equations */
316  SCIP_Bool rangedrowartcons; /**< should presolving and propagation extract sub-constraints from ranged rows and equations?*/
317  int rangedrowmaxdepth; /**< maximum depth to apply ranged row propagation */
318  int rangedrowfreq; /**< frequency for applying ranged row propagation */
319  SCIP_Bool multaggrremove; /**< should multi-aggregations only be performed if the constraint can be
320  * removed afterwards? */
321  SCIP_Real maxmultaggrquot; /**< maximum coefficient dynamism (ie. maxabsval / minabsval) for primal multiaggregation */
322  SCIP_Real maxdualmultaggrquot;/**< maximum coefficient dynamism (ie. maxabsval / minabsval) for dual multiaggregation */
323  SCIP_Bool extractcliques; /**< should cliques be extracted? */
324 };
325 
326 /** linear constraint update method */
327 struct SCIP_LinConsUpgrade
328 {
329  SCIP_DECL_LINCONSUPGD((*linconsupgd)); /**< method to call for upgrading linear constraint */
330  int priority; /**< priority of upgrading method */
331  SCIP_Bool active; /**< is upgrading enabled */
332 };
333 
334 
335 /*
336  * Propagation rules
337  */
338 
339 enum Proprule
340 {
341  PROPRULE_1_RHS = 1, /**< activity residuals of all other variables tighten bounds of single
342  * variable due to the right hand side of the inequality */
343  PROPRULE_1_LHS = 2, /**< activity residuals of all other variables tighten bounds of single
344  * variable due to the left hand side of the inequality */
345  PROPRULE_1_RANGEDROW = 3, /**< fixed variables and gcd of all left variables tighten bounds of a
346  * single variable in this reanged row */
347  PROPRULE_INVALID = 0 /**< propagation was applied without a specific propagation rule */
348 };
349 typedef enum Proprule PROPRULE;
351 /** inference information */
352 struct InferInfo
353 {
354  union
355  {
356  struct
357  {
358  unsigned int proprule:8; /**< propagation rule that was applied */
359  unsigned int pos:24; /**< variable position, the propagation rule was applied at */
360  } asbits;
361  int asint; /**< inference information as a single int value */
362  } val;
363 };
364 typedef struct InferInfo INFERINFO;
365 
366 /** converts an integer into an inference information */
367 static
369  int i /**< integer to convert */
370  )
371 {
372  INFERINFO inferinfo;
373 
374  inferinfo.val.asint = i;
375 
376  return inferinfo;
377 }
378 
379 /** converts an inference information into an int */
380 static
381 int inferInfoToInt(
382  INFERINFO inferinfo /**< inference information to convert */
383  )
384 {
385  return inferinfo.val.asint;
386 }
388 /** returns the propagation rule stored in the inference information */
389 static
391  INFERINFO inferinfo /**< inference information to convert */
392  )
393 {
394  return (int) inferinfo.val.asbits.proprule;
395 }
396 
397 /** returns the position stored in the inference information */
398 static
399 int inferInfoGetPos(
400  INFERINFO inferinfo /**< inference information to convert */
401  )
402 {
403  return (int) inferinfo.val.asbits.pos;
404 }
405 
406 /** constructs an inference information out of a propagation rule and a position number */
407 static
409  PROPRULE proprule, /**< propagation rule that deduced the value */
410  int pos /**< variable position, the propagation rule was applied at */
411  )
412 {
413  INFERINFO inferinfo;
414 
415  assert(pos >= 0);
416  /* in the inferinfo struct only 24 bits for 'pos' are reserved */
417  assert(pos < (1<<24));
419  inferinfo.val.asbits.proprule = (unsigned int) proprule; /*lint !e641*/
420  inferinfo.val.asbits.pos = (unsigned int) pos; /*lint !e732*/
421 
422  return inferinfo;
423 }
424 
425 /** constructs an inference information out of a propagation rule and a position number, returns info as int */
426 static
428  PROPRULE proprule, /**< propagation rule that deduced the value */
429  int pos /**< variable position, the propagation rule was applied at */
430  )
431 {
432  return inferInfoToInt(getInferInfo(proprule, pos));
433 }
434 
435 
436 /*
437  * memory growing methods for dynamically allocated arrays
438  */
439 
440 /** ensures, that linconsupgrades array can store at least num entries */
441 static
443  SCIP* scip, /**< SCIP data structure */
444  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
445  int num /**< minimum number of entries to store */
446  )
447 {
448  assert(scip != NULL);
449  assert(conshdlrdata != NULL);
450  assert(conshdlrdata->nlinconsupgrades <= conshdlrdata->linconsupgradessize);
451 
452  if( num > conshdlrdata->linconsupgradessize )
453  {
454  int newsize;
455 
456  newsize = SCIPcalcMemGrowSize(scip, num);
457  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &conshdlrdata->linconsupgrades, conshdlrdata->linconsupgradessize, newsize) );
458  conshdlrdata->linconsupgradessize = newsize;
459  }
460  assert(num <= conshdlrdata->linconsupgradessize);
462  return SCIP_OKAY;
463 }
464 
465 /** ensures, that vars and vals arrays can store at least num entries */
466 static
468  SCIP* scip, /**< SCIP data structure */
469  SCIP_CONSDATA* consdata, /**< linear constraint data */
470  int num /**< minimum number of entries to store */
471  )
472 {
473  assert(scip != NULL);
474  assert(consdata != NULL);
475  assert(consdata->nvars <= consdata->varssize);
476 
477  if( num > consdata->varssize )
478  {
479  int newsize;
480 
481  newsize = SCIPcalcMemGrowSize(scip, num);
482  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vars, consdata->varssize, newsize) );
483  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vals, consdata->varssize, newsize) );
484  if( consdata->eventdata != NULL )
485  {
486  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize, newsize) );
487  }
488  consdata->varssize = newsize;
489  }
490  assert(num <= consdata->varssize);
491 
492  return SCIP_OKAY;
493 }
494 
495 
496 /*
497  * local methods for managing linear constraint update methods
498  */
499 
500 /** creates a linear constraint upgrade data object */
501 static
503  SCIP* scip, /**< SCIP data structure */
504  SCIP_LINCONSUPGRADE** linconsupgrade, /**< pointer to store the linear constraint upgrade */
505  SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
506  int priority /**< priority of upgrading method */
507  )
508 {
509  assert(scip != NULL);
510  assert(linconsupgrade != NULL);
511  assert(linconsupgd != NULL);
512 
513  SCIP_CALL( SCIPallocBlockMemory(scip, linconsupgrade) );
514  (*linconsupgrade)->linconsupgd = linconsupgd;
515  (*linconsupgrade)->priority = priority;
516  (*linconsupgrade)->active = TRUE;
517 
518  return SCIP_OKAY;
519 }
520 
521 /** frees a linear constraint upgrade data object */
522 static
523 void linconsupgradeFree(
524  SCIP* scip, /**< SCIP data structure */
525  SCIP_LINCONSUPGRADE** linconsupgrade /**< pointer to the linear constraint upgrade */
526  )
527 {
528  assert(scip != NULL);
529  assert(linconsupgrade != NULL);
530  assert(*linconsupgrade != NULL);
531 
532  SCIPfreeBlockMemory(scip, linconsupgrade);
533 }
534 
535 /** creates constraint handler data for linear constraint handler */
536 static
538  SCIP* scip, /**< SCIP data structure */
539  SCIP_CONSHDLRDATA** conshdlrdata, /**< pointer to store the constraint handler data */
540  SCIP_EVENTHDLR* eventhdlr /**< event handler */
541  )
542 {
543  assert(scip != NULL);
544  assert(conshdlrdata != NULL);
545  assert(eventhdlr != NULL);
546 
547  SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
548  (*conshdlrdata)->linconsupgrades = NULL;
549  (*conshdlrdata)->linconsupgradessize = 0;
550  (*conshdlrdata)->nlinconsupgrades = 0;
551  (*conshdlrdata)->naddconss = 0;
552 
553  /* set event handler for updating linear constraint activity bounds */
554  (*conshdlrdata)->eventhdlr = eventhdlr;
555 
556  return SCIP_OKAY;
557 }
558 
559 /** frees constraint handler data for linear constraint handler */
560 static
561 void conshdlrdataFree(
562  SCIP* scip, /**< SCIP data structure */
563  SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to the constraint handler data */
564  )
565 {
566  int i;
567 
568  assert(scip != NULL);
569  assert(conshdlrdata != NULL);
570  assert(*conshdlrdata != NULL);
571 
572  for( i = 0; i < (*conshdlrdata)->nlinconsupgrades; ++i )
573  {
574  linconsupgradeFree(scip, &(*conshdlrdata)->linconsupgrades[i]);
575  }
576  SCIPfreeBlockMemoryArrayNull(scip, &(*conshdlrdata)->linconsupgrades, (*conshdlrdata)->linconsupgradessize);
577 
578  SCIPfreeBlockMemory(scip, conshdlrdata);
579 }
581 /** creates a linear constraint upgrade data object */
582 static
584  SCIP* scip, /**< SCIP data structure */
585  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
586  SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
587  const char* conshdlrname /**< name of the constraint handler */
588  )
589 {
590  int i;
591 
592  assert(scip != NULL);
593  assert(conshdlrdata != NULL);
594  assert(linconsupgd != NULL);
595  assert(conshdlrname != NULL);
596 
597  for( i = conshdlrdata->nlinconsupgrades - 1; i >= 0; --i )
598  {
599  if( conshdlrdata->linconsupgrades[i]->linconsupgd == linconsupgd )
600  {
601 #ifdef SCIP_DEBUG
602  SCIPwarningMessage(scip, "Try to add already known upgrade message for constraint handler %s.\n", conshdlrname);
603 #endif
604  return TRUE;
605  }
606  }
607 
608  return FALSE;
609 }
610 
611 /** adds a linear constraint update method to the constraint handler's data */
612 static
614  SCIP* scip, /**< SCIP data structure */
615  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
616  SCIP_LINCONSUPGRADE* linconsupgrade /**< linear constraint upgrade method */
617  )
618 {
619  int i;
620 
621  assert(scip != NULL);
622  assert(conshdlrdata != NULL);
623  assert(linconsupgrade != NULL);
624 
625  SCIP_CALL( conshdlrdataEnsureLinconsupgradesSize(scip, conshdlrdata, conshdlrdata->nlinconsupgrades+1) );
626 
627  for( i = conshdlrdata->nlinconsupgrades;
628  i > 0 && conshdlrdata->linconsupgrades[i-1]->priority < linconsupgrade->priority; --i )
629  {
630  conshdlrdata->linconsupgrades[i] = conshdlrdata->linconsupgrades[i-1];
631  }
632  assert(0 <= i && i <= conshdlrdata->nlinconsupgrades);
633  conshdlrdata->linconsupgrades[i] = linconsupgrade;
634  conshdlrdata->nlinconsupgrades++;
635 
636  return SCIP_OKAY;
637 }
638 
639 /*
640  * local methods
641  */
642 
643 /** installs rounding locks for the given variable associated to the given coefficient in the linear constraint */
644 static
646  SCIP* scip, /**< SCIP data structure */
647  SCIP_CONS* cons, /**< linear constraint */
648  SCIP_VAR* var, /**< variable of constraint entry */
649  SCIP_Real val /**< coefficient of constraint entry */
650  )
651 {
652  SCIP_CONSDATA* consdata;
653 
654  assert(scip != NULL);
655  assert(cons != NULL);
656  assert(var != NULL);
657 
658  consdata = SCIPconsGetData(cons);
659  assert(consdata != NULL);
660  assert(!SCIPisZero(scip, val));
661 
662  if( SCIPisPositive(scip, val) )
663  {
664  SCIP_CALL( SCIPlockVarCons(scip, var, cons,
665  !SCIPisInfinity(scip, -consdata->lhs), !SCIPisInfinity(scip, consdata->rhs)) );
666  }
667  else
668  {
669  SCIP_CALL( SCIPlockVarCons(scip, var, cons,
670  !SCIPisInfinity(scip, consdata->rhs), !SCIPisInfinity(scip, -consdata->lhs)) );
671  }
672 
673  return SCIP_OKAY;
674 }
675 
676 /** removes rounding locks for the given variable associated to the given coefficient in the linear constraint */
677 static
679  SCIP* scip, /**< SCIP data structure */
680  SCIP_CONS* cons, /**< linear constraint */
681  SCIP_VAR* var, /**< variable of constraint entry */
682  SCIP_Real val /**< coefficient of constraint entry */
683  )
684 {
685  SCIP_CONSDATA* consdata;
686 
687  assert(scip != NULL);
688  assert(cons != NULL);
689  assert(var != NULL);
690 
691  consdata = SCIPconsGetData(cons);
692  assert(consdata != NULL);
693  assert(!SCIPisZero(scip, val));
694 
695  if( SCIPisPositive(scip, val) )
696  {
697  SCIP_CALL( SCIPunlockVarCons(scip, var, cons, !SCIPisInfinity(scip, -consdata->lhs),
698  !SCIPisInfinity(scip, consdata->rhs)) );
699  }
700  else
701  {
702  SCIP_CALL( SCIPunlockVarCons(scip, var, cons, !SCIPisInfinity(scip, consdata->rhs),
703  !SCIPisInfinity(scip, -consdata->lhs)) );
704  }
705 
706  return SCIP_OKAY;
707 }
708 
709 /** creates event data for variable at given position, and catches events */
710 /**! [SnippetDebugAssertions] */
711 static
713  SCIP* scip, /**< SCIP data structure */
714  SCIP_CONS* cons, /**< linear constraint */
715  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
716  int pos /**< array position of variable to catch bound change events for */
717  )
718 {
719  SCIP_CONSDATA* consdata;
720  assert(scip != NULL);
721  assert(cons != NULL);
722  assert(eventhdlr != NULL);
723 
724  consdata = SCIPconsGetData(cons);
725  assert(consdata != NULL);
726 
727  assert(0 <= pos && pos < consdata->nvars);
728  assert(consdata->vars != NULL);
729  assert(consdata->vars[pos] != NULL);
730  assert(SCIPvarIsTransformed(consdata->vars[pos]));
731  assert(consdata->eventdata != NULL);
732  assert(consdata->eventdata[pos] == NULL);
733 
734  SCIP_CALL( SCIPallocBlockMemory(scip, &(consdata->eventdata[pos])) ); /*lint !e866*/
735  consdata->eventdata[pos]->cons = cons;
736  consdata->eventdata[pos]->varpos = pos;
737 
738  SCIP_CALL( SCIPcatchVarEvent(scip, consdata->vars[pos],
741  eventhdlr, consdata->eventdata[pos], &consdata->eventdata[pos]->filterpos) );
742 
743  consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(consdata->vars[pos]);
744 
745  return SCIP_OKAY;
746 }
747 /**! [SnippetDebugAssertions] */
748 
749 /** deletes event data for variable at given position, and drops events */
750 static
752  SCIP* scip, /**< SCIP data structure */
753  SCIP_CONS* cons, /**< linear constraint */
754  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
755  int pos /**< array position of variable to catch bound change events for */
756  )
757 {
758  SCIP_CONSDATA* consdata;
759  assert(scip != NULL);
760  assert(cons != NULL);
761  assert(eventhdlr != NULL);
762 
763  consdata = SCIPconsGetData(cons);
764  assert(consdata != NULL);
765 
766  assert(0 <= pos && pos < consdata->nvars);
767  assert(consdata->vars[pos] != NULL);
768  assert(consdata->eventdata != NULL);
769  assert(consdata->eventdata[pos] != NULL);
770  assert(consdata->eventdata[pos]->cons == cons);
771  assert(consdata->eventdata[pos]->varpos == pos);
772 
773  SCIP_CALL( SCIPdropVarEvent(scip, consdata->vars[pos],
776  eventhdlr, consdata->eventdata[pos], consdata->eventdata[pos]->filterpos) );
777 
778  SCIPfreeBlockMemory(scip, &consdata->eventdata[pos]); /*lint !e866*/
779 
780  return SCIP_OKAY;
781 }
782 
783 /** catches bound change events for all variables in transformed linear constraint */
784 static
786  SCIP* scip, /**< SCIP data structure */
787  SCIP_CONS* cons, /**< linear constraint */
788  SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
789  )
790 {
791  SCIP_CONSDATA* consdata;
792  int i;
793 
794  assert(scip != NULL);
795  assert(cons != NULL);
796 
797  consdata = SCIPconsGetData(cons);
798  assert(consdata != NULL);
799  assert(consdata->eventdata == NULL);
800 
801  /* allocate eventdata array */
802  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize) );
803  assert(consdata->eventdata != NULL);
804  BMSclearMemoryArray(consdata->eventdata, consdata->nvars);
805 
806  /* catch event for every single variable */
807  for( i = 0; i < consdata->nvars; ++i )
808  {
809  SCIP_CALL( consCatchEvent(scip, cons, eventhdlr, i) );
810  }
811 
812  return SCIP_OKAY;
813 }
814 
815 /** drops bound change events for all variables in transformed linear constraint */
816 static
818  SCIP* scip, /**< SCIP data structure */
819  SCIP_CONS* cons, /**< linear constraint */
820  SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
821  )
822 {
823  SCIP_CONSDATA* consdata;
824  int i;
825 
826  assert(scip != NULL);
827  assert(cons != NULL);
828 
829  consdata = SCIPconsGetData(cons);
830  assert(consdata != NULL);
831  assert(consdata->eventdata != NULL);
832 
833  /* drop event of every single variable */
834  for( i = consdata->nvars - 1; i >= 0; --i )
835  {
836  SCIP_CALL( consDropEvent(scip, cons, eventhdlr, i) );
837  }
838 
839  /* free eventdata array */
840  SCIPfreeBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize);
841  assert(consdata->eventdata == NULL);
842 
843  return SCIP_OKAY;
844 }
845 
846 /** creates a linear constraint data */
847 static
849  SCIP* scip, /**< SCIP data structure */
850  SCIP_CONSDATA** consdata, /**< pointer to linear constraint data */
851  int nvars, /**< number of nonzeros in the constraint */
852  SCIP_VAR** vars, /**< array with variables of constraint entries */
853  SCIP_Real* vals, /**< array with coefficients of constraint entries */
854  SCIP_Real lhs, /**< left hand side of row */
855  SCIP_Real rhs /**< right hand side of row */
856  )
857 {
858  int v;
859  SCIP_Real constant;
860 
861  assert(scip != NULL);
862  assert(consdata != NULL);
863  assert(nvars == 0 || vars != NULL);
864  assert(nvars == 0 || vals != NULL);
865 
866  if( SCIPisInfinity(scip, rhs) )
867  rhs = SCIPinfinity(scip);
868  else if( SCIPisInfinity(scip, -rhs) )
869  rhs = -SCIPinfinity(scip);
870 
871  if( SCIPisInfinity(scip, -lhs) )
872  lhs = -SCIPinfinity(scip);
873  else if( SCIPisInfinity(scip, lhs) )
874  lhs = SCIPinfinity(scip);
875 
876  if( SCIPisGT(scip, lhs, rhs) )
877  {
878  SCIPwarningMessage(scip, "left hand side of linear constraint greater than right hand side\n");
879  SCIPwarningMessage(scip, " -> lhs=%g, rhs=%g\n", lhs, rhs);
880  }
881 
882  SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
883 
884  (*consdata)->varssize = 0;
885  (*consdata)->nvars = nvars;
886  (*consdata)->hascontvar = FALSE;
887  (*consdata)->hasnonbinvar = FALSE;
888  (*consdata)->hasnonbinvalid = TRUE;
889  (*consdata)->vars = NULL;
890  (*consdata)->vals = NULL;
891 
892  constant = 0.0;
893  if( nvars > 0 )
894  {
895  int k;
896 
897  SCIP_VAR** varsbuffer;
898  SCIP_Real* valsbuffer;
899 
900  /* copy variables into temporary buffer */
901  SCIP_CALL( SCIPallocBufferArray(scip, &varsbuffer, nvars) );
902  SCIP_CALL( SCIPallocBufferArray(scip, &valsbuffer, nvars) );
903  k = 0;
904 
905  /* loop over variables and sort out fixed ones */
906  for( v = 0; v < nvars; ++v )
907  {
908  SCIP_VAR* var;
909  SCIP_Real val;
910 
911  var = vars[v];
912  val = vals[v];
913 
914  assert(var != NULL);
915  if( !SCIPisZero(scip, val) )
916  {
917  /* treat fixed variable as a constant if problem compression is enabled */
919  {
920  constant += SCIPvarGetLbGlobal(var) * val;
921  }
922  else
923  {
924  varsbuffer[k] = var;
925  valsbuffer[k] = val;
926  k++;
927 
928  /* update hascontvar and hasnonbinvar flags */
929  if( !(*consdata)->hascontvar )
930  {
931  SCIP_VARTYPE vartype = SCIPvarGetType(var);
932 
933  if( vartype != SCIP_VARTYPE_BINARY )
934  {
935  (*consdata)->hasnonbinvar = TRUE;
936 
937  if( vartype == SCIP_VARTYPE_CONTINUOUS )
938  (*consdata)->hascontvar = TRUE;
939  }
940  }
941  }
942  }
943  }
944  (*consdata)->nvars = k;
945 
946  if( k > 0 )
947  {
948  /* copy the possibly reduced buffer arrays into block */
949  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, varsbuffer, k) );
950  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vals, valsbuffer, k) );
951  (*consdata)->varssize = k;
952  }
953  /* free temporary buffer */
954  SCIPfreeBufferArray(scip, &valsbuffer);
955  SCIPfreeBufferArray(scip, &varsbuffer);
956  }
957 
958  (*consdata)->eventdata = NULL;
959 
960  /* due to compressed copying, we may have fixed variables contributing to the left and right hand side */
961  if( !SCIPisZero(scip, constant) )
962  {
963  if( !SCIPisInfinity(scip, REALABS(lhs)) )
964  lhs -= constant;
965 
966  if( !SCIPisInfinity(scip, REALABS(rhs)) )
967  rhs -= constant;
968  }
969 
970  (*consdata)->row = NULL;
971  (*consdata)->nlrow = NULL;
972  (*consdata)->lhs = lhs;
973  (*consdata)->rhs = rhs;
974  (*consdata)->maxabsval = SCIP_INVALID;
975  (*consdata)->minabsval = SCIP_INVALID;
976  (*consdata)->minactivity = SCIP_INVALID;
977  (*consdata)->maxactivity = SCIP_INVALID;
978  (*consdata)->lastminactivity = SCIP_INVALID;
979  (*consdata)->lastmaxactivity = SCIP_INVALID;
980  (*consdata)->maxactdelta = SCIP_INVALID;
981  (*consdata)->maxactdeltavar = NULL;
982  (*consdata)->minactivityneginf = -1;
983  (*consdata)->minactivityposinf = -1;
984  (*consdata)->maxactivityneginf = -1;
985  (*consdata)->maxactivityposinf = -1;
986  (*consdata)->minactivityneghuge = -1;
987  (*consdata)->minactivityposhuge = -1;
988  (*consdata)->maxactivityneghuge = -1;
989  (*consdata)->maxactivityposhuge = -1;
990  (*consdata)->glbminactivity = SCIP_INVALID;
991  (*consdata)->glbmaxactivity = SCIP_INVALID;
992  (*consdata)->lastglbminactivity = SCIP_INVALID;
993  (*consdata)->lastglbmaxactivity = SCIP_INVALID;
994  (*consdata)->glbminactivityneginf = -1;
995  (*consdata)->glbminactivityposinf = -1;
996  (*consdata)->glbmaxactivityneginf = -1;
997  (*consdata)->glbmaxactivityposinf = -1;
998  (*consdata)->glbminactivityneghuge = -1;
999  (*consdata)->glbminactivityposhuge = -1;
1000  (*consdata)->glbmaxactivityneghuge = -1;
1001  (*consdata)->glbmaxactivityposhuge = -1;
1002  (*consdata)->possignature = 0;
1003  (*consdata)->negsignature = 0;
1004  (*consdata)->validmaxabsval = FALSE;
1005  (*consdata)->validminabsval = FALSE;
1006  (*consdata)->validactivities = FALSE;
1007  (*consdata)->validminact = FALSE;
1008  (*consdata)->validmaxact = FALSE;
1009  (*consdata)->validglbminact = FALSE;
1010  (*consdata)->validglbmaxact = FALSE;
1011  (*consdata)->boundstightened = 0;
1012  (*consdata)->presolved = FALSE;
1013  (*consdata)->removedfixings = FALSE;
1014  (*consdata)->validsignature = FALSE;
1015  (*consdata)->changed = TRUE;
1016  (*consdata)->normalized = FALSE;
1017  (*consdata)->upgradetried = FALSE;
1018  (*consdata)->upgraded = FALSE;
1019  (*consdata)->indexsorted = (nvars <= 1);
1020  (*consdata)->merged = (nvars <= 1);
1021  (*consdata)->cliquesadded = FALSE;
1022  (*consdata)->implsadded = FALSE;
1023  (*consdata)->coefsorted = FALSE;
1024  (*consdata)->nbinvars = -1;
1025  (*consdata)->varsdeleted = FALSE;
1026  (*consdata)->rangedrowpropagated = 0;
1027  (*consdata)->checkabsolute = FALSE;
1028 
1029  if( SCIPisTransformed(scip) )
1030  {
1031  /* get transformed variables */
1032  SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
1033  }
1034 
1035  /* capture variables */
1036  for( v = 0; v < (*consdata)->nvars; v++ )
1037  {
1038  /* likely implies a deleted variable */
1039  if( (*consdata)->vars[v] == NULL )
1040  {
1041  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vars, (*consdata)->varssize);
1042  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vals, (*consdata)->varssize);
1043  SCIPfreeBlockMemory(scip, consdata);
1044  return SCIP_INVALIDDATA;
1045  }
1046 
1047  assert(!SCIPisZero(scip, (*consdata)->vals[v]));
1048  SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->vars[v]) );
1049  }
1050 
1051  return SCIP_OKAY;
1052 }
1053 
1054 /** frees a linear constraint data */
1055 static
1057  SCIP* scip, /**< SCIP data structure */
1058  SCIP_CONSDATA** consdata /**< pointer to linear constraint data */
1059  )
1060 {
1061  int v;
1062 
1063  assert(scip != NULL);
1064  assert(consdata != NULL);
1065  assert(*consdata != NULL);
1066  assert((*consdata)->varssize >= 0);
1067 
1068  /* release the row */
1069  if( (*consdata)->row != NULL )
1070  {
1071  SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->row) );
1072  }
1073 
1074  /* release the nlrow */
1075  if( (*consdata)->nlrow != NULL )
1076  {
1077  SCIP_CALL( SCIPreleaseNlRow(scip, &(*consdata)->nlrow) );
1078  }
1079 
1080  /* release variables */
1081  for( v = 0; v < (*consdata)->nvars; v++ )
1082  {
1083  assert((*consdata)->vars[v] != NULL);
1084  assert(!SCIPisZero(scip, (*consdata)->vals[v]));
1085  SCIP_CALL( SCIPreleaseVar(scip, &((*consdata)->vars[v])) );
1086  }
1087 
1088  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vars, (*consdata)->varssize);
1089  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vals, (*consdata)->varssize);
1090  SCIPfreeBlockMemory(scip, consdata);
1091 
1092  return SCIP_OKAY;
1093 }
1094 
1095 /** prints linear constraint in CIP format to file stream */
1096 static
1098  SCIP* scip, /**< SCIP data structure */
1099  SCIP_CONSDATA* consdata, /**< linear constraint data */
1100  FILE* file /**< output file (or NULL for standard output) */
1101  )
1102 {
1103  assert(scip != NULL);
1104  assert(consdata != NULL);
1105 
1106  /* print left hand side for ranged rows */
1107  if( !SCIPisInfinity(scip, -consdata->lhs)
1108  && !SCIPisInfinity(scip, consdata->rhs)
1109  && !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1110  SCIPinfoMessage(scip, file, "%.15g <= ", consdata->lhs);
1111 
1112  /* print coefficients and variables */
1113  if( consdata->nvars == 0 )
1114  SCIPinfoMessage(scip, file, "0");
1115  else
1116  {
1117  /* post linear sum of the linear constraint */
1118  SCIP_CALL( SCIPwriteVarsLinearsum(scip, file, consdata->vars, consdata->vals, consdata->nvars, TRUE) );
1119  }
1120 
1121  /* print right hand side */
1122  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1123  SCIPinfoMessage(scip, file, " == %.15g", consdata->rhs);
1124  else if( !SCIPisInfinity(scip, consdata->rhs) )
1125  SCIPinfoMessage(scip, file, " <= %.15g", consdata->rhs);
1126  else if( !SCIPisInfinity(scip, -consdata->lhs) )
1127  SCIPinfoMessage(scip, file, " >= %.15g", consdata->lhs);
1128  else
1129  SCIPinfoMessage(scip, file, " [free]");
1130 
1131  return SCIP_OKAY;
1132 }
1133 
1134 /** prints linear constraint and contained solution values of variables to file stream */
1135 static
1137  SCIP* scip, /**< SCIP data structure */
1138  SCIP_CONS* cons, /**< linear constraint */
1139  SCIP_SOL* sol, /**< solution to print */
1140  FILE* file /**< output file (or NULL for standard output) */
1141  )
1142 {
1143  SCIP_CONSDATA* consdata;
1144 
1145  assert(scip != NULL);
1146  assert(cons != NULL);
1147 
1148  consdata = SCIPconsGetData(cons);
1149  assert(consdata != NULL);
1150 
1152 
1153  /* print left hand side for ranged rows */
1154  if( !SCIPisInfinity(scip, -consdata->lhs)
1155  && !SCIPisInfinity(scip, consdata->rhs)
1156  && !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1157  SCIPinfoMessage(scip, file, "%.15g <= ", consdata->lhs);
1158 
1159  /* print coefficients and variables */
1160  if( consdata->nvars == 0 )
1161  SCIPinfoMessage(scip, file, "0");
1162  else
1163  {
1164  int v;
1165 
1166  /* post linear sum of the linear constraint */
1167  for( v = 0; v < consdata->nvars; ++v )
1168  {
1169  if( consdata->vals != NULL )
1170  {
1171  if( consdata->vals[v] == 1.0 )
1172  {
1173  if( v > 0 )
1174  SCIPinfoMessage(scip, file, " +");
1175  }
1176  else if( consdata->vals[v] == -1.0 )
1177  SCIPinfoMessage(scip, file, " -");
1178  else
1179  SCIPinfoMessage(scip, file, " %+.9g", consdata->vals[v]);
1180  }
1181  else if( consdata->nvars > 0 )
1182  SCIPinfoMessage(scip, file, " +");
1183 
1184  /* print variable name */
1185  SCIP_CALL( SCIPwriteVarName(scip, file, consdata->vars[v], TRUE) );
1186 
1187  SCIPinfoMessage(scip, file, " (%+.9g)", SCIPgetSolVal(scip, sol, consdata->vars[v]));
1188  }
1189  }
1190 
1191  /* print right hand side */
1192  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1193  SCIPinfoMessage(scip, file, " == %.15g", consdata->rhs);
1194  else if( !SCIPisInfinity(scip, consdata->rhs) )
1195  SCIPinfoMessage(scip, file, " <= %.15g", consdata->rhs);
1196  else if( !SCIPisInfinity(scip, -consdata->lhs) )
1197  SCIPinfoMessage(scip, file, " >= %.15g", consdata->lhs);
1198  else
1199  SCIPinfoMessage(scip, file, " [free]");
1200 
1201  SCIPinfoMessage(scip, file, ";\n");
1202 
1203  return SCIP_OKAY;
1204 }
1205 
1206 /** invalidates activity bounds, such that they are recalculated in next get */
1207 static
1209  SCIP_CONSDATA* consdata /**< linear constraint */
1210  )
1211 {
1212  assert(consdata != NULL);
1213 
1214  consdata->validactivities = FALSE;
1215  consdata->validminact = FALSE;
1216  consdata->validmaxact = FALSE;
1217  consdata->validglbminact = FALSE;
1218  consdata->validglbmaxact = FALSE;
1219  consdata->validmaxabsval = FALSE;
1220  consdata->validminabsval = FALSE;
1221  consdata->hasnonbinvalid = FALSE;
1222  consdata->minactivity = SCIP_INVALID;
1223  consdata->maxactivity = SCIP_INVALID;
1224  consdata->lastminactivity = SCIP_INVALID;
1225  consdata->lastmaxactivity = SCIP_INVALID;
1226  consdata->maxabsval = SCIP_INVALID;
1227  consdata->minabsval = SCIP_INVALID;
1228  consdata->maxactdelta = SCIP_INVALID;
1229  consdata->maxactdeltavar = NULL;
1230  consdata->minactivityneginf = -1;
1231  consdata->minactivityposinf = -1;
1232  consdata->maxactivityneginf = -1;
1233  consdata->maxactivityposinf = -1;
1234  consdata->minactivityneghuge = -1;
1235  consdata->minactivityposhuge = -1;
1236  consdata->maxactivityneghuge = -1;
1237  consdata->maxactivityposhuge = -1;
1238  consdata->glbminactivity = SCIP_INVALID;
1239  consdata->glbmaxactivity = SCIP_INVALID;
1240  consdata->lastglbminactivity = SCIP_INVALID;
1241  consdata->lastglbmaxactivity = SCIP_INVALID;
1242  consdata->glbminactivityneginf = -1;
1243  consdata->glbminactivityposinf = -1;
1244  consdata->glbmaxactivityneginf = -1;
1245  consdata->glbmaxactivityposinf = -1;
1246  consdata->glbminactivityneghuge = -1;
1247  consdata->glbminactivityposhuge = -1;
1248  consdata->glbmaxactivityneghuge = -1;
1249  consdata->glbmaxactivityposhuge = -1;
1250 }
1251 
1252 /** compute the pseudo activity of a constraint */
1253 static
1255  SCIP* scip, /**< SCIP data structure */
1256  SCIP_CONSDATA* consdata /**< linear constraint data */
1257  )
1258 {
1259  int i;
1260  int pseudoactivityposinf;
1261  int pseudoactivityneginf;
1262  SCIP_Real pseudoactivity;
1263  SCIP_Real bound;
1264  SCIP_Real val;
1265 
1266  pseudoactivity = 0;
1267  pseudoactivityposinf = 0;
1268  pseudoactivityneginf = 0;
1269 
1270  for( i = consdata->nvars - 1; i >= 0; --i )
1271  {
1272  val = consdata->vals[i];
1273  bound = (SCIPvarGetBestBoundType(consdata->vars[i]) == SCIP_BOUNDTYPE_LOWER) ? SCIPvarGetLbLocal(consdata->vars[i]) : SCIPvarGetUbLocal(consdata->vars[i]);
1274  if( SCIPisInfinity(scip, bound) )
1275  {
1276  if( val > 0.0 )
1277  pseudoactivityposinf++;
1278  else
1279  pseudoactivityneginf++;
1280  }
1281  else
1282  {
1283  if( SCIPisInfinity(scip, -bound) )
1284  {
1285  if( val > 0.0 )
1286  pseudoactivityneginf++;
1287  else
1288  pseudoactivityposinf++;
1289  }
1290  else
1291  pseudoactivity += val * bound;
1292  }
1293  }
1294 
1295  if( pseudoactivityneginf > 0 && pseudoactivityposinf > 0 )
1296  return SCIP_INVALID;
1297  else if( pseudoactivityneginf > 0 )
1298  return -SCIPinfinity(scip);
1299  else if( pseudoactivityposinf > 0 )
1300  return SCIPinfinity(scip);
1301 
1302  return pseudoactivity;
1303 }
1304 
1305 /** recompute the minactivity of a constraint */
1306 static
1308  SCIP* scip, /**< SCIP data structure */
1309  SCIP_CONSDATA* consdata /**< linear constraint data */
1310  )
1311 {
1312  int i;
1313  SCIP_Real bound;
1314 
1315  consdata->minactivity = 0;
1316 
1317  for( i = consdata->nvars - 1; i >= 0; --i )
1318  {
1319  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetLbLocal(consdata->vars[i]) : SCIPvarGetUbLocal(consdata->vars[i]);
1320  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1321  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1322  consdata->minactivity += consdata->vals[i] * bound;
1323  }
1324 
1325  /* the activity was just computed from scratch and is valid now */
1326  consdata->validminact = TRUE;
1327 
1328  /* the activity was just computed from scratch, mark it to be reliable */
1329  consdata->lastminactivity = consdata->minactivity;
1330 }
1331 
1332 /** recompute the maxactivity of a constraint */
1333 static
1335  SCIP* scip, /**< SCIP data structure */
1336  SCIP_CONSDATA* consdata /**< linear constraint data */
1337  )
1338 {
1339  int i;
1340  SCIP_Real bound;
1341 
1342  consdata->maxactivity = 0;
1343 
1344  for( i = consdata->nvars - 1; i >= 0; --i )
1345  {
1346  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetUbLocal(consdata->vars[i]) : SCIPvarGetLbLocal(consdata->vars[i]);
1347  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1348  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1349  consdata->maxactivity += consdata->vals[i] * bound;
1350  }
1351 
1352  /* the activity was just computed from scratch and is valid now */
1353  consdata->validmaxact = TRUE;
1354 
1355  /* the activity was just computed from scratch, mark it to be reliable */
1356  consdata->lastmaxactivity = consdata->maxactivity;
1357 }
1358 
1359 /** recompute the global minactivity of a constraint */
1360 static
1362  SCIP* scip, /**< SCIP data structure */
1363  SCIP_CONSDATA* consdata /**< linear constraint data */
1364  )
1365 {
1366  int i;
1367  SCIP_Real bound;
1368 
1369  consdata->glbminactivity = 0;
1370 
1371  for( i = consdata->nvars - 1; i >= 0; --i )
1372  {
1373  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetLbGlobal(consdata->vars[i]) : SCIPvarGetUbGlobal(consdata->vars[i]);
1374  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1375  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1376  consdata->glbminactivity += consdata->vals[i] * bound;
1377  }
1378 
1379  /* the activity was just computed from scratch and is valid now */
1380  consdata->validglbminact = TRUE;
1381 
1382  /* the activity was just computed from scratch, mark it to be reliable */
1383  consdata->lastglbminactivity = consdata->glbminactivity;
1384 }
1385 
1386 /** recompute the global maxactivity of a constraint */
1387 static
1389  SCIP* scip, /**< SCIP data structure */
1390  SCIP_CONSDATA* consdata /**< linear constraint data */
1391  )
1392 {
1393  int i;
1394  SCIP_Real bound;
1395 
1396  consdata->glbmaxactivity = 0;
1397 
1398  for( i = consdata->nvars - 1; i >= 0; --i )
1399  {
1400  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetUbGlobal(consdata->vars[i]) : SCIPvarGetLbGlobal(consdata->vars[i]);
1401  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1402  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1403  consdata->glbmaxactivity += consdata->vals[i] * bound;
1404  }
1405 
1406  /* the activity was just computed from scratch and is valid now */
1407  consdata->validglbmaxact = TRUE;
1408 
1409  /* the activity was just computed from scratch, mark it to be reliable */
1410  consdata->lastglbmaxactivity = consdata->glbmaxactivity;
1411 }
1412 
1413 /** calculates maximum absolute value of coefficients */
1414 static
1416  SCIP_CONSDATA* consdata /**< linear constraint data */
1417  )
1418 {
1419  SCIP_Real absval;
1420  int i;
1421 
1422  assert(consdata != NULL);
1423  assert(!consdata->validmaxabsval);
1424  assert(consdata->maxabsval >= SCIP_INVALID);
1425 
1426  consdata->validmaxabsval = TRUE;
1427  consdata->maxabsval = 0.0;
1428  for( i = 0; i < consdata->nvars; ++i )
1429  {
1430  absval = consdata->vals[i];
1431  absval = REALABS(absval);
1432  if( absval > consdata->maxabsval )
1433  consdata->maxabsval = absval;
1434  }
1435 }
1436 
1437 /** calculates minimum absolute value of coefficients */
1438 static
1440  SCIP_CONSDATA* consdata /**< linear constraint data */
1441  )
1442 {
1443  SCIP_Real absval;
1444  int i;
1445 
1446  assert(consdata != NULL);
1447  assert(!consdata->validminabsval);
1448  assert(consdata->minabsval >= SCIP_INVALID);
1449 
1450  consdata->validminabsval = TRUE;
1451 
1452  if( consdata->nvars > 0 )
1453  consdata->minabsval = REALABS(consdata->vals[0]);
1454  else
1455  consdata->minabsval = 0.0;
1456 
1457  for( i = 1; i < consdata->nvars; ++i )
1458  {
1459  absval = consdata->vals[i];
1460  absval = REALABS(absval);
1461  if( absval < consdata->minabsval )
1462  consdata->minabsval = absval;
1463  }
1464 }
1465 
1466 /** checks the type of all variables of the constraint and sets hasnonbinvar and hascontvar flags accordingly */
1467 static
1469  SCIP_CONSDATA* consdata /**< linear constraint data */
1470  )
1471 {
1472  int v;
1473 
1474  assert(!consdata->hasnonbinvalid);
1475  consdata->hasnonbinvar = FALSE;
1476  consdata->hascontvar = FALSE;
1477 
1478  for( v = consdata->nvars - 1; v >= 0; --v )
1479  {
1480  SCIP_VARTYPE vartype = SCIPvarGetType(consdata->vars[v]);
1481 
1482  if( vartype != SCIP_VARTYPE_BINARY )
1483  {
1484  consdata->hasnonbinvar = TRUE;
1485 
1486  if( vartype == SCIP_VARTYPE_CONTINUOUS )
1487  {
1488  consdata->hascontvar = TRUE;
1489  break;
1490  }
1491  }
1492  }
1493  assert(consdata->hascontvar || v < 0);
1494 
1495  consdata->hasnonbinvalid = TRUE;
1496 }
1497 
1498 
1499 #ifdef CHECKMAXACTDELTA
1500 /** checks that the stored maximal activity delta (if not invalid) is correct */
1501 static
1503  SCIP* scip, /**< SCIP data structure */
1504  SCIP_CONSDATA* consdata /**< linear constraint data */
1505  )
1506 {
1507  if( consdata->maxactdelta != SCIP_INVALID )
1508  {
1509  SCIP_Real maxactdelta = 0.0;
1510  SCIP_Real domain;
1511  SCIP_Real delta;
1512  SCIP_Real lb;
1513  SCIP_Real ub;
1514  int v;
1515 
1516  for( v = consdata->nvars - 1; v >= 0; --v )
1517  {
1518  lb = SCIPvarGetLbLocal(consdata->vars[v]);
1519  ub = SCIPvarGetUbLocal(consdata->vars[v]);
1520 
1521  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
1522  {
1523  maxactdelta = SCIPinfinity(scip);
1524  break;
1525  }
1526 
1527  domain = ub - lb;
1528  delta = REALABS(consdata->vals[v]) * domain;
1529 
1530  if( delta > maxactdelta )
1531  {
1532  maxactdelta = delta;
1533  }
1534  }
1535  assert(SCIPisFeasEQ(scip, maxactdelta, consdata->maxactdelta));
1536  }
1537 }
1538 #else
1539 #define checkMaxActivityDelta(scip, consdata) /**/
1540 #endif
1541 
1542 /** recompute maximal activity contribution for a single variable */
1543 static
1545  SCIP* scip, /**< SCIP data structure */
1546  SCIP_CONSDATA* consdata /**< linear constraint data */
1547  )
1548 {
1549  SCIP_Real delta;
1550  int v;
1551 
1552  consdata->maxactdelta = 0.0;
1553 
1554  if( !consdata->hasnonbinvalid )
1555  consdataCheckNonbinvar(consdata);
1556 
1557  /* easy case, the problem consists only of binary variables */
1558  if( !consdata->hasnonbinvar )
1559  {
1560  for( v = consdata->nvars - 1; v >= 0; --v )
1561  {
1562  if( SCIPvarGetLbLocal(consdata->vars[v]) < 0.5 && SCIPvarGetUbLocal(consdata->vars[v]) > 0.5 )
1563  {
1564  delta = REALABS(consdata->vals[v]);
1565 
1566  if( delta > consdata->maxactdelta )
1567  {
1568  consdata->maxactdelta = delta;
1569  consdata->maxactdeltavar = consdata->vars[v];
1570  }
1571  }
1572  }
1573  return;
1574  }
1575 
1576  for( v = consdata->nvars - 1; v >= 0; --v )
1577  {
1578  SCIP_Real domain;
1579  SCIP_Real lb;
1580  SCIP_Real ub;
1581 
1582  lb = SCIPvarGetLbLocal(consdata->vars[v]);
1583  ub = SCIPvarGetUbLocal(consdata->vars[v]);
1584 
1585  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
1586  {
1587  consdata->maxactdelta = SCIPinfinity(scip);
1588  consdata->maxactdeltavar = consdata->vars[v];
1589  break;
1590  }
1591 
1592  domain = ub - lb;
1593  delta = REALABS(consdata->vals[v]) * domain;
1594 
1595  if( delta > consdata->maxactdelta )
1596  {
1597  consdata->maxactdelta = delta;
1598  consdata->maxactdeltavar = consdata->vars[v];
1599  }
1600  }
1601 }
1602 
1603 
1604 /** updates activities for a change in a bound */
1605 static
1607  SCIP* scip, /**< SCIP data structure */
1608  SCIP_CONSDATA* consdata, /**< linear constraint data */
1609  SCIP_VAR* var, /**< variable that has been changed; can be NULL for global bound changes */
1610  SCIP_Real oldbound, /**< old bound of variable */
1611  SCIP_Real newbound, /**< new bound of variable */
1612  SCIP_Real val, /**< coefficient of constraint entry */
1613  SCIP_BOUNDTYPE boundtype, /**< type of the bound change */
1614  SCIP_Bool global, /**< is it a global or a local bound change? */
1615  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1616  )
1617 {
1618  SCIP_Real* activity;
1619  SCIP_Real* lastactivity;
1620  int* activityposinf;
1621  int* activityneginf;
1622  int* activityposhuge;
1623  int* activityneghuge;
1624  SCIP_Real oldcontribution;
1625  SCIP_Real newcontribution;
1626  SCIP_Real delta;
1627  SCIP_Bool validact;
1628  SCIP_Bool finitenewbound;
1629  SCIP_Bool hugevalnewcont;
1630 
1631  assert(scip != NULL);
1632  assert(consdata != NULL);
1633  assert(global || (var != NULL));
1634  assert(consdata->validactivities);
1635  assert(consdata->minactivity < SCIP_INVALID);
1636  assert(consdata->maxactivity < SCIP_INVALID);
1637  assert(consdata->lastminactivity < SCIP_INVALID);
1638  assert(consdata->lastmaxactivity < SCIP_INVALID);
1639  assert(consdata->minactivityneginf >= 0);
1640  assert(consdata->minactivityposinf >= 0);
1641  assert(consdata->maxactivityneginf >= 0);
1642  assert(consdata->maxactivityposinf >= 0);
1643  assert(consdata->minactivityneghuge >= 0);
1644  assert(consdata->minactivityposhuge >= 0);
1645  assert(consdata->maxactivityneghuge >= 0);
1646  assert(consdata->maxactivityposhuge >= 0);
1647  assert(consdata->glbminactivity < SCIP_INVALID);
1648  assert(consdata->glbmaxactivity < SCIP_INVALID);
1649  assert(consdata->lastglbminactivity < SCIP_INVALID);
1650  assert(consdata->lastglbmaxactivity < SCIP_INVALID);
1651  assert(consdata->glbminactivityneginf >= 0);
1652  assert(consdata->glbminactivityposinf >= 0);
1653  assert(consdata->glbmaxactivityneginf >= 0);
1654  assert(consdata->glbmaxactivityposinf >= 0);
1655  assert(consdata->glbminactivityneghuge >= 0);
1656  assert(consdata->glbminactivityposhuge >= 0);
1657  assert(consdata->glbmaxactivityneghuge >= 0);
1658  assert(consdata->glbmaxactivityposhuge >= 0);
1659 
1660  delta = 0.0;
1661 
1662  /* we are updating global activities */
1663  if( global )
1664  {
1665  /* depending on the boundtype and the coefficient, we choose the activity to be updated:
1666  * lower bound + pos. coef: update minactivity
1667  * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
1668  * upper bound + pos. coef: update maxactivity
1669  * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
1670  */
1671  if( boundtype == SCIP_BOUNDTYPE_LOWER )
1672  {
1673  if( val > 0.0 )
1674  {
1675  activity = &(consdata->glbminactivity);
1676  lastactivity = &(consdata->lastglbminactivity);
1677  activityposinf = &(consdata->glbminactivityposinf);
1678  activityneginf = &(consdata->glbminactivityneginf);
1679  activityposhuge = &(consdata->glbminactivityposhuge);
1680  activityneghuge = &(consdata->glbminactivityneghuge);
1681  validact = consdata->validglbminact;
1682  }
1683  else
1684  {
1685  activity = &(consdata->glbmaxactivity);
1686  lastactivity = &(consdata->lastglbmaxactivity);
1687  activityposinf = &(consdata->glbmaxactivityneginf);
1688  activityneginf = &(consdata->glbmaxactivityposinf);
1689  activityposhuge = &(consdata->glbmaxactivityposhuge);
1690  activityneghuge = &(consdata->glbmaxactivityneghuge);
1691  validact = consdata->validglbmaxact;
1692  }
1693  }
1694  else
1695  {
1696  if( val > 0.0 )
1697  {
1698  activity = &(consdata->glbmaxactivity);
1699  lastactivity = &(consdata->lastglbmaxactivity);
1700  activityposinf = &(consdata->glbmaxactivityposinf);
1701  activityneginf = &(consdata->glbmaxactivityneginf);
1702  activityposhuge = &(consdata->glbmaxactivityposhuge);
1703  activityneghuge = &(consdata->glbmaxactivityneghuge);
1704  validact = consdata->validglbmaxact;
1705  }
1706  else
1707  {
1708  activity = &(consdata->glbminactivity);
1709  lastactivity = &(consdata->lastglbminactivity);
1710  activityposinf = &(consdata->glbminactivityneginf);
1711  activityneginf = &(consdata->glbminactivityposinf);
1712  activityposhuge = &(consdata->glbminactivityposhuge);
1713  activityneghuge = &(consdata->glbminactivityneghuge);
1714  validact = consdata->validglbminact;
1715  }
1716  }
1717  }
1718  /* we are updating local activities */
1719  else
1720  {
1721  /* depending on the boundtype and the coefficient, we choose the activity to be updated:
1722  * lower bound + pos. coef: update minactivity
1723  * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
1724  * upper bound + pos. coef: update maxactivity
1725  * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
1726  */
1727  if( boundtype == SCIP_BOUNDTYPE_LOWER )
1728  {
1729  if( val > 0.0 )
1730  {
1731  activity = &(consdata->minactivity);
1732  lastactivity = &(consdata->lastminactivity);
1733  activityposinf = &(consdata->minactivityposinf);
1734  activityneginf = &(consdata->minactivityneginf);
1735  activityposhuge = &(consdata->minactivityposhuge);
1736  activityneghuge = &(consdata->minactivityneghuge);
1737  validact = consdata->validminact;
1738  }
1739  else
1740  {
1741  activity = &(consdata->maxactivity);
1742  lastactivity = &(consdata->lastmaxactivity);
1743  activityposinf = &(consdata->maxactivityneginf);
1744  activityneginf = &(consdata->maxactivityposinf);
1745  activityposhuge = &(consdata->maxactivityposhuge);
1746  activityneghuge = &(consdata->maxactivityneghuge);
1747  validact = consdata->validmaxact;
1748  }
1749  }
1750  else
1751  {
1752  if( val > 0.0 )
1753  {
1754  activity = &(consdata->maxactivity);
1755  lastactivity = &(consdata->lastmaxactivity);
1756  activityposinf = &(consdata->maxactivityposinf);
1757  activityneginf = &(consdata->maxactivityneginf);
1758  activityposhuge = &(consdata->maxactivityposhuge);
1759  activityneghuge = &(consdata->maxactivityneghuge);
1760  validact = consdata->validmaxact;
1761  }
1762  else
1763  {
1764  activity = &(consdata->minactivity);
1765  lastactivity = &(consdata->lastminactivity);
1766  activityposinf = &(consdata->minactivityneginf);
1767  activityneginf = &(consdata->minactivityposinf);
1768  activityposhuge = &(consdata->minactivityposhuge);
1769  activityneghuge = &(consdata->minactivityneghuge);
1770  validact = consdata->validminact;
1771  }
1772  }
1773  }
1774 
1775  oldcontribution = val * oldbound;
1776  newcontribution = val * newbound;
1777  hugevalnewcont = SCIPisHugeValue(scip, REALABS(newcontribution));
1778  finitenewbound = !SCIPisInfinity(scip, REALABS(newbound));
1779 
1780  if( SCIPisInfinity(scip, REALABS(oldbound)) )
1781  {
1782  /* old bound was +infinity */
1783  if( oldbound > 0.0 )
1784  {
1785  assert((*activityposinf) >= 1);
1786 
1787  /* we only have to do something if the new bound is not again +infinity */
1788  if( finitenewbound || newbound < 0.0 )
1789  {
1790  /* decrease the counter for positive infinite contributions */
1791  (*activityposinf)--;
1792 
1793  /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1794  if( !finitenewbound && newbound < 0.0 )
1795  (*activityneginf)++;
1796  else if( hugevalnewcont )
1797  {
1798  /* if the contribution of this variable is too large, increase the counter for huge values */
1799  if( newcontribution > 0.0 )
1800  (*activityposhuge)++;
1801  else
1802  (*activityneghuge)++;
1803  }
1804  /* "normal case": just add the contribution to the activity */
1805  else
1806  delta = newcontribution;
1807  }
1808  }
1809  /* old bound was -infinity */
1810  else
1811  {
1812  assert(oldbound < 0.0);
1813  assert((*activityneginf) >= 1);
1814 
1815  /* we only have to do something ig the new bound is not again -infinity */
1816  if( finitenewbound || newbound > 0.0 )
1817  {
1818  /* decrease the counter for negative infinite contributions */
1819  (*activityneginf)--;
1820 
1821  /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1822  if( !finitenewbound && newbound > 0.0 )
1823  (*activityposinf)++;
1824  else if( hugevalnewcont )
1825  {
1826  /* if the contribution of this variable is too large, increase the counter for huge values */
1827  if( newcontribution > 0.0 )
1828  (*activityposhuge)++;
1829  else
1830  (*activityneghuge)++;
1831  }
1832  /* "normal case": just add the contribution to the activity */
1833  else
1834  delta = newcontribution;
1835  }
1836  }
1837  }
1838  else if( SCIPisHugeValue(scip, REALABS(oldcontribution)) )
1839  {
1840  /* old contribution was too large and positive */
1841  if( oldcontribution > 0.0 )
1842  {
1843  assert((*activityposhuge) >= 1);
1844 
1845  /* decrease the counter for huge positive contributions; it might be increased again later,
1846  * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
1847  */
1848  (*activityposhuge)--;
1849 
1850  if( !finitenewbound )
1851  {
1852  /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1853  if( newbound > 0.0 )
1854  (*activityposinf)++;
1855  /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1856  else
1857  (*activityneginf)++;
1858  }
1859  else if( hugevalnewcont )
1860  {
1861  /* if the contribution of this variable is too large and positive, increase the corresponding counter */
1862  if( newcontribution > 0.0 )
1863  (*activityposhuge)++;
1864  /* if the contribution of this variable is too large and negative, increase the corresponding counter */
1865  else
1866  (*activityneghuge)++;
1867  }
1868  /* "normal case": just add the contribution to the activity */
1869  else
1870  delta = newcontribution;
1871  }
1872  /* old contribution was too large and negative */
1873  else
1874  {
1875  assert(oldcontribution < 0.0);
1876  assert((*activityneghuge) >= 1);
1877 
1878  /* decrease the counter for huge negative contributions; it might be increased again later,
1879  * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
1880  */
1881  (*activityneghuge)--;
1882 
1883  if( !finitenewbound )
1884  {
1885  /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1886  if( newbound > 0.0 )
1887  (*activityposinf)++;
1888  /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1889  else
1890  (*activityneginf)++;
1891  }
1892  else if( hugevalnewcont )
1893  {
1894  /* if the contribution of this variable is too large and positive, increase the corresponding counter */
1895  if( newcontribution > 0.0 )
1896  (*activityposhuge)++;
1897  /* if the contribution of this variable is too large and negative, increase the corresponding counter */
1898  else
1899  (*activityneghuge)++;
1900  }
1901  /* "normal case": just add the contribution to the activity */
1902  else
1903  delta = newcontribution;
1904  }
1905  }
1906  /* old bound was finite and not too large */
1907  else
1908  {
1909  if( !finitenewbound )
1910  {
1911  /* if the new bound is +infinity, the old contribution has to be subtracted
1912  * and the counter for positive infinite contributions has to be increased
1913  */
1914  if( newbound > 0.0 )
1915  {
1916  (*activityposinf)++;
1917  delta = -oldcontribution;
1918  }
1919  /* if the new bound is -infinity, the old contribution has to be subtracted
1920  * and the counter for negative infinite contributions has to be increased
1921  */
1922  else
1923  {
1924  assert(newbound < 0.0 );
1925 
1926  (*activityneginf)++;
1927  delta = -oldcontribution;
1928  }
1929  }
1930  /* if the contribution of this variable is too large, increase the counter for huge values */
1931  else if( hugevalnewcont )
1932  {
1933  if( newcontribution > 0.0 )
1934  {
1935  (*activityposhuge)++;
1936  delta = -oldcontribution;
1937  }
1938  else
1939  {
1940  (*activityneghuge)++;
1941  delta = -oldcontribution;
1942  }
1943  }
1944  /* "normal case": just update the activity */
1945  else
1946  delta = newcontribution - oldcontribution;
1947  }
1948 
1949  /* update the activity, if the current value is valid and there was a change in the finite part */
1950  if( validact && (delta != 0.0) )
1951  {
1952  /* if the absolute value of the activity is increased, this is regarded as reliable,
1953  * otherwise, we check whether we can still trust the updated value
1954  */
1955  (*activity) = (*activity) + delta;
1956  assert(!SCIPisInfinity(scip, -(*activity)) && !SCIPisInfinity(scip, *activity));
1957 
1958  if( REALABS((*lastactivity)) < REALABS(*activity) )
1959  {
1960  (*lastactivity) = (*activity);
1961  }
1962  else
1963  {
1964  if( checkreliability && SCIPisUpdateUnreliable(scip, (*activity), (*lastactivity)) )
1965  {
1966  SCIPdebugMsg(scip, "%s activity of linear constraint unreliable after update: %16.9g\n",
1967  (global ? "global " : ""), (*activity));
1968 
1969  /* mark the activity that was just changed and is not reliable anymore to be invalid */
1970  if( global )
1971  {
1972  if( (boundtype == SCIP_BOUNDTYPE_LOWER) == (val > 0.0) )
1973  consdata->validglbminact = FALSE;
1974  else
1975  consdata->validglbmaxact = FALSE;
1976  }
1977  else
1978  {
1979  if( (boundtype == SCIP_BOUNDTYPE_LOWER) == (val > 0.0) )
1980  consdata->validminact = FALSE;
1981  else
1982  consdata->validmaxact = FALSE;
1983  }
1984  }
1985  }
1986  }
1987 }
1988 
1989 /** updates minimum and maximum activity for a change in lower bound */
1990 static
1992  SCIP* scip, /**< SCIP data structure */
1993  SCIP_CONSDATA* consdata, /**< linear constraint data */
1994  SCIP_VAR* var, /**< variable that has been changed */
1995  SCIP_Real oldlb, /**< old lower bound of variable */
1996  SCIP_Real newlb, /**< new lower bound of variable */
1997  SCIP_Real val, /**< coefficient of constraint entry */
1998  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1999  )
2000 {
2001  assert(scip != NULL);
2002  assert(consdata != NULL);
2003  assert(var != NULL);
2004 
2005  if( consdata->validactivities )
2006  {
2007  consdataUpdateActivities(scip, consdata, var, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, FALSE, checkreliability);
2008 
2009  assert(!SCIPisInfinity(scip, -consdata->minactivity) && !SCIPisInfinity(scip, consdata->minactivity));
2010  assert(!SCIPisInfinity(scip, -consdata->maxactivity) && !SCIPisInfinity(scip, consdata->maxactivity));
2011  }
2012 }
2013 
2014 /** updates minimum and maximum activity for a change in upper bound */
2015 static
2017  SCIP* scip, /**< SCIP data structure */
2018  SCIP_CONSDATA* consdata, /**< linear constraint data */
2019  SCIP_VAR* var, /**< variable that has been changed */
2020  SCIP_Real oldub, /**< old upper bound of variable */
2021  SCIP_Real newub, /**< new upper bound of variable */
2022  SCIP_Real val, /**< coefficient of constraint entry */
2023  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2024  )
2025 {
2026  assert(scip != NULL);
2027  assert(consdata != NULL);
2028  assert(var != NULL);
2029 
2030  if( consdata->validactivities )
2031  {
2032  consdataUpdateActivities(scip, consdata, var, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, FALSE, checkreliability);
2033 
2034  assert(!SCIPisInfinity(scip, -consdata->minactivity) && !SCIPisInfinity(scip, consdata->minactivity));
2035  assert(!SCIPisInfinity(scip, -consdata->maxactivity) && !SCIPisInfinity(scip, consdata->maxactivity));
2036  }
2037 }
2038 
2039 /** updates minimum and maximum global activity for a change in the global lower bound */
2040 static
2042  SCIP* scip, /**< SCIP data structure */
2043  SCIP_CONSDATA* consdata, /**< linear constraint data */
2044  SCIP_Real oldlb, /**< old lower bound of variable */
2045  SCIP_Real newlb, /**< new lower bound of variable */
2046  SCIP_Real val, /**< coefficient of constraint entry */
2047  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2048  )
2049 {
2050  assert(scip != NULL);
2051  assert(consdata != NULL);
2052 
2053  if( consdata->validactivities )
2054  {
2055  consdataUpdateActivities(scip, consdata, NULL, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, TRUE, checkreliability);
2056 
2057  assert(!SCIPisInfinity(scip, -consdata->glbminactivity) && !SCIPisInfinity(scip, consdata->glbminactivity));
2058  assert(!SCIPisInfinity(scip, -consdata->glbmaxactivity) && !SCIPisInfinity(scip, consdata->glbmaxactivity));
2059  }
2061 
2062 /** updates minimum and maximum global activity for a change in global upper bound */
2063 static
2065  SCIP* scip, /**< SCIP data structure */
2066  SCIP_CONSDATA* consdata, /**< linear constraint data */
2067  SCIP_Real oldub, /**< old upper bound of variable */
2068  SCIP_Real newub, /**< new upper bound of variable */
2069  SCIP_Real val, /**< coefficient of constraint entry */
2070  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2071  )
2072 {
2073  assert(scip != NULL);
2074  assert(consdata != NULL);
2075 
2076  if( consdata->validactivities )
2077  {
2078  consdataUpdateActivities(scip, consdata, NULL, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, TRUE, checkreliability);
2079 
2080  assert(!SCIPisInfinity(scip, -consdata->glbminactivity) && !SCIPisInfinity(scip, consdata->glbminactivity));
2081  assert(!SCIPisInfinity(scip, -consdata->glbmaxactivity) && !SCIPisInfinity(scip, consdata->glbmaxactivity));
2082  }
2084 
2085 /** updates minimum and maximum activity and maximum absolute value for coefficient addition */
2086 static
2088  SCIP* scip, /**< SCIP data structure */
2089  SCIP_CONSDATA* consdata, /**< linear constraint data */
2090  SCIP_VAR* var, /**< variable of constraint entry */
2091  SCIP_Real val, /**< coefficient of constraint entry */
2092  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2093  )
2094 {
2095  assert(scip != NULL);
2096  assert(consdata != NULL);
2097  assert(var != NULL);
2098 
2099  /* update maximum absolute value */
2100  if( consdata->validmaxabsval )
2101  {
2102  SCIP_Real absval;
2103 
2104  assert(consdata->maxabsval < SCIP_INVALID);
2105 
2106  absval = REALABS(val);
2107  consdata->maxabsval = MAX(consdata->maxabsval, absval);
2108  }
2109 
2110  if( consdata->validminabsval )
2111  {
2112  SCIP_Real absval;
2113 
2114  assert(consdata->minabsval < SCIP_INVALID);
2115 
2116  absval = REALABS(val);
2117  consdata->minabsval = MIN(consdata->minabsval, absval);
2118  }
2119 
2120  /* update minimal and maximal activity */
2121  if( consdata->validactivities )
2122  {
2123  assert(consdata->minactivity < SCIP_INVALID);
2124  assert(consdata->maxactivity < SCIP_INVALID);
2125  assert(consdata->glbminactivity < SCIP_INVALID);
2126  assert(consdata->glbmaxactivity < SCIP_INVALID);
2127 
2128  consdataUpdateActivitiesLb(scip, consdata, var, 0.0, SCIPvarGetLbLocal(var), val, checkreliability);
2129  consdataUpdateActivitiesUb(scip, consdata, var, 0.0, SCIPvarGetUbLocal(var), val, checkreliability);
2130  consdataUpdateActivitiesGlbLb(scip, consdata, 0.0, SCIPvarGetLbGlobal(var), val, checkreliability);
2131  consdataUpdateActivitiesGlbUb(scip, consdata, 0.0, SCIPvarGetUbGlobal(var), val, checkreliability);
2132  }
2133 }
2134 
2135 /** updates minimum and maximum activity for coefficient deletion, invalidates maximum absolute value if necessary */
2136 static
2138  SCIP* scip, /**< SCIP data structure */
2139  SCIP_CONSDATA* consdata, /**< linear constraint data */
2140  SCIP_VAR* var, /**< variable of constraint entry */
2141  SCIP_Real val, /**< coefficient of constraint entry */
2142  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2143  )
2144 {
2145  assert(scip != NULL);
2146  assert(consdata != NULL);
2147  assert(var != NULL);
2148 
2149  /* invalidate maximum absolute value, if this coefficient was the maximum */
2150  if( consdata->validmaxabsval )
2151  {
2152  SCIP_Real absval;
2153 
2154  absval = REALABS(val);
2155 
2156  if( SCIPisEQ(scip, absval, consdata->maxabsval) )
2157  {
2158  consdata->validmaxabsval = FALSE;
2159  consdata->maxabsval = SCIP_INVALID;
2160  }
2161  }
2162 
2163  /* invalidate minimum absolute value, if this coefficient was the minimum */
2164  if( consdata->validminabsval )
2165  {
2166  SCIP_Real absval;
2167 
2168  absval = REALABS(val);
2169 
2170  if( SCIPisEQ(scip, absval, consdata->minabsval) )
2171  {
2172  consdata->validminabsval = FALSE;
2173  consdata->minabsval = SCIP_INVALID;
2174  }
2175  }
2176 
2177  /* update minimal and maximal activity */
2178  if( consdata->validactivities )
2179  {
2180  assert(consdata->minactivity < SCIP_INVALID);
2181  assert(consdata->maxactivity < SCIP_INVALID);
2182  assert(consdata->glbminactivity < SCIP_INVALID);
2183  assert(consdata->glbmaxactivity < SCIP_INVALID);
2184 
2185  consdataUpdateActivitiesLb(scip, consdata, var, SCIPvarGetLbLocal(var), 0.0, val, checkreliability);
2186  consdataUpdateActivitiesUb(scip, consdata, var, SCIPvarGetUbLocal(var), 0.0, val, checkreliability);
2187  consdataUpdateActivitiesGlbLb(scip, consdata, SCIPvarGetLbGlobal(var), 0.0, val, checkreliability);
2188  consdataUpdateActivitiesGlbUb(scip, consdata, SCIPvarGetUbGlobal(var), 0.0, val, checkreliability);
2189  }
2190 }
2191 
2192 /** updates minimum and maximum activity for coefficient change, invalidates maximum absolute value if necessary */
2193 static
2195  SCIP* scip, /**< SCIP data structure */
2196  SCIP_CONSDATA* consdata, /**< linear constraint data */
2197  SCIP_VAR* var, /**< variable of constraint entry */
2198  SCIP_Real oldval, /**< old coefficient of constraint entry */
2199  SCIP_Real newval, /**< new coefficient of constraint entry */
2200  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2201  )
2202 {
2203  assert(scip != NULL);
2204  assert(consdata != NULL);
2205  assert(var != NULL);
2206 
2207  /* old zero coefficients should be handled by consdataUpdateAddCoef() */
2208  assert(!SCIPisZero(scip, oldval));
2209 
2210  /* new zero coefficients should be handled by consdataUpdateDelCoef() */
2211  assert(!SCIPisZero(scip, newval));
2212 
2213  /* update maximum absolute value */
2214  if( consdata->validmaxabsval )
2215  {
2216  SCIP_Real absval;
2217 
2218  absval = REALABS(newval);
2219 
2220  if( SCIPisGE(scip, absval, consdata->maxabsval) )
2221  {
2222  consdata->maxabsval = absval;
2223  }
2224  else
2225  {
2226  absval = REALABS(oldval);
2227 
2228  /* invalidate maximum absolute value */
2229  if( SCIPisEQ(scip, absval, consdata->maxabsval) )
2230  {
2231  consdata->validmaxabsval = FALSE;
2232  consdata->maxabsval = SCIP_INVALID;
2233  }
2234  }
2235  }
2236 
2237  /* update minimum absolute value */
2238  if( consdata->validminabsval )
2239  {
2240  SCIP_Real absval;
2241 
2242  absval = REALABS(newval);
2243 
2244  if( SCIPisLE(scip, absval, consdata->minabsval) )
2245  {
2246  consdata->minabsval = absval;
2247  }
2248  else
2249  {
2250  absval = REALABS(oldval);
2251 
2252  /* invalidate minimum absolute value */
2253  if( SCIPisEQ(scip, absval, consdata->minabsval) )
2254  {
2255  consdata->validminabsval = FALSE;
2256  consdata->minabsval = SCIP_INVALID;
2257  }
2258  }
2259  }
2260 
2261  /* update maximum activity delta */
2262  if( !SCIPisInfinity(scip, consdata->maxactdelta ) )
2263  {
2264  SCIP_Real domain;
2265  SCIP_Real delta;
2266 
2267  assert(!SCIPisInfinity(scip, SCIPvarGetLbLocal(var)));
2268  assert(!SCIPisInfinity(scip, SCIPvarGetUbLocal(var)));
2269 
2270  domain = SCIPvarGetUbLocal(var) - SCIPvarGetLbLocal(var);
2271  delta = REALABS(newval) * domain;
2272 
2273  if( delta > consdata->maxactdelta )
2274  {
2275  consdata->maxactdelta = delta;
2276  consdata->maxactdeltavar = var;
2277  }
2278  else
2279  {
2280  /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
2281  if( consdata->maxactdeltavar == var )
2282  consdata->maxactdelta = SCIP_INVALID;
2283  }
2284  }
2285 
2286  /* @todo do something more clever here, e.g. if oldval * newval >= 0, do the update directly */
2287  consdataUpdateDelCoef(scip, consdata, var, oldval, checkreliability);
2288  consdataUpdateAddCoef(scip, consdata, var, newval, checkreliability);
2289 }
2290 
2291 /** returns the maximum absolute value of all coefficients in the constraint */
2292 static
2294  SCIP_CONSDATA* consdata /**< linear constraint data */
2295  )
2296 {
2297  assert(consdata != NULL);
2298 
2299  if( !consdata->validmaxabsval )
2300  consdataCalcMaxAbsval(consdata);
2301  assert(consdata->validmaxabsval);
2302  assert(consdata->maxabsval < SCIP_INVALID);
2303 
2304  return consdata->maxabsval;
2305 }
2306 
2307 /** returns the minimum absolute value of all coefficients in the constraint */
2308 static
2310  SCIP_CONSDATA* consdata /**< linear constraint data */
2311  )
2313  assert(consdata != NULL);
2314 
2315  if( !consdata->validminabsval )
2316  consdataCalcMinAbsval(consdata);
2317  assert(consdata->validminabsval);
2318  assert(consdata->minabsval < SCIP_INVALID);
2319 
2320  return consdata->minabsval;
2321 }
2322 
2323 /** calculates minimum and maximum local and global activity for constraint from scratch;
2324  * additionally recalculates maximum absolute value of coefficients
2325  */
2326 static
2328  SCIP* scip, /**< SCIP data structure */
2329  SCIP_CONSDATA* consdata /**< linear constraint data */
2330  )
2331 {
2332  int i;
2333 
2334  assert(scip != NULL);
2335  assert(consdata != NULL);
2336  assert(!consdata->validactivities);
2337  assert(consdata->minactivity >= SCIP_INVALID || consdata->validminact);
2338  assert(consdata->maxactivity >= SCIP_INVALID || consdata->validmaxact);
2339  assert(consdata->glbminactivity >= SCIP_INVALID || consdata->validglbminact);
2340  assert(consdata->glbmaxactivity >= SCIP_INVALID || consdata->validglbmaxact);
2341 
2342  consdata->validmaxabsval = TRUE;
2343  consdata->validminabsval = TRUE;
2344  consdata->validactivities = TRUE;
2345  consdata->validminact = TRUE;
2346  consdata->validmaxact = TRUE;
2347  consdata->validglbminact = TRUE;
2348  consdata->validglbmaxact = TRUE;
2349  consdata->maxabsval = 0.0;
2350  consdata->minabsval = (consdata->nvars == 0 ? 0.0 : REALABS(consdata->vals[0]));
2351  consdata->minactivity = 0.0;
2352  consdata->maxactivity = 0.0;
2353  consdata->lastminactivity = 0.0;
2354  consdata->lastmaxactivity = 0.0;
2355  consdata->minactivityneginf = 0;
2356  consdata->minactivityposinf = 0;
2357  consdata->maxactivityneginf = 0;
2358  consdata->maxactivityposinf = 0;
2359  consdata->minactivityneghuge = 0;
2360  consdata->minactivityposhuge = 0;
2361  consdata->maxactivityneghuge = 0;
2362  consdata->maxactivityposhuge = 0;
2363  consdata->glbminactivity = 0.0;
2364  consdata->glbmaxactivity = 0.0;
2365  consdata->lastglbminactivity = 0.0;
2366  consdata->lastglbmaxactivity = 0.0;
2367  consdata->glbminactivityneginf = 0;
2368  consdata->glbminactivityposinf = 0;
2369  consdata->glbmaxactivityneginf = 0;
2370  consdata->glbmaxactivityposinf = 0;
2371  consdata->glbminactivityneghuge = 0;
2372  consdata->glbminactivityposhuge = 0;
2373  consdata->glbmaxactivityneghuge = 0;
2374  consdata->glbmaxactivityposhuge = 0;
2375 
2376  for( i = 0; i < consdata->nvars; ++i )
2377  consdataUpdateAddCoef(scip, consdata, consdata->vars[i], consdata->vals[i], FALSE);
2378 
2379  consdata->lastminactivity = consdata->minactivity;
2380  consdata->lastmaxactivity = consdata->maxactivity;
2381  consdata->lastglbminactivity = consdata->glbminactivity;
2382  consdata->lastglbmaxactivity = consdata->glbmaxactivity;
2383 }
2384 
2385 /** gets minimal activity for constraint and given values of counters for infinite and huge contributions
2386  * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
2387  */
2388 static
2389 void getMinActivity(
2390  SCIP* scip, /**< SCIP data structure */
2391  SCIP_CONSDATA* consdata, /**< linear constraint */
2392  int posinf, /**< number of coefficients contributing pos. infinite value */
2393  int neginf, /**< number of coefficients contributing neg. infinite value */
2394  int poshuge, /**< number of coefficients contributing huge pos. value */
2395  int neghuge, /**< number of coefficients contributing huge neg. value */
2396  SCIP_Real delta, /**< value to subtract from stored minactivity
2397  * (contribution of the variable set to zero when getting residual activity) */
2398  SCIP_Bool global, /**< should the global or local minimal activity be returned? */
2399  SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
2400  SCIP_Real* minactivity, /**< pointer to store the minimal activity */
2401  SCIP_Bool* isrelax, /**< pointer to store whether the activity is a relaxation,
2402  * i.e. is <= the exact minactivity (in case of huge contributing values) */
2403  SCIP_Bool* issettoinfinity /**< pointer to store whether minactivity was set to infinity or calculated */
2404  )
2405 {
2406  assert(scip != NULL);
2407  assert(consdata != NULL);
2408  assert(posinf >= 0);
2409  assert(neginf >= 0);
2410  assert(poshuge >= 0);
2411  assert(neghuge >= 0);
2412  assert(minactivity != NULL);
2413  assert(isrelax != NULL);
2414  assert(issettoinfinity != NULL);
2415 
2416  /* if we have pos. infinite contributions, the minactivity is +infty */
2417  if( posinf > 0 )
2418  {
2419  *minactivity = SCIPinfinity(scip);
2420  *issettoinfinity = TRUE;
2421  *isrelax = FALSE;
2422  }
2423  /* if we have neg. (and no pos.) infinite contributions, the minactivity is -infty */
2424  else if( neginf > 0 )
2425  {
2426  *minactivity = -SCIPinfinity(scip);
2427  *issettoinfinity = TRUE;
2428  *isrelax = FALSE;
2429  }
2430  /* if we have neg. huge contributions, we only know that -infty is a relaxation of the minactivity */
2431  else if( neghuge > 0 )
2432  {
2433  *minactivity = -SCIPinfinity(scip);
2434  *issettoinfinity = TRUE;
2435  *isrelax = TRUE;
2436  }
2437  /* we do not need a good relaxation and we have positive huge contributions, so we just return -infty as activity */
2438  else if( !goodrelax && poshuge > 0 )
2439  {
2440  *minactivity = -SCIPinfinity(scip);
2441  *issettoinfinity = TRUE;
2442  *isrelax = TRUE;
2443  }
2444  else
2445  {
2446  SCIP_Real tmpactivity;
2447 
2448  /* recompute minactivity if it is not valid */
2449  if( global )
2450  {
2451  if( !consdata->validglbminact )
2452  consdataRecomputeGlbMinactivity(scip, consdata);
2453  assert(consdata->validglbminact);
2454 
2455  tmpactivity = consdata->glbminactivity;
2456  }
2457  else
2458  {
2459  if( !consdata->validminact )
2460  consdataRecomputeMinactivity(scip, consdata);
2461  assert(consdata->validminact);
2462 
2463  tmpactivity = consdata->minactivity;
2464  }
2465 
2466  /* we have no infinite and no neg. huge contributions, but pos. huge contributions;
2467  * a feasible relaxation of the minactivity is the number of positive huge contributions
2468  * times the minimum value counting as "huge" plus finite (and non-huge) part of minactivity - delta
2469  */
2470  if( poshuge > 0 )
2471  {
2472  *minactivity = 1.0 * poshuge * SCIPgetHugeValue(scip) + (tmpactivity - delta);
2473  *issettoinfinity = FALSE;
2474  *isrelax = TRUE;
2475  }
2476  /* all counters are zero, so the minactivity is just stored and we subtract the delta */
2477  else
2478  {
2479  *minactivity = tmpactivity - delta;
2480  *issettoinfinity = FALSE;
2481  *isrelax = FALSE;
2482  }
2483  }
2484 }
2485 
2486 /** gets maximal activity for constraint and given values of counters for infinite and huge contributions
2487  * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
2488  */
2489 static
2490 void getMaxActivity(
2491  SCIP* scip, /**< SCIP data structure */
2492  SCIP_CONSDATA* consdata, /**< linear constraint */
2493  int posinf, /**< number of coefficients contributing pos. infinite value */
2494  int neginf, /**< number of coefficients contributing neg. infinite value */
2495  int poshuge, /**< number of coefficients contributing huge pos. value */
2496  int neghuge, /**< number of coefficients contributing huge neg. value */
2497  SCIP_Real delta, /**< value to subtract from stored maxactivity
2498  * (contribution of the variable set to zero when getting residual activity) */
2499  SCIP_Bool global, /**< should the global or local maximal activity be returned? */
2500  SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
2501  SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
2502  SCIP_Bool* isrelax, /**< pointer to store whether the activity is a relaxation,
2503  * i.e. is >= the exact maxactivity (in case of huge contributing values) */
2504  SCIP_Bool* issettoinfinity /**< pointer to store whether maxactivity was set to infinity or calculated */
2505  )
2506 {
2507  assert(scip != NULL);
2508  assert(consdata != NULL);
2509  assert(posinf >= 0);
2510  assert(neginf >= 0);
2511  assert(poshuge >= 0);
2512  assert(neghuge >= 0);
2513  assert(maxactivity != NULL);
2514  assert(isrelax != NULL);
2515  assert(issettoinfinity != NULL);
2516 
2517  /* if we have neg. infinite contributions, the maxactivity is -infty */
2518  if( neginf > 0 )
2519  {
2520  *maxactivity = -SCIPinfinity(scip);
2521  *issettoinfinity = TRUE;
2522  *isrelax = FALSE;
2523  }
2524  /* if we have pos. (and no neg.) infinite contributions, the maxactivity is +infty */
2525  else if( posinf > 0 )
2526  {
2527  *maxactivity = SCIPinfinity(scip);
2528  *issettoinfinity = TRUE;
2529  *isrelax = FALSE;
2530  }
2531  /* if we have pos. huge contributions, we only know that +infty is a relaxation of the maxactivity */
2532  else if( poshuge > 0 )
2533  {
2534  *maxactivity = SCIPinfinity(scip);
2535  *issettoinfinity = TRUE;
2536  *isrelax = TRUE;
2537  }
2538  /* we do not need a good relaxation and we have positve huge contributions, so we just return +infty as activity */
2539  else if( !goodrelax && neghuge > 0 )
2540  {
2541  *maxactivity = SCIPinfinity(scip);
2542  *issettoinfinity = TRUE;
2543  *isrelax = TRUE;
2544  }
2545  else
2546  {
2547  SCIP_Real tmpactivity;
2548 
2549  /* recompute maxactivity if it is not valid */
2550  if( global )
2551  {
2552  if( !consdata->validglbmaxact )
2553  consdataRecomputeGlbMaxactivity(scip, consdata);
2554  assert(consdata->validglbmaxact);
2555 
2556  tmpactivity = consdata->glbmaxactivity;
2557  }
2558  else
2559  {
2560  if( !consdata->validmaxact )
2561  consdataRecomputeMaxactivity(scip, consdata);
2562  assert(consdata->validmaxact);
2563 
2564  tmpactivity = consdata->maxactivity;
2565  }
2566 
2567  /* we have no infinite, and no pos. huge contributions, but neg. huge contributions;
2568  * a feasible relaxation of the maxactivity is minus the number of negative huge contributions
2569  * times the minimum value counting as "huge" plus the finite (and non-huge) part of maxactivity minus delta
2570  */
2571  if( neghuge > 0 )
2572  {
2573  *maxactivity = -1.0 * neghuge * SCIPgetHugeValue(scip) + tmpactivity - delta;
2574  *issettoinfinity = FALSE;
2575  *isrelax = TRUE;
2576  }
2577  /* all counters are zero, so the maxactivity is just stored and we subtract the delta */
2578  else
2579  {
2580  *maxactivity = tmpactivity - delta;
2581  *issettoinfinity = FALSE;
2582  *isrelax = FALSE;
2583  }
2584  }
2585 }
2586 
2587 /** gets activity bounds for constraint */
2588 static
2590  SCIP* scip, /**< SCIP data structure */
2591  SCIP_CONSDATA* consdata, /**< linear constraint */
2592  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2593  * relaxed activities ignored, anyway? */
2594  SCIP_Real* minactivity, /**< pointer to store the minimal activity */
2595  SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
2596  SCIP_Bool* minisrelax, /**< pointer to store whether the returned minactivity is just a relaxation,
2597  * i.e. <= the exact minactivity (in case of huge contributions),
2598  * or equal to the exact minimal activity */
2599  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned maxactivity is just a relaxation,
2600  * i.e. >= the exact maxactivity (in case of huge contributions),
2601  * or equal to the exact maximal activity */
2602  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minactivity was set to infinity or calculated */
2603  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxactivity was set to infinity or calculated */
2604 
2605  )
2606 {
2607  assert(scip != NULL);
2608  assert(consdata != NULL);
2609  assert(minactivity != NULL);
2610  assert(maxactivity != NULL);
2611  assert(isminsettoinfinity != NULL);
2612  assert(ismaxsettoinfinity != NULL);
2613 
2614  if( !consdata->validactivities )
2615  {
2616  consdataCalcActivities(scip, consdata);
2617  assert(consdata->validminact);
2618  assert(consdata->validmaxact);
2619  }
2620  assert(consdata->minactivity < SCIP_INVALID);
2621  assert(consdata->maxactivity < SCIP_INVALID);
2622  assert(consdata->minactivityneginf >= 0);
2623  assert(consdata->minactivityposinf >= 0);
2624  assert(consdata->maxactivityneginf >= 0);
2625  assert(consdata->maxactivityposinf >= 0);
2626 
2627  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2628  consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2629  minactivity, minisrelax, isminsettoinfinity);
2630 
2631  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2632  consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2633  maxactivity, maxisrelax, ismaxsettoinfinity);
2634 }
2635 
2636 /** calculates activity bounds for constraint after setting variable to zero */
2637 static
2639  SCIP* scip, /**< SCIP data structure */
2640  SCIP_CONSDATA* consdata, /**< linear constraint */
2641  SCIP_VAR* cancelvar, /**< variable to calculate activity residual for */
2642  SCIP_Real* resactivity, /**< pointer to store the residual activity */
2643  SCIP_Bool isminresact, /**< should minimal or maximal residual activity be calculated? */
2644  SCIP_Bool useglobalbounds /**< should global or local bounds be used? */
2645  )
2646 {
2647  SCIP_VAR* var;
2648  SCIP_Real val;
2649  SCIP_Real lb;
2650  SCIP_Real ub;
2651  int v;
2652 
2653  assert(scip != NULL);
2654  assert(consdata != NULL);
2655  assert(cancelvar != NULL);
2656  assert(resactivity != NULL);
2658  *resactivity = 0.0;
2659 
2660  for( v = 0; v < consdata->nvars; ++v )
2661  {
2662  var = consdata->vars[v];
2663  assert(var != NULL);
2664  if( var == cancelvar )
2665  continue;
2666 
2667  val = consdata->vals[v];
2668 
2669  if( useglobalbounds )
2670  {
2671  lb = SCIPvarGetLbGlobal(var);
2672  ub = SCIPvarGetUbGlobal(var);
2673  }
2674  else
2675  {
2676  lb = SCIPvarGetLbLocal(var);
2677  ub = SCIPvarGetUbLocal(var);
2678  }
2679 
2680  assert(!SCIPisZero(scip, val));
2681  assert(SCIPisLE(scip, lb, ub));
2682 
2683  if( val > 0.0 )
2684  {
2685  if( isminresact )
2686  {
2687  assert(!SCIPisInfinity(scip, -lb));
2688  assert(!SCIPisHugeValue(scip, REALABS(val*lb)));
2689  *resactivity += val*lb;
2690  }
2691  else
2692  {
2693  assert(!SCIPisInfinity(scip, ub));
2694  assert(!SCIPisHugeValue(scip, REALABS(val*ub)));
2695  *resactivity += val*ub;
2696  }
2697  }
2698  else
2699  {
2700  if( isminresact)
2701  {
2702  assert(!SCIPisInfinity(scip, ub));
2703  assert(!SCIPisHugeValue(scip, REALABS(val*ub)));
2704  *resactivity += val*ub;
2705  }
2706  else
2707  {
2708  assert(!SCIPisInfinity(scip, -lb));
2709  assert(!SCIPisHugeValue(scip, REALABS(val*lb)));
2710  *resactivity += val*lb;
2711  }
2712  }
2713  }
2714  assert(!SCIPisInfinity(scip, *resactivity) && !SCIPisInfinity(scip, -(*resactivity)));
2715 }
2716 
2717 /** gets activity bounds for constraint after setting variable to zero */
2718 static
2720  SCIP* scip, /**< SCIP data structure */
2721  SCIP_CONSDATA* consdata, /**< linear constraint */
2722  SCIP_VAR* var, /**< variable to calculate activity residual for */
2723  SCIP_Real val, /**< coefficient value of variable in linear constraint */
2724  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2725  * relaxed acticities ignored, anyway? */
2726  SCIP_Real* minresactivity, /**< pointer to store the minimal residual activity */
2727  SCIP_Real* maxresactivity, /**< pointer to store the maximal residual activity */
2728  SCIP_Bool* minisrelax, /**< pointer to store whether the returned residual minactivity is just a
2729  * relaxation, i.e. <= the exact residual minactivity (in case of huge
2730  * contributions), or equal to the exact residual minactivity */
2731  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned residual maxactivity is just a
2732  * relaxation, i.e. <= the exact residual maxactivity (in case of huge
2733  * contributions), or equal to the exact residual minactivity */
2734  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2735  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
2736  )
2737 {
2738  SCIP_Real minactbound;
2739  SCIP_Real maxactbound;
2740  SCIP_Real absval;
2741 
2742  assert(scip != NULL);
2743  assert(consdata != NULL);
2744  assert(var != NULL);
2745  assert(minresactivity != NULL);
2746  assert(maxresactivity != NULL);
2747  assert(minisrelax != NULL);
2748  assert(maxisrelax != NULL);
2749  assert(isminsettoinfinity != NULL);
2750  assert(ismaxsettoinfinity != NULL);
2751 
2752  /* get activity bounds of linear constraint */
2753  if( !consdata->validactivities )
2754  {
2755  consdataCalcActivities(scip, consdata);
2756  assert(consdata->validminact);
2757  assert(consdata->validmaxact);
2758  }
2759  assert(consdata->minactivity < SCIP_INVALID);
2760  assert(consdata->maxactivity < SCIP_INVALID);
2761  assert(consdata->minactivityneginf >= 0);
2762  assert(consdata->minactivityposinf >= 0);
2763  assert(consdata->maxactivityneginf >= 0);
2764  assert(consdata->maxactivityposinf >= 0);
2765  assert(consdata->minactivityneghuge >= 0);
2766  assert(consdata->minactivityposhuge >= 0);
2767  assert(consdata->maxactivityneghuge >= 0);
2768  assert(consdata->maxactivityposhuge >= 0);
2769 
2770  if( val > 0.0 )
2771  {
2772  minactbound = SCIPvarGetLbLocal(var);
2773  maxactbound = SCIPvarGetUbLocal(var);
2774  absval = val;
2775  }
2776  else
2777  {
2778  minactbound = -SCIPvarGetUbLocal(var);
2779  maxactbound = -SCIPvarGetLbLocal(var);
2780  absval = -val;
2781  }
2782 
2783  /* get/compute minactivity by calling getMinActivity() with updated counters for infinite and huge values
2784  * and contribution of variable set to zero that has to be subtracted from finite part of activity
2785  */
2786  if( SCIPisInfinity(scip, minactbound) )
2787  {
2788  assert(consdata->minactivityposinf >= 1);
2789 
2790  getMinActivity(scip, consdata, consdata->minactivityposinf - 1, consdata->minactivityneginf,
2791  consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2792  minresactivity, minisrelax, isminsettoinfinity);
2793  }
2794  else if( SCIPisInfinity(scip, -minactbound) )
2795  {
2796  assert(consdata->minactivityneginf >= 1);
2797 
2798  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf - 1,
2799  consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2800  minresactivity, minisrelax, isminsettoinfinity);
2801  }
2802  else if( SCIPisHugeValue(scip, minactbound * absval) )
2803  {
2804  assert(consdata->minactivityposhuge >= 1);
2805 
2806  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2807  consdata->minactivityposhuge - 1, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2808  minresactivity, minisrelax, isminsettoinfinity);
2809  }
2810  else if( SCIPisHugeValue(scip, -minactbound * absval) )
2811  {
2812  assert(consdata->minactivityneghuge >= 1);
2813 
2814  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2815  consdata->minactivityposhuge, consdata->minactivityneghuge - 1, 0.0, FALSE, goodrelax,
2816  minresactivity, minisrelax, isminsettoinfinity);
2817  }
2818  else
2819  {
2820  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2821  consdata->minactivityposhuge, consdata->minactivityneghuge, absval * minactbound, FALSE, goodrelax,
2822  minresactivity, minisrelax, isminsettoinfinity);
2823  }
2824 
2825  /* get/compute maxactivity by calling getMaxActivity() with updated counters for infinite and huge values
2826  * and contribution of variable set to zero that has to be subtracted from finite part of activity
2827  */
2828  if( SCIPisInfinity(scip, -maxactbound) )
2829  {
2830  assert(consdata->maxactivityneginf >= 1);
2831 
2832  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf - 1,
2833  consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2834  maxresactivity, maxisrelax, ismaxsettoinfinity);
2835  }
2836  else if( SCIPisInfinity(scip, maxactbound) )
2837  {
2838  assert(consdata->maxactivityposinf >= 1);
2839 
2840  getMaxActivity(scip, consdata, consdata->maxactivityposinf - 1, consdata->maxactivityneginf,
2841  consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2842  maxresactivity, maxisrelax, ismaxsettoinfinity);
2843  }
2844  else if( SCIPisHugeValue(scip, absval * maxactbound) )
2845  {
2846  assert(consdata->maxactivityposhuge >= 1);
2847 
2848  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2849  consdata->maxactivityposhuge - 1, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2850  maxresactivity, maxisrelax, ismaxsettoinfinity);
2851  }
2852  else if( SCIPisHugeValue(scip, -absval * maxactbound) )
2853  {
2854  assert(consdata->maxactivityneghuge >= 1);
2855 
2856  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2857  consdata->maxactivityposhuge, consdata->maxactivityneghuge - 1, 0.0, FALSE, goodrelax,
2858  maxresactivity, maxisrelax, ismaxsettoinfinity);
2859  }
2860  else
2861  {
2862  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2863  consdata->maxactivityposhuge, consdata->maxactivityneghuge, absval * maxactbound, FALSE, goodrelax,
2864  maxresactivity, maxisrelax, ismaxsettoinfinity);
2865  }
2866 }
2867 
2868 /** gets global activity bounds for constraint */
2869 static
2871  SCIP* scip, /**< SCIP data structure */
2872  SCIP_CONSDATA* consdata, /**< linear constraint */
2873  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2874  * relaxed acticities ignored, anyway? */
2875  SCIP_Real* glbminactivity, /**< pointer to store the minimal activity, or NULL, if not needed */
2876  SCIP_Real* glbmaxactivity, /**< pointer to store the maximal activity, or NULL, if not needed */
2877  SCIP_Bool* minisrelax, /**< pointer to store whether the returned minactivity is just a relaxation,
2878  * i.e. <= the exact minactivity (in case of huge contributions),
2879  * or equal to the exact minimal activity */
2880  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned maxactivity is just a relaxation,
2881  * i.e. >= the exact maxactivity (in case of huge contributions),
2882  * or equal to the exact maximal activity */
2883  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2884  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
2885  )
2886 {
2887  assert(scip != NULL);
2888  assert(consdata != NULL);
2889  assert((glbminactivity != NULL && minisrelax != NULL && isminsettoinfinity != NULL)
2890  || (glbmaxactivity != NULL && maxisrelax != NULL && ismaxsettoinfinity != NULL));
2891 
2892  if( !consdata->validactivities )
2893  {
2894  consdataCalcActivities(scip, consdata);
2895  assert(consdata->validglbminact);
2896  assert(consdata->validglbmaxact);
2897  }
2898  assert(consdata->glbminactivity < SCIP_INVALID);
2899  assert(consdata->glbmaxactivity < SCIP_INVALID);
2900  assert(consdata->glbminactivityneginf >= 0);
2901  assert(consdata->glbminactivityposinf >= 0);
2902  assert(consdata->glbmaxactivityneginf >= 0);
2903  assert(consdata->glbmaxactivityposinf >= 0);
2904  assert(consdata->glbminactivityneghuge >= 0);
2905  assert(consdata->glbminactivityposhuge >= 0);
2906  assert(consdata->glbmaxactivityneghuge >= 0);
2907  assert(consdata->glbmaxactivityposhuge >= 0);
2908 
2909  if( glbminactivity != NULL )
2910  {
2911  assert(isminsettoinfinity != NULL);
2912  assert(minisrelax != NULL);
2913 
2914  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
2915  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
2916  glbminactivity, minisrelax, isminsettoinfinity);
2917  }
2918 
2919  if( glbmaxactivity != NULL )
2920  {
2921  assert(ismaxsettoinfinity != NULL);
2922  assert(maxisrelax != NULL);
2923 
2924  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
2925  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
2926  glbmaxactivity, maxisrelax, ismaxsettoinfinity);
2927  }
2928 }
2929 
2930 /** gets global activity bounds for constraint after setting variable to zero */
2931 static
2933  SCIP* scip, /**< SCIP data structure */
2934  SCIP_CONSDATA* consdata, /**< linear constraint */
2935  SCIP_VAR* var, /**< variable to calculate activity residual for */
2936  SCIP_Real val, /**< coefficient value of variable in linear constraint */
2937  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2938  * relaxed acticities ignored, anyway? */
2939  SCIP_Real* minresactivity, /**< pointer to store the minimal residual activity, or NULL, if not needed */
2940  SCIP_Real* maxresactivity, /**< pointer to store the maximal residual activity, or NULL, if not needed */
2941  SCIP_Bool* minisrelax, /**< pointer to store whether the returned residual minactivity is just a
2942  * relaxation, i.e. <= the exact residual minactivity (in case of huge
2943  * contributions), or equal to the exact residual minactivity */
2944  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned residual maxactivity is just a
2945  * relaxation, i.e. <= the exact residual maxactivity (in case of huge
2946  * contributions), or equal to the exact residual minactivity */
2947  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2948  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
2949  )
2950 {
2951  SCIP_Real minactbound;
2952  SCIP_Real maxactbound;
2953  SCIP_Real absval;
2954 
2955  assert(scip != NULL);
2956  assert(consdata != NULL);
2957  assert(var != NULL);
2958  assert((minresactivity != NULL && minisrelax != NULL && isminsettoinfinity != NULL )
2959  || (maxresactivity != NULL && maxisrelax != NULL && ismaxsettoinfinity != NULL));
2960 
2961  /* get activity bounds of linear constraint */
2962  if( !consdata->validactivities )
2963  consdataCalcActivities(scip, consdata);
2964 
2965  assert(consdata->glbminactivity < SCIP_INVALID);
2966  assert(consdata->glbmaxactivity < SCIP_INVALID);
2967  assert(consdata->glbminactivityneginf >= 0);
2968  assert(consdata->glbminactivityposinf >= 0);
2969  assert(consdata->glbmaxactivityneginf >= 0);
2970  assert(consdata->glbmaxactivityposinf >= 0);
2971 
2972  if( val > 0.0 )
2973  {
2974  minactbound = SCIPvarGetLbGlobal(var);
2975  maxactbound = SCIPvarGetUbGlobal(var);
2976  absval = val;
2977  }
2978  else
2979  {
2980  minactbound = -SCIPvarGetUbGlobal(var);
2981  maxactbound = -SCIPvarGetLbGlobal(var);
2982  absval = -val;
2983  }
2984 
2985  if( minresactivity != NULL )
2986  {
2987  assert(isminsettoinfinity != NULL);
2988  assert(minisrelax != NULL);
2989 
2990  /* get/compute minactivity by calling getMinActivity() with updated counters for infinite and huge values
2991  * and contribution of variable set to zero that has to be subtracted from finite part of activity
2992  */
2993  if( SCIPisInfinity(scip, minactbound) )
2994  {
2995  assert(consdata->glbminactivityposinf >= 1);
2996 
2997  getMinActivity(scip, consdata, consdata->glbminactivityposinf - 1, consdata->glbminactivityneginf,
2998  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
2999  minresactivity, minisrelax, isminsettoinfinity);
3000  }
3001  else if( SCIPisInfinity(scip, -minactbound) )
3002  {
3003  assert(consdata->glbminactivityneginf >= 1);
3004 
3005  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf - 1,
3006  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
3007  minresactivity, minisrelax, isminsettoinfinity);
3008  }
3009  else if( SCIPisHugeValue(scip, minactbound * absval) )
3010  {
3011  assert(consdata->glbminactivityposhuge >= 1);
3012 
3013  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
3014  consdata->glbminactivityposhuge - 1, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
3015  minresactivity, minisrelax, isminsettoinfinity);
3016  }
3017  else if( SCIPisHugeValue(scip, -minactbound * absval) )
3018  {
3019  assert(consdata->glbminactivityneghuge >= 1);
3020 
3021  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
3022  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge - 1, 0.0, TRUE, goodrelax,
3023  minresactivity, minisrelax, isminsettoinfinity);
3024  }
3025  else
3026  {
3027  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
3028  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, absval * minactbound, TRUE,
3029  goodrelax, minresactivity, minisrelax, isminsettoinfinity);
3030  }
3031  }
3032 
3033  if( maxresactivity != NULL )
3034  {
3035  assert(ismaxsettoinfinity != NULL);
3036  assert(maxisrelax != NULL);
3037 
3038  /* get/compute maxactivity by calling getMaxActivity() with updated counters for infinite and huge values
3039  * and contribution of variable set to zero that has to be subtracted from finite part of activity
3040  */
3041  if( SCIPisInfinity(scip, -maxactbound) )
3042  {
3043  assert(consdata->glbmaxactivityneginf >= 1);
3044 
3045  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf - 1,
3046  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
3047  maxresactivity, maxisrelax, ismaxsettoinfinity);
3048  }
3049  else if( SCIPisInfinity(scip, maxactbound) )
3050  {
3051  assert(consdata->glbmaxactivityposinf >= 1);
3052 
3053  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf - 1, consdata->glbmaxactivityneginf,
3054  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
3055  maxresactivity, maxisrelax, ismaxsettoinfinity);
3056  }
3057  else if( SCIPisHugeValue(scip, absval * maxactbound) )
3058  {
3059  assert(consdata->glbmaxactivityposhuge >= 1);
3060 
3061  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
3062  consdata->glbmaxactivityposhuge - 1, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
3063  maxresactivity, maxisrelax, ismaxsettoinfinity);
3064  }
3065  else if( SCIPisHugeValue(scip, -absval * maxactbound) )
3066  {
3067  assert(consdata->glbmaxactivityneghuge >= 1);
3068 
3069  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
3070  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge - 1, 0.0, TRUE, goodrelax,
3071  maxresactivity, maxisrelax, ismaxsettoinfinity);
3072  }
3073  else
3074  {
3075  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
3076  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, absval * maxactbound, TRUE,
3077  goodrelax, maxresactivity, maxisrelax, ismaxsettoinfinity);
3078  }
3079  }
3080 }
3081 
3082 /** calculates the activity of the linear constraint for given solution */
3083 static
3085  SCIP* scip, /**< SCIP data structure */
3086  SCIP_CONSDATA* consdata, /**< linear constraint data */
3087  SCIP_SOL* sol /**< solution to get activity for, NULL to current solution */
3088  )
3089 {
3090  SCIP_Real activity;
3091 
3092  assert(scip != NULL);
3093  assert(consdata != NULL);
3094 
3095  if( sol == NULL && !SCIPhasCurrentNodeLP(scip) )
3096  activity = consdataComputePseudoActivity(scip, consdata);
3097  else
3098  {
3099  SCIP_Real solval;
3100  int nposinf;
3101  int nneginf;
3102  SCIP_Bool negsign;
3103  int v;
3104 
3105  activity = 0.0;
3106  nposinf = 0;
3107  nneginf = 0;
3108 
3109  for( v = 0; v < consdata->nvars; ++v )
3110  {
3111  solval = SCIPgetSolVal(scip, sol, consdata->vars[v]);
3112 
3113  if( consdata->vals[v] < 0 )
3114  negsign = TRUE;
3115  else
3116  negsign = FALSE;
3117 
3118  if( (SCIPisInfinity(scip, solval) && !negsign) || (SCIPisInfinity(scip, -solval) && negsign) )
3119  ++nposinf;
3120  else if( (SCIPisInfinity(scip, solval) && negsign) || (SCIPisInfinity(scip, -solval) && !negsign) )
3121  ++nneginf;
3122  else
3123  activity += consdata->vals[v] * solval;
3124  }
3125  assert(nneginf >= 0 && nposinf >= 0);
3126 
3127  SCIPdebugMsg(scip, "activity of linear constraint: %.15g, %d positive infinity values, %d negative infinity values \n", activity, nposinf, nneginf);
3128 
3129  /* check for amount of infinity values and correct the activity */
3130  if( nposinf > 0 && nneginf > 0 )
3131  activity = (consdata->rhs + consdata->lhs) / 2;
3132  else if( nposinf > 0 )
3133  activity = SCIPinfinity(scip);
3134  else if( nneginf > 0 )
3135  activity = -SCIPinfinity(scip);
3136 
3137  SCIPdebugMsg(scip, "corrected activity of linear constraint: %.15g\n", activity);
3138  }
3139 
3140  if( activity == SCIP_INVALID ) /*lint !e777*/
3141  return activity;
3142  else if( activity < 0 )
3143  activity = MAX(activity, -SCIPinfinity(scip)); /*lint !e666*/
3144  else
3145  activity = MIN(activity, SCIPinfinity(scip)); /*lint !e666*/
3146 
3147  return activity;
3148 }
3149 
3150 /** calculates the feasibility of the linear constraint for given solution */
3151 static
3153  SCIP* scip, /**< SCIP data structure */
3154  SCIP_CONSDATA* consdata, /**< linear constraint data */
3155  SCIP_SOL* sol /**< solution to get feasibility for, NULL to current solution */
3156  )
3157 {
3158  SCIP_Real activity;
3159 
3160  assert(scip != NULL);
3161  assert(consdata != NULL);
3162 
3163  activity = consdataGetActivity(scip, consdata, sol);
3164 
3165  if( activity == SCIP_INVALID ) /*lint !e777*/
3166  return -SCIPinfinity(scip);
3167 
3168  return MIN(consdata->rhs - activity, activity - consdata->lhs);
3169 }
3170 
3171 /** updates bit signatures after adding a single coefficient */
3172 static
3174  SCIP_CONSDATA* consdata, /**< linear constraint data */
3175  int pos /**< position of coefficient to update signatures for */
3176  )
3177 {
3178  uint64_t varsignature;
3179  SCIP_Real lb;
3180  SCIP_Real ub;
3181  SCIP_Real val;
3182 
3183  assert(consdata != NULL);
3184  assert(consdata->validsignature);
3185 
3186  varsignature = SCIPhashSignature64(SCIPvarGetIndex(consdata->vars[pos]));
3187  lb = SCIPvarGetLbGlobal(consdata->vars[pos]);
3188  ub = SCIPvarGetUbGlobal(consdata->vars[pos]);
3189  val = consdata->vals[pos];
3190  if( (val > 0.0 && ub > 0.0) || (val < 0.0 && lb < 0.0) )
3191  consdata->possignature |= varsignature;
3192  if( (val > 0.0 && lb < 0.0) || (val < 0.0 && ub > 0.0) )
3193  consdata->negsignature |= varsignature;
3194 }
3195 
3196 /** calculates the bit signatures of the given constraint data */
3197 static
3199  SCIP_CONSDATA* consdata /**< linear constraint data */
3200  )
3201 {
3202  assert(consdata != NULL);
3203 
3204  if( !consdata->validsignature )
3205  {
3206  int i;
3207 
3208  consdata->validsignature = TRUE;
3209  consdata->possignature = 0;
3210  consdata->negsignature = 0;
3211  for( i = 0; i < consdata->nvars; ++i )
3212  consdataUpdateSignatures(consdata, i);
3213  }
3214 }
3215 
3216 /** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
3217 static
3218 SCIP_DECL_SORTINDCOMP(consdataCompVar)
3219 { /*lint --e{715}*/
3220  SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
3221  SCIP_VAR* var1;
3222  SCIP_VAR* var2;
3223 
3224  assert(consdata != NULL);
3225  assert(0 <= ind1 && ind1 < consdata->nvars);
3226  assert(0 <= ind2 && ind2 < consdata->nvars);
3227 
3228  var1 = consdata->vars[ind1];
3229  var2 = consdata->vars[ind2];
3230 
3231  /* exactly one variable is binary */
3232  if( SCIPvarIsBinary(var1) != SCIPvarIsBinary(var2) )
3233  {
3234  return (SCIPvarIsBinary(var1) ? -1 : +1);
3235  }
3236  /* both variables are binary */
3237  else if( SCIPvarIsBinary(var1) )
3238  {
3239  return SCIPvarCompare(var1, var2);
3240  }
3241  else
3242  {
3243  SCIP_VARTYPE vartype1 = SCIPvarGetType(var1);
3244  SCIP_VARTYPE vartype2 = SCIPvarGetType(var2);
3245 
3246  if( vartype1 < vartype2 )
3247  return -1;
3248  else if( vartype1 > vartype2 )
3249  return +1;
3250  else
3251  return SCIPvarCompare(var1, var2);
3252  }
3253 }
3254 
3255 /** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
3256 static
3257 SCIP_DECL_SORTINDCOMP(consdataCompVarProp)
3258 { /*lint --e{715}*/
3259  SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
3260  SCIP_VAR* var1;
3261  SCIP_VAR* var2;
3262 
3263  assert(consdata != NULL);
3264  assert(0 <= ind1 && ind1 < consdata->nvars);
3265  assert(0 <= ind2 && ind2 < consdata->nvars);
3266 
3267  var1 = consdata->vars[ind1];
3268  var2 = consdata->vars[ind2];
3269 
3270  /* exactly one variable is binary */
3271  if( SCIPvarIsBinary(var1) != SCIPvarIsBinary(var2) )
3272  {
3273  return (SCIPvarIsBinary(var1) ? -1 : +1);
3274  }
3275  /* both variables are binary */
3276  else if( SCIPvarIsBinary(var1) )
3277  {
3278  SCIP_Real abscoef1 = REALABS(consdata->vals[ind1]);
3279  SCIP_Real abscoef2 = REALABS(consdata->vals[ind2]);
3280 
3281  if( EPSGT(abscoef1, abscoef2, 1e-9) )
3282  return -1;
3283  else if( EPSGT(abscoef2, abscoef1, 1e-9) )
3284  return +1;
3285  else
3286  return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
3287  }
3288  else
3289  {
3290  SCIP_VARTYPE vartype1 = SCIPvarGetType(var1);
3291  SCIP_VARTYPE vartype2 = SCIPvarGetType(var2);
3292 
3293  if( vartype1 < vartype2 )
3294  {
3295  return -1;
3296  }
3297  else if( vartype1 > vartype2 )
3298  {
3299  return +1;
3300  }
3301  else
3302  {
3303  /* both variables are continuous */
3304  if( !SCIPvarIsIntegral(var1) )
3305  {
3306  assert(!SCIPvarIsIntegral(var2));
3307  return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
3308  }
3309  else
3310  {
3311  SCIP_Real abscont1 = REALABS(consdata->vals[ind1] * (SCIPvarGetUbGlobal(var1) - SCIPvarGetLbGlobal(var1)));
3312  SCIP_Real abscont2 = REALABS(consdata->vals[ind2] * (SCIPvarGetUbGlobal(var2) - SCIPvarGetLbGlobal(var2)));
3313 
3314  if( EPSGT(abscont1, abscont2, 1e-9) )
3315  return -1;
3316  else if( EPSGT(abscont2, abscont1, 1e-9) )
3317  return +1;
3318  else
3319  return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
3320  }
3321  }
3322  }
3323 }
3324 
3325 /** permutes the constraint's variables according to a given permutation. */
3326 static
3327 void permSortConsdata(
3328  SCIP_CONSDATA* consdata, /**< the constraint data */
3329  int* perm, /**< the target permutation */
3330  int nvars /**< the number of variables */
3331  )
3332 { /*lint --e{715}*/
3333  SCIP_VAR* varv;
3334  SCIP_EVENTDATA* eventdatav;
3335  SCIP_Real valv;
3336  int v;
3337  int i;
3338  int nexti;
3339 
3340  assert(perm != NULL);
3341  assert(consdata != NULL);
3342 
3343  /* permute the variables in the linear constraint according to the target permutation */
3344  eventdatav = NULL;
3345  for( v = 0; v < nvars; ++v )
3346  {
3347  if( perm[v] != v )
3348  {
3349  varv = consdata->vars[v];
3350  valv = consdata->vals[v];
3351  if( consdata->eventdata != NULL )
3352  eventdatav = consdata->eventdata[v];
3353  i = v;
3354  do
3355  {
3356  assert(0 <= perm[i] && perm[i] < nvars);
3357  assert(perm[i] != i);
3358  consdata->vars[i] = consdata->vars[perm[i]];
3359  consdata->vals[i] = consdata->vals[perm[i]];
3360  if( consdata->eventdata != NULL )
3361  {
3362  consdata->eventdata[i] = consdata->eventdata[perm[i]];
3363  consdata->eventdata[i]->varpos = i;
3364  }
3365  nexti = perm[i];
3366  perm[i] = i;
3367  i = nexti;
3368  }
3369  while( perm[i] != v );
3370  consdata->vars[i] = varv;
3371  consdata->vals[i] = valv;
3372  if( consdata->eventdata != NULL )
3373  {
3374  consdata->eventdata[i] = eventdatav;
3375  consdata->eventdata[i]->varpos = i;
3376  }
3377  perm[i] = i;
3378  }
3379  }
3380 #ifdef SCIP_DEBUG
3381  /* check sorting */
3382  for( v = 0; v < nvars; ++v )
3383  {
3384  assert(perm[v] == v);
3385  assert(consdata->eventdata == NULL || consdata->eventdata[v]->varpos == v);
3386  }
3387 #endif
3388 }
3389 
3390 /** sorts linear constraint's variables depending on the stage of the solving process:
3391  * - during PRESOLVING
3392  * sorts variables by binaries, integers, implicit integers, and continuous variables,
3393  * and the variables of the same type by non-decreasing variable index
3394  *
3395  * - during SOLVING
3396  * sorts variables of the remaining problem by binaries, integers, implicit integers, and continuous variables,
3397  * and binary and integer variables by their global max activity delta (within each group),
3398  * ties within a group are broken by problem index of the variable.
3399  *
3400  * This fastens the propagation time of the constraint handler.
3401  */
3402 static
3404  SCIP* scip, /**< SCIP data structure */
3405  SCIP_CONSDATA* consdata /**< linear constraint data */
3406  )
3407 {
3408  assert(scip != NULL);
3409  assert(consdata != NULL);
3410 
3411  /* check if there are variables for sorting */
3412  if( consdata->nvars <= 1 )
3413  {
3414  consdata->indexsorted = TRUE;
3415  consdata->coefsorted = TRUE;
3416  consdata->nbinvars = (consdata->nvars == 1 ? (int)SCIPvarIsBinary(consdata->vars[0]) : 0);
3417  }
3418  else if( (!consdata->indexsorted && SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE)
3419  || (!consdata->coefsorted && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE) )
3420  {
3421  int* perm;
3422  int v;
3423 
3424  /* get temporary memory to store the sorted permutation */
3425  SCIP_CALL( SCIPallocBufferArray(scip, &perm, consdata->nvars) );
3426 
3427  /* call sorting method */
3428  if( SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE )
3429  SCIPsort(perm, consdataCompVar, (void*)consdata, consdata->nvars);
3430  else
3431  SCIPsort(perm, consdataCompVarProp, (void*)consdata, consdata->nvars);
3432 
3433  permSortConsdata(consdata, perm, consdata->nvars);
3434 
3435  /* free temporary memory */
3436  SCIPfreeBufferArray(scip, &perm);
3437 
3438  if( SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE )
3439  {
3440  consdata->indexsorted = FALSE;
3441  consdata->coefsorted = TRUE;
3442 
3443  /* count binary variables in the sorted vars array */
3444  consdata->nbinvars = 0;
3445  for( v = 0; v < consdata->nvars; ++v )
3446  {
3447  if( SCIPvarIsBinary(consdata->vars[v]) )
3448  ++consdata->nbinvars;
3449  else
3450  break;
3451  }
3452  }
3453  else
3454  {
3455  consdata->indexsorted = TRUE;
3456  consdata->coefsorted = FALSE;
3457  }
3458  }
3459 
3460  return SCIP_OKAY;
3461 }
3462 
3463 
3464 /*
3465  * local linear constraint handler methods
3466  */
3467 
3468 /** sets left hand side of linear constraint */
3469 static
3471  SCIP* scip, /**< SCIP data structure */
3472  SCIP_CONS* cons, /**< linear constraint */
3473  SCIP_Real lhs /**< new left hand side */
3474  )
3475 {
3476  SCIP_CONSDATA* consdata;
3477  SCIP_Bool locked;
3478  int i;
3479 
3480  assert(scip != NULL);
3481  assert(cons != NULL);
3482  assert(!SCIPisInfinity(scip, lhs));
3483 
3484  /* adjust value to not be smaller than -inf */
3485  if ( SCIPisInfinity(scip, -lhs) )
3486  lhs = -SCIPinfinity(scip);
3487 
3488  consdata = SCIPconsGetData(cons);
3489  assert(consdata != NULL);
3490  assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
3491  assert(!SCIPisInfinity(scip, consdata->lhs));
3492 
3493  /* check whether the side is not changed */
3494  if( SCIPisEQ(scip, consdata->lhs, lhs) )
3495  return SCIP_OKAY;
3496 
3497  /* ensure that rhs >= lhs is satisfied without numerical tolerance */
3498  if( SCIPisEQ(scip, lhs, consdata->rhs) )
3499  {
3500  consdata->rhs = lhs;
3501  assert(consdata->row == NULL);
3502  }
3503 
3504  locked = FALSE;
3505  for( i = 0; i < NLOCKTYPES && !locked; i++ )
3506  locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
3507 
3508  /* if necessary, update the rounding locks of variables */
3509  if( locked )
3510  {
3511  if( SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, -lhs) )
3512  {
3513  SCIP_VAR** vars;
3514  SCIP_Real* vals;
3515  int v;
3516 
3517  /* the left hand side switched from -infinity to a non-infinite value -> install rounding locks */
3518  vars = consdata->vars;
3519  vals = consdata->vals;
3520 
3521  for( v = 0; v < consdata->nvars; ++v )
3522  {
3523  assert(vars[v] != NULL);
3524  assert(!SCIPisZero(scip, vals[v]));
3525 
3526  if( SCIPisPositive(scip, vals[v]) )
3527  {
3528  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3529  }
3530  else
3531  {
3532  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3533  }
3534  }
3535  }
3536  else if( !SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, -lhs) )
3537  {
3538  SCIP_VAR** vars;
3539  SCIP_Real* vals;
3540  int v;
3541 
3542  /* the left hand side switched from a non-infinite value to -infinity -> remove rounding locks */
3543  vars = consdata->vars;
3544  vals = consdata->vals;
3545 
3546  for( v = 0; v < consdata->nvars; ++v )
3547  {
3548  assert(vars[v] != NULL);
3549  assert(!SCIPisZero(scip, vals[v]));
3550 
3551  if( SCIPisPositive(scip, vals[v]) )
3552  {
3553  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3554  }
3555  else
3556  {
3557  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3558  }
3559  }
3560  }
3561  }
3562 
3563  /* 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 */
3564  if( !SCIPisInfinity(scip, -lhs) && SCIPisGT(scip, lhs, consdata->lhs) )
3565  {
3566  consdata->boundstightened = 0;
3567  consdata->presolved = FALSE;
3568  consdata->cliquesadded = FALSE;
3569  consdata->implsadded = FALSE;
3570 
3571  /* mark the constraint for propagation */
3572  if( SCIPconsIsTransformed(cons) )
3573  {
3574  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3575  }
3576  }
3577 
3578  /* set new left hand side and update constraint data */
3579  consdata->lhs = lhs;
3580  consdata->changed = TRUE;
3581  consdata->normalized = FALSE;
3582  consdata->upgradetried = FALSE;
3583  consdata->rangedrowpropagated = 0;
3584 
3585  /* update the lhs of the LP row */
3586  if( consdata->row != NULL )
3587  {
3588  SCIP_CALL( SCIPchgRowLhs(scip, consdata->row, lhs) );
3589  }
3590 
3591  return SCIP_OKAY;
3592 }
3593 
3594 /** sets right hand side of linear constraint */
3595 static
3597  SCIP* scip, /**< SCIP data structure */
3598  SCIP_CONS* cons, /**< linear constraint */
3599  SCIP_Real rhs /**< new right hand side */
3600  )
3601 {
3602  SCIP_CONSDATA* consdata;
3603  SCIP_Bool locked;
3604  int i;
3605 
3606  assert(scip != NULL);
3607  assert(cons != NULL);
3608  assert(!SCIPisInfinity(scip, -rhs));
3609 
3610  /* adjust value to not be larger than inf */
3611  if ( SCIPisInfinity(scip, rhs) )
3612  rhs = SCIPinfinity(scip);
3613 
3614  consdata = SCIPconsGetData(cons);
3615  assert(consdata != NULL);
3616  assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
3617  assert(!SCIPisInfinity(scip, -consdata->rhs));
3618 
3619  /* check whether the side is not changed */
3620  if( SCIPisEQ(scip, consdata->rhs, rhs) )
3621  return SCIP_OKAY;
3622 
3623  /* ensure that rhs >= lhs is satisfied without numerical tolerance */
3624  if( SCIPisEQ(scip, rhs, consdata->lhs) )
3625  {
3626  consdata->lhs = rhs;
3627  assert(consdata->row == NULL);
3628  }
3629 
3630  locked = FALSE;
3631  for( i = 0; i < NLOCKTYPES && !locked; i++ )
3632  locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
3633 
3634  /* if necessary, update the rounding locks of variables */
3635  if( locked )
3636  {
3637  assert(SCIPconsIsTransformed(cons));
3638 
3639  if( SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, rhs) )
3640  {
3641  SCIP_VAR** vars;
3642  SCIP_Real* vals;
3643  int v;
3644 
3645  /* the right hand side switched from infinity to a non-infinite value -> install rounding locks */
3646  vars = consdata->vars;
3647  vals = consdata->vals;
3648 
3649  for( v = 0; v < consdata->nvars; ++v )
3650  {
3651  assert(vars[v] != NULL);
3652  assert(!SCIPisZero(scip, vals[v]));
3653 
3654  if( SCIPisPositive(scip, vals[v]) )
3655  {
3656  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3657  }
3658  else
3659  {
3660  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3661  }
3662  }
3663  }
3664  else if( !SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, rhs) )
3665  {
3666  SCIP_VAR** vars;
3667  SCIP_Real* vals;
3668  int v;
3669 
3670  /* the right hand side switched from a non-infinite value to infinity -> remove rounding locks */
3671  vars = consdata->vars;
3672  vals = consdata->vals;
3673 
3674  for( v = 0; v < consdata->nvars; ++v )
3675  {
3676  assert(vars[v] != NULL);
3677  assert(!SCIPisZero(scip, vals[v]));
3678 
3679  if( SCIPisPositive(scip, vals[v]) )
3680  {
3681  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3682  }
3683  else
3684  {
3685  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3686  }
3687  }
3688  }
3689  }
3690 
3691  /* 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 */
3692  if( !SCIPisInfinity(scip, rhs) && SCIPisLT(scip, rhs, consdata->rhs) )
3693  {
3694  consdata->boundstightened = 0;
3695  consdata->presolved = FALSE;
3696  consdata->cliquesadded = FALSE;
3697  consdata->implsadded = FALSE;
3698 
3699  /* mark the constraint for propagation */
3700  if( SCIPconsIsTransformed(cons) )
3701  {
3702  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3703  }
3704  }
3705 
3706  /* set new right hand side and update constraint data */
3707  consdata->rhs = rhs;
3708  consdata->changed = TRUE;
3709  consdata->normalized = FALSE;
3710  consdata->upgradetried = FALSE;
3711  consdata->rangedrowpropagated = 0;
3712 
3713  /* update the rhs of the LP row */
3714  if( consdata->row != NULL )
3715  {
3716  SCIP_CALL( SCIPchgRowRhs(scip, consdata->row, rhs) );
3717  }
3718 
3719  return SCIP_OKAY;
3720 }
3721 
3722 /** adds coefficient in linear constraint */
3723 static
3725  SCIP* scip, /**< SCIP data structure */
3726  SCIP_CONS* cons, /**< linear constraint */
3727  SCIP_VAR* var, /**< variable of constraint entry */
3728  SCIP_Real val /**< coefficient of constraint entry */
3729  )
3730 {
3731  SCIP_CONSDATA* consdata;
3732  SCIP_Bool transformed;
3733 
3734  assert(scip != NULL);
3735  assert(cons != NULL);
3736  assert(var != NULL);
3737 
3738  /* relaxation-only variables must not be used in checked or enforced constraints */
3739  assert(!SCIPvarIsRelaxationOnly(var) || (!SCIPconsIsChecked(cons) && !SCIPconsIsEnforced(cons)));
3740 
3741  /* ignore coefficient if it is nearly zero */
3742  if( SCIPisZero(scip, val) )
3743  return SCIP_OKAY;
3744 
3745  consdata = SCIPconsGetData(cons);
3746  assert(consdata != NULL);
3747 
3748  /* are we in the transformed problem? */
3749  transformed = SCIPconsIsTransformed(cons);
3750 
3751  /* always use transformed variables in transformed constraints */
3752  if( transformed )
3753  {
3754  SCIP_CALL( SCIPgetTransformedVar(scip, var, &var) );
3755  }
3756  assert(var != NULL);
3757  assert(transformed == SCIPvarIsTransformed(var));
3758 
3759  SCIP_CALL( consdataEnsureVarsSize(scip, consdata, consdata->nvars+1) );
3760  consdata->vars[consdata->nvars] = var;
3761  consdata->vals[consdata->nvars] = val;
3762  consdata->nvars++;
3763 
3764  /* capture variable */
3765  SCIP_CALL( SCIPcaptureVar(scip, var) );
3766 
3767  /* if we are in transformed problem, the variable needs an additional event data */
3768  if( transformed )
3769  {
3770  if( consdata->eventdata != NULL )
3771  {
3772  SCIP_CONSHDLR* conshdlr;
3773  SCIP_CONSHDLRDATA* conshdlrdata;
3774 
3775  /* check for event handler */
3776  conshdlr = SCIPconsGetHdlr(cons);
3777  conshdlrdata = SCIPconshdlrGetData(conshdlr);
3778  assert(conshdlrdata != NULL);
3779  assert(conshdlrdata->eventhdlr != NULL);
3780 
3781  /* initialize eventdata array */
3782  consdata->eventdata[consdata->nvars-1] = NULL;
3783 
3784  /* catch bound change events of variable */
3785  SCIP_CALL( consCatchEvent(scip, cons, conshdlrdata->eventhdlr, consdata->nvars-1) );
3786  }
3787 
3788  /* update minimum and maximum activities */
3789  consdataUpdateAddCoef(scip, consdata, var, val, FALSE);
3790 
3791  /* update maximum activity delta */
3792  if( !SCIPisInfinity(scip, consdata->maxactdelta ) )
3793  {
3794  SCIP_Real lb;
3795  SCIP_Real ub;
3796 
3797  lb = SCIPvarGetLbLocal(var);
3798  ub = SCIPvarGetUbLocal(var);
3799 
3800  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
3801  {
3802  consdata->maxactdelta = SCIPinfinity(scip);
3803  consdata->maxactdeltavar = var;
3804  }
3805  else
3806  {
3807  SCIP_Real domain = ub - lb;
3808  SCIP_Real delta = REALABS(val) * domain;
3809 
3810  if( delta > consdata->maxactdelta )
3811  {
3812  consdata->maxactdelta = delta;
3813  consdata->maxactdeltavar = var;
3814  }
3815  }
3816  }
3817  }
3818 
3819  /* install rounding locks for new variable */
3820  SCIP_CALL( lockRounding(scip, cons, var, val) );
3821 
3822  /* mark the constraint for propagation */
3823  if( transformed )
3824  {
3825  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3826  }
3827 
3828  consdata->boundstightened = 0;
3829  consdata->presolved = FALSE;
3830  consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(var);
3831 
3832  if( consdata->validsignature )
3833  consdataUpdateSignatures(consdata, consdata->nvars-1);
3834 
3835  consdata->changed = TRUE;
3836  consdata->normalized = FALSE;
3837  consdata->upgradetried = FALSE;
3838  consdata->cliquesadded = FALSE;
3839  consdata->implsadded = FALSE;
3840  consdata->rangedrowpropagated = 0;
3841 
3842  if( consdata->nvars == 1 )
3843  {
3844  consdata->indexsorted = TRUE;
3845  consdata->coefsorted = TRUE;
3846  consdata->merged = TRUE;
3847  }
3848  else
3849  {
3850  consdata->merged = FALSE;
3851 
3852  if( SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE )
3853  {
3854  consdata->indexsorted = consdata->indexsorted && (consdataCompVar((void*)consdata, consdata->nvars-2, consdata->nvars-1) <= 0);
3855  consdata->coefsorted = FALSE;
3856  }
3857  else
3858  {
3859  consdata->indexsorted = FALSE;
3860  consdata->coefsorted = consdata->coefsorted && (consdataCompVarProp((void*)consdata, consdata->nvars-2, consdata->nvars-1) <= 0);
3861  }
3862  }
3863 
3864  /* update hascontvar and hasnonbinvar flags */
3865  if( consdata->hasnonbinvalid && !consdata->hascontvar )
3866  {
3867  SCIP_VARTYPE vartype = SCIPvarGetType(var);
3868 
3869  if( vartype != SCIP_VARTYPE_BINARY )
3870  {
3871  consdata->hasnonbinvar = TRUE;
3872 
3873  if( vartype == SCIP_VARTYPE_CONTINUOUS )
3874  consdata->hascontvar = TRUE;
3875  }
3876  }
3877 
3878  /* add the new coefficient to the LP row */
3879  if( consdata->row != NULL )
3880  {
3881  SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, var, val) );
3882  }
3883 
3884  return SCIP_OKAY;
3885 }
3886 
3887 /** deletes coefficient at given position from linear constraint data */
3888 static
3890  SCIP* scip, /**< SCIP data structure */
3891  SCIP_CONS* cons, /**< linear constraint */
3892  int pos /**< position of coefficient to delete */
3893  )
3894 {
3895  SCIP_CONSDATA* consdata;
3896  SCIP_VAR* var;
3897  SCIP_Real val;
3898 
3899  assert(scip != NULL);
3900  assert(cons != NULL);
3901 
3902  consdata = SCIPconsGetData(cons);
3903  assert(consdata != NULL);
3904  assert(0 <= pos && pos < consdata->nvars);
3905 
3906  var = consdata->vars[pos];
3907  val = consdata->vals[pos];
3908  assert(var != NULL);
3909 
3910  /* remove rounding locks for deleted variable */
3911  SCIP_CALL( unlockRounding(scip, cons, var, val) );
3912 
3913  /* if we are in transformed problem, delete the event data of the variable */
3914  if( SCIPconsIsTransformed(cons) )
3915  {
3916  SCIP_CONSHDLR* conshdlr;
3917  SCIP_CONSHDLRDATA* conshdlrdata;
3918 
3919  /* check for event handler */
3920  conshdlr = SCIPconsGetHdlr(cons);
3921  conshdlrdata = SCIPconshdlrGetData(conshdlr);
3922  assert(conshdlrdata != NULL);
3923  assert(conshdlrdata->eventhdlr != NULL);
3924 
3925  /* drop bound change events of variable */
3926  if( consdata->eventdata != NULL )
3927  {
3928  SCIP_CALL( consDropEvent(scip, cons, conshdlrdata->eventhdlr, pos) );
3929  assert(consdata->eventdata[pos] == NULL);
3930  }
3931  }
3932 
3933  /* move the last variable to the free slot */
3934  if( pos != consdata->nvars - 1 )
3935  {
3936  consdata->vars[pos] = consdata->vars[consdata->nvars-1];
3937  consdata->vals[pos] = consdata->vals[consdata->nvars-1];
3938 
3939  if( consdata->eventdata != NULL )
3940  {
3941  consdata->eventdata[pos] = consdata->eventdata[consdata->nvars-1];
3942  assert(consdata->eventdata[pos] != NULL);
3943  consdata->eventdata[pos]->varpos = pos;
3944  }
3945 
3946  consdata->indexsorted = consdata->indexsorted && (pos + 2 >= consdata->nvars);
3947  consdata->coefsorted = consdata->coefsorted && (pos + 2 >= consdata->nvars);
3948  }
3949  consdata->nvars--;
3950 
3951  /* if at most one variable is left, the activities should be recalculated (to correspond exactly to the bounds
3952  * of the remaining variable, or give exactly 0.0)
3953  */
3954  if( consdata->nvars <= 1 )
3955  consdataInvalidateActivities(consdata);
3956  else
3957  {
3958  if( SCIPconsIsTransformed(cons) )
3959  {
3960  /* if we are in transformed problem, update minimum and maximum activities */
3961  consdataUpdateDelCoef(scip, consdata, var, val, TRUE);
3962 
3963  /* if the variable defining the maximal activity delta was removed from the constraint, the maximal activity
3964  * delta needs to be recalculated on the next real propagation
3965  */
3966  if( consdata->maxactdeltavar == var )
3967  {
3968  consdata->maxactdelta = SCIP_INVALID;
3969  consdata->maxactdeltavar = NULL;
3970  }
3971  }
3972  }
3973 
3974  /* mark the constraint for propagation */
3975  if( SCIPconsIsTransformed(cons) )
3976  {
3977  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3978  }
3979 
3980  consdata->boundstightened = 0;
3981  consdata->presolved = FALSE;
3982  consdata->validsignature = FALSE;
3983  consdata->changed = TRUE;
3984  consdata->normalized = FALSE;
3985  consdata->upgradetried = FALSE;
3986  consdata->cliquesadded = FALSE;
3987  consdata->implsadded = FALSE;
3988  consdata->rangedrowpropagated = 0;
3989 
3990  /* check if hasnonbinvar flag might be incorrect now */
3991  if( consdata->hasnonbinvar && SCIPvarGetType(var) != SCIP_VARTYPE_BINARY )
3992  {
3993  consdata->hasnonbinvalid = FALSE;
3994  }
3995 
3996  /* delete coefficient from the LP row */
3997  if( consdata->row != NULL )
3998  {
3999  SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, var, -val) );
4000  }
4001 
4002  /* release variable */
4003  SCIP_CALL( SCIPreleaseVar(scip, &var) );
4004 
4005  return SCIP_OKAY;
4006 }
4007 
4008 /** changes coefficient value at given position of linear constraint data */
4009 static
4011  SCIP* scip, /**< SCIP data structure */
4012  SCIP_CONS* cons, /**< linear constraint */
4013  int pos, /**< position of coefficient to delete */
4014  SCIP_Real newval /**< new value of coefficient */
4015  )
4016 {
4017  SCIP_CONSDATA* consdata;
4018  SCIP_VAR* var;
4019  SCIP_Real val;
4020  SCIP_Bool locked;
4021  int i;
4022 
4023  assert(scip != NULL);
4024  assert(cons != NULL);
4025  assert(!SCIPisZero(scip, newval));
4026 
4027  consdata = SCIPconsGetData(cons);
4028  assert(consdata != NULL);
4029  assert(0 <= pos && pos < consdata->nvars);
4030  assert(!SCIPisZero(scip, newval));
4031 
4032  var = consdata->vars[pos];
4033  val = consdata->vals[pos];
4034  assert(var != NULL);
4035  assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(var));
4036 
4037  locked = FALSE;
4038  for( i = 0; i < NLOCKTYPES && !locked; i++ )
4039  locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
4040 
4041  /* if necessary, update the rounding locks of the variable */
4042  if( locked && newval * val < 0.0 )
4043  {
4044  assert(SCIPconsIsTransformed(cons));
4045 
4046  /* remove rounding locks for variable with old coefficient */
4047  SCIP_CALL( unlockRounding(scip, cons, var, val) );
4048 
4049  /* install rounding locks for variable with new coefficient */
4050  SCIP_CALL( lockRounding(scip, cons, var, newval) );
4051  }
4052 
4053  /* change the value */
4054  consdata->vals[pos] = newval;
4055 
4056  if( consdata->coefsorted )
4057  {
4058  if( pos > 0 )
4059  consdata->coefsorted = (consdataCompVarProp((void*)consdata, pos - 1, pos) <= 0);
4060  if( consdata->coefsorted && pos < consdata->nvars - 1 )
4061  consdata->coefsorted = (consdataCompVarProp((void*)consdata, pos, pos + 1) <= 0);
4062  }
4063 
4064  /* update minimum and maximum activities */
4065  if( SCIPconsIsTransformed(cons) )
4066  consdataUpdateChgCoef(scip, consdata, var, val, newval, TRUE);
4067 
4068  /* mark the constraint for propagation */
4069  if( SCIPconsIsTransformed(cons) )
4070  {
4071  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
4072  }
4073 
4074  consdata->boundstightened = 0;
4075  consdata->presolved = FALSE;
4076  consdata->validsignature = consdata->validsignature && (newval * val > 0.0);
4077  consdata->changed = TRUE;
4078  consdata->normalized = FALSE;
4079  consdata->upgradetried = FALSE;
4080  consdata->cliquesadded = FALSE;
4081  consdata->implsadded = FALSE;
4082  consdata->rangedrowpropagated = 0;
4083 
4084  return SCIP_OKAY;
4085 }
4086 
4087 /** scales a linear constraint with a constant scalar */
4088 static
4090  SCIP* scip, /**< SCIP data structure */
4091  SCIP_CONS* cons, /**< linear constraint to scale */
4092  SCIP_Real scalar /**< value to scale constraint with */
4093  )
4094 {
4095  SCIP_CONSDATA* consdata;
4096  SCIP_Real newval;
4097  SCIP_Real absscalar;
4098  int i;
4099 
4100  assert(scip != NULL);
4101  assert(cons != NULL);
4102 
4103  consdata = SCIPconsGetData(cons);
4104  assert(consdata != NULL);
4105  assert(consdata->row == NULL);
4106  assert(!SCIPisEQ(scip, scalar, 1.0));
4107 
4108  if( (!SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, -consdata->lhs * scalar))
4109  || (!SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, consdata->rhs * scalar)) )
4110  {
4111  SCIPwarningMessage(scip, "skipped scaling for linear constraint <%s> to avoid numerical troubles (scalar: %.15g)\n",
4112  SCIPconsGetName(cons), scalar);
4113 
4114  return SCIP_OKAY;
4115  }
4116 
4117  /* scale the coefficients */
4118  for( i = consdata->nvars - 1; i >= 0; --i )
4119  {
4120  newval = scalar * consdata->vals[i];
4121 
4122  /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasFloor, we add an additional 0.5 before
4123  * flooring down our new value
4124  */
4125  if( SCIPisScalingIntegral(scip, consdata->vals[i], scalar) )
4126  newval = SCIPfeasFloor(scip, newval + 0.5);
4127 
4128  if( SCIPisZero(scip, newval) )
4129  {
4130  SCIPwarningMessage(scip, "coefficient %.15g of variable <%s> in linear constraint <%s> scaled to zero (scalar: %.15g)\n",
4131  consdata->vals[i], SCIPvarGetName(consdata->vars[i]), SCIPconsGetName(cons), scalar);
4132  SCIP_CALL( delCoefPos(scip, cons, i) );
4133  }
4134  else
4135  consdata->vals[i] = newval;
4136  }
4137 
4138  /* scale the sides */
4139  if( scalar < 0.0 )
4140  {
4141  SCIP_Real lhs;
4142 
4143  lhs = consdata->lhs;
4144  consdata->lhs = -consdata->rhs;
4145  consdata->rhs = -lhs;
4146  }
4147  absscalar = REALABS(scalar);
4148  if( !SCIPisInfinity(scip, -consdata->lhs) )
4149  {
4150  newval = absscalar * consdata->lhs;
4151 
4152  /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasFloor, we add an additional 0.5 before
4153  * flooring down our new value
4154  */
4155  if( SCIPisScalingIntegral(scip, consdata->lhs, absscalar) )
4156  consdata->lhs = SCIPfeasFloor(scip, newval + 0.5);
4157  else
4158  consdata->lhs = newval;
4159  }
4160  if( !SCIPisInfinity(scip, consdata->rhs) )
4161  {
4162  newval = absscalar * consdata->rhs;
4163 
4164  /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasCeil, we subtract 0.5 before ceiling up
4165  * our new value
4166  */
4167  if( SCIPisScalingIntegral(scip, consdata->rhs, absscalar) )
4168  consdata->rhs = SCIPfeasCeil(scip, newval - 0.5);
4169  else
4170  consdata->rhs = newval;
4171  }
4172 
4173  consdataInvalidateActivities(consdata);
4174  consdata->cliquesadded = FALSE;
4175  consdata->implsadded = FALSE;
4176 
4177  return SCIP_OKAY;
4178 }
4179 
4180 /** perform deletion of variables in all constraints of the constraint handler */
4181 static
4183  SCIP* scip, /**< SCIP data structure */
4184  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4185  SCIP_CONS** conss, /**< array of constraints */
4186  int nconss /**< number of constraints */
4187  )
4188 {
4189  SCIP_CONSDATA* consdata;
4190  int i;
4191  int v;
4192 
4193  assert(scip != NULL);
4194  assert(conshdlr != NULL);
4195  assert(conss != NULL);
4196  assert(nconss >= 0);
4197  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
4198 
4199  /* iterate over all constraints */
4200  for( i = 0; i < nconss; i++ )
4201  {
4202  consdata = SCIPconsGetData(conss[i]);
4203 
4204  /* constraint is marked, that some of its variables were deleted */
4205  if( consdata->varsdeleted )
4206  {
4207  /* iterate over all variables of the constraint and delete them from the constraint */
4208  for( v = consdata->nvars - 1; v >= 0; --v )
4209  {
4210  if( SCIPvarIsDeleted(consdata->vars[v]) )
4211  {
4212  SCIP_CALL( delCoefPos(scip, conss[i], v) );
4213  }
4214  }
4215  consdata->varsdeleted = FALSE;
4216  }
4217  }
4218 
4219  return SCIP_OKAY;
4220 }
4221 
4222 
4223 /** normalizes a linear constraint with the following rules:
4224  * - if all coefficients have them same absolute value, change them to (-)1.0
4225  * - multiplication with +1 or -1:
4226  * Apply the following rules in the given order, until the sign of the factor is determined. Later rules only apply,
4227  * if the current rule doesn't determine the sign):
4228  * 1. the right hand side must not be negative
4229  * 2. the right hand side must not be infinite
4230  * 3. the absolute value of the right hand side must be greater than that of the left hand side
4231  * 4. the number of positive coefficients must not be smaller than the number of negative coefficients
4232  * 5. multiply with +1
4233  * - rationals to integrals
4234  * Try to identify a rational representation of the fractional coefficients, and multiply all coefficients
4235  * by the smallest common multiple of all denominators to get integral coefficients.
4236  * Forbid large denominators due to numerical stability.
4237  * - division by greatest common divisor
4238  * If all coefficients are integral, divide them by the greatest common divisor.
4239  */
4240 static
4242  SCIP* scip, /**< SCIP data structure */
4243  SCIP_CONS* cons, /**< linear constraint to normalize */
4244  SCIP_Bool* infeasible /**< pointer to store whether infeasibility was detected */
4245  )
4246 {
4247  SCIP_CONSDATA* consdata;
4248  SCIP_Real* vals;
4249  SCIP_Longint scm;
4250  SCIP_Longint nominator;
4251  SCIP_Longint denominator;
4252  SCIP_Longint gcd;
4253  SCIP_Longint maxmult;
4254  SCIP_Real epsilon;
4255  SCIP_Real feastol;
4256  SCIP_Real maxabsval;
4257  SCIP_Real minabsval;
4258  SCIP_Bool success;
4259  SCIP_Bool onlyintegral;
4260  int nvars;
4261  int mult;
4262  int nposcoeffs;
4263  int nnegcoeffs;
4264  int i;
4265  int v;
4266 
4267  assert(scip != NULL);
4268  assert(cons != NULL);
4269  assert(infeasible != NULL);
4270 
4271  *infeasible = FALSE;
4272 
4273  /* we must not change a modifiable constraint in any way */
4274  if( SCIPconsIsModifiable(cons) )
4275  return SCIP_OKAY;
4276 
4277  /* get constraint data */
4278  consdata = SCIPconsGetData(cons);
4279  assert(consdata != NULL);
4280 
4281  /* check, if the constraint is already normalized */
4282  if( consdata->normalized )
4283  return SCIP_OKAY;
4284 
4285  /* get coefficient arrays */
4286  vals = consdata->vals;
4287  nvars = consdata->nvars;
4288  assert(nvars == 0 || vals != NULL);
4289 
4290  if( nvars == 0 )
4291  {
4292  consdata->normalized = TRUE;
4293  return SCIP_OKAY;
4294  }
4295 
4296  assert(vals != NULL);
4297 
4298  /* get maximal and minimal absolute coefficient */
4299  maxabsval = consdataGetMaxAbsval(consdata);
4300  minabsval = consdataGetMinAbsval(consdata);
4301 
4302  /* return if scaling by maxval will eliminate coefficients */
4303  if( SCIPisZero(scip, minabsval/maxabsval) )
4304  return SCIP_OKAY;
4305 
4306  /* check if all coefficients are in absolute value equal, and not 1.0 */
4307  if( !SCIPisEQ(scip, maxabsval, 1.0) )
4308  {
4309  SCIP_Bool abscoefsequ;
4310 
4311  abscoefsequ = TRUE;
4312 
4313  for( v = nvars - 1; v >= 0; --v )
4314  {
4315  if( !SCIPisEQ(scip, REALABS(vals[v]), maxabsval) )
4316  {
4317  abscoefsequ = FALSE;
4318  break;
4319  }
4320  }
4321 
4322  /* all coefficients are in absolute value equal, so change them to (-)1.0 */
4323  if( abscoefsequ )
4324  {
4325  SCIPdebugMsg(scip, "divide linear constraint with %g, because all coefficients are in absolute value the same\n", maxabsval);
4326  SCIPdebugPrintCons(scip, cons, NULL);
4327  SCIP_CALL( scaleCons(scip, cons, 1/maxabsval) );
4328 
4329  if( consdata->validmaxabsval )
4330  {
4331  if( !SCIPisEQ(scip, consdata->maxabsval, 1.0) )
4332  consdata->maxabsval = 1.0;
4333  if( !SCIPisEQ(scip, consdata->minabsval, 1.0) )
4334  consdata->minabsval = 1.0;
4335 
4336  maxabsval = 1.0;
4337  }
4338  else
4339  {
4340  /* get maximal absolute coefficient */
4341  maxabsval = consdataGetMaxAbsval(consdata);
4342  }
4343 
4344  /* get new consdata information, because scaleCons() might have deleted variables */
4345  vals = consdata->vals;
4346  nvars = consdata->nvars;
4347 
4348  assert(nvars == 0 || vals != NULL);
4349  }
4350  }
4351 
4352  /* nvars might have changed */
4353  if( nvars == 0 )
4354  {
4355  consdata->normalized = TRUE;
4356  return SCIP_OKAY;
4357  }
4358 
4359  assert(vals != NULL);
4360 
4361  /* calculate the maximal multiplier for common divisor calculation:
4362  * |p/q - val| < epsilon and q < feastol/epsilon => |p - q*val| < feastol
4363  * which means, a value of feastol/epsilon should be used as maximal multiplier;
4364  * additionally, we don't want to scale the constraint if this would lead to too
4365  * large coefficients
4366  */
4367  epsilon = SCIPepsilon(scip) * 0.9; /* slightly decrease epsilon to be safe in rational conversion below */
4368  feastol = SCIPfeastol(scip);
4369  maxmult = (SCIP_Longint)(feastol/epsilon + feastol);
4370 
4371  if( !consdata->hasnonbinvalid )
4372  consdataCheckNonbinvar(consdata);
4373 
4374  /* if all variables are of integral type we will allow a greater multiplier */
4375  if( !consdata->hascontvar )
4376  maxmult = MIN(maxmult, (SCIP_Longint) (MAXSCALEDCOEFINTEGER / MAX(maxabsval, 1.0))); /*lint !e835*/
4377  else
4378  maxmult = MIN(maxmult, (SCIP_Longint) (MAXSCALEDCOEF / MAX(maxabsval, 1.0))); /*lint !e835*/
4379 
4380  /*
4381  * multiplication with +1 or -1
4382  */
4383  mult = 0;
4384 
4385  /* 1. the right hand side must not be negative */
4386  if( SCIPisPositive(scip, consdata->lhs) )
4387  mult = +1;
4388  else if( SCIPisNegative(scip, consdata->rhs) )
4389  mult = -1;
4390 
4391  if( mult == 0 )
4392  {
4393  /* 2. the right hand side must not be infinite */
4394  if( SCIPisInfinity(scip, -consdata->lhs) )
4395  mult = +1;
4396  else if( SCIPisInfinity(scip, consdata->rhs) )
4397  mult = -1;
4398  }
4399 
4400  if( mult == 0 )
4401  {
4402  /* 3. the absolute value of the right hand side must be greater than that of the left hand side */
4403  if( SCIPisGT(scip, REALABS(consdata->rhs), REALABS(consdata->lhs)) )
4404  mult = +1;
4405  else if( SCIPisLT(scip, REALABS(consdata->rhs), REALABS(consdata->lhs)) )
4406  mult = -1;
4407  }
4408 
4409  if( mult == 0 )
4410  {
4411  /* 4. the number of positive coefficients must not be smaller than the number of negative coefficients */
4412  nposcoeffs = 0;
4413  nnegcoeffs = 0;
4414  for( i = 0; i < nvars; ++i )
4415  {
4416  if( vals[i] > 0.0 )
4417  nposcoeffs++;
4418  else
4419  nnegcoeffs++;
4420  }
4421  if( nposcoeffs > nnegcoeffs )
4422  mult = +1;
4423  else if( nposcoeffs < nnegcoeffs )
4424  mult = -1;
4425  }
4426 
4427  if( mult == 0 )
4428  {
4429  /* 5. multiply with +1 */
4430  mult = +1;
4431  }
4432 
4433  assert(mult == +1 || mult == -1);
4434  if( mult == -1 )
4435  {
4436  /* scale the constraint with -1 */
4437  SCIPdebugMsg(scip, "multiply linear constraint with -1.0\n");
4438  SCIPdebugPrintCons(scip, cons, NULL);
4439  SCIP_CALL( scaleCons(scip, cons, -1.0) );
4440 
4441  /* scalecons() can delete variables, but scaling with -1 should not do that */
4442  assert(nvars == consdata->nvars);
4443  }
4444 
4445  /*
4446  * rationals to integrals
4447  *
4448  * @todo try scaling only on behalf of non-continuous variables
4449  */
4450  success = TRUE;
4451  scm = 1;
4452  for( i = 0; i < nvars && success && scm <= maxmult; ++i )
4453  {
4454  if( !SCIPisIntegral(scip, vals[i]) )
4455  {
4456  /* epsilon has been slightly decreased above - to be on the safe side */
4457  success = SCIPrealToRational(vals[i], -epsilon, epsilon , maxmult, &nominator, &denominator);
4458  if( success )
4459  scm = SCIPcalcSmaComMul(scm, denominator);
4460  }
4461  }
4462  assert(scm >= 1);
4463 
4464  /* it might be that we have really big coefficients, but all are integral, in that case we want to divide them by
4465  * their greatest common divisor
4466  */
4467  onlyintegral = TRUE;
4468  if( scm == 1 )
4469  {
4470  for( i = nvars - 1; i >= 0; --i )
4471  {
4472  if( !SCIPisIntegral(scip, vals[i]) )
4473  {
4474  onlyintegral = FALSE;
4475  break;
4476  }
4477  }
4478  }
4479 
4480  success = success && (scm <= maxmult || (scm == 1 && onlyintegral));
4481  if( success && scm != 1 )
4482  {
4483  /* scale the constraint with the smallest common multiple of all denominators */
4484  SCIPdebugMsg(scip, "scale linear constraint with %" SCIP_LONGINT_FORMAT " to make coefficients integral\n", scm);
4485  SCIPdebugPrintCons(scip, cons, NULL);
4486  SCIP_CALL( scaleCons(scip, cons, (SCIP_Real)scm) );
4487 
4488  if( consdata->validmaxabsval )
4489  {
4490  consdata->maxabsval *= REALABS((SCIP_Real)scm);
4491  if( !SCIPisIntegral(scip, consdata->maxabsval) )
4492  {
4493  consdata->validmaxabsval = FALSE;
4494  consdata->maxabsval = SCIP_INVALID;
4495  consdataCalcMaxAbsval(consdata);
4496  }
4497  }
4498 
4499  if( consdata->validminabsval )
4500  {
4501  consdata->minabsval *= REALABS((SCIP_Real)scm);
4502  if( !SCIPisIntegral(scip, consdata->minabsval) )
4503  {
4504  consdata->validminabsval = FALSE;
4505  consdata->minabsval = SCIP_INVALID;
4506  consdataCalcMinAbsval(consdata);
4507  }
4508  }
4509 
4510  /* get new consdata information, because scalecons() might have deleted variables */
4511  vals = consdata->vals;
4512  nvars = consdata->nvars;
4513  assert(nvars == 0 || vals != NULL);
4514  }
4515 
4516  /*
4517  * division by greatest common divisor
4518  */
4519  if( success && nvars >= 1 )
4520  {
4521  /* all coefficients are integral: divide them by their greatest common divisor */
4522  assert(SCIPisIntegral(scip, vals[0]));
4523 
4524  gcd = (SCIP_Longint)(REALABS(vals[0]) + feastol);
4525  for( i = 1; i < nvars && gcd > 1; ++i )
4526  {
4527  assert(SCIPisIntegral(scip, vals[i]));
4528  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[i]) + feastol));
4529  }
4530 
4531  if( gcd > 1 )
4532  {
4533  /* since the lhs/rhs is not respected for gcd calculation it can happen that we detect infeasibility */
4534  if( !consdata->hascontvar && onlyintegral )
4535  {
4536  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) && !SCIPisFeasIntegral(scip, consdata->rhs / gcd) )
4537  {
4538  *infeasible = TRUE;
4539 
4540  SCIPdebugMsg(scip, "detected infeasibility of constraint after scaling with gcd=%" SCIP_LONGINT_FORMAT ":\n", gcd);
4541  SCIPdebugPrintCons(scip, cons, NULL);
4542 
4543  return SCIP_OKAY;
4544  }
4545  }
4546 
4547  /* divide the constraint by the greatest common divisor of the coefficients */
4548  SCIPdebugMsg(scip, "divide linear constraint by greatest common divisor %" SCIP_LONGINT_FORMAT "\n", gcd);
4549  SCIPdebugPrintCons(scip, cons, NULL);
4550  SCIP_CALL( scaleCons(scip, cons, 1.0/(SCIP_Real)gcd) );
4551 
4552  if( consdata->validmaxabsval )
4553  {
4554  consdata->maxabsval /= REALABS((SCIP_Real)gcd);
4555  }
4556  if( consdata->validminabsval )
4557  {
4558  consdata->minabsval /= REALABS((SCIP_Real)gcd);
4559  }
4560  }
4561  }
4562 
4563  /* mark constraint to be normalized */
4564  consdata->normalized = TRUE;
4565 
4566  SCIPdebugMsg(scip, "normalized constraint:\n");
4567  SCIPdebugPrintCons(scip, cons, NULL);
4568 
4569  return SCIP_OKAY;
4570 }
4571 
4572 /** replaces multiple occurrences of a variable by a single coefficient */
4573 static
4575  SCIP* scip, /**< SCIP data structure */
4576  SCIP_CONS* cons /**< linear constraint */
4577  )
4578 {
4579  SCIP_CONSDATA* consdata;
4580  SCIP_VAR* var;
4581  SCIP_Real valsum;
4582  int v;
4583 
4584  assert(scip != NULL);
4585  assert(cons != NULL);
4586 
4587  consdata = SCIPconsGetData(cons);
4588  assert(consdata != NULL);
4589 
4590  if( consdata->merged )
4591  return SCIP_OKAY;
4592 
4593  /* sort the constraint */
4594  SCIP_CALL( consdataSort(scip, consdata) );
4595 
4596  /* go backwards through the constraint looking for multiple occurrences of the same variable;
4597  * backward direction is necessary, since delCoefPos() modifies the given position and
4598  * the subsequent ones
4599  */
4600  v = consdata->nvars-1;
4601  while( v >= 1 )
4602  {
4603  var = consdata->vars[v];
4604  if( consdata->vars[v-1] == var )
4605  {
4606  valsum = consdata->vals[v];
4607  do
4608  {
4609  SCIP_CALL( delCoefPos(scip, cons, v) );
4610  --v;
4611  valsum += consdata->vals[v];
4612  }
4613  while( v >= 1 && consdata->vars[v-1] == var );
4614 
4615  /* modify the last existing occurrence of the variable */
4616  assert(consdata->vars[v] == var);
4617  if( SCIPisZero(scip, valsum) )
4618  {
4619  SCIP_CALL( delCoefPos(scip, cons, v) );
4620 
4621  /* if the variable defining the maximal activity delta was removed from the constraint, the maximal activity
4622  * delta needs to be recalculated on the next real propagation
4623  */
4624  if( consdata->maxactdeltavar == var )
4625  {
4626  consdata->maxactdelta = SCIP_INVALID;
4627  consdata->maxactdeltavar = NULL;
4628  }
4629  }
4630  else
4631  {
4632  SCIP_CALL( chgCoefPos(scip, cons, v, valsum) );
4633  }
4634  }
4635  --v;
4636  }
4637 
4638  consdata->merged = TRUE;
4639 
4640  return SCIP_OKAY;
4641 }
4642 
4643 /** replaces all fixed and aggregated variables by their non-fixed counterparts */
4644 static
4646  SCIP* scip, /**< SCIP data structure */
4647  SCIP_CONS* cons, /**< linear constraint */
4648  SCIP_Bool* infeasible /**< pointer to store if infeasibility is detected; or NULL if this
4649  * information is not needed; in this case, we apply all fixings
4650  * instead of stopping after the first infeasible one */
4651  )
4652 {
4653  SCIP_CONSDATA* consdata;
4654  SCIP_VAR* var;
4655  SCIP_VAR** aggrvars;
4656  SCIP_Real val;
4657  SCIP_Real* aggrscalars;
4658  SCIP_Real fixedval;
4659  SCIP_Real aggrconst;
4660  int v;
4661  int naggrvars;
4662  int i;
4663 
4664  assert(scip != NULL);
4665  assert(cons != NULL);
4666 
4667  if( infeasible != NULL )
4668  *infeasible = FALSE;
4669 
4670  consdata = SCIPconsGetData(cons);
4671  assert(consdata != NULL);
4672 
4673  if( consdata->eventdata == NULL )
4674  {
4675  SCIP_CONSHDLR* conshdlr;
4676  SCIP_CONSHDLRDATA* conshdlrdata;
4677 
4678  conshdlr = SCIPconsGetHdlr(cons);
4679  assert(conshdlr != NULL);
4680 
4681  conshdlrdata = SCIPconshdlrGetData(conshdlr);
4682  assert(conshdlrdata != NULL);
4683 
4684  /* catch bound change events of variables */
4685  SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
4686  assert(consdata->eventdata != NULL);
4687  }
4688 
4689  if( !consdata->removedfixings )
4690  {
4691  SCIP_Real lhssubtrahend;
4692  SCIP_Real rhssubtrahend;
4693 
4694  /* if an unmodifiable row has been added to the LP, then we cannot apply fixing anymore (cannot change a row)
4695  * this should not happen, as applyFixings is called in addRelaxation() before creating and adding a row
4696  */
4697  assert(consdata->row == NULL || !SCIProwIsInLP(consdata->row) || SCIProwIsModifiable(consdata->row));
4698 
4699  lhssubtrahend = 0.0;
4700  rhssubtrahend = 0.0;
4701 
4702  SCIPdebugMsg(scip, "applying fixings:\n");
4703  SCIPdebugPrintCons(scip, cons, NULL);
4704 
4705  v = 0;
4706  while( v < consdata->nvars )
4707  {
4708  var = consdata->vars[v];
4709  val = consdata->vals[v];
4710  assert(SCIPvarIsTransformed(var));
4711 
4712  switch( SCIPvarGetStatus(var) )
4713  {
4715  SCIPerrorMessage("original variable in transformed linear constraint\n");
4716  return SCIP_INVALIDDATA;
4717 
4718  case SCIP_VARSTATUS_LOOSE:
4719  case SCIP_VARSTATUS_COLUMN:
4720  ++v;
4721  break;
4722 
4723  case SCIP_VARSTATUS_FIXED:
4724  assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)));
4725  fixedval = SCIPvarGetLbGlobal(var);
4726  if( !SCIPisInfinity(scip, -consdata->lhs) )
4727  {
4728  if( SCIPisInfinity(scip, ABS(fixedval)) )
4729  {
4730  if( val * fixedval > 0.0 )
4731  {
4732  SCIP_CALL( chgLhs(scip, cons, -SCIPinfinity(scip)) );
4733  }
4734  else
4735  {
4736  if( infeasible != NULL )
4737  {
4738  /* if lhs gets infinity it means that the problem is infeasible */
4739  *infeasible = TRUE;
4740  return SCIP_OKAY;
4741  }
4742  else
4743  {
4744  SCIP_CALL( chgLhs(scip, cons, SCIPinfinity(scip)) );
4745  }
4746  }
4747  }
4748  else
4749  lhssubtrahend += val * fixedval;
4750  }
4751  if( !SCIPisInfinity(scip, consdata->rhs) )
4752  {
4753  if( SCIPisInfinity(scip, ABS(fixedval)) )
4754  {
4755  if( val * fixedval > 0.0 )
4756  {
4757  if( infeasible != NULL )
4758  {
4759  /* if rhs gets -infinity it means that the problem is infeasible */
4760  *infeasible = TRUE;
4761  return SCIP_OKAY;
4762  }
4763  else
4764  {
4765  SCIP_CALL( chgRhs(scip, cons, -SCIPinfinity(scip)) );
4766  }
4767  }
4768  else
4769  {
4770  SCIP_CALL( chgRhs(scip, cons, SCIPinfinity(scip)) );
4771  }
4772  }
4773  else
4774  rhssubtrahend += val * fixedval;
4775  }
4776  SCIP_CALL( delCoefPos(scip, cons, v) );
4777  break;
4778 
4780  {
4781  SCIP_VAR* activevar = SCIPvarGetAggrVar(var);
4782  SCIP_Real activescalar = val * SCIPvarGetAggrScalar(var);
4783  SCIP_Real activeconstant = val * SCIPvarGetAggrConstant(var);
4784 
4785  assert(activevar != NULL);
4786  SCIP_CALL( SCIPgetProbvarSum(scip, &activevar, &activescalar, &activeconstant) );
4787  assert(activevar != NULL);
4788 
4789  if( !SCIPisZero(scip, activescalar) )
4790  {
4791  SCIP_CALL( addCoef(scip, cons, activevar, activescalar) );
4792  }
4793 
4794  if( !SCIPisZero(scip, activeconstant) )
4795  {
4796  if( !SCIPisInfinity(scip, -consdata->lhs) )
4797  lhssubtrahend += activeconstant;
4798  if( !SCIPisInfinity(scip, consdata->rhs) )
4799  rhssubtrahend += activeconstant;
4800  }
4801 
4802  SCIP_CALL( delCoefPos(scip, cons, v) );
4803  break;
4804  }
4807  naggrvars = SCIPvarGetMultaggrNVars(var);
4808  aggrvars = SCIPvarGetMultaggrVars(var);
4809  aggrscalars = SCIPvarGetMultaggrScalars(var);
4810  for( i = 0; i < naggrvars; ++i )
4811  {
4812  SCIP_CALL( addCoef(scip, cons, aggrvars[i], val * aggrscalars[i]) );
4813  }
4814  aggrconst = SCIPvarGetMultaggrConstant(var);
4815 
4816  if( !SCIPisInfinity(scip, -consdata->lhs) )
4817  lhssubtrahend += val * aggrconst;
4818  if( !SCIPisInfinity(scip, consdata->rhs) )
4819  rhssubtrahend += val * aggrconst;
4820 
4821  SCIP_CALL( delCoefPos(scip, cons, v) );
4822  break;
4823 
4825  SCIP_CALL( addCoef(scip, cons, SCIPvarGetNegationVar(var), -val) );
4826  aggrconst = SCIPvarGetNegationConstant(var);
4827 
4828  if( !SCIPisInfinity(scip, -consdata->lhs) )
4829  lhssubtrahend += val * aggrconst;
4830  if( !SCIPisInfinity(scip, consdata->rhs) )
4831  rhssubtrahend += val * aggrconst;
4832 
4833  SCIP_CALL( delCoefPos(scip, cons, v) );
4834  break;
4835 
4836  default:
4837  SCIPerrorMessage("unknown variable status\n");
4838  SCIPABORT();
4839  return SCIP_INVALIDDATA; /*lint !e527*/
4840  }
4841  }
4842 
4843  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->lhs) )
4844  {
4845  /* for large numbers that are relatively equal, substraction can lead to cancellation,
4846  * causing wrong fixings of other variables --> better use a real zero here;
4847  * for small numbers, polishing the difference might lead to wrong results -->
4848  * better use the exact difference in this case
4849  */
4850  if( SCIPisEQ(scip, lhssubtrahend, consdata->lhs) && SCIPisFeasGE(scip, REALABS(lhssubtrahend), 1.0) )
4851  {
4852  SCIP_CALL( chgLhs(scip, cons, 0.0) );
4853  }
4854  else
4855  {
4856  SCIP_CALL( chgLhs(scip, cons, consdata->lhs - lhssubtrahend) );
4857  }
4858  }
4859  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, -consdata->rhs))
4860  {
4861  /* for large numbers that are relatively equal, substraction can lead to cancellation,
4862  * causing wrong fixings of other variables --> better use a real zero here;
4863  * for small numbers, polishing the difference might lead to wrong results -->
4864  * better use the exact difference in this case
4865  */
4866  if( SCIPisEQ(scip, rhssubtrahend, consdata->rhs ) && SCIPisFeasGE(scip, REALABS(rhssubtrahend), 1.0) )
4867  {
4868  SCIP_CALL( chgRhs(scip, cons, 0.0) );
4869  }
4870  else
4871  {
4872  SCIP_CALL( chgRhs(scip, cons, consdata->rhs - rhssubtrahend) );
4873  }
4874  }
4875  consdata->removedfixings = TRUE;
4876 
4877  SCIPdebugMsg(scip, "after fixings:\n");
4878  SCIPdebugPrintCons(scip, cons, NULL);
4879 
4880  /* if aggregated variables have been replaced, multiple entries of the same variable are possible and we have
4881  * to clean up the constraint
4882  */
4883  SCIP_CALL( mergeMultiples(scip, cons) );
4884 
4885  SCIPdebugMsg(scip, "after merging:\n");
4886  SCIPdebugPrintCons(scip, cons, NULL);
4887  }
4888  assert(consdata->removedfixings);
4889 
4890 #ifndef NDEBUG
4891  /* check, if all fixings are applied */
4892  for( v = 0; v < consdata->nvars; ++v )
4893  assert(SCIPvarIsActive(consdata->vars[v]));
4894 #endif
4895 
4896  return SCIP_OKAY;
4897 }
4898 
4899 /** for each variable in the linear constraint, except the inferred variable, adds one bound to the conflict analysis'
4900  * candidate store (bound depends on sign of coefficient and whether the left or right hand side was the reason for the
4901  * inference variable's bound change); the conflict analysis can be initialized with the linear constraint being the
4902  * conflict detecting constraint by using NULL as inferred variable
4903  */
4904 static
4906  SCIP* scip, /**< SCIP data structure */
4907  SCIP_CONS* cons, /**< constraint that inferred the bound change */
4908  SCIP_VAR* infervar, /**< variable that was deduced, or NULL */
4909  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
4910  int inferpos, /**< position of the inferred variable in the vars array */
4911  SCIP_Bool reasonisrhs /**< is the right hand side responsible for the bound change? */
4912  )
4913 {
4914  SCIP_CONSDATA* consdata;
4915  SCIP_VAR** vars;
4916  SCIP_Real* vals;
4917  int nvars;
4918  int i;
4919 
4920  assert(scip != NULL);
4921  assert(cons != NULL);
4922 
4923  consdata = SCIPconsGetData(cons);
4925  assert(consdata != NULL);
4926 
4927  vars = consdata->vars;
4928  vals = consdata->vals;
4929  nvars = consdata->nvars;
4930 
4931  assert(vars != NULL || nvars == 0);
4932  assert(vals != NULL || nvars == 0);
4933 
4934  assert(-1 <= inferpos && inferpos < nvars);
4935  assert((infervar == NULL) == (inferpos == -1));
4936  assert(inferpos == -1 || vars[inferpos] == infervar); /*lint !e613*/
4937 
4938  /* for each variable, add the bound to the conflict queue, that is responsible for the minimal or maximal
4939  * residual value, depending on whether the left or right hand side is responsible for the bound change:
4940  * - if the right hand side is the reason, the minimal residual activity is responsible
4941  * - if the left hand side is the reason, the maximal residual activity is responsible
4942  */
4943 
4944  /* if the variable is integral we only need to add reason bounds until the propagation could be applied */
4945  if( infervar == NULL || SCIPvarIsIntegral(infervar) )
4946  {
4947  SCIP_Real minresactivity;
4948  SCIP_Real maxresactivity;
4949  SCIP_Bool minisrelax;
4950  SCIP_Bool maxisrelax;
4951  SCIP_Bool isminsettoinfinity;
4952  SCIP_Bool ismaxsettoinfinity;
4953 
4954  minresactivity = -SCIPinfinity(scip);
4955  maxresactivity = SCIPinfinity(scip);
4956 
4957  /* calculate the minimal and maximal global activity of all other variables involved in the constraint */
4958  if( infervar != NULL )
4959  {
4960  assert(vals != NULL); /* for flexelint */
4961  if( reasonisrhs )
4962  consdataGetGlbActivityResiduals(scip, consdata, infervar, vals[inferpos], FALSE, &minresactivity, NULL,
4963  &minisrelax, NULL, &isminsettoinfinity, NULL);
4964  else
4965  consdataGetGlbActivityResiduals(scip, consdata, infervar, vals[inferpos], FALSE, NULL, &maxresactivity,
4966  NULL, &maxisrelax, NULL, &ismaxsettoinfinity);
4967  }
4968  else
4969  {
4970  if( reasonisrhs )
4971  consdataGetGlbActivityBounds(scip, consdata, FALSE, &minresactivity, NULL,
4972  &minisrelax, NULL, &isminsettoinfinity, NULL);
4973  else
4974  consdataGetGlbActivityBounds(scip, consdata, FALSE, NULL, &maxresactivity,
4975  NULL, &maxisrelax, NULL, &ismaxsettoinfinity);
4976  }
4977 
4978  /* we can only do something clever, if the residual activity is finite and not relaxed */
4979  if( (reasonisrhs && !isminsettoinfinity && !minisrelax) || (!reasonisrhs && !ismaxsettoinfinity && !maxisrelax) ) /*lint !e644*/
4980  {
4981  SCIP_Real rescap;
4982  SCIP_Bool resactisinf;
4983 
4984  resactisinf = FALSE;
4985 
4986  /* calculate the residual capacity that would be left, if the variable would be set to one more / one less
4987  * than its inferred bound
4988  */
4989  if( infervar != NULL )
4990  {
4991  assert(vals != NULL); /* for flexelint */
4992 
4993  if( reasonisrhs )
4994  {
4995  if( SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastglbminactivity) )
4996  {
4997  consdataGetReliableResidualActivity(scip, consdata, infervar, &minresactivity, TRUE, TRUE);
4998  if( SCIPisInfinity(scip, -minresactivity) )
4999  resactisinf = TRUE;
5000  }
5001  rescap = consdata->rhs - minresactivity;
5002  }
5003  else
5004  {
5005  if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastglbmaxactivity) )
5006  {
5007  consdataGetReliableResidualActivity(scip, consdata, infervar, &maxresactivity, FALSE, TRUE);
5008  if( SCIPisInfinity(scip, maxresactivity) )
5009  resactisinf = TRUE;
5010  }
5011  rescap = consdata->lhs - maxresactivity;
5012  }
5013 
5014  if( reasonisrhs == (vals[inferpos] > 0.0) )
5015  rescap -= vals[inferpos] * (SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) + 1.0);
5016  else
5017  rescap -= vals[inferpos] * (SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) - 1.0);
5018  }
5019  else
5020  rescap = (reasonisrhs ? consdata->rhs - minresactivity : consdata->lhs - maxresactivity);
5021 
5022  if( !resactisinf )
5023  {
5024  /* now add bounds as reasons until the residual capacity is exceeded */
5025  for( i = 0; i < nvars; ++i )
5026  {
5027  assert( vars != NULL && vals != NULL ); /* for lint */
5028 
5029  /* zero coefficients and the infered variable can be ignored */
5030  if( vars[i] == infervar || SCIPisZero(scip, vals[i]) )
5031  continue;
5032 
5033  /* check if the residual capacity is exceeded */
5034  if( (reasonisrhs && SCIPisFeasNegative(scip, rescap))
5035  || (!reasonisrhs && SCIPisFeasPositive(scip, rescap)) )
5036  break;
5037 
5038  /* update the residual capacity due to the local bound of this variable */
5039  if( reasonisrhs == (vals[i] > 0.0) )
5040  {
5041  /* rhs is reason and coeff is positive, or lhs is reason and coeff is negative -> lower bound */
5042  SCIP_CALL( SCIPaddConflictLb(scip, vars[i], bdchgidx) );
5043  rescap -= vals[i] * (SCIPgetVarLbAtIndex(scip, vars[i], bdchgidx, FALSE) - SCIPvarGetLbGlobal(vars[i]));
5044  }
5045  else
5046  {
5047  /* lhs is reason and coeff is positive, or rhs is reason and coeff is negative -> upper bound */
5048  SCIP_CALL( SCIPaddConflictUb(scip, vars[i], bdchgidx) );
5049  rescap -= vals[i] * (SCIPgetVarUbAtIndex(scip, vars[i], bdchgidx, FALSE) - SCIPvarGetUbGlobal(vars[i]));
5050  }
5051  }
5052  return SCIP_OKAY;
5053  }
5054  }
5055  }
5056 
5057  /* for a bound change on a continuous variable, all locally changed bounds are responsible */
5058  for( i = 0; i < nvars; ++i )
5059  {
5060  assert(vars != NULL); /* for flexelint */
5061  assert(vals != NULL); /* for flexelint */
5062 
5063  /* zero coefficients and the infered variable can be ignored */
5064  if( vars[i] == infervar || SCIPisZero(scip, vals[i]) )
5065  continue;
5066 
5067  if( reasonisrhs == (vals[i] > 0.0) )
5068  {
5069  /* rhs is reason and coeff is positive, or lhs is reason and coeff is negative -> lower bound is responsible */
5070  SCIP_CALL( SCIPaddConflictLb(scip, vars[i], bdchgidx) );
5071  }
5072  else
5073  {
5074  /* lhs is reason and coeff is positive, or rhs is reason and coeff is negative -> upper bound is responsible */
5075  SCIP_CALL( SCIPaddConflictUb(scip, vars[i], bdchgidx) );
5076  }
5077  }
5078 
5079  return SCIP_OKAY;
5080 }
5081 
5082 /** for each variable in the linear ranged row constraint, except the inferred variable, adds the bounds of all fixed
5083  * variables to the conflict analysis' candidate store; the conflict analysis can be initialized
5084  * with the linear constraint being the conflict detecting constraint by using NULL as inferred variable
5085  */
5086 static
5088  SCIP* scip, /**< SCIP data structure */
5089  SCIP_CONS* cons, /**< constraint that inferred the bound change */
5090  SCIP_VAR* infervar, /**< variable that was deduced, or NULL */
5091  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
5092  int inferpos /**< position of the inferred variable in the vars array, or -1 */
5093  )
5094 {
5095  SCIP_CONSDATA* consdata;
5096  SCIP_VAR** vars;
5097  int nvars;
5098  int v;
5099 
5100  assert(scip != NULL);
5101  assert(cons != NULL);
5102 
5103  consdata = SCIPconsGetData(cons);
5104  assert(consdata != NULL);
5105  vars = consdata->vars;
5106  nvars = consdata->nvars;
5107  assert(vars != NULL || nvars == 0);
5108  assert(-1 <= inferpos && inferpos < nvars);
5109  assert((infervar == NULL) == (inferpos == -1));
5110  assert(inferpos == -1 || vars != NULL);
5111  assert(inferpos == -1 || vars[inferpos] == infervar); /*lint !e613*/
5112 
5113  /* collect all fixed variables */
5114  for( v = nvars - 1; v >= 0; --v )
5115  {
5116  assert(vars != NULL); /* for flexelint */
5117 
5118  /* need to add old bounds before propagation of inferrence variable */
5119  if( vars[v] == infervar )
5120  {
5121  assert(vars[v] != NULL);
5122 
5123  if( !SCIPisEQ(scip, SCIPgetVarLbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPvarGetLbGlobal(vars[v])) )
5124  {
5125  /* @todo get boundchange index before this last boundchange and correct the index */
5126  SCIP_CALL( SCIPaddConflictLb(scip, vars[v], bdchgidx) );
5127  }
5128 
5129  if( !SCIPisEQ(scip, SCIPgetVarUbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPvarGetUbGlobal(vars[v])) )
5130  {
5131  /* @todo get boundchange index before this last boundchange and correct the index */
5132  SCIP_CALL( SCIPaddConflictUb(scip, vars[v], bdchgidx) );
5133  }
5134 
5135  continue;
5136  }
5137 
5138  /* check for fixed variables */
5139  if( SCIPisEQ(scip, SCIPgetVarLbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPgetVarUbAtIndex(scip, vars[v], bdchgidx, FALSE)) )
5140  {
5141  /* add all bounds of fixed variables which lead to the boundchange of the given inference variable */
5142  SCIP_CALL( SCIPaddConflictLb(scip, vars[v], bdchgidx) );
5143  SCIP_CALL( SCIPaddConflictUb(scip, vars[v], bdchgidx) );
5144  }
5145  }
5146 
5147  return SCIP_OKAY;
5148 }
5149 
5150 /** add reasoning variables to conflict candidate queue which led to the conflict */
5151 static
5153  SCIP* scip, /**< SCIP data structure */
5154  SCIP_VAR** vars, /**< variables reasoning the infeasibility */
5155  int nvars, /**< number of variables reasoning the infeasibility */
5156  SCIP_VAR* var, /**< variable which was tried to fix/tighten, or NULL */
5157  SCIP_Real bound /**< bound of variable which was tried to apply, or SCIP_INVALID */
5158  )
5159 {
5160  int v;
5161 
5162  assert(scip != NULL);
5163 
5164  /* collect all variables for which the local bounds differ from their global bounds */
5165  for( v = nvars - 1; v >= 0; --v )
5166  {
5167  assert(vars != NULL);
5168 
5169  /* check for local bound changes variables */
5170  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(vars[v]), SCIPvarGetLbGlobal(vars[v])) )
5171  {
5172  /* add conflict bound */
5173  SCIP_CALL( SCIPaddConflictLb(scip, vars[v], 0) );
5174  }
5175 
5176  if( !SCIPisEQ(scip, SCIPvarGetUbLocal(vars[v]), SCIPvarGetUbGlobal(vars[v])) )
5177  {
5178  SCIP_CALL( SCIPaddConflictUb(scip, vars[v], 0) );
5179  }
5180  }
5181 
5182  if( var != NULL )
5183  {
5184  if( bound < SCIPvarGetLbLocal(var) )
5185  {
5186  SCIP_CALL( SCIPaddConflictLb(scip, var, 0) );
5187  }
5188 
5189  if( bound > SCIPvarGetUbLocal(var) )
5190  {
5191  SCIP_CALL( SCIPaddConflictUb(scip, var, 0) );
5192  }
5193  }
5194 
5195  return SCIP_OKAY;
5196 }
5197 
5198 /** resolves a propagation on the given variable by supplying the variables needed for applying the corresponding
5199  * propagation rule (see propagateCons()):
5200  * (1) activity residuals of all other variables tighten bounds of single variable
5201  */
5202 static
5204  SCIP* scip, /**< SCIP data structure */
5205  SCIP_CONS* cons, /**< constraint that inferred the bound change */
5206  SCIP_VAR* infervar, /**< variable that was deduced */
5207  INFERINFO inferinfo, /**< inference information */
5208  SCIP_BOUNDTYPE boundtype, /**< the type of the changed bound (lower or upper bound) */
5209  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
5210  SCIP_RESULT* result /**< pointer to store the result of the propagation conflict resolving call */
5211  )
5212 {
5213  SCIP_CONSDATA* consdata;
5214  SCIP_VAR** vars;
5215 #ifndef NDEBUG
5216  SCIP_Real* vals;
5217 #endif
5218  int nvars;
5219  int inferpos;
5220 
5221  assert(scip != NULL);
5222  assert(cons != NULL);
5223  assert(result != NULL);
5224 
5225  consdata = SCIPconsGetData(cons);
5226  assert(consdata != NULL);
5227  vars = consdata->vars;
5228  nvars = consdata->nvars;
5229 #ifndef NDEBUG
5230  vals = consdata->vals;
5231  assert(vars != NULL);
5232  assert(vals != NULL);
5233 #endif
5234 
5235  /* get the position of the inferred variable in the vars array */
5236  inferpos = inferInfoGetPos(inferinfo);
5237  if( inferpos >= nvars || vars[inferpos] != infervar )
5238  {
5239  /* find inference variable in constraint */
5240  /**@todo use a binary search here; the variables can be sorted by variable index */
5241  for( inferpos = 0; inferpos < nvars && vars[inferpos] != infervar; ++inferpos )
5242  {}
5243  }
5244  assert(inferpos < nvars);
5245  assert(vars[inferpos] == infervar);
5246  assert(!SCIPisZero(scip, vals[inferpos]));
5247 
5248  switch( inferInfoGetProprule(inferinfo) )
5249  {
5250  case PROPRULE_1_RHS:
5251  /* the bound of the variable was tightened, because the minimal or maximal residual activity of the linear
5252  * constraint (only taking the other variables into account) didn't leave enough space for a larger
5253  * domain in order to not exceed the right hand side of the inequality
5254  */
5255  assert((vals[inferpos] > 0.0) == (boundtype == SCIP_BOUNDTYPE_UPPER));
5256  SCIP_CALL( addConflictBounds(scip, cons, infervar, bdchgidx, inferpos, TRUE) );
5257  *result = SCIP_SUCCESS;
5258  break;
5259 
5260  case PROPRULE_1_LHS:
5261  /* the bound of the variable was tightened, because the minimal or maximal residual activity of the linear
5262  * constraint (only taking the other variables into account) didn't leave enough space for a larger
5263  * domain in order to not fall below the left hand side of the inequality
5264  */
5265  assert((vals[inferpos] > 0.0) == (boundtype == SCIP_BOUNDTYPE_LOWER));
5266  SCIP_CALL( addConflictBounds(scip, cons, infervar, bdchgidx, inferpos, FALSE) );
5267  *result = SCIP_SUCCESS;
5268  break;
5269 
5270  case PROPRULE_1_RANGEDROW:
5271  /* the bound of the variable was tightened, because some variables were already fixed and the leftover only allow
5272  * the given inference variable to their bounds in this given ranged row
5273  */
5274 
5275  /* check that we really have a ranged row here */
5276  assert(!SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->rhs));
5277  SCIP_CALL( addConflictFixedVars(scip, cons, infervar, bdchgidx, inferpos) );
5278  *result = SCIP_SUCCESS;
5279  break;
5280 
5281  case PROPRULE_INVALID:
5282  default:
5283  SCIPerrorMessage("invalid inference information %d in linear constraint <%s> at position %d for %s bound of variable <%s>\n",
5284  inferInfoGetProprule(inferinfo), SCIPconsGetName(cons), inferInfoGetPos(inferinfo),
5285  boundtype == SCIP_BOUNDTYPE_LOWER ? "lower" : "upper", SCIPvarGetName(infervar));
5286  SCIP_CALL( SCIPprintCons(scip, cons, NULL) );
5287  SCIPinfoMessage(scip, NULL, ";\n");
5288  return SCIP_INVALIDDATA;
5289  }
5290 
5291  return SCIP_OKAY;
5292 }
5293 
5294 /** analyzes conflicting bounds on given constraint, and adds conflict constraint to problem */
5295 static
5297  SCIP* scip, /**< SCIP data structure */
5298  SCIP_CONS* cons, /**< conflict detecting constraint */
5299  SCIP_Bool reasonisrhs /**< is the right hand side responsible for the conflict? */
5300  )
5301 {
5302  /* conflict analysis can only be applied in solving stage and if it is turned on */
5304  return SCIP_OKAY;
5305 
5306  /* initialize conflict analysis */
5308 
5309  /* add the conflicting bound for each variable of infeasible constraint to conflict candidate queue */
5310  SCIP_CALL( addConflictBounds(scip, cons, NULL, NULL, -1, reasonisrhs) );
5311 
5312  /* analyze the conflict */
5313  SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
5314 
5315  return SCIP_OKAY;
5316 }
5317 
5318 /** check if there is any hope of tightening some bounds */
5319 static
5321  SCIP_CONS* cons /**< linear constraint */
5322  )
5323 {
5324  SCIP_CONSDATA* consdata;
5325  int infcountmin;
5326  int infcountmax;
5327 
5328  consdata = SCIPconsGetData(cons);
5329  assert(consdata != NULL);
5330 
5331  infcountmin = consdata->minactivityneginf
5332  + consdata->minactivityposinf
5333  + consdata->minactivityneghuge
5334  + consdata->minactivityposhuge;
5335  infcountmax = consdata->maxactivityneginf
5336  + consdata->maxactivityposinf
5337  + consdata->maxactivityneghuge
5338  + consdata->maxactivityposhuge;
5340  if( infcountmin > 1 && infcountmax > 1 )
5341  return FALSE;
5342 
5343  return TRUE;
5344 }
5345 
5346 /** tighten upper bound */
5347 static
5349  SCIP* scip, /**< SCIP data structure */
5350  SCIP_CONS* cons, /**< linear constraint */
5351  int pos, /**< variable position */
5352  PROPRULE proprule, /**< propagation rule that deduced the value */
5353  SCIP_Real newub, /**< new upper bound */
5354  SCIP_Real oldub, /**< old upper bound */
5355  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
5356  int* nchgbds, /**< pointer to count the total number of tightened bounds */
5357  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
5358  )
5359 {
5360  SCIP_CONSDATA* consdata;
5361  SCIP_VAR* var;
5362  SCIP_Real lb;
5363  SCIP_Bool infeasible;
5364  SCIP_Bool tightened;
5365 
5366  assert(cons != NULL);
5367  assert(!SCIPisInfinity(scip, newub));
5368 
5369  consdata = SCIPconsGetData(cons);
5370  assert(consdata != NULL);
5371  var = consdata->vars[pos];
5372  assert(var != NULL);
5373 
5374  lb = SCIPvarGetLbLocal(var);
5375  newub = SCIPadjustedVarUb(scip, var, newub);
5376 
5377  if( force || SCIPisUbBetter(scip, newub, lb, oldub) )
5378  {
5379  SCIP_VARTYPE vartype;
5380 
5381  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, activity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newub=%.15g\n",
5382  SCIPconsGetName(cons), SCIPvarGetName(var), lb, oldub, consdata->vals[pos], consdata->minactivity, consdata->maxactivity, consdata->lhs, consdata->rhs, newub);
5383 
5384  vartype = SCIPvarGetType(var);
5385 
5386  /* tighten upper bound */
5387  SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(proprule, pos), force, &infeasible, &tightened) );
5388 
5389  if( infeasible )
5390  {
5391  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5392  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5393 
5394  /* analyze conflict */
5395  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
5396 
5397  *cutoff = TRUE;
5398  }
5399  else if( tightened )
5400  {
5401  assert(SCIPisFeasLE(scip, SCIPvarGetUbLocal(var), oldub));
5402  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
5403  SCIPconsGetName(cons), SCIPvarGetName(var), lb, SCIPvarGetUbLocal(var));
5404 
5405  (*nchgbds)++;
5406 
5407  /* if variable type was changed we might be able to upgrade the constraint */
5408  if( vartype != SCIPvarGetType(var) )
5409  consdata->upgradetried = FALSE;
5410  }
5411  }
5412  return SCIP_OKAY;
5413 }
5414 
5415 /** tighten lower bound */
5416 static
5418  SCIP* scip, /**< SCIP data structure */
5419  SCIP_CONS* cons, /**< linear constraint */
5420  int pos, /**< variable position */
5421  PROPRULE proprule, /**< propagation rule that deduced the value */
5422  SCIP_Real newlb, /**< new lower bound */
5423  SCIP_Real oldlb, /**< old lower bound */
5424  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
5425  int* nchgbds, /**< pointer to count the total number of tightened bounds */
5426  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
5427  )
5428 {
5429  SCIP_CONSDATA* consdata;
5430  SCIP_VAR* var;
5431  SCIP_Real ub;
5432  SCIP_Bool infeasible;
5433  SCIP_Bool tightened;
5434 
5435  assert(cons != NULL);
5436  assert(!SCIPisInfinity(scip, newlb));
5437 
5438  consdata = SCIPconsGetData(cons);
5439  assert(consdata != NULL);
5440  var = consdata->vars[pos];
5441  assert(var != NULL);
5442 
5443  ub = SCIPvarGetUbLocal(var);
5444  newlb = SCIPadjustedVarLb(scip, var, newlb);
5445 
5446  if( force || SCIPisLbBetter(scip, newlb, oldlb, ub) )
5447  {
5448  SCIP_VARTYPE vartype;
5449 
5450  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, activity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
5451  SCIPconsGetName(cons), SCIPvarGetName(var), oldlb, ub, consdata->vals[pos], consdata->minactivity, consdata->maxactivity, consdata->lhs, consdata->rhs, newlb);
5452 
5453  vartype = SCIPvarGetType(var);
5454 
5455  /* tighten lower bound */
5456  SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(proprule, pos), force, &infeasible, &tightened) );
5457 
5458  if( infeasible )
5459  {
5460  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5461  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5462 
5463  /* analyze conflict */
5464  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
5465 
5466  *cutoff = TRUE;
5467  }
5468  else if( tightened )
5469  {
5470  assert(SCIPisFeasGE(scip, SCIPvarGetLbLocal(var), oldlb));
5471  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
5472  SCIPconsGetName(cons), SCIPvarGetName(var), SCIPvarGetLbLocal(var), ub);
5473 
5474  (*nchgbds)++;
5475 
5476  /* if variable type was changed we might be able to upgrade the constraint */
5477  if( vartype != SCIPvarGetType(var) )
5478  consdata->upgradetried = FALSE;
5479  }
5480  }
5481  return SCIP_OKAY;
5482 }
5483 
5484 /** tightens bounds of a single variable due to activity bounds (easy case) */
5485 static
5487  SCIP* scip, /**< SCIP data structure */
5488  SCIP_CONS* cons, /**< linear constraint */
5489  int pos, /**< position of the variable in the vars array */
5490  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
5491  int* nchgbds, /**< pointer to count the total number of tightened bounds */
5492  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
5493  )
5494 {
5495  SCIP_CONSDATA* consdata;
5496  SCIP_VAR* var;
5497  SCIP_Real val;
5498  SCIP_Real lb;
5499  SCIP_Real ub;
5500  SCIP_Real lhs;
5501  SCIP_Real rhs;
5502 
5503  assert(scip != NULL);
5504  assert(cons != NULL);
5505  assert(cutoff != NULL);
5506  assert(nchgbds != NULL);
5507 
5508  /* we cannot tighten variables' bounds, if the constraint may be not complete */
5509  if( SCIPconsIsModifiable(cons) )
5510  return SCIP_OKAY;
5511 
5512  consdata = SCIPconsGetData(cons);
5513  assert(consdata != NULL);
5514  assert(0 <= pos && pos < consdata->nvars);
5515 
5516  *cutoff = FALSE;
5517 
5518  var = consdata->vars[pos];
5519  assert(var != NULL);
5520 
5521  /* we cannot tighten bounds of multi-aggregated variables */
5523  return SCIP_OKAY;
5524 
5525  val = consdata->vals[pos];
5526  lhs = consdata->lhs;
5527  rhs = consdata->rhs;
5528  assert(!SCIPisZero(scip, val));
5529  assert(!SCIPisInfinity(scip, lhs));
5530  assert(!SCIPisInfinity(scip, -rhs));
5531 
5532  lb = SCIPvarGetLbLocal(var);
5533  ub = SCIPvarGetUbLocal(var);
5534  assert(SCIPisLE(scip, lb, ub));
5535 
5536  /* recompute activities if needed */
5537  if( !consdata->validactivities )
5538  consdataCalcActivities(scip, consdata);
5539  assert(consdata->validactivities);
5540  if( !consdata->validminact )
5541  consdataRecomputeMinactivity(scip, consdata);
5542  assert(consdata->validminact);
5543 
5544  if( val > 0.0 )
5545  {
5546  /* check, if we can tighten the variable's upper bound */
5547  if( !SCIPisInfinity(scip, rhs) )
5548  {
5549  SCIP_Real slack;
5550  SCIP_Real alpha;
5551 
5552  /* min activity should be valid at this point (if this is not true, then some decisions might be wrong!) */
5553  assert(consdata->validminact);
5554 
5555  /* if the minactivity is larger than the right hand side by feasibility epsilon, the constraint is infeasible */
5556  if( SCIPisFeasLT(scip, rhs, consdata->minactivity) )
5557  {
5558  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, minactivity=%.15g > rhs=%.15g\n",
5559  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->minactivity, rhs);
5560 
5561  *cutoff = TRUE;
5562  return SCIP_OKAY;
5563  }
5564 
5565  slack = rhs - consdata->minactivity;
5566 
5567  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5568  * it to zero
5569  */
5570  if( !SCIPisPositive(scip, slack) )
5571  slack = 0.0;
5572 
5573  alpha = val * (ub - lb);
5574  assert(!SCIPisNegative(scip, alpha));
5575 
5576  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5577  {
5578  SCIP_Real newub;
5579 
5580  /* compute new upper bound */
5581  newub = lb + (slack / val);
5582 
5583  SCIP_CALL( tightenVarUb(scip, cons, pos, PROPRULE_1_RHS, newub, ub, cutoff, nchgbds, force) );
5584 
5585  if( *cutoff )
5586  {
5587  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5588  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5589 
5590  return SCIP_OKAY;
5591  }
5592 
5593  /* collect the new upper bound which is needed for the lower bound computation */
5594  ub = SCIPvarGetUbLocal(var);
5595  }
5596  }
5597 
5598  /* check, if we can tighten the variable's lower bound */
5599  if( !SCIPisInfinity(scip, -lhs) )
5600  {
5601  SCIP_Real slack;
5602  SCIP_Real alpha;
5603 
5604  /* make sure the max activity is reliable */
5605  if( !consdata->validmaxact )
5606  {
5607  consdataRecomputeMaxactivity(scip, consdata);
5608  }
5609  assert(consdata->validmaxact);
5610 
5611  /* if the maxactivity is smaller than the left hand side by feasibility epsilon, the constraint is infeasible */
5612  if( SCIPisFeasLT(scip, consdata->maxactivity, lhs) )
5613  {
5614  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, maxactivity=%.15g < lhs=%.15g\n",
5615  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->maxactivity, lhs);
5616  *cutoff = TRUE;
5617  return SCIP_OKAY;
5618  }
5619 
5620  slack = consdata->maxactivity - lhs;
5621 
5622  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5623  * it to zero
5624  */
5625  if( !SCIPisPositive(scip, slack) )
5626  slack = 0.0;
5627 
5628  alpha = val * (ub - lb);
5629  assert(!SCIPisNegative(scip, alpha));
5630 
5631  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5632  {
5633  SCIP_Real newlb;
5634 
5635  /* compute new lower bound */
5636  newlb = ub - (slack / val);
5637 
5638  SCIP_CALL( tightenVarLb(scip, cons, pos, PROPRULE_1_LHS, newlb, lb, cutoff, nchgbds, force) );
5639 
5640  if( *cutoff )
5641  {
5642  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5643  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5644 
5645  return SCIP_OKAY;
5646  }
5647  }
5648  }
5649  }
5650  else
5651  {
5652  /* check, if we can tighten the variable's lower bound */
5653  if( !SCIPisInfinity(scip, rhs) )
5654  {
5655  SCIP_Real slack;
5656  SCIP_Real alpha;
5657 
5658  /* min activity should be valid at this point (if this is not true, then some decisions might be wrong!) */
5659  assert(consdata->validminact);
5660 
5661  /* if the minactivity is larger than the right hand side by feasibility epsilon, the constraint is infeasible */
5662  if( SCIPisFeasLT(scip, rhs, consdata->minactivity) )
5663  {
5664  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, minactivity=%.15g > rhs=%.15g\n",
5665  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->minactivity, rhs);
5666 
5667  *cutoff = TRUE;
5668  return SCIP_OKAY;
5669  }
5670 
5671  slack = rhs - consdata->minactivity;
5672 
5673  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5674  * it to zero
5675  */
5676  if( !SCIPisPositive(scip, slack) )
5677  slack = 0.0;
5678 
5679  alpha = val * (lb - ub);
5680  assert(!SCIPisNegative(scip, alpha));
5681 
5682  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5683  {
5684  SCIP_Real newlb;
5685 
5686  /* compute new lower bound */
5687  newlb = ub + slack / val;
5688 
5689  SCIP_CALL( tightenVarLb(scip, cons, pos, PROPRULE_1_RHS, newlb, lb, cutoff, nchgbds, force) );
5690 
5691  if( *cutoff )
5692  {
5693  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5694  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5695 
5696  return SCIP_OKAY;
5697  }
5698  /* collect the new lower bound which is needed for the upper bound computation */
5699  lb = SCIPvarGetLbLocal(var);
5700  }
5701  }
5702 
5703  /* check, if we can tighten the variable's upper bound */
5704  if( !SCIPisInfinity(scip, -lhs) )
5705  {
5706  SCIP_Real slack;
5707  SCIP_Real alpha;
5708 
5709  /* make sure the max activity is reliable */
5710  if( !consdata->validmaxact )
5711  {
5712  consdataRecomputeMaxactivity(scip, consdata);
5713  }
5714  assert(consdata->validmaxact);
5715 
5716  /* if the maxactivity is smaller than the left hand side by feasibility epsilon, the constraint is infeasible */
5717  if( SCIPisFeasLT(scip, consdata->maxactivity, lhs) )
5718  {
5719  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, maxactivity=%.15g < lhs=%.15g\n",
5720  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->maxactivity, lhs);
5721 
5722  *cutoff = TRUE;
5723  return SCIP_OKAY;
5724  }
5725 
5726  slack = consdata->maxactivity - lhs;
5727 
5728  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5729  * it to zero
5730  */
5731  if( !SCIPisPositive(scip, slack) )
5732  slack = 0.0;
5733 
5734  alpha = val * (lb - ub);
5735  assert(!SCIPisNegative(scip, alpha));
5736 
5737  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5738  {
5739  SCIP_Real newub;
5740 
5741  /* compute new upper bound */
5742  newub = lb - (slack / val);
5743 
5744  SCIP_CALL( tightenVarUb(scip, cons, pos, PROPRULE_1_LHS, newub, ub, cutoff, nchgbds, force) );
5745 
5746  if( *cutoff )
5747  {
5748  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5749  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5750 
5751  return SCIP_OKAY;
5752  }
5753  }
5754  }
5755  }
5756 
5757  return SCIP_OKAY;
5758 }
5759 
5760 /** analyzes conflicting bounds on given ranged row constraint, and adds conflict constraint to problem */
5761 static
5763  SCIP* scip, /**< SCIP data structure */
5764  SCIP_CONS* cons, /**< conflict detecting constraint */
5765  SCIP_VAR** vars, /**< variables reasoning the infeasibility */
5766  int nvars, /**< number of variables reasoning the infeasibility */
5767  SCIP_VAR* var, /**< variable which was tried to fix/tighten, or NULL */
5768  SCIP_Real bound /**< bound of variable which was tried to apply, or SCIP_INVALID */
5769  )
5770 {
5771 #ifndef NDEBUG
5772  SCIP_CONSDATA* consdata;
5773 
5774  assert(scip != NULL);
5775  assert(cons != NULL);
5776 
5777  consdata = SCIPconsGetData(cons);
5778  assert(consdata != NULL);
5779  assert(!SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->rhs));
5780 #endif
5782  /* conflict analysis can only be applied in solving stage and if it is turned on */
5784  return SCIP_OKAY;
5785 
5786  /* initialize conflict analysis */
5788 
5789  /* add the conflicting fixed variables of this ranged row constraint to conflict candidate queue */
5790  SCIP_CALL( addConflictFixedVars(scip, cons, NULL, NULL, -1) );
5791 
5792  /* add reasoning variables to conflict candidate queue which led to the conflict */
5793  SCIP_CALL( addConflictReasonVars(scip, vars, nvars, var, bound) );
5794 
5795  /* analyze the conflict */
5796  SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
5797 
5798  return SCIP_OKAY;
5799 }
5800 
5801 /** propagate ranged rows
5802  *
5803  * Check ranged rows for possible solutions, possibly detect infeasibility, fix variables due to having only one possible
5804  * solution, tighten bounds if having only two possible solutions or add constraints which propagate a subset of
5805  * variables better.
5806  *
5807  * Example:
5808  * c1: 12 x1 + 9 x2 - x3 = 0 with x1, x2 free and 1 <= x3 <= 2
5809  *
5810  * x3 needs to be a multiple of 3, so the instance is infeasible.
5811  *
5812  * Example:
5813  * c1: 12 x1 + 9 x2 - x3 = 1 with x1, x2 free and 1 <= x3 <= 2
5814  *
5815  * The only possible value for x3 is 2, so the variable will be fixed.
5816  *
5817  * @todo add holes if possible
5818  */
5819 static
5821  SCIP* scip, /**< SCIP data structure */
5822  SCIP_CONS* cons, /**< linear constraint */
5823  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
5824  int* nfixedvars, /**< pointer to count number of fixed variables */
5825  int* nchgbds, /**< pointer to count the number of bound changes */
5826  int* naddconss /**< pointer to count number of added constraints */
5827  )
5828 {
5829  SCIP_CONSHDLRDATA* conshdlrdata;
5830  SCIP_CONSHDLR* conshdlr;
5831  SCIP_CONSDATA* consdata;
5832  SCIP_VAR** infcheckvars;
5833  SCIP_Real* infcheckvals;
5834  SCIP_Real minactinfvars;
5835  SCIP_Real maxactinfvars;
5836  SCIP_Real lb;
5837  SCIP_Real ub;
5838  SCIP_Real feastol;
5839  SCIP_Real fixedact;
5840  SCIP_Real lhs;
5841  SCIP_Real rhs;
5842  SCIP_Real absminbincoef;
5843  SCIP_Longint gcd;
5844  SCIP_Longint gcdtmp;
5845  SCIP_Bool minactinfvarsinvalid;
5846  SCIP_Bool maxactinfvarsinvalid;
5847  SCIP_Bool possiblegcd;
5848  SCIP_Bool gcdisone;
5849  SCIP_Bool addartconss;
5850  int ninfcheckvars;
5851  int nunfixedvars;
5852  int nfixedconsvars;
5853  int ncontvars;
5854  int pos;
5855  int v;
5856 
5857  assert(scip != NULL);
5858  assert(cons != NULL);
5859  assert(cutoff != NULL);
5860  assert(nfixedvars != NULL);
5861  assert(nchgbds != NULL);
5862  assert(naddconss != NULL);
5863 
5864  /* modifiable constraint can be changed so we do not have all necessary information */
5865  if( SCIPconsIsModifiable(cons) )
5866  return SCIP_OKAY;
5867 
5868  consdata = SCIPconsGetData(cons);
5869  assert(consdata != NULL);
5870 
5871  /* we already did full ranged row propagation */
5872  if( consdata->rangedrowpropagated == 2 )
5873  return SCIP_OKAY;
5874 
5875  /* at least three variables are needed */
5876  if( consdata->nvars < 3 )
5877  return SCIP_OKAY;
5878 
5879  /* do nothing on normal inequalities */
5880  if( SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, consdata->rhs) )
5881  return SCIP_OKAY;
5882 
5883  /* get constraint handler data */
5884  conshdlr = SCIPconsGetHdlr(cons);
5885  assert(conshdlr != NULL);
5886  conshdlrdata = SCIPconshdlrGetData(conshdlr);
5887  assert(conshdlrdata != NULL);
5888 
5889  addartconss = conshdlrdata->rangedrowartcons && SCIPgetDepth(scip) < 1 && !SCIPinProbing(scip) && !SCIPinRepropagation(scip);
5890 
5891  /* we may add artificial constraints */
5892  if( addartconss )
5893  consdata->rangedrowpropagated = 2;
5894  /* we are not allowed to add artificial constraints during propagation; if nothing changed on this constraint since
5895  * the last rangedrowpropagation, we can stop; otherwise, we mark this constraint to be rangedrowpropagated without
5896  * artificial constraints
5897  */
5898  else
5899  {
5900  if( consdata->rangedrowpropagated > 0 )
5901  return SCIP_OKAY;
5902 
5903  consdata->rangedrowpropagated = 1;
5904  }
5905  fixedact = 0;
5906  nfixedconsvars = 0;
5907  /* calculate fixed activity and number of fixed variables */
5908  for( v = consdata->nvars - 1; v >= 0; --v )
5909  {
5910  /* all zero coefficients should be eliminated */
5911  assert(!SCIPisZero(scip, consdata->vals[v]));
5912 
5913  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5914  {
5915  fixedact += SCIPvarGetLbLocal(consdata->vars[v]) * consdata->vals[v];
5916  ++nfixedconsvars;
5917  }
5918  }
5919 
5920  /* do not work with huge fixed activities */
5921  if( SCIPisHugeValue(scip, REALABS(fixedact)) )
5922  return SCIP_OKAY;
5923 
5924  /* compute lhs and rhs for unfixed variables only and get number of unfixed variables */
5925  assert(!SCIPisInfinity(scip, -fixedact) && !SCIPisInfinity(scip, fixedact));
5926  lhs = consdata->lhs - fixedact;
5927  rhs = consdata->rhs - fixedact;
5928  nunfixedvars = consdata->nvars - nfixedconsvars;
5929 
5930  /* allocate temporary memory for variables and coefficients which may lead to infeasibility */
5931  SCIP_CALL( SCIPallocBufferArray(scip, &infcheckvars, nunfixedvars) );
5932  SCIP_CALL( SCIPallocBufferArray(scip, &infcheckvals, nunfixedvars) );
5933 
5934  absminbincoef = SCIP_REAL_MAX;
5935  ncontvars = 0;
5936  gcdisone = TRUE;
5937  possiblegcd = TRUE;
5938 
5939  /* we now partition all unfixed variables in two groups:
5940  *
5941  * the first one contains all integral variable with integral
5942  * coefficient so that all variables in this group will have a gcd greater than 1, this group will be implicitly
5943  * given
5944  *
5945  * the second group will contain all left unfixed variables and will be saved as infcheckvars with corresponding
5946  * coefficients as infcheckvals, the order of these variables should be the same as in the consdata object
5947  */
5948 
5949  /* find first integral variables with integral coefficient greater than 1, thereby collecting all other unfixed
5950  * variables
5951  */
5952  ninfcheckvars = 0;
5953  v = -1;
5954  pos = -1;
5955  do
5956  {
5957  ++v;
5958 
5959  /* partition the variables, do not change the order of collection, because it might be used later on */
5960  while( v < consdata->nvars && (SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS ||
5961  !SCIPisIntegral(scip, consdata->vals[v]) || SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0)) )
5962  {
5963  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5964  {
5965  if( SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS )
5966  {
5967  ++ncontvars;
5968  }
5969  else if( SCIPvarIsBinary(consdata->vars[v]) )
5970  {
5971  SCIP_Real absval;
5972 
5973  absval = REALABS(consdata->vals[v]);
5974 
5975  if( absminbincoef > absval )
5976  absminbincoef = absval;
5977  }
5978 
5979  gcdisone = gcdisone && SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0);
5980  possiblegcd = FALSE;
5981  infcheckvars[ninfcheckvars] = consdata->vars[v];
5982  infcheckvals[ninfcheckvars] = consdata->vals[v];
5983  ++ninfcheckvars;
5984 
5985  if( pos == -1 )
5986  pos = v;
5987  }
5988  ++v;
5989  }
5990  }
5991  while( v < consdata->nvars && SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) );
5992 
5993  /* if the first group of variables is empty, we stop */
5994  /* @todo try to propagate/split up a constraint of the form:
5995  * x_1 + ... + x_m + a_1*y_1 + ... + a_n*y_n = k + c,
5996  * 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]
5997  */
5998  if( v == consdata->nvars )
5999  goto TERMINATE;
6000 
6001  /* we need at least two non-continuous variables */
6002  if( ncontvars + 2 > nunfixedvars )
6003  goto TERMINATE;
6004 
6005  assert(!SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])));
6006  assert(SCIPisIntegral(scip, consdata->vals[v]) && SCIPvarGetType(consdata->vars[v]) != SCIP_VARTYPE_CONTINUOUS && REALABS(consdata->vals[v]) > 1.5);
6007 
6008  feastol = SCIPfeastol(scip);
6009 
6010  gcd = (SCIP_Longint)(REALABS(consdata->vals[v]) + feastol);
6011  assert(gcd >= 2);
6012 
6013  /* go on to partition the variables, do not change the order of collection, because it might be used later on;
6014  * calculate gcd over the first part of variables */
6015  for( ; v < consdata->nvars; ++v )
6016  {
6017  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6018  continue;
6019 
6020  if( SCIPvarIsBinary(consdata->vars[v]) )
6021  {
6022  SCIP_Real absval;
6023 
6024  absval = REALABS(consdata->vals[v]);
6025 
6026  if( absminbincoef > absval )
6027  absminbincoef = absval;
6028  }
6029 
6030  if( !SCIPisIntegral(scip, consdata->vals[v]) || SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS ||
6031  SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0) )
6032  {
6033  if( SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS )
6034  ++ncontvars;
6035 
6036  gcdisone = gcdisone && SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0);
6037  possiblegcd = FALSE;
6038  infcheckvars[ninfcheckvars] = consdata->vars[v];
6039  infcheckvals[ninfcheckvars] = consdata->vals[v];
6040 
6041  ++ninfcheckvars;
6042 
6043  if( pos == -1 )
6044  pos = v;
6045  }
6046  else
6047  {
6048  assert(REALABS(consdata->vals[v]) > 1.5);
6049 
6050  gcdtmp = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(consdata->vals[v]) + feastol));
6051  assert(gcdtmp >= 1);
6052 
6053  if( gcdtmp == 1 )
6054  {
6055  infcheckvars[ninfcheckvars] = consdata->vars[v];
6056  infcheckvals[ninfcheckvars] = consdata->vals[v];
6057 
6058  ++ninfcheckvars;
6059 
6060  if( pos == -1 )
6061  pos = v;
6062  }
6063  else
6064  gcd = gcdtmp;
6065  }
6066  }
6067  assert(gcd >= 2);
6068 
6069  /* it should not happen that all variables are of integral type and have a gcd >= 2, this should be done by
6070  * normalizeCons() */
6071  if( ninfcheckvars == 0 )
6072  goto TERMINATE;
6073 
6074  assert(pos >= 0);
6075 
6076  minactinfvarsinvalid = FALSE;
6077  maxactinfvarsinvalid = FALSE;
6078  maxactinfvars = 0.0;
6079  minactinfvars = 0.0;
6080 
6081  /* calculate activities over all infcheckvars */
6082  for( v = ninfcheckvars - 1; v >= 0; --v )
6083  {
6084  lb = SCIPvarGetLbLocal(infcheckvars[v]);
6085  ub = SCIPvarGetUbLocal(infcheckvars[v]);
6086 
6087  if( SCIPisInfinity(scip, -lb) )
6088  {
6089  if( infcheckvals[v] < 0.0 )
6090  maxactinfvarsinvalid = TRUE;
6091  else
6092  minactinfvarsinvalid = TRUE;
6093  }
6094  else
6095  {
6096  if( infcheckvals[v] < 0.0 )
6097  maxactinfvars += infcheckvals[v] * lb;
6098  else
6099  minactinfvars += infcheckvals[v] * lb;
6100  }
6101 
6102  if( SCIPisInfinity(scip, ub) )
6103  {
6104  if( infcheckvals[v] > 0.0 )
6105  maxactinfvarsinvalid = TRUE;
6106  else
6107  minactinfvarsinvalid = TRUE;
6108  }
6109  else
6110  {
6111  if( infcheckvals[v] > 0.0 )
6112  maxactinfvars += infcheckvals[v] * ub;
6113  else
6114  minactinfvars += infcheckvals[v] * ub;
6115  }
6116 
6117  /* better abort on to big values */
6118  if( SCIPisHugeValue(scip, -minactinfvars) )
6119  minactinfvarsinvalid = TRUE;
6120  if( SCIPisHugeValue(scip, maxactinfvars) )
6121  maxactinfvarsinvalid = TRUE;
6122 
6123  if( minactinfvarsinvalid || maxactinfvarsinvalid )
6124  goto TERMINATE;
6125  }
6126  assert(!minactinfvarsinvalid && !maxactinfvarsinvalid);
6127 
6128  SCIPdebugMsg(scip, "minactinfvarsinvalid = %u, minactinfvars = %g, maxactinfvarsinvalid = %u, maxactinfvars = %g, gcd = %lld, ninfcheckvars = %d, ncontvars = %d\n",
6129  minactinfvarsinvalid, minactinfvars, maxactinfvarsinvalid, maxactinfvars, gcd, ninfcheckvars, ncontvars);
6130 
6131  /* @todo maybe we took the wrong variables as infcheckvars we could try to exchange integer variables */
6132  /* @todo if minactinfvarsinvalid or maxactinfvarsinvalid are true, try to exchange both partitions to maybe get valid
6133  * activities */
6134  /* @todo calculate minactivity and maxactivity for all non-intcheckvars, and use this for better bounding,
6135  * !!!note!!!
6136  * that therefore the conflict variables in addConflictFixedVars() need to be extended by all variables which
6137  * are not at their global bound
6138  */
6139 
6140  /* check if between left hand side and right hand side exist a feasible point, if not the constraint leads to
6141  * infeasibility */
6142  if( !SCIPisIntegral(scip, (lhs - maxactinfvars) / gcd) &&
6143  SCIPisGT(scip, SCIPceil(scip, (lhs - maxactinfvars) / gcd) * gcd, rhs - minactinfvars) )
6144  {
6145  SCIPdebugMsg(scip, "no feasible value exist, constraint <%s> lead to infeasibility", SCIPconsGetName(cons));
6146  SCIPdebugPrintCons(scip, cons, NULL);
6147 
6148  /* start conflict analysis */
6149  /* @todo improve conflict analysis by adding relaxed bounds */
6150  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6151 
6152  *cutoff = TRUE;
6153  }
6154  else if( ncontvars == 0 )
6155  {
6156  SCIP_Longint gcdinfvars = -1;
6157 
6158  /* check for gcd over all infcheckvars */
6159  if( possiblegcd )
6160  {
6161  v = ninfcheckvars - 1;
6162  gcdinfvars = (SCIP_Longint)(REALABS(infcheckvals[v]) + feastol);
6163  assert(gcdinfvars >= 2);
6164 
6165  for( ; v >= 0 && gcdinfvars >= 2; --v )
6166  {
6167  gcdinfvars = SCIPcalcGreComDiv(gcdinfvars, (SCIP_Longint)(REALABS(infcheckvals[v]) + feastol));
6168  }
6169  }
6170  else if( gcdisone )
6171  gcdinfvars = 1;
6172 
6173  SCIPdebugMsg(scip, "gcdinfvars =%lld, possiblegcd = %u\n", gcdinfvars, possiblegcd);
6174 
6175  /* compute solutions for this ranged row, if all variables are of integral type with integral coefficients */
6176  if( gcdinfvars >= 1 )
6177  {
6178  SCIP_Real value;
6179  SCIP_Real value2;
6180  SCIP_Real minvalue = SCIP_INVALID;
6181  SCIP_Real maxvalue = SCIP_INVALID;
6182  int nsols = 0;
6183 
6184  value = SCIPceil(scip, minactinfvars - SCIPfeastol(scip));
6185 
6186  /* check how many possible solutions exist */
6187  while( SCIPisLE(scip, value, maxactinfvars) )
6188  {
6189  value2 = value + gcd * (SCIPceil(scip, (lhs - value) / gcd));
6190 
6191  /* value2 might violate lhs due to numerics, in this case take the next divisible number */
6192  if( !SCIPisGE(scip, value2, lhs) )
6193  {
6194  value2 += gcd;
6195  }
6196 
6197  if( SCIPisLE(scip, value2, rhs) )
6198  {
6199  ++nsols;
6200 
6201  /* early termination if we found more than two solutions */
6202  if( nsols == 3 )
6203  break;
6204 
6205  if( minvalue == SCIP_INVALID ) /*lint !e777*/
6206  minvalue = value;
6207 
6208  maxvalue = value;
6209  }
6210  value += gcdinfvars;
6211  }
6212  assert(nsols < 2 || minvalue <= maxvalue);
6213 
6214  /* determine last possible solution for better bounding */
6215  if( nsols == 3 )
6216  {
6217 #ifndef NDEBUG
6218  SCIP_Real secondsolval = maxvalue;
6219 #endif
6220  value = SCIPfloor(scip, maxactinfvars + SCIPfeastol(scip));
6221 
6222  /* check how many possible solutions exist */
6223  while( SCIPisGE(scip, value, minactinfvars) )
6224  {
6225  value2 = value + gcd * (SCIPfloor(scip, (rhs - value) / gcd));
6226 
6227  /* value2 might violate rhs due to numerics, in this case take the next divisible number */
6228  if( !SCIPisLE(scip, value2, rhs) )
6229  {
6230  value2 -= gcd;
6231  }
6232 
6233  if( SCIPisGE(scip, value2, lhs) )
6234  {
6235  maxvalue = value;
6236  assert(maxvalue > minvalue);
6237  break;
6238  }
6239  value -= gcdinfvars;
6240  }
6241  assert(maxvalue > secondsolval);
6242  }
6243 
6244  SCIPdebugMsg(scip, "here nsols %s %d, minsolvalue = %g, maxsolvalue = %g, ninfcheckvars = %d, nunfixedvars = %d\n",
6245  nsols > 2 ? ">=" : "=", nsols, minvalue, maxvalue, ninfcheckvars, nunfixedvars);
6246 
6247  /* no possible solution found */
6248  if( nsols == 0 )
6249  {
6250  SCIPdebugMsg(scip, "gcdinfvars = %lld, gcd = %lld, correctedlhs = %g, correctedrhs = %g\n",
6251  gcdinfvars, gcd, lhs, rhs);
6252  SCIPdebugMsg(scip, "no solution found; constraint <%s> lead to infeasibility\n", SCIPconsGetName(cons));
6253  SCIPdebugPrintCons(scip, cons, NULL);
6254 
6255  /* start conflict analysis */
6256  /* @todo improve conflict analysis by adding relaxed bounds */
6257  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6258 
6259  *cutoff = TRUE;
6260  }
6261  /* if only one solution exist we can extract a new constraint or fix variables */
6262  else if( nsols == 1 )
6263  {
6264  assert(minvalue == maxvalue); /*lint !e777*/
6265 
6266  /* we can fix the only variable in our second set of variables */
6267  if( ninfcheckvars == 1 )
6268  {
6269  SCIP_Bool fixed;
6270 
6271  assert(SCIPisEQ(scip, (SCIP_Real)gcdinfvars, REALABS(infcheckvals[0])));
6272 
6273  SCIPdebugMsg(scip, "fixing single variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
6274  SCIPvarGetName(infcheckvars[0]), SCIPvarGetLbLocal(infcheckvars[0]),
6275  SCIPvarGetUbLocal(infcheckvars[0]), maxvalue/infcheckvals[0]);
6276 
6277  /* fix variable to only possible value */
6278  SCIP_CALL( SCIPinferVarFixCons(scip, infcheckvars[0], maxvalue/infcheckvals[0], cons,
6279  getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &fixed) );
6280 
6281  if( *cutoff )
6282  {
6283  /* start conflict analysis */
6284  /* @todo improve conflict analysis by adding relaxed bounds */
6285  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6286  }
6287 
6288  if( fixed )
6289  ++(*nfixedvars);
6290  }
6291  else
6292  {
6293  /* check for exactly one unfixed variable which is not part of the infcheckvars */
6294  if( ninfcheckvars == nunfixedvars - 1 )
6295  {
6296  SCIP_Real bound;
6297  SCIP_Bool foundvar = FALSE;
6298  SCIP_Bool fixed;
6299  int w = 0;
6300 
6301  assert(ninfcheckvars > 0);
6302 
6303  /* find variable which is not an infcheckvar and fix it */
6304  for( v = 0; v < consdata->nvars - 1; ++v )
6305  {
6306  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6307  {
6308  if( w >= ninfcheckvars || consdata->vars[v] != infcheckvars[w] )
6309  {
6310 #ifndef NDEBUG
6311  int v2 = v + 1;
6312  int w2 = w;
6313 
6314  assert((nfixedconsvars == 0) ? (consdata->nvars - v - 1 == ninfcheckvars - w) : TRUE);
6315 
6316  for( ; v2 < consdata->nvars && w2 < ninfcheckvars; ++v2 )
6317  {
6318  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v2]), SCIPvarGetUbLocal(consdata->vars[v2])) )
6319  continue;
6320 
6321  assert(consdata->vars[v2] == infcheckvars[w2]);
6322  ++w2;
6323  }
6324  assert(w2 == ninfcheckvars);
6325 #endif
6326  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6327 
6328  foundvar = TRUE;
6329 
6330  if( consdata->vals[v] < 0 )
6331  {
6332  bound = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6333  }
6334  else
6335  {
6336  bound = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6337  }
6338 
6339  SCIPdebugMsg(scip, "fixing variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
6340  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]),
6341  SCIPvarGetUbLocal(consdata->vars[v]), bound);
6342 
6343  /* fix variable to only possible value */
6344  SCIP_CALL( SCIPinferVarFixCons(scip, consdata->vars[v], bound, cons,
6345  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &fixed) );
6346 
6347  if( *cutoff )
6348  {
6349  /* start conflict analysis */
6350  /* @todo improve conflict analysis by adding relaxed bounds */
6351  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6352  consdata->vars[v], bound) );
6353  }
6354 
6355  if( fixed )
6356  ++(*nfixedvars);
6357 
6358  break;
6359  }
6360 
6361  ++w;
6362  }
6363  }
6364 
6365  /* maybe last variable was the not infcheckvar */
6366  if( !foundvar )
6367  {
6368  assert(v == consdata->nvars - 1);
6369  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6370 
6371  if( consdata->vals[v] < 0 )
6372  {
6373  bound = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6374  }
6375  else
6376  {
6377  bound = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6378  }
6379 
6380  SCIPdebugMsg(scip, "fixing variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
6381  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]),
6382  SCIPvarGetUbLocal(consdata->vars[v]), bound);
6383 
6384  /* fix variable to only possible value */
6385  SCIP_CALL( SCIPinferVarFixCons(scip, consdata->vars[v], bound, cons,
6386  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &fixed) );
6387 
6388  if( *cutoff )
6389  {
6390  /* start conflict analysis */
6391  /* @todo improve conflict analysis by adding relaxed bounds */
6392  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6393  consdata->vars[v], bound) );
6394  }
6395 
6396  if( fixed )
6397  ++(*nfixedvars);
6398  }
6399  }
6400  else if( addartconss && (SCIPisGT(scip, minvalue, minactinfvars) || SCIPisLT(scip, maxvalue, maxactinfvars)) )
6401  {
6402  /* aggregation possible if we have two variables, but this will be done later on */
6403  SCIP_CONS* newcons;
6404  char name[SCIP_MAXSTRLEN];
6405 
6406  /* create, add, and release new artificial constraint */
6407  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6408  ++conshdlrdata->naddconss;
6409 
6410  SCIPdebugMsg(scip, "adding artificial constraint %s\n", name);
6411 
6412  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals,
6413  maxvalue, maxvalue, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6414  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6415 
6416  SCIPdebugPrintCons(scip, newcons, NULL);
6417 
6418  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6419 
6420  ++(*naddconss);
6421  }
6422  }
6423  }
6424  /* at least two solutions */
6425  else
6426  {
6427  /* @todo if we found more then one solution, we may reduced domains due to dualpresolving? */
6428 
6429  /* only one variable in the second set, so we can bound this variables */
6430  if( ninfcheckvars == 1 )
6431  {
6432  SCIP_Bool tightened;
6433  SCIP_Real newlb;
6434  SCIP_Real newub;
6435 
6436  assert(SCIPisEQ(scip, (SCIP_Real)gcdinfvars, REALABS(infcheckvals[0])));
6437 
6438  if( infcheckvals[0] < 0 )
6439  {
6440  newlb = maxvalue/infcheckvals[0];
6441  newub = minvalue/infcheckvals[0];
6442  }
6443  else
6444  {
6445  newlb = minvalue/infcheckvals[0];
6446  newub = maxvalue/infcheckvals[0];
6447  }
6448  assert(newlb < newub);
6449 
6450  if( newlb > SCIPvarGetLbLocal(infcheckvars[0]) )
6451  {
6452  /* update lower bound of variable */
6453  SCIPdebugMsg(scip, "tightening lower bound of variable <%s> from %g to %g\n",
6454  SCIPvarGetName(infcheckvars[0]), SCIPvarGetLbLocal(infcheckvars[0]), newlb);
6455 
6456  /* tighten variable lower bound to minimal possible value */
6457  SCIP_CALL( SCIPinferVarLbCons(scip, infcheckvars[0], newlb, cons,
6458  getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &tightened) );
6459 
6460  if( *cutoff )
6461  {
6462  /* start conflict analysis */
6463  /* @todo improve conflict analysis by adding relaxed bounds */
6464  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6465  }
6466 
6467  if( tightened )
6468  ++(*nchgbds);
6469  }
6470 
6471  if( newub < SCIPvarGetUbLocal(infcheckvars[0]) )
6472  {
6473  /* update upper bound of variable */
6474  SCIPdebugMsg(scip, "tightening upper bound of variable <%s> from %g to %g\n",
6475  SCIPvarGetName(infcheckvars[0]), SCIPvarGetUbLocal(infcheckvars[0]), newub);
6476 
6477  /* tighten variable upper bound to maximal possible value */
6478  SCIP_CALL( SCIPinferVarUbCons(scip, infcheckvars[0], newub, cons,
6479  getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &tightened) );
6480 
6481  if( *cutoff )
6482  {
6483  /* start conflict analysis */
6484  /* @todo improve conflict analysis by adding relaxed bounds */
6485  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6486  }
6487 
6488  if( tightened )
6489  ++(*nchgbds);
6490  }
6491  }
6492  /* check if we have only one not infcheckvars, if so we can tighten this variable */
6493  else if( ninfcheckvars == nunfixedvars - 1 )
6494  {
6495  SCIP_Bool foundvar = FALSE;
6496  SCIP_Bool tightened;
6497  SCIP_Real newlb;
6498  SCIP_Real newub;
6499  int w = 0;
6500 
6501  assert(ninfcheckvars > 0);
6502  assert(minvalue < maxvalue);
6503 
6504  /* find variable which is not an infcheckvar and fix it */
6505  for( v = 0; v < consdata->nvars - 1; ++v )
6506  {
6507  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6508  {
6509  if( w >= ninfcheckvars || consdata->vars[v] != infcheckvars[w] )
6510  {
6511 #ifndef NDEBUG
6512  int v2 = v + 1;
6513  int w2 = w;
6514 
6515  assert((nfixedconsvars == 0) ? (consdata->nvars - v - 1 == ninfcheckvars - w) : TRUE);
6516 
6517  for( ; v2 < consdata->nvars && w2 < ninfcheckvars; ++v2 )
6518  {
6519  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v2]), SCIPvarGetUbLocal(consdata->vars[v2])) )
6520  continue;
6521 
6522  assert(consdata->vars[v2] == infcheckvars[w2]);
6523  ++w2;
6524  }
6525  assert(w2 == ninfcheckvars);
6526 #endif
6527 
6528  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6529  foundvar = TRUE;
6530 
6531  if( consdata->vals[v] < 0 )
6532  {
6533  newlb = SCIPfloor(scip, (rhs - minvalue) / consdata->vals[v]);
6534  newub = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6535  }
6536  else
6537  {
6538  newlb = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6539  newub = SCIPceil(scip, (rhs - minvalue) / consdata->vals[v]);
6540  }
6541  assert(SCIPisLE(scip, newlb, newub));
6542 
6543  if( newlb > SCIPvarGetLbLocal(consdata->vars[v]) )
6544  {
6545  /* update lower bound of variable */
6546  SCIPdebugMsg(scip, "tightening lower bound of variable <%s> from %g to %g\n",
6547  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]), newlb);
6548 
6549  /* tighten variable lower bound to minimal possible value */
6550  SCIP_CALL( SCIPinferVarLbCons(scip, consdata->vars[v], newlb, cons,
6551  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6552 
6553  if( *cutoff )
6554  {
6555  /* start conflict analysis */
6556  /* @todo improve conflict analysis by adding relaxed bounds */
6557  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6558  consdata->vars[v], newlb) );
6559  }
6560 
6561  if( tightened )
6562  ++(*nchgbds);
6563  }
6564 
6565  if( newub < SCIPvarGetUbLocal(consdata->vars[v]) )
6566  {
6567  /* update upper bound of variable */
6568  SCIPdebugMsg(scip, "tightening upper bound of variable <%s> from %g to %g\n",
6569  SCIPvarGetName(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v]), newub);
6570 
6571  /* tighten variable upper bound to maximal possible value */
6572  SCIP_CALL( SCIPinferVarUbCons(scip, consdata->vars[v], newub, cons,
6573  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6574 
6575  if( *cutoff )
6576  {
6577  /* start conflict analysis */
6578  /* @todo improve conflict analysis by adding relaxed bounds */
6579  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6580  consdata->vars[v], newub) );
6581  }
6582 
6583  if( tightened )
6584  ++(*nchgbds);
6585  }
6586 
6587  break;
6588  }
6589 
6590  ++w;
6591  }
6592  }
6593 
6594  /* maybe last variable was the not infcheckvar */
6595  if( !foundvar )
6596  {
6597  assert(v == consdata->nvars - 1);
6598  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6599 
6600  if( consdata->vals[v] < 0 )
6601  {
6602  newlb = SCIPfloor(scip, (rhs - minvalue) / consdata->vals[v]);
6603  newub = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6604  }
6605  else
6606  {
6607  newlb = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6608  newub = SCIPceil(scip, (rhs - minvalue) / consdata->vals[v]);
6609  }
6610  assert(SCIPisLE(scip, newlb, newub));
6611 
6612  if( newlb > SCIPvarGetLbLocal(consdata->vars[v]) )
6613  {
6614  /* update lower bound of variable */
6615  SCIPdebugMsg(scip, "tightening lower bound of variable <%s> from %g to %g\n",
6616  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]), newlb);
6617 
6618  /* tighten variable lower bound to minimal possible value */
6619  SCIP_CALL( SCIPinferVarLbCons(scip, consdata->vars[v], newlb, cons,
6620  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6621 
6622  if( *cutoff )
6623  {
6624  /* start conflict analysis */
6625  /* @todo improve conflict analysis by adding relaxed bounds */
6626  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, consdata->vars[v], newlb) );
6627  }
6628 
6629  if( tightened )
6630  ++(*nchgbds);
6631  }
6632 
6633  if( newub < SCIPvarGetUbLocal(consdata->vars[v]) )
6634  {
6635  /* update upper bound of variable */
6636  SCIPdebugMsg(scip, "tightening upper bound of variable <%s> from %g to %g\n",
6637  SCIPvarGetName(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v]), newub);
6638 
6639  /* tighten variable upper bound to maximal possible value */
6640  SCIP_CALL( SCIPinferVarUbCons(scip, consdata->vars[v], newub, cons,
6641  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6642 
6643  if( *cutoff )
6644  {
6645  /* start conflict analysis */
6646  /* @todo improve conflict analysis by adding relaxed bounds */
6647  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, consdata->vars[v], newub) );
6648  }
6649 
6650  if( tightened )
6651  ++(*nchgbds);
6652  }
6653  }
6654  }
6655  /* at least two solutions and more than one variable, so we add a new constraint which bounds the feasible
6656  * region for our infcheckvars, if possible
6657  */
6658  else if( addartconss && (SCIPisGT(scip, minvalue, minactinfvars) || SCIPisLT(scip, maxvalue, maxactinfvars)) )
6659  {
6660  SCIP_CONS* newcons;
6661  char name[SCIP_MAXSTRLEN];
6662  SCIP_Real newlhs;
6663  SCIP_Real newrhs;
6664 
6665  assert(maxvalue > minvalue);
6666 
6667  if( SCIPisGT(scip, minvalue, minactinfvars) )
6668  newlhs = minvalue;
6669  else
6670  newlhs = -SCIPinfinity(scip);
6671 
6672  if( SCIPisLT(scip, maxvalue, maxactinfvars) )
6673  newrhs = maxvalue;
6674  else
6675  newrhs = SCIPinfinity(scip);
6676 
6677  if( !SCIPisInfinity(scip, -newlhs) || !SCIPisInfinity(scip, newrhs) )
6678  {
6679  /* create, add, and release new artificial constraint */
6680  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons1_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6681  ++conshdlrdata->naddconss;
6682 
6683  SCIPdebugMsg(scip, "adding artificial constraint %s\n", name);
6684 
6685  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals, newlhs, newrhs,
6686  TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6687  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6688 
6689  SCIPdebugPrintCons(scip, newcons, NULL);
6690  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6691 
6692  ++(*naddconss);
6693  }
6694  /* @todo maybe add constraint for all variables which are not infcheckvars, lhs should be minvalue, rhs
6695  * should be maxvalue */
6696  }
6697  }
6698  }
6699  }
6700  else if( addartconss && ncontvars < ninfcheckvars )
6701  {
6702  SCIP_Real maxact = 0.0;
6703  SCIP_Real minact = 0.0;
6704  int w = 0;
6705 
6706  /* compute activities of non-infcheckvars */
6707  for( v = 0; v < consdata->nvars; ++v )
6708  {
6709  if( w < ninfcheckvars && consdata->vars[v] == infcheckvars[w] )
6710  {
6711  ++w;
6712  continue;
6713  }
6714 
6715  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6716  {
6717  if( SCIPvarIsBinary(consdata->vars[v]) )
6718  {
6719  if( consdata->vals[v] > 0.0 )
6720  maxact += consdata->vals[v];
6721  else
6722  minact += consdata->vals[v];
6723  }
6724  else
6725  {
6726  SCIP_Real tmpval;
6727 
6728  assert(SCIPvarIsIntegral(consdata->vars[v]));
6729 
6730  if( consdata->vals[v] > 0.0 )
6731  {
6732  tmpval = consdata->vals[v] * SCIPvarGetLbLocal(consdata->vars[v]);
6733 
6734  if( SCIPisHugeValue(scip, -tmpval) )
6735  break;
6736 
6737  minact += tmpval;
6738 
6739  tmpval = consdata->vals[v] * SCIPvarGetUbLocal(consdata->vars[v]);
6740 
6741  if( SCIPisHugeValue(scip, tmpval) )
6742  break;
6743 
6744  maxact += tmpval;
6745  }
6746  else
6747  {
6748  tmpval = consdata->vals[v] * SCIPvarGetUbLocal(consdata->vars[v]);
6749 
6750  if( SCIPisHugeValue(scip, -tmpval) )
6751  break;
6752 
6753  minact += tmpval;
6754 
6755  tmpval = consdata->vals[v] * SCIPvarGetLbLocal(consdata->vars[v]);
6756 
6757  if( SCIPisHugeValue(scip, tmpval) )
6758  break;
6759 
6760  maxact += tmpval;
6761  }
6762  }
6763  }
6764  }
6765  if( v == consdata->nvars && !SCIPisHugeValue(scip, -minact) && !SCIPisHugeValue(scip, maxact) )
6766  {
6767  SCIP_CONS* newcons;
6768  char name[SCIP_MAXSTRLEN];
6769  SCIP_Real newlhs;
6770  SCIP_Real newrhs;
6771 
6772  assert(maxact > minact);
6773  assert(w == ninfcheckvars);
6774 
6775  newlhs = lhs - maxact;
6776  newrhs = rhs - minact;
6777  assert(newlhs < newrhs);
6778 
6779  /* create, add, and release new artificial constraint */
6780  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons2_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6781  ++conshdlrdata->naddconss;
6782 
6783  SCIPdebugMsg(scip, "adding artificial constraint %s\n", name);
6784 
6785  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals, newlhs, newrhs,
6786  TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6787  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6788 
6789  SCIPdebugPrintCons(scip, newcons, NULL);
6790  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6791 
6792  ++(*naddconss);
6793  }
6794  }
6795 
6796  TERMINATE:
6797  SCIPfreeBufferArray(scip, &infcheckvals);
6798  SCIPfreeBufferArray(scip, &infcheckvars);
6799 
6800  return SCIP_OKAY;
6801 }
6802 
6803 /** tightens bounds of a single variable due to activity bounds */
6804 static
6806  SCIP* scip, /**< SCIP data structure */
6807  SCIP_CONS* cons, /**< linear constraint */
6808  int pos, /**< position of the variable in the vars array */
6809  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
6810  int* nchgbds, /**< pointer to count the total number of tightened bounds */
6811  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
6812  )
6813 {
6814  SCIP_CONSDATA* consdata;
6815  SCIP_VAR* var;
6816  SCIP_Real val;
6817  SCIP_Real lb;
6818  SCIP_Real ub;
6819  SCIP_Real minresactivity;
6820  SCIP_Real maxresactivity;
6821  SCIP_Real lhs;
6822  SCIP_Real rhs;
6823  SCIP_Bool infeasible;
6824  SCIP_Bool tightened;
6825  SCIP_Bool minisrelax;
6826  SCIP_Bool maxisrelax;
6827  SCIP_Bool isminsettoinfinity;
6828  SCIP_Bool ismaxsettoinfinity;
6829 
6830  assert(scip != NULL);
6831  assert(cons != NULL);
6832  assert(cutoff != NULL);
6833  assert(nchgbds != NULL);
6834 
6835  /* we cannot tighten variables' bounds, if the constraint may be not complete */
6836  if( SCIPconsIsModifiable(cons) )
6837  return SCIP_OKAY;
6838 
6839  consdata = SCIPconsGetData(cons);
6840  assert(consdata != NULL);
6841  assert(0 <= pos && pos < consdata->nvars);
6842 
6843  *cutoff = FALSE;
6844 
6845  var = consdata->vars[pos];
6846 
6847  /* we cannot tighten bounds of multi-aggregated variables */
6849  return SCIP_OKAY;
6850 
6851  val = consdata->vals[pos];
6852  lhs = consdata->lhs;
6853  rhs = consdata->rhs;
6854  consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
6855  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
6856  assert(var != NULL);
6857  assert(!SCIPisZero(scip, val));
6858  assert(!SCIPisInfinity(scip, lhs));
6859  assert(!SCIPisInfinity(scip, -rhs));
6860 
6861  lb = SCIPvarGetLbLocal(var);
6862  ub = SCIPvarGetUbLocal(var);
6863  assert(SCIPisLE(scip, lb, ub));
6864 
6865  if( val > 0.0 )
6866  {
6867  /* check, if we can tighten the variable's bounds */
6868  if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && !minisrelax )
6869  {
6870  SCIP_Real newub;
6871 
6872  newub = (rhs - minresactivity)/val;
6873 
6874  if( !SCIPisInfinity(scip, newub) &&
6875  ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
6876  {
6877  SCIP_Bool activityunreliable;
6878  activityunreliable = SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity);
6879 
6880  /* check minresactivities for reliability */
6881  if( activityunreliable )
6882  {
6883  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
6884  newub = (rhs - minresactivity)/val;
6885  activityunreliable = SCIPisInfinity(scip, -minresactivity) ||
6886  (!SCIPisUbBetter(scip, newub, lb, ub) && (!SCIPisFeasLT(scip, newub, ub) || !SCIPvarIsIntegral(var))
6887  && (!force || !SCIPisLT(scip, newub, ub)));
6888  }
6889 
6890  if( !activityunreliable )
6891  {
6892  /* tighten upper bound */
6893  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newub=%.15g\n",
6894  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newub);
6895  SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_RHS, pos), force,
6896  &infeasible, &tightened) );
6897  if( infeasible )
6898  {
6899  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
6900  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
6901 
6902  /* analyze conflict */
6903  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
6904 
6905  *cutoff = TRUE;
6906  return SCIP_OKAY;
6907  }
6908  if( tightened )
6909  {
6910  ub = SCIPvarGetUbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6911  assert(SCIPisFeasLE(scip, ub, newub));
6912  (*nchgbds)++;
6913 
6914  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6915  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6916  }
6917  }
6918  }
6919  }
6920 
6921  if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && !maxisrelax )
6922  {
6923  SCIP_Real newlb;
6924 
6925  newlb = (lhs - maxresactivity)/val;
6926  if( !SCIPisInfinity(scip, -newlb) &&
6927  ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
6928  {
6929  /* check maxresactivities for reliability */
6930  if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
6931  {
6932  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
6933  newlb = (lhs - maxresactivity)/val;
6934 
6935  if( SCIPisInfinity(scip, maxresactivity) || (!SCIPisLbBetter(scip, newlb, lb, ub)
6936  && (!SCIPisFeasGT(scip, newlb, lb) || !SCIPvarIsIntegral(var))
6937  && (!force || !SCIPisGT(scip, newlb, lb))) )
6938  return SCIP_OKAY;
6939  }
6940 
6941  /* tighten lower bound */
6942  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
6943  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newlb);
6944  SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_LHS, pos), force,
6945  &infeasible, &tightened) );
6946  if( infeasible )
6947  {
6948  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
6949  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
6950 
6951  /* analyze conflict */
6952  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
6953 
6954  *cutoff = TRUE;
6955  return SCIP_OKAY;
6956  }
6957  if( tightened )
6958  {
6959  lb = SCIPvarGetLbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6960  assert(SCIPisFeasGE(scip, lb, newlb));
6961  (*nchgbds)++;
6962  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6963  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6964  }
6965  }
6966  }
6967  }
6968  else
6969  {
6970  /* check, if we can tighten the variable's bounds */
6971  if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && !minisrelax )
6972  {
6973  SCIP_Real newlb;
6974 
6975  newlb = (rhs - minresactivity)/val;
6976  if( !SCIPisInfinity(scip, -newlb) &&
6977  ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
6978  {
6979  SCIP_Bool activityunreliable;
6980  activityunreliable = SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity);
6981  /* check minresactivities for reliability */
6982  if( activityunreliable )
6983  {
6984  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
6985  newlb = (rhs - minresactivity)/val;
6986 
6987  activityunreliable = SCIPisInfinity(scip, -minresactivity)
6988  || (!SCIPisLbBetter(scip, newlb, lb, ub) && (!SCIPisFeasGT(scip, newlb, lb) || !SCIPvarIsIntegral(var))
6989  && (!force || !SCIPisGT(scip, newlb, lb)));
6990  }
6991 
6992  if( !activityunreliable )
6993  {
6994  /* tighten lower bound */
6995  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
6996  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newlb);
6997  SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_RHS, pos), force,
6998  &infeasible, &tightened) );
6999  if( infeasible )
7000  {
7001  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
7002  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
7003 
7004  /* analyze conflict */
7005  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
7006 
7007  *cutoff = TRUE;
7008  return SCIP_OKAY;
7009  }
7010  if( tightened )
7011  {
7012  lb = SCIPvarGetLbLocal(var); /* get bound again: it may be additionally modified due to integrality */
7013  assert(SCIPisFeasGE(scip, lb, newlb));
7014  (*nchgbds)++;
7015  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
7016  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
7017  }
7018  }
7019  }
7020  }
7021 
7022  if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && !maxisrelax )
7023  {
7024  SCIP_Real newub;
7025 
7026  newub = (lhs - maxresactivity)/val;
7027  if( !SCIPisInfinity(scip, newub) &&
7028  ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
7029  {
7030  /* check maxresactivities for reliability */
7031  if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
7032  {
7033  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
7034  newub = (lhs - maxresactivity)/val;
7035 
7036  if( SCIPisInfinity(scip, maxresactivity) || (!SCIPisUbBetter(scip, newub, lb, ub)
7037  && (!SCIPisFeasLT(scip, newub, ub) && !SCIPvarIsIntegral(var))
7038  && (!force || !SCIPisLT(scip, newub, ub))) )
7039  return SCIP_OKAY;
7040  }
7041 
7042  /* tighten upper bound */
7043  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g], newub=%.15g\n",
7044  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newub);
7045  SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_LHS, pos), force,
7046  &infeasible, &tightened) );
7047  if( infeasible )
7048  {
7049  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
7050  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
7051 
7052  /* analyze conflict */
7053  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
7054 
7055  *cutoff = TRUE;
7056  return SCIP_OKAY;
7057  }
7058  if( tightened )
7059  {
7060  ub = SCIPvarGetUbLocal(var); /* get bound again: it may be additionally modified due to integrality */
7061  assert(SCIPisFeasLE(scip, ub, newub));
7062  (*nchgbds)++;
7063  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
7064  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
7065  }
7066  }
7067  }
7068  }
7069 
7070  return SCIP_OKAY;
7071 }
7072 
7073 #define MAXTIGHTENROUNDS 10
7074 
7075 /** tightens bounds of variables in constraint due to activity bounds */
7076 static
7078  SCIP* scip, /**< SCIP data structure */
7079  SCIP_CONS* cons, /**< linear constraint */
7080  SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
7081  SCIP_Bool sortvars, /**< should variables be used in sorted order? */
7082  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
7083  int* nchgbds /**< pointer to count the total number of tightened bounds */
7084  )
7085 {
7086  SCIP_CONSDATA* consdata;
7087  unsigned int tightenmode;
7088  int nvars;
7089  int nrounds;
7090  int lastchange;
7091  int oldnchgbds;
7092 #ifndef SCIP_DEBUG
7093  int oldnchgbdstotal;
7094 #endif
7095  int v;
7096  SCIP_Bool force;
7097  SCIP_Bool easycase;
7098 
7099  assert(scip != NULL);
7100  assert(cons != NULL);
7101  assert(nchgbds != NULL);
7102  assert(cutoff != NULL);
7103 
7104  *cutoff = FALSE;
7105 
7106  /* we cannot tighten variables' bounds, if the constraint may be not complete */
7107  if( SCIPconsIsModifiable(cons) )
7108  return SCIP_OKAY;
7109 
7110  /* if a constraint was created after presolve, then it may hold fixed variables
7111  * if there are even multi-aggregated variables, then we cannot do bound tightening on these
7112  * thus, ensure here again that variable fixings have been applied
7113  */
7114  SCIP_CALL( applyFixings(scip, cons, cutoff) );
7115  if( *cutoff )
7116  return SCIP_OKAY;
7117 
7118  /* check if constraint has any chances of tightening bounds */
7119  if( !canTightenBounds(cons) )
7120  return SCIP_OKAY;
7121 
7122  consdata = SCIPconsGetData(cons);
7123  assert(consdata != NULL);
7124 
7125  nvars = consdata->nvars;
7126  force = (nvars == 1) && !SCIPconsIsModifiable(cons);
7127 
7128  /* we are at the root node or during presolving */
7129  if( SCIPgetDepth(scip) < 1 )
7130  tightenmode = 2;
7131  else
7132  tightenmode = 1;
7133 
7134  /* stop if we already tightened the constraint and the tightening is not forced */
7135  if( !force && (consdata->boundstightened >= tightenmode) ) /*lint !e574*/
7136  return SCIP_OKAY;
7137 
7138  /* ensure that the variables are properly sorted */
7139  if( sortvars && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE && !consdata->coefsorted )
7140  {
7141  SCIP_CALL( consdataSort(scip, consdata) );
7142  assert(consdata->coefsorted);
7143  }
7144 
7145  /* update maximal activity delta if necessary */
7146  if( consdata->maxactdelta == SCIP_INVALID ) /*lint !e777*/
7147  consdataRecomputeMaxActivityDelta(scip, consdata);
7148 
7149  assert(consdata->maxactdelta != SCIP_INVALID); /*lint !e777*/
7150  assert(!SCIPisFeasNegative(scip, consdata->maxactdelta));
7151  checkMaxActivityDelta(scip, consdata);
7152 
7153  /* this may happen if all variables are fixed */
7154  if( SCIPisFeasZero(scip, consdata->maxactdelta) )
7155  return SCIP_OKAY;
7156 
7157  if( !SCIPisInfinity(scip, consdata->maxactdelta) )
7158  {
7159  SCIP_Real slack;
7160  SCIP_Real surplus;
7161  SCIP_Real minactivity;
7162  SCIP_Real maxactivity;
7163  SCIP_Bool minisrelax;
7164  SCIP_Bool maxisrelax;
7165  SCIP_Bool isminsettoinfinity;
7166  SCIP_Bool ismaxsettoinfinity;
7167 
7168  /* use maximal activity delta to skip propagation (cannot deduce anything) */
7169  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minisrelax, &maxisrelax,
7170  &isminsettoinfinity, &ismaxsettoinfinity);
7171  assert(!SCIPisInfinity(scip, minactivity));
7172  assert(!SCIPisInfinity(scip, -maxactivity));
7173 
7174  slack = (SCIPisInfinity(scip, consdata->rhs) || isminsettoinfinity) ? SCIPinfinity(scip) : (consdata->rhs - minactivity);
7175  surplus = (SCIPisInfinity(scip, -consdata->lhs) || ismaxsettoinfinity) ? SCIPinfinity(scip) : (maxactivity - consdata->lhs);
7176 
7177  /* check if the constraint will propagate */
7178  if( SCIPisLE(scip, consdata->maxactdelta, MIN(slack, surplus)) )
7179  return SCIP_OKAY;
7180  }
7181 
7182  /* check if we can use fast implementation for easy and numerically well behaved cases */
7183  easycase = SCIPisLT(scip, consdata->maxactdelta, maxeasyactivitydelta);
7184 
7185  /* as long as the bounds might be tightened again, try to tighten them; abort after a maximal number of rounds */
7186  lastchange = -1;
7187  oldnchgbds = 0;
7188 
7189 #ifndef SCIP_DEBUG
7190  oldnchgbdstotal = *nchgbds;
7191 #endif
7192 
7193  for( nrounds = 0; (force || consdata->boundstightened < tightenmode) && nrounds < MAXTIGHTENROUNDS; ++nrounds ) /*lint !e574*/
7194  {
7195  /* ensure that the variables are properly sorted
7196  *
7197  * note: it might happen that integer variables become binary during bound tightening at the root node
7198  */
7199  if( sortvars && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE && !consdata->coefsorted )
7200  {
7201  SCIP_CALL( consdataSort(scip, consdata) );
7202  assert(consdata->coefsorted);
7203  }
7204 
7205  /* mark the constraint to have the variables' bounds tightened */
7206  consdata->boundstightened = (unsigned int)tightenmode;
7207 
7208  /* try to tighten the bounds of each variable in the constraint. During solving process, the binary variable
7209  * sorting enables skipping variables
7210  */
7211  v = 0;
7212  while( v < nvars && v != lastchange && !(*cutoff) )
7213  {
7214  oldnchgbds = *nchgbds;
7215 
7216  if( easycase )
7217  {
7218  SCIP_CALL( tightenVarBoundsEasy(scip, cons, v, cutoff, nchgbds, force) );
7219  }
7220  else
7221  {
7222  SCIP_CALL( tightenVarBounds(scip, cons, v, cutoff, nchgbds, force) );
7223  }
7224 
7225  /* if there was no progress, skip the rest of the binary variables */
7226  if( *nchgbds > oldnchgbds )
7227  {
7228  lastchange = v;
7229  ++v;
7230  }
7231  else if( consdata->coefsorted && v < consdata->nbinvars - 1
7232  && !SCIPisFeasEQ(scip, SCIPvarGetUbLocal(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v])) )
7233  v = consdata->nbinvars;
7234  else
7235  ++v;
7236  }
7237 
7238 #ifndef SCIP_DEBUG
7239  SCIPdebugMessage("linear constraint <%s> found %d bound changes in round %d\n", SCIPconsGetName(cons),
7240  *nchgbds - oldnchgbdstotal, nrounds);
7241  oldnchgbdstotal += oldnchgbds;
7242 #endif
7243  }
7244 
7245 #ifndef NDEBUG
7246  if( force && SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
7247  assert(*cutoff || SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->vars[0]), SCIPvarGetUbLocal(consdata->vars[0])));
7248 #endif
7249 
7250  return SCIP_OKAY;
7251 }
7252 
7253 /** checks linear constraint for feasibility of given solution or current solution */
7254 static
7256  SCIP* scip, /**< SCIP data structure */
7257  SCIP_CONS* cons, /**< linear constraint */
7258  SCIP_SOL* sol, /**< solution to be checked, or NULL for current solution */
7259  SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
7260  SCIP_Bool checkrelmaxabs, /**< Should the violation for a constraint with side 0.0 be checked relative
7261  * to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
7262  SCIP_Bool* violated /**< pointer to store whether the constraint is violated */
7263  )
7264 {
7265  SCIP_CONSDATA* consdata;
7266  SCIP_Real activity;
7267  SCIP_Real absviol;
7268  SCIP_Real relviol;
7269  SCIP_Real lhsviol;
7270  SCIP_Real rhsviol;
7271 
7272  assert(scip != NULL);
7273  assert(cons != NULL);
7274  assert(violated != NULL);
7275 
7276  SCIPdebugMsg(scip, "checking linear constraint <%s>\n", SCIPconsGetName(cons));
7277  SCIPdebugPrintCons(scip, cons, NULL);
7278 
7279  consdata = SCIPconsGetData(cons);
7280  assert(consdata != NULL);
7281 
7282  *violated = FALSE;
7283 
7284  if( consdata->row != NULL )
7285  {
7286  if( !checklprows && SCIProwIsInLP(consdata->row) )
7287  return SCIP_OKAY;
7288  else if( sol == NULL && !SCIPhasCurrentNodeLP(scip) )
7289  activity = consdataComputePseudoActivity(scip, consdata);
7290  else
7291  activity = SCIPgetRowSolActivity(scip, consdata->row, sol);
7292  }
7293  else
7294  activity = consdataGetActivity(scip, consdata, sol);
7295 
7296  SCIPdebugMsg(scip, " consdata activity=%.15g (lhs=%.15g, rhs=%.15g, row=%p, checklprows=%u, rowinlp=%u, sol=%p, hascurrentnodelp=%u)\n",
7297  activity, consdata->lhs, consdata->rhs, (void*)consdata->row, checklprows,
7298  consdata->row == NULL ? 0 : SCIProwIsInLP(consdata->row), (void*)sol,
7299  consdata->row == NULL ? FALSE : SCIPhasCurrentNodeLP(scip));
7300 
7301  /* calculate absolute and relative bound violations */
7302  lhsviol = consdata->lhs - activity;
7303  rhsviol = activity - consdata->rhs;
7304 
7305  absviol = 0.0;
7306  relviol = 0.0;
7307  if( (lhsviol > 0) && (lhsviol > rhsviol) )
7308  {
7309  absviol = lhsviol;
7310  relviol = SCIPrelDiff(consdata->lhs, activity);
7311  }
7312  else if( rhsviol > 0 )
7313  {
7314  absviol = rhsviol;
7315  relviol = SCIPrelDiff(activity, consdata->rhs);
7316  }
7317 
7318  /* the activity of pseudo solutions may be invalid if it comprises positive and negative infinity contributions; we
7319  * return infeasible for safety
7320  */
7321  if( activity == SCIP_INVALID ) /*lint !e777*/
7322  {
7323  assert(sol == NULL);
7324  *violated = TRUE;
7325 
7326  /* set violation of invalid pseudo solutions */
7327  absviol = SCIP_INVALID;
7328  relviol = SCIP_INVALID;
7329 
7330  /* reset constraint age since we are in enforcement */
7331  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7332  }
7333  /* check with relative tolerances (the default) */
7334  else if( !consdata->checkabsolute && (SCIPisFeasLT(scip, activity, consdata->lhs) || SCIPisFeasGT(scip, activity, consdata->rhs)) )
7335  {
7336  /* the "normal" check: one of the two sides is violated */
7337  if( !checkrelmaxabs )
7338  {
7339  *violated = TRUE;
7340 
7341  /* only reset constraint age if we are in enforcement */
7342  if( sol == NULL )
7343  {
7344  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7345  }
7346  }
7347  /* the (much) more complicated check: we try to disregard random noise and violations of a 0.0 side which are
7348  * small compared to the absolute values occurring in the activity
7349  */
7350  else
7351  {
7352  SCIP_Real maxabs;
7353  SCIP_Real coef;
7354  SCIP_Real absval;
7355  SCIP_Real solval;
7356  int v;
7357 
7358  maxabs = 1.0;
7359 
7360  /* compute maximum absolute value */
7361  for( v = 0; v < consdata->nvars; ++v )
7362  {
7363  if( consdata->vals != NULL )
7364  {
7365  coef = consdata->vals[v];
7366  }
7367  else
7368  coef = 1.0;
7369 
7370  solval = SCIPgetSolVal(scip, sol, consdata->vars[v]);
7371  absval = REALABS( coef * solval );
7372  maxabs = MAX( maxabs, absval );
7373  }
7374 
7375  /* regard left hand side, first */
7376  if( SCIPisFeasLT(scip, activity, consdata->lhs) )
7377  {
7378  /* check whether violation is random noise */
7379  if( (consdata->lhs - activity) <= (1e-15 * maxabs) )
7380  {
7381  SCIPdebugMsg(scip, " lhs violated due to random noise: violation=%16.9g, maxabs=%16.9g\n",
7382  consdata->lhs - activity, maxabs);
7383  SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
7384 
7385  /* only increase constraint age if we are in enforcement */
7386  if( sol == NULL )
7387  {
7388  SCIP_CALL( SCIPincConsAge(scip, cons) );
7389  }
7390  }
7391  /* lhs is violated and lhs is 0.0: use relative tolerance w.r.t. largest absolute value */
7392  else if( SCIPisZero(scip, consdata->lhs) )
7393  {
7394  if( (consdata->lhs - activity) <= (SCIPfeastol(scip) * maxabs) )
7395  {
7396  SCIPdebugMsg(scip, " lhs violated absolutely (violation=%16.9g), but feasible when using relative tolerance w.r.t. maximum absolute value (%16.9g)\n",
7397  consdata->lhs - activity, maxabs);
7398  SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
7399 
7400  /* only increase constraint age if we are in enforcement */
7401  if( sol == NULL )
7402  {
7403  SCIP_CALL( SCIPincConsAge(scip, cons) );
7404  }
7405  }
7406  else
7407  {
7408  *violated = TRUE;
7409 
7410  /* only reset constraint age if we are in enforcement */
7411  if( sol == NULL )
7412  {
7413  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7414  }
7415  }
7416  }
7417  else
7418  {
7419  *violated = TRUE;
7420 
7421  /* only reset constraint age if we are in enforcement */
7422  if( sol == NULL )
7423  {
7424  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7425  }
7426  }
7427  }
7428 
7429  /* now regard right hand side */
7430  if( SCIPisFeasGT(scip, activity, consdata->rhs) )
7431  {
7432  /* check whether violation is random noise */
7433  if( (activity - consdata->rhs) <= (1e-15 * maxabs) )
7434  {
7435  SCIPdebugMsg(scip, " rhs violated due to random noise: violation=%16.9g, maxabs=%16.9g\n",
7436  activity - consdata->rhs, maxabs);
7437  SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
7438 
7439  /* only increase constraint age if we are in enforcement */
7440  if( sol == NULL )
7441  {
7442  SCIP_CALL( SCIPincConsAge(scip, cons) );
7443  }
7444  }
7445  /* rhs is violated and rhs is 0.0, use relative tolerance w.r.t. largest absolute value */
7446  else if( SCIPisZero(scip, consdata->rhs) )
7447  {
7448  if( (activity - consdata->rhs) <= (SCIPfeastol(scip) * maxabs) )
7449  {
7450  SCIPdebugMsg(scip, " rhs violated absolutely (violation=%16.9g), but feasible when using relative tolerance w.r.t. maximum absolute value (%16.9g)\n",
7451  activity - consdata->rhs, maxabs);
7452  SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
7453 
7454  /* only increase constraint age if we are in enforcement */
7455  if( sol == NULL )
7456  {
7457  SCIP_CALL( SCIPincConsAge(scip, cons) );
7458  }
7459  }
7460  else
7461  {
7462  *violated = TRUE;
7463 
7464  /* only reset constraint age if we are in enforcement */
7465  if( sol == NULL )
7466  {
7467  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7468  }
7469  }
7470  }
7471  else
7472  {
7473  *violated = TRUE;
7474 
7475  /* only reset constraint age if we are in enforcement */
7476  if( sol == NULL )
7477  {
7478  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7479  }
7480  }
7481  }
7482  }
7483  }
7484  /* check with absolute tolerances */
7485  else if( consdata->checkabsolute &&
7486  ((!SCIPisInfinity(scip, -consdata->lhs) && SCIPisGT(scip, consdata->lhs-activity, SCIPfeastol(scip))) ||
7487  (!SCIPisInfinity(scip, consdata->rhs) && SCIPisGT(scip, activity-consdata->rhs, SCIPfeastol(scip)))) )
7488  {
7489  *violated = TRUE;
7490 
7491  /* only reset constraint age if we are in enforcement */
7492  if( sol == NULL )
7493  {
7494  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7495  }
7496  }
7497  else
7498  {
7499  /* only increase constraint age if we are in enforcement */
7500  if( sol == NULL )
7501  {
7502  SCIP_CALL( SCIPincConsAge(scip, cons) );
7503  }
7504  }
7505 
7506  /* update absolute and relative violation of the solution */
7507  if( sol != NULL )
7508  SCIPupdateSolLPConsViolation(scip, sol, absviol, relviol);
7509 
7510  return SCIP_OKAY;
7511 }
7512 
7513 /** creates an LP row in a linear constraint data */
7514 static
7516  SCIP* scip, /**< SCIP data structure */
7517  SCIP_CONS* cons /**< linear constraint */
7518  )
7519 {
7520  SCIP_CONSDATA* consdata;
7521 
7522  assert(scip != NULL);
7523  assert(cons != NULL);
7524 
7525  consdata = SCIPconsGetData(cons);
7526  assert(consdata != NULL);
7527  assert(consdata->row == NULL);
7528 
7529  SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row, cons, SCIPconsGetName(cons), consdata->lhs, consdata->rhs,
7531 
7532  SCIP_CALL( SCIPaddVarsToRow(scip, consdata->row, consdata->nvars, consdata->vars, consdata->vals) );
7533 
7534  return SCIP_OKAY;
7535 }
7536 
7537 /** adds linear constraint as cut to the LP */
7538 static
7540  SCIP* scip, /**< SCIP data structure */
7541  SCIP_CONS* cons, /**< linear constraint */
7542  SCIP_Bool* cutoff /**< pointer to store whether a cutoff was found */
7543  )
7544 {
7545  SCIP_CONSDATA* consdata;
7546 
7547  assert(scip != NULL);
7548  assert(cons != NULL);
7549 
7550  consdata = SCIPconsGetData(cons);
7551  assert(consdata != NULL);
7552 
7553  if( consdata->row == NULL )
7554  {
7555  if( !SCIPconsIsModifiable(cons) )
7556  {
7557  /* replace all fixed variables by active counterparts, as we have no chance to do this anymore after the row has been added to the LP
7558  * removing this here will make test cons/linear/fixedvar.c fail (as of 2018-12-03)
7559  */
7560  SCIP_CALL( applyFixings(scip, cons, cutoff) );
7561  if( *cutoff )
7562  return SCIP_OKAY;
7563  }
7564 
7565  /* convert consdata object into LP row */
7566  SCIP_CALL( createRow(scip, cons) );
7567  }
7568  assert(consdata->row != NULL);
7569 
7570  if( consdata->nvars == 0 )
7571  {
7572  SCIPdebugMsg(scip, "Empty linear constraint enters LP: <%s>\n", SCIPconsGetName(cons));
7573  }
7574 
7575  /* insert LP row as cut */
7576  if( !SCIProwIsInLP(consdata->row) )
7577  {
7578  SCIPdebugMsg(scip, "adding relaxation of linear constraint <%s>: ", SCIPconsGetName(cons));
7579  SCIPdebug( SCIP_CALL( SCIPprintRow(scip, consdata->row, NULL)) );
7580  /* if presolving is turned off, the row might be trivial */
7581  if ( ! SCIPisInfinity(scip, -consdata->lhs) || ! SCIPisInfinity(scip, consdata->rhs) )
7582  {
7583  SCIP_CALL( SCIPaddRow(scip, consdata->row, FALSE, cutoff) );
7584  }
7585 #ifndef NDEBUG
7586  else
7587  {
7588  int pr;
7589  int cr;
7590  SCIP_CALL( SCIPgetIntParam(scip, "presolving/maxrounds", &pr) );
7591  SCIP_CALL( SCIPgetIntParam(scip, "constraints/linear/maxprerounds", &cr) );
7592  assert( pr == 0 || cr == 0 );
7593  }
7594 #endif
7595  }
7596 
7597  return SCIP_OKAY;
7598 }
7599 
7600 /** adds linear constraint as row to the NLP, if not added yet */
7601 static
7603  SCIP* scip, /**< SCIP data structure */
7604  SCIP_CONS* cons /**< linear constraint */
7605  )
7606 {
7607  SCIP_CONSDATA* consdata;
7608 
7609  assert(SCIPisNLPConstructed(scip));
7610 
7611  /* skip deactivated, redundant, or local linear constraints (the NLP does not allow for local rows at the moment) */
7612  if( !SCIPconsIsActive(cons) || !SCIPconsIsChecked(cons) || SCIPconsIsLocal(cons) )
7613  return SCIP_OKAY;
7614 
7615  consdata = SCIPconsGetData(cons);
7616  assert(consdata != NULL);
7617 
7618  if( consdata->nlrow == NULL )
7619  {
7620  assert(consdata->lhs <= consdata->rhs);
7622  SCIP_CALL( SCIPcreateNlRow(scip, &consdata->nlrow, SCIPconsGetName(cons),
7623  0.0, consdata->nvars, consdata->vars, consdata->vals, NULL, consdata->lhs, consdata->rhs, SCIP_EXPRCURV_LINEAR) );
7624 
7625  assert(consdata->nlrow != NULL);
7626  }
7627 
7628  if( !SCIPnlrowIsInNLP(consdata->nlrow) )
7629  {
7630  SCIP_CALL( SCIPaddNlRow(scip, consdata->nlrow) );
7631  }
7632 
7633  return SCIP_OKAY;
7634 }
7635 
7636 /** separates linear constraint: adds linear constraint as cut, if violated by given solution */
7637 static
7639  SCIP* scip, /**< SCIP data structure */
7640  SCIP_CONS* cons, /**< linear constraint */
7641  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
7642  SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
7643  SCIP_Bool separatecards, /**< should knapsack cardinality cuts be generated? */
7644  SCIP_Bool separateall, /**< should all constraints be subject to cardinality cut generation instead of only
7645  * the ones with non-zero dual value? */
7646  int* ncuts, /**< pointer to add up the number of found cuts */
7647  SCIP_Bool* cutoff /**< pointer to store whether a cutoff was found */
7648  )
7649 {
7650  SCIP_CONSDATA* consdata;
7651  SCIP_Bool violated;
7652  int oldncuts;
7653 
7654  assert(scip != NULL);
7655  assert(conshdlrdata != NULL);
7656  assert(cons != NULL);
7657  assert(cutoff != NULL);
7658 
7659  consdata = SCIPconsGetData(cons);
7660  assert(ncuts != NULL);
7661  assert(consdata != NULL);
7662 
7663  oldncuts = *ncuts;
7664  *cutoff = FALSE;
7665 
7666  SCIP_CALL( checkCons(scip, cons, sol, (sol != NULL), conshdlrdata->checkrelmaxabs, &violated) );
7667 
7668  if( violated )
7669  {
7670  /* insert LP row as cut */
7671  SCIP_CALL( addRelaxation(scip, cons, cutoff) );
7672  (*ncuts)++;
7673  }
7674  else if( !SCIPconsIsModifiable(cons) && separatecards )
7675  {
7676  /* relax linear constraint into knapsack constraint and separate lifted cardinality cuts */
7677  if( !separateall && sol == NULL )
7678  {
7679  /* we only want to call the knapsack cardinality cut separator for rows that have a non-zero dual solution */
7680  if( consdata->row != NULL && SCIProwIsInLP(consdata->row) )
7681  {
7682  SCIP_Real dualsol;
7683 
7684  dualsol = SCIProwGetDualsol(consdata->row);
7685  if( SCIPisFeasNegative(scip, dualsol) )
7686  {
7687  if( !SCIPisInfinity(scip, consdata->rhs) )
7688  {
7689  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7690  consdata->vals, +1.0, consdata->rhs, sol, cutoff, ncuts) );
7691  }
7692  }
7693  else if( SCIPisFeasPositive(scip, dualsol) )
7694  {
7695  if( !SCIPisInfinity(scip, -consdata->lhs) )
7696  {
7697  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7698  consdata->vals, -1.0, -consdata->lhs, sol, cutoff, ncuts) );
7699  }
7700  }
7701  }
7702  }
7703  else
7704  {
7705  if( !SCIPisInfinity(scip, consdata->rhs) )
7706  {
7707  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7708  consdata->vals, +1.0, consdata->rhs, sol, cutoff, ncuts) );
7709  }
7710  if( !SCIPisInfinity(scip, -consdata->lhs) )
7711  {
7712  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7713  consdata->vals, -1.0, -consdata->lhs, sol, cutoff, ncuts) );
7714  }
7715  }
7716  }
7717 
7718  if( *ncuts > oldncuts )
7719  {
7720  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7721  }
7722 
7723  return SCIP_OKAY;
7724 }
7725 
7726 /** propagation method for linear constraints */
7727 static
7729  SCIP* scip, /**< SCIP data structure */
7730  SCIP_CONS* cons, /**< linear constraint */
7731  SCIP_Bool tightenbounds, /**< should the variable's bounds be tightened? */
7732  SCIP_Bool rangedrowpropagation,/**< should ranged row propagation be performed? */
7733  SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
7734  SCIP_Bool sortvars, /**< should variable sorting for faster propagation be used? */
7735  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
7736  int* nchgbds /**< pointer to count the total number of tightened bounds */
7737  )
7738 {
7739  SCIP_CONSDATA* consdata;
7740  SCIP_Real minactivity;
7741  SCIP_Real maxactivity;
7742  SCIP_Bool minactisrelax;
7743  SCIP_Bool maxactisrelax;
7744  SCIP_Bool isminsettoinfinity;
7745  SCIP_Bool ismaxsettoinfinity;
7746 
7747  assert(scip != NULL);
7748  assert(cons != NULL);
7749  assert(cutoff != NULL);
7750  assert(nchgbds != NULL);
7751 
7752  /*SCIPdebugMsg(scip, "propagating linear constraint <%s>\n", SCIPconsGetName(cons));*/
7753 
7754  consdata = SCIPconsGetData(cons);
7755  assert(consdata != NULL);
7756 
7757  if( consdata->eventdata == NULL )
7758  {
7759  SCIP_CONSHDLR* conshdlr;
7760  SCIP_CONSHDLRDATA* conshdlrdata;
7761 
7762  conshdlr = SCIPconsGetHdlr(cons);
7763  assert(conshdlr != NULL);
7764 
7765  conshdlrdata = SCIPconshdlrGetData(conshdlr);
7766  assert(conshdlrdata != NULL);
7767 
7768  /* catch bound change events of variables */
7769  SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
7770  assert(consdata->eventdata != NULL);
7771  }
7772 
7773  *cutoff = FALSE;
7774 
7775  /* we can only infer activity bounds of the linear constraint, if it is not modifiable */
7776  if( !SCIPconsIsModifiable(cons) )
7777  {
7778  /* increase age of constraint; age is reset to zero, if a conflict or a propagation was found */
7779  if( !SCIPinRepropagation(scip) )
7780  {
7781  SCIP_CALL( SCIPincConsAge(scip, cons) );
7782  }
7783 
7784  /* tighten the variable's bounds */
7785  if( tightenbounds )
7786  {
7787  int oldnchgbds;
7788 
7789  oldnchgbds = *nchgbds;
7790 
7791  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
7792 
7793  if( *nchgbds > oldnchgbds )
7794  {
7795  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7796  }
7797  }
7798 
7799  /* propagate ranged rows */
7800  if( rangedrowpropagation && tightenbounds && !(*cutoff) )
7801  {
7802  int nfixedvars;
7803  int naddconss;
7804  SCIPdebug( int oldnchgbds = *nchgbds; )
7805 
7806  nfixedvars = 0;
7807  naddconss = 0;
7808 
7809  SCIP_CALL( rangedRowPropagation(scip, cons, cutoff, &nfixedvars, nchgbds, &naddconss) );
7810 
7811  if( *cutoff )
7812  {
7813  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible\n", SCIPconsGetName(cons));
7814  }
7815  else
7816  {
7817  SCIPdebug( SCIPdebugMsg(scip, "linear constraint <%s> found %d bound changes and %d fixings\n", SCIPconsGetName(cons), *nchgbds - oldnchgbds, nfixedvars); )
7818  }
7819 
7820  if( nfixedvars > 0 )
7821  *nchgbds += 2*nfixedvars;
7822  } /*lint !e438*/
7823 
7824  /* check constraint for infeasibility and redundancy */
7825  if( !(*cutoff) )
7826  {
7827  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
7828  &isminsettoinfinity, &ismaxsettoinfinity);
7829 
7830  if( SCIPisFeasGT(scip, minactivity, consdata->rhs) )
7831  {
7832  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible (rhs): activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7833  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7834 
7835  /* analyze conflict */
7836  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
7837 
7838  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7839  *cutoff = TRUE;
7840  }
7841  else if( SCIPisFeasLT(scip, maxactivity, consdata->lhs) )
7842  {
7843  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible (lhs): activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7844  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7845 
7846  /* analyze conflict */
7847  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
7848 
7849  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7850  *cutoff = TRUE;
7851  }
7852  else if( SCIPisGE(scip, minactivity, consdata->lhs) && SCIPisLE(scip, maxactivity, consdata->rhs) )
7853  {
7854  SCIPdebugMsg(scip, "linear constraint <%s> is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7855  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7856 
7857  /* remove the constraint locally unless it has become empty, in which case it is removed globally */
7858  if( consdata->nvars > 0 )
7859  SCIP_CALL( SCIPdelConsLocal(scip, cons) );
7860  else
7861  SCIP_CALL( SCIPdelCons(scip, cons) );
7862  }
7863  }
7864  }
7865 
7866  return SCIP_OKAY;
7867 }
7868 
7869 
7870 /*
7871  * Presolving methods
7872  */
7873 
7874 /** converts all variables with fixed domain into FIXED variables */
7875 static
7877  SCIP* scip, /**< SCIP data structure */
7878  SCIP_CONS* cons, /**< linear constraint */
7879  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
7880  int* nfixedvars /**< pointer to count the total number of fixed variables */
7881  )
7882 {
7883  SCIP_CONSDATA* consdata;
7884  SCIP_VAR* var;
7885  SCIP_VARSTATUS varstatus;
7886  SCIP_Real lb;
7887  SCIP_Real ub;
7888  SCIP_Bool fixed;
7889  SCIP_Bool infeasible;
7890  int v;
7891 
7892  assert(scip != NULL);
7893  assert(cons != NULL);
7894  assert(cutoff != NULL);
7895  assert(nfixedvars != NULL);
7896 
7897  consdata = SCIPconsGetData(cons);
7898  assert(consdata != NULL);
7899 
7900  for( v = 0; v < consdata->nvars; ++v )
7901  {
7902  assert(consdata->vars != NULL);
7903  var = consdata->vars[v];
7904  varstatus = SCIPvarGetStatus(var);
7905 
7906  if( varstatus != SCIP_VARSTATUS_FIXED )
7907  {
7908  lb = SCIPvarGetLbGlobal(var);
7909  ub = SCIPvarGetUbGlobal(var);
7910  if( SCIPisEQ(scip, lb, ub) )
7911  {
7912  SCIP_Real fixval;
7913 
7914  fixval = SCIPselectSimpleValue(lb, ub, MAXDNOM);
7915  SCIPdebugMsg(scip, "converting variable <%s> with fixed bounds [%.15g,%.15g] into fixed variable fixed at %.15g\n",
7916  SCIPvarGetName(var), lb, ub, fixval);
7917  SCIP_CALL( SCIPfixVar(scip, var, fixval, &infeasible, &fixed) );
7918  if( infeasible )
7919  {
7920  SCIPdebugMsg(scip, " -> infeasible fixing\n");
7921  *cutoff = TRUE;
7922  return SCIP_OKAY;
7923  }
7924  if( fixed )
7925  (*nfixedvars)++;
7926  }
7927  }
7928  }
7929 
7930  SCIP_CALL( applyFixings(scip, cons, &infeasible) );
7931 
7932  if( infeasible )
7933  {
7934  SCIPdebugMsg(scip, " -> infeasible fixing\n");
7935  *cutoff = TRUE;
7936  return SCIP_OKAY;
7937  }
7938 
7939  assert(consdata->removedfixings);
7940 
7941  return SCIP_OKAY;
7942 }
7943 
7944 #define MAX_CLIQUE_NONZEROS_PER_CONS 1000000
7945 
7946 /** extracts cliques of the constraint and adds them to SCIP
7947  *
7948  * The following clique extraction mechanism are implemeneted
7949  *
7950  * 1. collect binary variables and sort them in non increasing order, then
7951  *
7952  * a) if the constraint has a finite right hand side and the negative infinity counters for the minactivity are zero
7953  * then add the variables as a clique for which all successive pairs of coefficients fullfill the following
7954  * condition
7955  *
7956  * minactivity + vals[i] + vals[i+1] > rhs
7957  *
7958  * and also add the binary to binary implication also for non-successive variables for which the same argument
7959  * holds
7960  *
7961  * minactivity + vals[i] + vals[j] > rhs
7962  *
7963  * e.g. 5.3 x1 + 3.6 x2 + 3.3 x3 + 2.1 x4 <= 5.5 (all x are binary) would lead to the clique (x1, x2, x3) and the
7964  * binary to binary implications x1 = 1 => x4 = 0 and x2 = 1 => x4 = 0
7965  *
7966  * b) if the constraint has a finite left hand side and the positive infinity counters for the maxactivity are zero
7967  * then add the variables as a clique for which all successive pairs of coefficients fullfill the follwoing
7968  * condition
7969  *
7970  * maxactivity + vals[i] + vals[i-1] < lhs
7971  *
7972  * and also add the binary to binary implication also for non-successive variables for which the same argument
7973  * holds
7974  *
7975  * maxactivity + vals[i] + vals[j] < lhs
7976  *
7977  * e.g. you could multiply the above example by -1
7978  *
7979  * c) the constraint has a finite right hand side and a finite minactivity then add the variables as a negated
7980  * clique(clique on the negated variables) for which all successive pairs of coefficients fullfill the following
7981  * condition
7982  *
7983  * minactivity - vals[i] - vals[i-1] > rhs
7984  *
7985  * and also add the binary to binary implication also for non-successive variables for which the
7986  * same argument holds
7987  *
7988  * minactivity - vals[i] - vals[j] > rhs
7989  *
7990  * e.g. -4 x1 -3 x2 - 2 x3 + 2 x4 <= -4 would lead to the (negated) clique (~x1, ~x2) and the binary to binary
7991  * implication x1 = 0 => x3 = 1
7992  *
7993  * d) the constraint has a finite left hand side and a finite maxactivity then add the variables as a negated
7994  * clique(clique on the negated variables) for which all successive pairs of coefficients fullfill the following
7995  * condition
7996  *
7997  * maxactivity - vals[i] - vals[i+1] < lhs
7998  *
7999  * and also add the binary to binary implication also for non-successive variables for which the same argument
8000  * holds
8001  *
8002  * maxactivity - vals[i] - vals[j] < lhs
8003  *
8004  * e.g. you could multiply the above example by -1
8005  *
8006  * 2. if the linear constraint represents a set-packing or set-partitioning constraint, the whole constraint is added
8007  * as clique, (this part is done at the end of the method)
8008  *
8009  */
8010 static
8012  SCIP* scip, /**< SCIP data structure */
8013  SCIP_CONS* cons, /**< linear constraint */
8014  SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
8015  SCIP_Bool sortvars, /**< should variables be used in sorted order? */
8016  int* nfixedvars, /**< pointer to count number of fixed variables */
8017  int* nchgbds, /**< pointer to count the total number of tightened bounds */
8018  SCIP_Bool* cutoff /**< pointer to store TRUE, if a cutoff was found */
8019  )
8020 {
8021  SCIP_VAR** vars;
8022  SCIP_Real* vals;
8023  SCIP_CONSDATA* consdata;
8024  SCIP_Bool lhsclique;
8025  SCIP_Bool rhsclique;
8026  SCIP_Bool finitelhs;
8027  SCIP_Bool finiterhs;
8028  SCIP_Bool finiteminact;
8029  SCIP_Bool finitemaxact;
8030  SCIP_Bool finitenegminact;
8031  SCIP_Bool finitenegmaxact;
8032  SCIP_Bool finiteposminact;
8033  SCIP_Bool finiteposmaxact;
8034  SCIP_Bool infeasible;
8035  SCIP_Bool stopped;
8036  int cliquenonzerosadded;
8037  int v;
8038  int i;
8039  int nposcoefs;
8040  int nnegcoefs;
8041  int nvars;
8042 
8043  assert(scip != NULL);
8044  assert(cons != NULL);
8045  assert(nfixedvars != NULL);
8046  assert(nchgbds != NULL);
8047  assert(cutoff != NULL);
8048  assert(!SCIPconsIsDeleted(cons));
8049 
8050  consdata = SCIPconsGetData(cons);
8051  assert(consdata != NULL);
8052 
8053  if( consdata->nvars < 2 )
8054  return SCIP_OKAY;
8055 
8056  /* add implications if posibble
8057  *
8058  * for now we only add binary to non-binary implications, and this is only done for the binary variable with the
8059  * maximal absolute contribution and also only if this variable would force all other variables to their bound
8060  * corresponding to the global minimal activity of the constraint
8061  */
8062  if( !consdata->implsadded )
8063  {
8064  /* sort variables by variable type */
8065  SCIP_CALL( consdataSort(scip, consdata) );
8066 
8067  /* @todo we might extract implications/cliques if SCIPvarIsBinary() variables exist and we have integer variables
8068  * up front, might change sorting correspondingly
8069  */
8070  /* fast abort if no binaries exist */
8071  if( !SCIPvarIsBinary(consdata->vars[0]) )
8072  {
8073 #ifndef NDEBUG
8074  for( i = 1; i < consdata->nvars; i++ )
8075  assert(!SCIPvarIsBinary(consdata->vars[i]));
8076 #endif
8077  return SCIP_OKAY;
8078  }
8079  nvars = consdata->nvars;
8080  vars = consdata->vars;
8081  vals = consdata->vals;
8082 
8083  /* recompute activities if needed */
8084  if( !consdata->validactivities )
8085  consdataCalcActivities(scip, consdata);
8086  assert(consdata->validactivities);
8087 
8088  finitelhs = !SCIPisInfinity(scip, -consdata->lhs);
8089  finiterhs = !SCIPisInfinity(scip, consdata->rhs);
8090  finitenegminact = (consdata->glbminactivityneginf == 0 && consdata->glbminactivityneghuge == 0);
8091  finitenegmaxact = (consdata->glbmaxactivityneginf == 0 && consdata->maxactivityneghuge == 0);
8092  finiteposminact = (consdata->glbminactivityposinf == 0 && consdata->glbminactivityposhuge == 0);
8093  finiteposmaxact = (consdata->glbmaxactivityposinf == 0 && consdata->glbmaxactivityposhuge == 0);
8094  finiteminact = (finitenegminact && finiteposminact);
8095  finitemaxact = (finitenegmaxact && finiteposmaxact);
8096 
8097  if( (finiterhs || finitelhs) && (finitenegminact || finiteposminact || finitenegmaxact || finiteposmaxact) )
8098  {
8099  SCIP_Real maxabscontrib = -1.0;
8100  SCIP_Bool posval = FALSE;
8101  SCIP_Bool allbinary = TRUE;
8102  int oldnchgbds = *nchgbds;
8103  int nbdchgs = 0;
8104  int nimpls = 0;
8105  int position = -1;
8106 
8107  /* we need a valid minimal/maximal activity to add cliques */
8108  if( (finitenegminact || finiteposminact) && !consdata->validglbminact )
8109  {
8110  consdataRecomputeGlbMinactivity(scip, consdata);
8111  assert(consdata->validglbminact);
8112  }
8113 
8114  if( (finitenegmaxact || finiteposmaxact) && !consdata->validglbmaxact )
8115  {
8116  consdataRecomputeGlbMaxactivity(scip, consdata);
8117  assert(consdata->validglbmaxact);
8118  }
8119  assert(consdata->validglbminact || consdata->validglbmaxact);
8120 
8121  /* @todo extend this to local/constraint probing */
8122 
8123  /* determine maximal contribution to the activity */
8124  for( v = nvars - 1; v >= 0; --v )
8125  {
8126  if( SCIPvarIsBinary(vars[v]) )
8127  {
8128  if( vals[v] > 0 )
8129  {
8130  SCIP_Real value = vals[v] * SCIPvarGetUbGlobal(vars[v]);
8131 
8132  if( value > maxabscontrib )
8133  {
8134  maxabscontrib = value;
8135  position = v;
8136  posval = TRUE;
8137  }
8138  }
8139  else
8140  {
8141  SCIP_Real value = vals[v] * SCIPvarGetLbGlobal(vars[v]);
8142 
8143  value = REALABS(value);
8144 
8145  if( value > maxabscontrib )
8146  {
8147  maxabscontrib = value;
8148  position = v;
8149  posval = FALSE;
8150  }
8151  }
8152  }
8153  else
8154  allbinary = FALSE;
8155  }
8156  assert(0 <= position && position < nvars);
8157 
8158  if( !SCIPisEQ(scip, maxabscontrib, 1.0) && !allbinary )
8159  {
8160  /* if the right hand side and the minimal activity are finite and changing the variable with the biggest
8161  * influence to their bound forces all other variables to be at their minimal contribution, we can add these
8162  * implications
8163  */
8164  if( finiterhs && finiteminact && SCIPisEQ(scip, consdata->glbminactivity, consdata->rhs - maxabscontrib) )
8165  {
8166  for( v = nvars - 1; v >= 0; --v )
8167  {
8168  /* binary to binary implications will be collected when extrating cliques */
8169  if( !SCIPvarIsBinary(vars[v]) )
8170  {
8171  if( v != position )
8172  {
8173  if( vals[v] > 0 )
8174  {
8175  /* add implications */
8176  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_UPPER, SCIPvarGetLbGlobal(vars[v]), &infeasible, &nbdchgs) );
8177  ++nimpls;
8178  *nchgbds += nbdchgs;
8179  }
8180  else
8181  {
8182  /* add implications */
8183  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_LOWER, SCIPvarGetUbGlobal(vars[v]), &infeasible, &nbdchgs) );
8184  ++nimpls;
8185  *nchgbds += nbdchgs;
8186  }
8187 
8188  if( infeasible )
8189  {
8190  *cutoff = TRUE;
8191  break;
8192  }
8193  }
8194  }
8195  /* stop when reaching a 'real' binary variable because the variables are sorted after their type */
8196  else if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_BINARY )
8197  break;
8198  }
8199  }
8200 
8201  /* if the left hand side and the maximal activity are finite and changing the variable with the biggest
8202  * influence to their bound forces all other variables to be at their minimal contribution, we can add these
8203  * implications
8204  */
8205  if( finitelhs && finitemaxact && SCIPisEQ(scip, consdata->glbmaxactivity, consdata->lhs - maxabscontrib) )
8206  {
8207  for( v = nvars - 1; v >= 0; --v )
8208  {
8209  /* binary to binary implications will be collected when extrating cliques */
8210  if( !SCIPvarIsBinary(vars[v]) )
8211  {
8212  if( v != position )
8213  {
8214  if( vals[v] > 0 )
8215  {
8216  /* add implications */
8217  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_LOWER, SCIPvarGetUbGlobal(vars[v]), &infeasible, &nbdchgs) );
8218  ++nimpls;
8219  *nchgbds += nbdchgs;
8220  }
8221  else
8222  {
8223  /* add implications */
8224  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_UPPER, SCIPvarGetLbGlobal(vars[v]), &infeasible, &nbdchgs) );
8225  ++nimpls;
8226  *nchgbds += nbdchgs;
8227  }
8228 
8229  if( infeasible )
8230  {
8231  *cutoff = TRUE;
8232  break;
8233  }
8234  }
8235  }
8236  /* stop when reaching a 'real' binary variable because the variables are sorted after their type */
8237  else if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_BINARY )
8238  break;
8239  }
8240  }
8241 
8242  /* did we find some implications */
8243  if( nimpls > 0 )
8244  {
8245  SCIPdebugMsg(scip, "extracted %d implications from constraint %s which led to %d bound changes, %scutoff detetcted\n", nimpls, SCIPconsGetName(cons), *nchgbds - oldnchgbds, *cutoff ? "" : "no ");
8246 
8247  if( *cutoff )
8248  return SCIP_OKAY;
8249 
8250  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8251  if( *nchgbds - oldnchgbds > 0 )
8252  {
8253  /* check for fixed variables */
8254  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8255  if( *cutoff )
8256  return SCIP_OKAY;
8257 
8258  /* tighten variable's bounds */
8259  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8260  if( *cutoff )
8261  return SCIP_OKAY;
8262 
8263  /* check for fixed variables */
8264  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8265  if( *cutoff )
8266  return SCIP_OKAY;
8267  }
8268  }
8269  }
8270  }
8271 
8272  consdata->implsadded = TRUE;
8273  }
8274 
8275  /* check if we already added the cliques of this constraint */
8276  if( consdata->cliquesadded )
8277  return SCIP_OKAY;
8278 
8279  consdata->cliquesadded = TRUE;
8280  cliquenonzerosadded = 0;
8281  stopped = FALSE;
8282 
8283  /* sort variables by variable type */
8284  SCIP_CALL( consdataSort(scip, consdata) );
8285 
8286  nvars = consdata->nvars;
8287  vars = consdata->vars;
8288  vals = consdata->vals;
8289 
8290  /**@todo extract more cliques, implications and variable bounds from linear constraints */
8291 
8292  /* recompute activities if needed */
8293  if( !consdata->validactivities )
8294  consdataCalcActivities(scip, consdata);
8295  assert(consdata->validactivities);
8296 
8297  finitelhs = !SCIPisInfinity(scip, -consdata->lhs);
8298  finiterhs = !SCIPisInfinity(scip, consdata->rhs);
8299  finitenegminact = (consdata->glbminactivityneginf == 0 && consdata->glbminactivityneghuge == 0);
8300  finitenegmaxact = (consdata->glbmaxactivityneginf == 0 && consdata->maxactivityneghuge == 0);
8301  finiteposminact = (consdata->glbminactivityposinf == 0 && consdata->glbminactivityposhuge == 0);
8302  finiteposmaxact = (consdata->glbmaxactivityposinf == 0 && consdata->glbmaxactivityposhuge == 0);
8303  finiteminact = (finitenegminact && finiteposminact);
8304  finitemaxact = (finitenegmaxact && finiteposmaxact);
8305 
8306  /* 1. we wheck whether some variables do not fit together into this constraint and add the corresponding clique
8307  * information
8308  */
8309  if( (finiterhs || finitelhs) && (finitenegminact || finiteposminact || finitenegmaxact || finiteposmaxact) )
8310  {
8311  SCIP_VAR** binvars;
8312  SCIP_Real* binvarvals;
8313  int nposbinvars = 0;
8314  int nnegbinvars = 0;
8315  int allonebinary = 0;
8316 
8317  SCIP_CALL( SCIPallocBufferArray(scip, &binvars, nvars) );
8318  SCIP_CALL( SCIPallocBufferArray(scip, &binvarvals, nvars) );
8319 
8320  /* collect binary variables */
8321  for( i = 0; i < nvars; ++i )
8322  {
8323  if( SCIPvarIsBinary(vars[i]) )
8324  {
8325  assert(!SCIPisZero(scip, vals[i]));
8326 
8327  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8328  ++allonebinary;
8329 
8330  binvars[nposbinvars + nnegbinvars] = vars[i];
8331  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8332 
8333  if( SCIPisPositive(scip, vals[i]) )
8334  ++nposbinvars;
8335  else
8336  ++nnegbinvars;
8337 
8338  assert(nposbinvars + nnegbinvars <= nvars);
8339  }
8340  /* stop searching for binary variables, because the constraint data is sorted */
8341  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8342  break;
8343  }
8344  assert(nposbinvars + nnegbinvars <= nvars);
8345 
8346  /* setppc constraints will be handled later; we need at least two binary variables with same sign to extract
8347  * cliques
8348  */
8349  if( allonebinary < nvars && (nposbinvars >= 2 || nnegbinvars >= 2) )
8350  {
8351  SCIP_Real threshold;
8352  int oldnchgbds = *nchgbds;
8353  int nbdchgs;
8354  int jstart;
8355  int j;
8356 
8357  /* we need a valid minimal/maximal activity to add cliques */
8358  if( (finitenegminact || finiteposminact) && !consdata->validglbminact )
8359  {
8360  consdataRecomputeGlbMinactivity(scip, consdata);
8361  assert(consdata->validglbminact);
8362  }
8363 
8364  if( (finitenegmaxact || finiteposmaxact) && !consdata->validglbmaxact )
8365  {
8366  consdataRecomputeGlbMaxactivity(scip, consdata);
8367  assert(consdata->validglbmaxact);
8368  }
8369  assert(consdata->validglbminact || consdata->validglbmaxact);
8370 
8371  /* sort coefficients non-increasing to be faster in the clique search */
8372  SCIPsortDownRealPtr(binvarvals, (void**) binvars, nposbinvars + nnegbinvars);
8373 
8374  /* case a) */
8375  if( finiterhs && finitenegminact && nposbinvars >= 2 )
8376  {
8377  /* compute value that needs to be exceeded */
8378  threshold = consdata->rhs - consdata->glbminactivity;
8379 
8380  j = 1;
8381 #ifdef SCIP_DISABLED_CODE /* assertion should only hold when constraints were fully propagated and boundstightened */
8382  /* check that it is possible to choose binvar[i], otherwise it should have been fixed to zero */
8383  assert(SCIPisFeasLE(scip, binvarvals[0], threshold));
8384 #endif
8385  /* check if at least two variables are in a clique */
8386  if( SCIPisFeasGT(scip, binvarvals[0] + binvarvals[j], threshold) )
8387  {
8388  ++j;
8389  /* check for extending the clique */
8390  while( j < nposbinvars )
8391  {
8392  if( !SCIPisFeasGT(scip, binvarvals[j-1] + binvarvals[j], threshold) )
8393  break;
8394  ++j;
8395  }
8396  assert(j >= 2);
8397 
8398  /* add clique with at least two variables */
8399  SCIP_CALL( SCIPaddClique(scip, binvars, NULL, j, FALSE, &infeasible, &nbdchgs) );
8400 
8401  if( infeasible )
8402  *cutoff = TRUE;
8403 
8404  *nchgbds += nbdchgs;
8405 
8406  cliquenonzerosadded += j;
8407  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8408  stopped = TRUE;
8409 
8410  /* exchange the last variable in the clique if possible and add all new ones */
8411  if( !stopped && !(*cutoff) && j < nposbinvars )
8412  {
8413  SCIP_VAR** clqvars;
8414  int lastfit = j - 2;
8415  assert(lastfit >= 0);
8416 
8417  /* copy all 'main'-clique variables */
8418  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, binvars, j) );
8419 
8420  /* iterate up to the end with j and up to the front with lastfit, and check for different cliques */
8421  while( lastfit >= 0 && j < nposbinvars )
8422  {
8423  /* check if two variables are in a clique */
8424  if( SCIPisFeasGT(scip, binvarvals[lastfit] + binvarvals[j], threshold) )
8425  {
8426  clqvars[lastfit + 1] = binvars[j];
8427 
8428  /* add clique with at least two variables */
8429  SCIP_CALL( SCIPaddClique(scip, clqvars, NULL, lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8430 
8431  if( infeasible )
8432  {
8433  *cutoff = TRUE;
8434  break;
8435  }
8436 
8437  *nchgbds += nbdchgs;
8438 
8439  cliquenonzerosadded += (lastfit + 2);
8440  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8441  {
8442  stopped = TRUE;
8443  break;
8444  }
8445 
8446  ++j;
8447  }
8448  else
8449  --lastfit;
8450  }
8451 
8452  SCIPfreeBufferArray(scip, &clqvars);
8453  }
8454  }
8455  }
8456 
8457  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8458  if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8459  {
8460  /* check for fixed variables */
8461  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8462 
8463  if( !*cutoff )
8464  {
8465  /* tighten variable's bounds */
8466  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8467 
8468  if( !*cutoff )
8469  {
8470  /* check for fixed variables */
8471  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8472 
8473  if( !*cutoff )
8474  {
8475  /* sort variables by variable type */
8476  SCIP_CALL( consdataSort(scip, consdata) );
8477 
8478  /* recompute activities if needed */
8479  if( !consdata->validactivities )
8480  consdataCalcActivities(scip, consdata);
8481  assert(consdata->validactivities);
8482 
8483  nvars = consdata->nvars;
8484  vars = consdata->vars;
8485  vals = consdata->vals;
8486  nposbinvars = 0;
8487  nnegbinvars = 0;
8488  allonebinary = 0;
8489 
8490  /* update binary variables */
8491  for( i = 0; i < nvars; ++i )
8492  {
8493  if( SCIPvarIsBinary(vars[i]) )
8494  {
8495  assert(!SCIPisZero(scip, vals[i]));
8496 
8497  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8498  ++allonebinary;
8499 
8500  binvars[nposbinvars + nnegbinvars] = vars[i];
8501  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8502 
8503  if( SCIPisPositive(scip, vals[i]) )
8504  ++nposbinvars;
8505  else
8506  ++nnegbinvars;
8507 
8508  assert(nposbinvars + nnegbinvars <= nvars);
8509  }
8510  /* stop searching for binary variables, because the constraint data is sorted */
8511  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8512  break;
8513  }
8514  assert(nposbinvars + nnegbinvars <= nvars);
8515  }
8516  }
8517  }
8518 
8519  oldnchgbds = *nchgbds;
8520  }
8521 
8522  /* case b) */
8523  if( !stopped && !(*cutoff) && finitelhs && finiteposmaxact && nnegbinvars >= 2 )
8524  {
8525  /* compute value that needs to be deceeded */
8526  threshold = consdata->lhs - consdata->glbmaxactivity;
8527 
8528  i = nposbinvars + nnegbinvars - 1;
8529  j = i - 1;
8530 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8531  /* check that it is possible to choose binvar[i], otherwise it should have been fixed to zero */
8532  assert(SCIPisFeasGE(scip, binvarvals[i], threshold));
8533 #endif
8534  /* check if two variables are in a clique */
8535  if( SCIPisFeasLT(scip, binvarvals[i] + binvarvals[j], threshold) )
8536  {
8537  --j;
8538  /* check for extending the clique */
8539  while( j >= nposbinvars )
8540  {
8541  if( !SCIPisFeasLT(scip, binvarvals[j+1] + binvarvals[j], threshold) )
8542  break;
8543  --j;
8544  }
8545  jstart = j;
8546 
8547  assert(i - j >= 2);
8548  /* add clique with at least two variables */
8549  SCIP_CALL( SCIPaddClique(scip, &(binvars[j+1]), NULL, i - j, FALSE, &infeasible, &nbdchgs) );
8550 
8551  if( infeasible )
8552  *cutoff = TRUE;
8553 
8554  *nchgbds += nbdchgs;
8555 
8556  cliquenonzerosadded += (i - j);
8557  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8558  stopped = TRUE;
8559 
8560  /* exchange the last variable in the clique if possible and add all new ones */
8561  if( !stopped && !(*cutoff) && jstart >= nposbinvars )
8562  {
8563  SCIP_VAR** clqvars;
8564  int lastfit = jstart + 1;
8565  assert(lastfit < i);
8566 
8567  /* copy all 'main'-clique variables */
8568  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[lastfit]), i - j) );
8569  ++lastfit;
8570 
8571  /* iterate up to the front with j and up to the end with lastfit, and check for different cliques */
8572  while( lastfit <= i && j >= nposbinvars )
8573  {
8574  /* check if two variables are in a clique */
8575  if( SCIPisFeasLT(scip, binvarvals[lastfit] + binvarvals[j], threshold) )
8576  {
8577  assert(lastfit - jstart - 2 >= 0 && lastfit - jstart - 2 < i);
8578  clqvars[lastfit - jstart - 2] = binvars[j];
8579 
8580  assert(i - lastfit + 2 >= 2);
8581  /* add clique with at least two variables */
8582  SCIP_CALL( SCIPaddClique(scip, &(clqvars[lastfit - jstart - 2]), NULL, i - lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8583 
8584  if( infeasible )
8585  {
8586  *cutoff = TRUE;
8587  break;
8588  }
8589 
8590  *nchgbds += nbdchgs;
8591 
8592  cliquenonzerosadded += (i - lastfit + 2);
8593  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8594  {
8595  stopped = TRUE;
8596  break;
8597  }
8598 
8599  --j;
8600  }
8601  else
8602  ++lastfit;
8603  }
8604 
8605  SCIPfreeBufferArray(scip, &clqvars);
8606  }
8607  }
8608  }
8609 
8610  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8611  if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8612  {
8613  /* check for fixed variables */
8614  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8615 
8616  if( !*cutoff )
8617  {
8618  /* tighten variable's bounds */
8619  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8620 
8621  if( !*cutoff )
8622  {
8623  /* check for fixed variables */
8624  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8625 
8626  if( !*cutoff )
8627  {
8628  /* sort variables by variable type */
8629  SCIP_CALL( consdataSort(scip, consdata) );
8630 
8631  /* recompute activities if needed */
8632  if( !consdata->validactivities )
8633  consdataCalcActivities(scip, consdata);
8634  assert(consdata->validactivities);
8635 
8636  nvars = consdata->nvars;
8637  vars = consdata->vars;
8638  vals = consdata->vals;
8639  nposbinvars = 0;
8640  nnegbinvars = 0;
8641  allonebinary = 0;
8642 
8643  /* update binary variables */
8644  for( i = 0; i < nvars; ++i )
8645  {
8646  if( SCIPvarIsBinary(vars[i]) )
8647  {
8648  assert(!SCIPisZero(scip, vals[i]));
8649 
8650  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8651  ++allonebinary;
8652 
8653  binvars[nposbinvars + nnegbinvars] = vars[i];
8654  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8655 
8656  if( SCIPisPositive(scip, vals[i]) )
8657  ++nposbinvars;
8658  else
8659  ++nnegbinvars;
8660 
8661  assert(nposbinvars + nnegbinvars <= nvars);
8662  }
8663  /* stop searching for binary variables, because the constraint data is sorted */
8664  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8665  break;
8666  }
8667  assert(nposbinvars + nnegbinvars <= nvars);
8668  }
8669  }
8670  }
8671 
8672  oldnchgbds = *nchgbds;
8673  }
8674 
8675  /* case c) */
8676  if( !(*cutoff) && finiterhs && finiteminact && nnegbinvars >= 2 )
8677  {
8678  SCIP_Bool* values;
8679 
8680  /* initialize clique values array for adding a negated clique */
8681  SCIP_CALL( SCIPallocBufferArray(scip, &values, nnegbinvars) );
8682  BMSclearMemoryArray(values, nnegbinvars);
8683 
8684  /* compute value that needs to be exceeded */
8685  threshold = consdata->rhs - consdata->glbminactivity;
8686 
8687  i = nposbinvars + nnegbinvars - 1;
8688  j = i - 1;
8689 
8690 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8691  /* check if the variable should not have already been fixed to one */
8692  assert(!SCIPisFeasGT(scip, binvarvals[i], threshold));
8693 #endif
8694 
8695  if( SCIPisFeasGT(scip, -binvarvals[i] - binvarvals[j], threshold) )
8696  {
8697  --j;
8698  /* check for extending the clique */
8699  while( j >= nposbinvars )
8700  {
8701  if( !SCIPisFeasGT(scip, -binvarvals[j+1] - binvarvals[j], threshold) )
8702  break;
8703  --j;
8704  }
8705  jstart = j;
8706 
8707  assert(i - j >= 2);
8708  /* add negated clique with at least two variables */
8709  SCIP_CALL( SCIPaddClique(scip, &(binvars[j+1]), values, i - j, FALSE, &infeasible, &nbdchgs) );
8710 
8711  if( infeasible )
8712  *cutoff = TRUE;
8713 
8714  *nchgbds += nbdchgs;
8715 
8716  cliquenonzerosadded += (i - j);
8717  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8718  stopped = TRUE;
8719 
8720  /* exchange the last variable in the clique if possible and add all new ones */
8721  if( !stopped && !(*cutoff) && jstart >= nposbinvars )
8722  {
8723  SCIP_VAR** clqvars;
8724  int lastfit = j + 1;
8725  assert(lastfit < i);
8726 
8727  /* copy all 'main'-clique variables */
8728  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[lastfit]), i - j) );
8729  ++lastfit;
8730 
8731  /* iterate up to the front with j and up to the end with lastfit, and check for different cliques */
8732  while( lastfit <= i && j >= nposbinvars )
8733  {
8734  /* check if two variables are in a negated clique */
8735  if( SCIPisFeasGT(scip, -binvarvals[lastfit] - binvarvals[j], threshold) )
8736  {
8737  assert(lastfit - jstart - 2 >= 0 && lastfit - jstart - 2 < i);
8738  clqvars[lastfit - jstart - 2] = binvars[j];
8739 
8740  assert(i - lastfit + 2 >= 2);
8741  /* add clique with at least two variables */
8742  SCIP_CALL( SCIPaddClique(scip, &(clqvars[lastfit - jstart - 2]), values, i - lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8743 
8744  if( infeasible )
8745  {
8746  *cutoff = TRUE;
8747  break;
8748  }
8749 
8750  *nchgbds += nbdchgs;
8751 
8752  cliquenonzerosadded += (i - lastfit + 2);
8753  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8754  {
8755  stopped = TRUE;
8756  break;
8757  }
8758 
8759  --j;
8760  }
8761  else
8762  ++lastfit;
8763  }
8764 
8765  SCIPfreeBufferArray(scip, &clqvars);
8766  }
8767  }
8768 
8769  SCIPfreeBufferArray(scip, &values);
8770  }
8771 
8772  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8773  if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8774  {
8775  /* check for fixed variables */
8776  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8777 
8778  if( !*cutoff )
8779  {
8780  /* tighten variable's bounds */
8781  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8782 
8783  if( !*cutoff )
8784  {
8785  /* check for fixed variables */
8786  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8787 
8788  if( !*cutoff )
8789  {
8790  /* sort variables by variable type */
8791  SCIP_CALL( consdataSort(scip, consdata) );
8792 
8793  /* recompute activities if needed */
8794  if( !consdata->validactivities )
8795  consdataCalcActivities(scip, consdata);
8796  assert(consdata->validactivities);
8797 
8798  nvars = consdata->nvars;
8799  vars = consdata->vars;
8800  vals = consdata->vals;
8801  nposbinvars = 0;
8802  nnegbinvars = 0;
8803  allonebinary = 0;
8804 
8805  /* update binary variables */
8806  for( i = 0; i < nvars; ++i )
8807  {
8808  if( SCIPvarIsBinary(vars[i]) )
8809  {
8810  assert(!SCIPisZero(scip, vals[i]));
8811 
8812  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8813  ++allonebinary;
8814 
8815  binvars[nposbinvars + nnegbinvars] = vars[i];
8816  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8817 
8818  if( SCIPisPositive(scip, vals[i]) )
8819  ++nposbinvars;
8820  else
8821  ++nnegbinvars;
8822 
8823  assert(nposbinvars + nnegbinvars <= nvars);
8824  }
8825  /* stop searching for binary variables, because the constraint data is sorted */
8826  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8827  break;
8828  }
8829  assert(nposbinvars + nnegbinvars <= nvars);
8830  }
8831  }
8832  }
8833  }
8834 
8835  /* case d) */
8836  if( !stopped && !(*cutoff) && finitelhs && finitemaxact && nposbinvars >= 2 )
8837  {
8838  SCIP_Bool* values;
8839 
8840  /* initialize clique values array for adding a negated clique */
8841  SCIP_CALL( SCIPallocBufferArray(scip, &values, nposbinvars) );
8842  BMSclearMemoryArray(values, nposbinvars);
8843 
8844  /* compute value that needs to be exceeded */
8845  threshold = consdata->lhs - consdata->glbmaxactivity;
8846 
8847  j = 1;
8848 
8849 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8850  /* check if the variable should not have already been fixed to one */
8851  assert(!SCIPisFeasLT(scip, -binvarvals[0], threshold));
8852 #endif
8853 
8854  if( SCIPisFeasLT(scip, -binvarvals[0] - binvarvals[j], threshold) )
8855  {
8856  ++j;
8857  /* check for extending the clique */
8858  while( j < nposbinvars )
8859  {
8860  if( !SCIPisFeasLT(scip, -binvarvals[j-1] - binvarvals[j], threshold) )
8861  break;
8862  ++j;
8863  }
8864  assert(j >= 2);
8865 
8866  /* add negated clique with at least two variables */
8867  SCIP_CALL( SCIPaddClique(scip, binvars, values, j, FALSE, &infeasible, &nbdchgs) );
8868 
8869  if( infeasible )
8870  *cutoff = TRUE;
8871 
8872  *nchgbds += nbdchgs;
8873 
8874  cliquenonzerosadded += j;
8875  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8876  stopped = TRUE;
8877 
8878  /* exchange the last variable in the clique if possible and add all new ones */
8879  if( !stopped && !(*cutoff) && j < nposbinvars )
8880  {
8881  SCIP_VAR** clqvars;
8882  int lastfit = j - 2;
8883  assert(lastfit >= 0);
8884 
8885  /* copy all 'main'-clique variables */
8886  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, binvars, j) );
8887 
8888  /* iterate up to the end with j and up to the front with lastfit, and check for different cliques */
8889  while( lastfit >= 0 && j < nposbinvars )
8890  {
8891  /* check if two variables are in a negated clique */
8892  if( SCIPisFeasLT(scip, -binvarvals[lastfit] - binvarvals[j], threshold) )
8893  {
8894  clqvars[lastfit + 1] = binvars[j];
8895 
8896  /* add clique with at least two variables */
8897  SCIP_CALL( SCIPaddClique(scip, clqvars, values, lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8898 
8899  if( infeasible )
8900  {
8901  *cutoff = TRUE;
8902  break;
8903  }
8904 
8905  *nchgbds += nbdchgs;
8906 
8907  cliquenonzerosadded += lastfit + 2;
8908  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8909  break;
8910 
8911  ++j;
8912  }
8913  else
8914  --lastfit;
8915  }
8916 
8917  SCIPfreeBufferArray(scip, &clqvars);
8918  }
8919  }
8920 
8921  SCIPfreeBufferArray(scip, &values);
8922  }
8923  }
8924 
8925  SCIPfreeBufferArray(scip, &binvarvals);
8926  SCIPfreeBufferArray(scip, &binvars);
8927 
8928  if( *cutoff )
8929  return SCIP_OKAY;
8930  }
8931 
8932  /* 2. we only check if the constraint is a set packing / partitioning constraint */
8933 
8934  /* check if all variables are binary, if the coefficients are +1 or -1, and if the right hand side is equal
8935  * to 1 - number of negative coefficients, or if the left hand side is equal to number of positive coefficients - 1
8936  */
8937  nposcoefs = 0;
8938  nnegcoefs = 0;
8939  for( i = 0; i < nvars; ++i )
8940  {
8941  if( !SCIPvarIsBinary(vars[i]) )
8942  return SCIP_OKAY;
8943  else if( SCIPisEQ(scip, vals[i], +1.0) )
8944  nposcoefs++;
8945  else if( SCIPisEQ(scip, vals[i], -1.0) )
8946  nnegcoefs++;
8947  else
8948  return SCIP_OKAY;
8949  }
8950 
8951  lhsclique = SCIPisEQ(scip, consdata->lhs, (SCIP_Real)nposcoefs - 1.0);
8952  rhsclique = SCIPisEQ(scip, consdata->rhs, 1.0 - (SCIP_Real)nnegcoefs);
8953 
8954  if( lhsclique || rhsclique )
8955  {
8956  SCIP_Bool* values;
8957  int nbdchgs;
8958 
8959  SCIPdebugMsg(scip, "linear constraint <%s>: adding clique with %d vars (%d pos, %d neg)\n",
8960  SCIPconsGetName(cons), nvars, nposcoefs, nnegcoefs);
8961  SCIP_CALL( SCIPallocBufferArray(scip, &values, nvars) );
8962 
8963  for( i = 0; i < nvars; ++i )
8964  values[i] = (rhsclique == (vals[i] > 0.0));
8965 
8966  SCIP_CALL( SCIPaddClique(scip, vars, values, nvars, SCIPisEQ(scip, consdata->lhs, consdata->rhs), &infeasible, &nbdchgs) );
8967 
8968  if( infeasible )
8969  *cutoff = TRUE;
8970 
8971  *nchgbds += nbdchgs;
8972  SCIPfreeBufferArray(scip, &values);
8973  }
8974 
8975  return SCIP_OKAY;
8976 }
8977 
8978 /** tightens left and right hand side of constraint due to integrality */
8979 static
8981  SCIP* scip, /**< SCIP data structure */
8982  SCIP_CONS* cons, /**< linear constraint */
8983  int* nchgsides, /**< pointer to count number of side changes */
8984  SCIP_Bool* infeasible /**< pointer to store whether infeasibility was detected */
8985  )
8986 {
8987  SCIP_CONSDATA* consdata;
8988  SCIP_Real newlhs;
8989  SCIP_Real newrhs;
8990  SCIP_Bool chglhs;
8991  SCIP_Bool chgrhs;
8992  SCIP_Bool integral;
8993  int i;
8994 
8995  assert(scip != NULL);
8996  assert(cons != NULL);
8997  assert(nchgsides != NULL);
8998  assert(infeasible != NULL);
9000  consdata = SCIPconsGetData(cons);
9001  assert(consdata != NULL);
9002 
9003  *infeasible = FALSE;
9004 
9005  chglhs = FALSE;
9006  chgrhs = FALSE;
9007  newlhs = -SCIPinfinity(scip);
9008  newrhs = SCIPinfinity(scip);
9009 
9010  if( !SCIPisIntegral(scip, consdata->lhs) || !SCIPisIntegral(scip, consdata->rhs) )
9011  {
9012  integral = TRUE;
9013  for( i = 0; i < consdata->nvars && integral; ++i )
9014  {
9015  integral = SCIPisIntegral(scip, consdata->vals[i])
9016  && (SCIPvarGetType(consdata->vars[i]) != SCIP_VARTYPE_CONTINUOUS);
9017  }
9018  if( integral )
9019  {
9020  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisIntegral(scip, consdata->lhs) )
9021  {
9022  newlhs = SCIPfeasCeil(scip, consdata->lhs);
9023  chglhs = TRUE;
9024  }
9025  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisIntegral(scip, consdata->rhs) )
9026  {
9027  newrhs = SCIPfeasFloor(scip, consdata->rhs);
9028  chgrhs = TRUE;
9029  }
9030 
9031  /* check whether rounding would lead to an unsatisfiable constraint */
9032  if( SCIPisGT(scip, newlhs, newrhs) )
9033  {
9034  SCIPdebugMsg(scip, "rounding sides=[%.15g,%.15g] of linear constraint <%s> with integral coefficients and variables only "
9035  "is infeasible\n", consdata->lhs, consdata->rhs, SCIPconsGetName(cons));
9036 
9037  *infeasible = TRUE;
9038  return SCIP_OKAY;
9039  }
9040 
9041  SCIPdebugMsg(scip, "linear constraint <%s>: make sides integral: sides=[%.15g,%.15g]\n",
9042  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
9043 
9044  if( chglhs )
9045  {
9046  assert(!SCIPisInfinity(scip, -newlhs));
9047 
9048  SCIP_CALL( chgLhs(scip, cons, newlhs) );
9049  if( !consdata->upgraded )
9050  (*nchgsides)++;
9051  }
9052  if( chgrhs )
9053  {
9054  assert(!SCIPisInfinity(scip, newrhs));
9055 
9056  SCIP_CALL( chgRhs(scip, cons, newrhs) );
9057  if( !consdata->upgraded )
9058  (*nchgsides)++;
9059  }
9060  SCIPdebugMsg(scip, "linear constraint <%s>: new integral sides: sides=[%.15g,%.15g]\n",
9061  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
9062  }
9063  }
9064 
9065  return SCIP_OKAY;
9066 }
9067 
9068 /** tightens coefficients of binary, integer, and implicit integer variables due to activity bounds in presolving:
9069  * given an inequality lhs <= a*x + ai*xi <= rhs, with a non-continuous variable li <= xi <= ui
9070  * let minact := min{a*x + ai*xi}, maxact := max{a*x + ai*xi}
9071  * (i) ai >= 0:
9072  * if minact + ai >= lhs and maxact - ai <= rhs: (**)
9073  * - a deviation from the lower/upper bound of xi would make the left/right hand side redundant
9074  * - ai, lhs and rhs can be changed to have the same redundancy effect and the same results for
9075  * xi fixed to its bounds, but with a reduced ai and tightened sides to tighten the LP relaxation
9076  * - change coefficients:
9077  * ai' := max(lhs - minact, maxact - rhs)
9078  * lhs' := lhs - (ai - ai')*li
9079  * rhs' := rhs - (ai - ai')*ui
9080  * (ii) ai < 0:
9081  * if minact - ai >= lhs and maxact + ai <= rhs: (***)
9082  * - a deviation from the upper/lower bound of xi would make the left/right hand side redundant
9083  * - ai, lhs and rhs can be changed to have the same redundancy effect and the same results for
9084  * xi fixed to its bounds, but with a reduced ai and tightened sides to tighten the LP relaxation
9085  * - change coefficients:
9086  * ai' := min(rhs - maxact, minact - lhs)
9087  * lhs' := lhs - (ai - ai')*ui
9088  * rhs' := rhs - (ai - ai')*li
9089  *
9090  * We further try to remove redundant variable from the constraint;
9091  * Variables which fulfill conditions (**) or (***) are called surely non-redundant variables.
9092  * A deviation of only one from their bound makes the lhs/rhs feasible (i.e., redundant), even if all other
9093  * variables are set to their "worst" bound. If all variables which are not surely non-redundant cannot make
9094  * the lhs/rhs redundant, even if they are set to their "best" bound, they can be removed from the constraint.
9095  * E.g., for binary variables and an inequality x_1 +x_2 +10y_1 +10y_2 >= 5, setting either of the y_i to one
9096  * suffices to fulfill the inequality, whereas the x_i do not contribute to feasibility and can be removed.
9097  *
9098  * @todo use also some tightening procedures for (knapsack) constraints with non-integer coefficients, see
9099  * cons_knapsack.c the following methods detectRedundantVars() and tightenWeights()
9100  */
9101 static
9103  SCIP* scip, /**< SCIP data structure */
9104  SCIP_CONS* cons, /**< linear constraint */
9105  int* nchgcoefs, /**< pointer to count total number of changed coefficients */
9106  int* nchgsides /**< pointer to count number of side changes */
9107  )
9108 {
9109  SCIP_CONSDATA* consdata;
9110  SCIP_VAR* var;
9111  SCIP_Real minactivity; /* minimal value w.r.t. the variable's local bounds for the constraint's
9112  * activity, ignoring the coefficients contributing with infinite value */
9113  SCIP_Real maxactivity; /* maximal value w.r.t. the variable's local bounds for the constraint's
9114  * activity, ignoring the coefficients contributing with infinite value */
9115  SCIP_Bool minactisrelax; /* do huge finite values contribute to the minactivity? */
9116  SCIP_Bool maxactisrelax; /* do huge finite values contribute to the maxactivity? */
9117  SCIP_Bool isminsettoinfinity;
9118  SCIP_Bool ismaxsettoinfinity;
9119  SCIP_Real minleftactivity; /* minimal activity without surely non-redundant variables. */
9120  SCIP_Real maxleftactivity; /* maximal activity without surely non-redundant variables. */
9121  SCIP_Real aggrlhs; /* lhs without minimal activity of surely non-redundant variables. */
9122  SCIP_Real aggrrhs; /* rhs without maximal activity of surely non-redundant variables. */
9123  SCIP_Real lval; /* candidate for new value arising from considering the left hand side */
9124  SCIP_Real rval; /* candidate for new value arising from considering the left hand side */
9125  SCIP_Real val;
9126  SCIP_Real newval;
9127  SCIP_Real newlhs;
9128  SCIP_Real newrhs;
9129  SCIP_Real lb;
9130  SCIP_Real ub;
9131  int i;
9132 
9133  assert(scip != NULL);
9134  assert(cons != NULL);
9135  assert(nchgcoefs != NULL);
9136  assert(nchgsides != NULL);
9137 
9138  consdata = SCIPconsGetData(cons);
9139  assert(consdata != NULL);
9140 
9141  /* @todo Is this still needed with automatic recomputation of activities? */
9142  /* if the maximal coefficient is too large, recompute the activities */
9143  if( (consdata->validmaxabsval && consdata->maxabsval > MAXVALRECOMP)
9144  || (consdata->validminabsval && consdata->minabsval < MINVALRECOMP) )
9145  {
9146  consdataRecomputeMinactivity(scip, consdata);
9147  consdataRecomputeMaxactivity(scip, consdata);
9148  }
9149 
9150  /* get the minimal and maximal activity of the constraint */
9151  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9152  &isminsettoinfinity, &ismaxsettoinfinity);
9153 
9154  minleftactivity = 0.0;
9155  maxleftactivity = 0.0;
9156 
9157  /* try to tighten each coefficient */
9158  i = 0;
9159  while( i < consdata->nvars )
9160  {
9161  var = consdata->vars[i];
9162 
9163  /* get coefficient and variable's bounds */
9164  lb = SCIPvarGetLbLocal(var);
9165  ub = SCIPvarGetUbLocal(var);
9166  val = consdata->vals[i];
9167  assert(!SCIPisZero(scip, val));
9168 
9169  /* check sign of coefficient */
9170  if( val >= 0.0 )
9171  {
9172  /* check, if a deviation from lower/upper bound would make lhs/rhs redundant */
9174  SCIPisGE(scip, minactivity + val, consdata->lhs) && SCIPisLE(scip, maxactivity - val, consdata->rhs) )
9175  {
9176  /* change coefficients:
9177  * ai' := max(lhs - minact, maxact - rhs)
9178  * lhs' := lhs - (ai - ai')*li
9179  * rhs' := rhs - (ai - ai')*ui
9180  */
9181 
9182  lval = consdata->lhs - minactivity;
9183  rval = maxactivity - consdata->rhs;
9184 
9185  /* Try to avoid cancellation, if there are only two variables */
9186  if( consdata->nvars == 2 )
9187  {
9188  SCIP_Real otherval;
9189  otherval = consdata->vals[1-i];
9190 
9191  if( !SCIPisInfinity(scip, -consdata->lhs) && !isminsettoinfinity )
9192  {
9193  lval = consdata->lhs - val*lb;
9194  lval -= otherval > 0.0 ? otherval * SCIPvarGetLbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetUbLocal(consdata->vars[1-i]);
9195  }
9196 
9197  if( !SCIPisInfinity(scip, consdata->rhs) && !ismaxsettoinfinity )
9198  {
9199  rval = val*ub - consdata->rhs;
9200  rval += otherval > 0.0 ? otherval * SCIPvarGetUbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetLbLocal(consdata->vars[1-i]);
9201  }
9202  }
9203 
9204  newval = MAX(lval, rval);
9205  assert(SCIPisSumRelLE(scip, newval, val));
9206 
9207  /* Try to avoid cancellation in computation of lhs/rhs */
9208  newlhs = consdata->lhs - val * lb;
9209  newlhs += newval * lb;
9210  newrhs = consdata->rhs - val * ub;
9211  newrhs += newval * ub;
9212 
9213  if( !SCIPisSumRelEQ(scip, newval, val) )
9214  {
9215  SCIPdebugMsg(scip, "linear constraint <%s>: change coefficient %+.15g<%s> to %+.15g<%s>, act=[%.15g,%.15g], side=[%.15g,%.15g]\n",
9216  SCIPconsGetName(cons), val, SCIPvarGetName(var), newval, SCIPvarGetName(var),
9217  minactivity, maxactivity, consdata->lhs, consdata->rhs);
9218 
9219  /* update the coefficient and the activity bounds */
9220  if( SCIPisZero(scip, newval) )
9221  {
9222  SCIP_CALL( delCoefPos(scip, cons, i) );
9223  i--;
9224  }
9225  else
9226  {
9227  SCIP_CALL( chgCoefPos(scip, cons, i, newval) );
9228  }
9229  (*nchgcoefs)++;
9230 
9231  /* get the new minimal and maximal activity of the constraint */
9232  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9233  &isminsettoinfinity, &ismaxsettoinfinity);
9234 
9235  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisEQ(scip, newlhs, consdata->lhs) )
9236  {
9237  SCIPdebugMsg(scip, "linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
9238 
9239  SCIP_CALL( chgLhs(scip, cons, newlhs) );
9240  (*nchgsides)++;
9241  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
9242  }
9243 
9244  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisEQ(scip, newrhs, consdata->rhs) )
9245  {
9246  SCIPdebugMsg(scip, "linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
9247 
9248  SCIP_CALL( chgRhs(scip, cons, newrhs) );
9249  (*nchgsides)++;
9250  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
9251  }
9252  }
9253  }
9254  else
9255  {
9256  if( !SCIPisInfinity(scip, -minleftactivity) )
9257  {
9258  assert(!SCIPisInfinity(scip, val));
9259  assert(!SCIPisInfinity(scip, lb));
9260  if( SCIPisInfinity(scip, -lb) )
9261  minleftactivity = -SCIPinfinity(scip);
9262  else
9263  minleftactivity += val * lb;
9264  }
9265 
9266  if( !SCIPisInfinity(scip, maxleftactivity) )
9267  {
9268  assert(!SCIPisInfinity(scip, val));
9269  assert(!SCIPisInfinity(scip, -ub));
9270  if( SCIPisInfinity(scip,ub) )
9271  maxleftactivity = SCIPinfinity(scip);
9272  else
9273  maxleftactivity += val * ub;
9274  }
9275  }
9276  }
9277  else
9278  {
9279  /* check, if a deviation from lower/upper bound would make lhs/rhs redundant */
9281  SCIPisGE(scip, minactivity - val, consdata->lhs) && SCIPisLE(scip, maxactivity + val, consdata->rhs) )
9282  {
9283  /* change coefficients:
9284  * ai' := min(rhs - maxact, minact - lhs)
9285  * lhs' := lhs - (ai - ai')*ui
9286  * rhs' := rhs - (ai - ai')*li
9287  */
9288 
9289  lval = minactivity - consdata->lhs;
9290  rval = consdata->rhs - maxactivity;
9291 
9292  /* Try to avoid cancellation, if there are only two variables */
9293  if( consdata->nvars == 2 )
9294  {
9295  SCIP_Real otherval;
9296  otherval = consdata->vals[1-i];
9297 
9298  if( !SCIPisInfinity(scip, -consdata->lhs) && !isminsettoinfinity )
9299  {
9300  lval = val*ub - consdata->lhs;
9301  lval += otherval > 0.0 ? otherval * SCIPvarGetLbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetUbLocal(consdata->vars[1-i]);
9302  }
9303 
9304  if( !SCIPisInfinity(scip, consdata->rhs) && !ismaxsettoinfinity )
9305  {
9306  rval = consdata->rhs - val*lb;
9307  rval -= otherval > 0.0 ? otherval * SCIPvarGetUbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetLbLocal(consdata->vars[1-i]);
9308  }
9309  }
9310 
9311  newval = MIN(lval, rval);
9312  assert(SCIPisSumRelGE(scip, newval, val));
9313 
9314  /* Try to avoid cancellation in computation of lhs/rhs */
9315  newlhs = consdata->lhs - val * ub;
9316  newlhs += newval * ub;
9317  newrhs = consdata->rhs - val * lb;
9318  newrhs += newval * lb;
9319 
9320  if( !SCIPisSumRelEQ(scip, newval, val) )
9321  {
9322  SCIPdebugMsg(scip, "linear constraint <%s>: change coefficient %+.15g<%s> to %+.15g<%s>, act=[%.15g,%.15g], side=[%.15g,%.15g]\n",
9323  SCIPconsGetName(cons), val, SCIPvarGetName(var), newval, SCIPvarGetName(var),
9324  minactivity, maxactivity, consdata->lhs, consdata->rhs);
9325 
9326  /* update the coefficient and the activity bounds */
9327  if( SCIPisZero(scip, newval) )
9328  {
9329  SCIP_CALL( delCoefPos(scip, cons, i) );
9330  i--;
9331  }
9332  else
9333  {
9334  SCIP_CALL( chgCoefPos(scip, cons, i, newval) );
9335  }
9336  (*nchgcoefs)++;
9337 
9338  /* get the new minimal and maximal activity of the constraint */
9339  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9340  &isminsettoinfinity, &ismaxsettoinfinity);
9341 
9342  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisEQ(scip, newlhs, consdata->lhs) )
9343  {
9344  SCIPdebugMsg(scip, "linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
9345 
9346  SCIP_CALL( chgLhs(scip, cons, newlhs) );
9347  (*nchgsides)++;
9348  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
9349  }
9350 
9351  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisEQ(scip, newrhs, consdata->rhs) )
9352  {
9353  SCIPdebugMsg(scip, "linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
9354 
9355  SCIP_CALL( chgRhs(scip, cons, newrhs) );
9356  (*nchgsides)++;
9357  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
9358  }
9359  }
9360  }
9361  else
9362  {
9363  if( !SCIPisInfinity(scip, -minleftactivity) )
9364  {
9365  assert(!SCIPisInfinity(scip, -val));
9366  assert(!SCIPisInfinity(scip, -ub));
9367  if( SCIPisInfinity(scip, ub) )
9368  minleftactivity = -SCIPinfinity(scip);
9369  else
9370  minleftactivity += val * ub;
9371  }
9372 
9373  if( !SCIPisInfinity(scip, maxleftactivity) )
9374  {
9375  assert(!SCIPisInfinity(scip, -val));
9376  assert(!SCIPisInfinity(scip, lb));
9377  if( SCIPisInfinity(scip, -lb) )
9378  maxleftactivity = SCIPinfinity(scip);
9379  else
9380  maxleftactivity += val * lb;
9381  }
9382  }
9383  }
9384  ++i;
9385  }
9386 
9387  SCIPdebugMsg(scip, "minleftactivity = %.15g, rhs = %.15g\n",
9388  minleftactivity, consdata->rhs);
9389  SCIPdebugMsg(scip, "maxleftactivity = %.15g, lhs = %.15g\n",
9390  maxleftactivity, consdata->lhs);
9391 
9392  /* minleft == \infty ==> minactivity == \infty */
9393  assert(!SCIPisInfinity(scip, -minleftactivity) || SCIPisInfinity(scip, -minactivity));
9394  assert(!SCIPisInfinity(scip, maxleftactivity) || SCIPisInfinity(scip, maxactivity));
9395 
9396  /* if the lhs is finite, we will check in the following whether the not non-redundant variables can make lhs feasible;
9397  * this is not valid, if the minactivity is -\infty (aggrlhs would be minus infinity in the following computation)
9398  * or if huge values contributed to the minactivity, because the minactivity is then just a relaxation
9399  * (<= the exact minactivity), and we might falsely claim variables to be redundant in the following
9400  */
9401  assert(!SCIPisInfinity(scip, minactivity));
9402  if( !SCIPisInfinity(scip, -consdata->lhs) && (SCIPisInfinity(scip, -minactivity) || minactisrelax) )
9403  return SCIP_OKAY;
9404 
9405  /* if the rhs is finite, we will check in the following whether the not non-redundant variables can make rhs feasible;
9406  * this is not valid, if the maxactivity is \infty (aggrrhs would be infinity in the following computation)
9407  * or if huge values contributed to the maxactivity, because the maxactivity is then just a relaxation
9408  * (>= the exact maxactivity), and we might falsely claim variables to be redundant in the following
9409  */
9410  assert(!SCIPisInfinity(scip, -maxactivity));
9411  if( !SCIPisInfinity(scip, consdata->rhs) && (SCIPisInfinity(scip, maxactivity) || maxactisrelax) )
9412  return SCIP_OKAY;
9413 
9414  /* correct lhs and rhs by min/max activity of surely non-redundant variables
9415  * surely non-redundant variables are all those where a deviation from the bound makes the lhs/rhs redundant
9416  */
9417  aggrlhs = consdata->lhs - minactivity + minleftactivity;
9418  aggrrhs = consdata->rhs - maxactivity + maxleftactivity;
9419 
9420  /* check if the constraint contains variables which are redundant. The reasoning is the following:
9421  * Each non-redundant variable can make the lhs/rhs feasible with a deviation of only one in the bound.
9422  * If _all_ variables which are not non-redundant together cannot make lhs/rhs feasible,
9423  * they can be removed from the constraint.
9424  * aggrrhs may contain some near-infinity value, but only if rhs is infinity.
9425  */
9426  if( (SCIPisInfinity(scip, -consdata->lhs) || SCIPisFeasLT(scip, maxleftactivity, aggrlhs))
9427  && (SCIPisInfinity(scip, consdata->rhs) || SCIPisFeasGT(scip, minleftactivity, aggrrhs)) )
9428  {
9429  SCIP_Real minleftactivitypart;
9430  SCIP_Real maxleftactivitypart;
9431 
9432  assert(!SCIPisInfinity(scip, -consdata->lhs) || !SCIPisInfinity(scip, consdata->rhs));
9433 
9434  /* try to remove redundant variables from constraint */
9435  i = 0;
9436  while( i < consdata->nvars )
9437  {
9438  var = consdata->vars[i];
9439  minleftactivitypart = 0.0;
9440  maxleftactivitypart = 0.0;
9441  lb = SCIPvarGetLbLocal(var);
9442  ub = SCIPvarGetUbLocal(var);
9443 
9444  /* get coefficient and variable's bounds */
9445  val = consdata->vals[i];
9446  assert(!SCIPisZero(scip, val));
9447 
9448  /* check sign of coefficient */
9449  if( val >= 0.0 )
9450  {
9451  /* negation of condition above in case of positive val */
9453  SCIPisLT(scip, minactivity + val, consdata->lhs) || SCIPisGT(scip, maxactivity - val, consdata->rhs) )
9454  {
9455  SCIPdebugMsg(scip, "minactivity = %g\tval = %g\tlhs = %g\n", minactivity, val, consdata->lhs);
9456  SCIPdebugMsg(scip, "maxactivity = %g\tval = %g\trhs = %g\n", maxactivity, val, consdata->rhs);
9457  SCIPdebugMsg(scip, "linear constraint <%s>: remove variable <%s> with coefficient <%g> from constraint since it is redundant\n",
9458  SCIPconsGetName(cons), SCIPvarGetName(consdata->vars[i]), val);
9459 
9460  minleftactivitypart = val * lb;
9461  maxleftactivitypart = val * ub;
9462 
9463  SCIP_CALL( delCoefPos(scip, cons, i) );
9464  i--;
9465 
9466  /* get the new minimal and maximal activity of the constraint */
9467  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9468  &isminsettoinfinity, &ismaxsettoinfinity);
9469 
9470  /* we return above if the condition does not hold and deleting a variable cannot increase the number of
9471  * huge contributions
9472  */
9473  assert(!minactisrelax || SCIPisInfinity(scip, -consdata->lhs));
9474  assert(!maxactisrelax || SCIPisInfinity(scip, consdata->rhs));
9475  }
9476  }
9477  else
9478  {
9479  /* negation of condition above in case of negative val */
9481  SCIPisLT(scip, minactivity - val, consdata->lhs) || SCIPisGT(scip, maxactivity + val, consdata->rhs) )
9482  {
9483  SCIPdebugMsg(scip, "linear constraint <%s>: remove variable <%s> with coefficient <%g> from constraint since it is redundant\n",
9484  SCIPconsGetName(cons), SCIPvarGetName(consdata->vars[i]), val);
9485 
9486  minleftactivitypart = val * ub;
9487  maxleftactivitypart = val * lb;
9488 
9489  SCIP_CALL( delCoefPos(scip, cons, i) );
9490  i--;
9491 
9492  /* get the new minimal and maximal activity of the constraint */
9493  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9494  &isminsettoinfinity, &ismaxsettoinfinity);
9495 
9496  /* we return above if the condition does not hold and deleting a variable cannot increase the number of
9497  * huge contributions
9498  */
9499  assert(!minactisrelax || SCIPisInfinity(scip, -consdata->lhs));
9500  assert(!maxactisrelax || SCIPisInfinity(scip, consdata->rhs));
9501  }
9502  }
9503 
9504  /* the following update step is needed in every iteration cause otherwise it is possible that the surely none-
9505  * redundant variables could get deleted,
9506  * e.g. y_1 + 16y_2 >= 25, y1 with bounds [9,12], y2 with bounds [0,2], minactivity would be 9, it follows that
9507  * y_2 is surely not redundant and y_1 is redundant so we would first delete y1 and without updating the sides
9508  * we would also delete y2 and as a result we would have gotten infeasibility */
9509  /* adjust lhs and right hand side */
9510  newlhs = consdata->lhs - minleftactivitypart;
9511  newrhs = consdata->rhs - maxleftactivitypart;
9512 
9513  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisFeasEQ(scip, newlhs, consdata->lhs) )
9514  {
9515  SCIPdebugMsg(scip, "linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
9516  SCIP_CALL( chgLhs(scip, cons, newlhs) );
9517  ++(*nchgsides);
9518  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
9519  }
9520  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisFeasEQ(scip, newrhs, consdata->rhs) )
9521  {
9522  SCIPdebugMsg(scip, "linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
9523  SCIP_CALL( chgRhs(scip, cons, newrhs) );
9524  ++(*nchgsides);
9525  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
9526  }
9527  ++i;
9528  }
9529  }
9530 
9531  return SCIP_OKAY;
9532 }
9533 
9534 /** processes equality with only one variable by fixing the variable and deleting the constraint */
9535 static
9537  SCIP* scip, /**< SCIP data structure */
9538  SCIP_CONS* cons, /**< linear constraint */
9539  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
9540  int* nfixedvars, /**< pointer to count number of fixed variables */
9541  int* ndelconss /**< pointer to count number of deleted constraints */
9542  )
9543 {
9544  SCIP_CONSDATA* consdata;
9545  SCIP_VAR* var;
9546  SCIP_Real val;
9547  SCIP_Real fixval;
9548  SCIP_Bool infeasible;
9549  SCIP_Bool fixed;
9550 
9551  assert(scip != NULL);
9552  assert(cons != NULL);
9553  assert(cutoff != NULL);
9554  assert(nfixedvars != NULL);
9555  assert(ndelconss != NULL);
9556 
9557  consdata = SCIPconsGetData(cons);
9558  assert(consdata != NULL);
9559  assert(consdata->nvars == 1);
9560  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9561 
9562  /* calculate the value to fix the variable to */
9563  var = consdata->vars[0];
9564  val = consdata->vals[0];
9565  assert(!SCIPisZero(scip, val));
9566  fixval = SCIPselectSimpleValue(consdata->lhs/val - 0.9 * SCIPepsilon(scip),
9567  consdata->rhs/val + 0.9 * SCIPepsilon(scip), MAXDNOM);
9568  SCIPdebugMsg(scip, "linear equality <%s>: fix <%s> == %.15g\n",
9569  SCIPconsGetName(cons), SCIPvarGetName(var), fixval);
9570 
9571  /* fix variable */
9572  SCIP_CALL( SCIPfixVar(scip, var, fixval, &infeasible, &fixed) );
9573  if( infeasible )
9574  {
9575  SCIPdebugMsg(scip, " -> infeasible fixing\n");
9576  *cutoff = TRUE;
9577  return SCIP_OKAY;
9578  }
9579  if( fixed )
9580  (*nfixedvars)++;
9581 
9582  /* disable constraint */
9583  SCIP_CALL( SCIPdelCons(scip, cons) );
9584  if( !consdata->upgraded )
9585  (*ndelconss)++;
9586 
9587  return SCIP_OKAY;
9588 }
9589 
9590 /** processes equality with exactly two variables by aggregating one of the variables and deleting the constraint */
9591 static
9593  SCIP* scip, /**< SCIP data structure */
9594  SCIP_CONS* cons, /**< linear constraint */
9595  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
9596  int* naggrvars, /**< pointer to count number of aggregated variables */
9597  int* ndelconss /**< pointer to count number of deleted constraints */
9598  )
9599 {
9600  SCIP_CONSDATA* consdata;
9601  SCIP_Bool infeasible;
9602  SCIP_Bool redundant;
9603  SCIP_Bool aggregated;
9604 
9605  assert(scip != NULL);
9606  assert(cons != NULL);
9607  assert(cutoff != NULL);
9608  assert(naggrvars != NULL);
9609  assert(ndelconss != NULL);
9610 
9611  consdata = SCIPconsGetData(cons);
9612  assert(consdata != NULL);
9613  assert(consdata->nvars == 2);
9614  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9615 
9616  SCIPdebugMsg(scip, "linear constraint <%s>: aggregate %.15g<%s> + %.15g<%s> == %.15g\n",
9617  SCIPconsGetName(cons), consdata->vals[0], SCIPvarGetName(consdata->vars[0]),
9618  consdata->vals[1], SCIPvarGetName(consdata->vars[1]), consdata->rhs);
9619 
9620  /* aggregate the equality */
9621  SCIP_CALL( SCIPaggregateVars(scip, consdata->vars[0], consdata->vars[1], consdata->vals[0], consdata->vals[1],
9622  consdata->rhs, &infeasible, &redundant, &aggregated) );
9623 
9624  /* check for infeasibility of aggregation */
9625  if( infeasible )
9626  {
9627  SCIPdebugMsg(scip, " -> infeasible aggregation\n");
9628  *cutoff = TRUE;
9629  return SCIP_OKAY;
9630  }
9631 
9632  /* count the aggregation */
9633  if( aggregated )
9634  (*naggrvars)++;
9635 
9636  /* delete the constraint, if it is redundant */
9637  if( redundant )
9638  {
9639  SCIP_CALL( SCIPdelCons(scip, cons) );
9640 
9641  if( !consdata->upgraded )
9642  (*ndelconss)++;
9643  }
9644 
9645  return SCIP_OKAY;
9646 }
9647 
9648 /** calculates the new lhs and rhs of the constraint after the given variable is aggregated out */
9649 static
9651  SCIP* scip, /**< SCIP data structure */
9652  SCIP_CONSDATA* consdata, /**< linear constraint data */
9653  SCIP_VAR* slackvar, /**< variable to be aggregated out */
9654  SCIP_Real slackcoef, /**< coefficient of variable in constraint */
9655  SCIP_Real* newlhs, /**< pointer to store new lhs of constraint */
9656  SCIP_Real* newrhs /**< pointer to store new rhs of constraint */
9657  )
9658 {
9659  SCIP_Real slackvarlb;
9660  SCIP_Real slackvarub;
9661 
9662  assert(scip != NULL);
9663  assert(consdata != NULL);
9664  assert(newlhs != NULL);
9665  assert(newrhs != NULL);
9666  assert(!SCIPisInfinity(scip, -consdata->lhs));
9667  assert(!SCIPisInfinity(scip, consdata->rhs));
9668 
9669  slackvarlb = SCIPvarGetLbGlobal(slackvar);
9670  slackvarub = SCIPvarGetUbGlobal(slackvar);
9671  if( slackcoef > 0.0 )
9672  {
9673  if( SCIPisInfinity(scip, -slackvarlb) )
9674  *newrhs = SCIPinfinity(scip);
9675  else
9676  *newrhs = consdata->rhs - slackcoef * slackvarlb;
9677  if( SCIPisInfinity(scip, slackvarub) )
9678  *newlhs = -SCIPinfinity(scip);
9679  else
9680  *newlhs = consdata->lhs - slackcoef * slackvarub;
9681  }
9682  else
9683  {
9684  if( SCIPisInfinity(scip, -slackvarlb) )
9685  *newlhs = -SCIPinfinity(scip);
9686  else
9687  *newlhs = consdata->rhs - slackcoef * slackvarlb;
9688  if( SCIPisInfinity(scip, slackvarub) )
9689  *newrhs = SCIPinfinity(scip);
9690  else
9691  *newrhs = consdata->lhs - slackcoef * slackvarub;
9692  }
9693  assert(SCIPisLE(scip, *newlhs, *newrhs));
9694 }
9695 
9696 /** processes equality with more than two variables by multi-aggregating one of the variables and converting the equality
9697  * into an inequality; if multi-aggregation is not possible, tries to identify one continuous or integer variable that
9698  * is implicitly integral by this constraint
9699  *
9700  * @todo Check whether a more clever way of avoiding aggregation of variables containing implicitly integer variables
9701  * can help.
9702  */
9703 static
9705  SCIP* scip, /**< SCIP data structure */
9706  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
9707  SCIP_CONS* cons, /**< linear constraint */
9708  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
9709  int* naggrvars, /**< pointer to count number of aggregated variables */
9710  int* ndelconss /**< pointer to count number of deleted constraints */
9711  )
9712 {
9713  SCIP_CONSDATA* consdata;
9714  SCIP_VAR** vars;
9715  SCIP_Real* vals;
9716  SCIP_VARTYPE bestslacktype;
9717  SCIP_VARTYPE slacktype;
9718  SCIP_Real lhs;
9719  SCIP_Real rhs;
9720  SCIP_Real bestslackdomrng;
9721  SCIP_Real minabsval;
9722  SCIP_Real maxabsval;
9723  SCIP_Bool bestremovescons;
9724  SCIP_Bool coefszeroone;
9725  SCIP_Bool coefsintegral;
9726  SCIP_Bool varsintegral;
9727  SCIP_Bool infeasible;
9728  SCIP_Bool samevar;
9729  int supinf; /* counter for infinite contributions to the supremum of a possible
9730  * multi-aggregation
9731  */
9732  int infinf; /* counter for infinite contributions to the infimum of a possible
9733  * multi-aggregation
9734  */
9735  int maxnlocksstay;
9736  int maxnlocksremove;
9737  int bestslackpos;
9738  int bestnlocks;
9739  int ncontvars;
9740  int contvarpos;
9741  int nintvars;
9742  int nimplvars;
9743  int intvarpos;
9744  int v;
9745 
9746  assert(scip != NULL);
9747  assert(cons != NULL);
9748  assert(cutoff != NULL);
9749  assert(naggrvars != NULL);
9750 
9751  consdata = SCIPconsGetData(cons);
9752  assert(consdata != NULL);
9753  assert(consdata->nvars > 2);
9754  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9755 
9756  SCIPdebugMsg(scip, "linear constraint <%s>: try to multi-aggregate equality\n", SCIPconsGetName(cons));
9757 
9758  /* We do not want to increase the total number of non-zeros due to the multi-aggregation.
9759  * Therefore, we have to restrict the number of locks of a variable that is aggregated out.
9760  * maxnlocksstay: maximal sum of lock numbers if the constraint does not become redundant after the aggregation
9761  * maxnlocksremove: maximal sum of lock numbers if the constraint can be deleted after the aggregation
9762  */
9763  lhs = consdata->lhs;
9764  rhs = consdata->rhs;
9765  maxnlocksstay = 0;
9766  if( consdata->nvars == 3 )
9767  {
9768  /* If the constraint becomes redundant, 3 non-zeros are removed, and we get 1 additional non-zero for each
9769  * constraint the variable appears in. Thus, the variable must appear in at most 3 other constraints.
9770  */
9771  maxnlocksremove = 3;
9772  }
9773  else if( consdata->nvars == 4 )
9774  {
9775  /* If the constraint becomes redundant, 4 non-zeros are removed, and we get 2 additional non-zeros for each
9776  * constraint the variable appears in. Thus, the variable must appear in at most 2 other constraints.
9777  */
9778  maxnlocksremove = 2;
9779  }
9780  else
9781  {
9782  /* If the constraint is redundant but has more than 4 variables, we can only accept one other constraint. */
9783  maxnlocksremove = 1;
9784  }
9785 
9786  /* the locks on this constraint can be ignored */
9787  if( SCIPconsIsChecked(cons) )
9788  {
9789  if( !SCIPisInfinity(scip, -lhs) )
9790  {
9791  maxnlocksstay++;
9792  maxnlocksremove++;
9793  }
9794  if( !SCIPisInfinity(scip, rhs) )
9795  {
9796  maxnlocksstay++;
9797  maxnlocksremove++;
9798  }
9799  }
9800 
9801  /* look for a slack variable s to convert a*x + s == b into lhs <= a*x <= rhs */
9802  vars = consdata->vars;
9803  vals = consdata->vals;
9804  bestslackpos = -1;
9805  bestslacktype = SCIP_VARTYPE_BINARY;
9806  bestnlocks = INT_MAX;
9807  bestremovescons = FALSE;
9808  bestslackdomrng = 0.0;
9809  coefszeroone = TRUE;
9810  coefsintegral = TRUE;
9811  varsintegral = TRUE;
9812  ncontvars = 0;
9813  contvarpos = -1;
9814  nintvars = 0;
9815  nimplvars = 0;
9816  intvarpos = -1;
9817  minabsval = SCIPinfinity(scip);
9818  maxabsval = -1.0;
9819  for( v = 0; v < consdata->nvars; ++v )
9820  {
9821  SCIP_VAR* var;
9822  SCIP_Real val;
9823  SCIP_Real absval;
9824  SCIP_Real varlb;
9825  SCIP_Real varub;
9826  SCIP_Bool iscont;
9827  int nlocks;
9828 
9829  assert(vars != NULL);
9830  assert(vals != NULL);
9831 
9832  var = vars[v];
9833  assert(!SCIPconsIsChecked(cons) || SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) >= 1); /* because variable is locked in this equality */
9834  assert(!SCIPconsIsChecked(cons) || SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) >= 1);
9835  varlb = SCIPvarGetLbGlobal(var);
9836  varub = SCIPvarGetUbGlobal(var);
9837 
9838  val = vals[v];
9839  absval = REALABS(val);
9840  assert(SCIPisPositive(scip, absval));
9841 
9842  /* calculate minimal and maximal absolute value */
9843  if( absval < minabsval )
9844  minabsval = absval;
9845  if( absval > maxabsval )
9846  maxabsval = absval;
9847 
9848  /* do not try to multi aggregate, when numerical bad */
9849  if( maxabsval / minabsval > conshdlrdata->maxmultaggrquot )
9850  return SCIP_OKAY;
9851 
9852  slacktype = SCIPvarGetType(var);
9853  coefszeroone = coefszeroone && SCIPisEQ(scip, absval, 1.0);
9854  coefsintegral = coefsintegral && SCIPisIntegral(scip, val);
9855  varsintegral = varsintegral && (slacktype != SCIP_VARTYPE_CONTINUOUS);
9856  iscont = (slacktype == SCIP_VARTYPE_CONTINUOUS || slacktype == SCIP_VARTYPE_IMPLINT);
9857 
9858  /* update candidates for continuous -> implint and integer -> implint conversion */
9859  if( slacktype == SCIP_VARTYPE_CONTINUOUS )
9860  {
9861  ncontvars++;
9862  contvarpos = v;
9863  }
9864  else if( slacktype == SCIP_VARTYPE_IMPLINT )
9865  {
9866  ++nimplvars;
9867  }
9868  else if( slacktype == SCIP_VARTYPE_INTEGER )
9869  {
9870  nintvars++;
9871  intvarpos = v;
9872  }
9873 
9874  /* check, if variable is already fixed or aggregated */
9875  if( !SCIPvarIsActive(var) )
9876  continue;
9877 
9878  /* check, if variable is used in too many other constraints, even if this constraint could be deleted */
9880 
9881  if( nlocks > maxnlocksremove )
9882  continue;
9883 
9884  /* check, if variable can be used as a slack variable */
9885  if( (iscont || (coefsintegral && varsintegral && SCIPisEQ(scip, absval, 1.0))) &&
9886  !SCIPdoNotMultaggrVar(scip, var) )
9887  {
9888  SCIP_Bool better;
9889  SCIP_Bool equal;
9890  SCIP_Real slackdomrng;
9891 
9892  if( SCIPisInfinity(scip, varub) || SCIPisInfinity(scip, -varlb) )
9893  slackdomrng = SCIPinfinity(scip);
9894  /* we do not want to perform multi-aggregation due to numerics, if the bounds are huge */
9895  else if( SCIPisHugeValue(scip, varub) || SCIPisHugeValue(scip, -varlb) )
9896  return SCIP_OKAY;
9897  else
9898  {
9899  slackdomrng = (varub - varlb)*absval;
9900  assert(!SCIPisInfinity(scip, slackdomrng));
9901  }
9902  equal = FALSE;
9903  better = (slacktype > bestslacktype) || (bestslackpos == -1);
9904  if( !better && slacktype == bestslacktype )
9905  {
9906  better = (nlocks < bestnlocks);
9907  if( nlocks == bestnlocks && !bestremovescons )
9908  {
9909  better = SCIPisGT(scip, slackdomrng, bestslackdomrng);
9910  equal = !better && SCIPisGE(scip, slackdomrng, bestslackdomrng);
9911  }
9912  }
9913 
9914  if( better || equal )
9915  {
9916  SCIP_Real minresactivity;
9917  SCIP_Real maxresactivity;
9918  SCIP_Real newlhs;
9919  SCIP_Real newrhs;
9920  SCIP_Bool removescons;
9921  SCIP_Bool minisrelax;
9922  SCIP_Bool maxisrelax;
9923  SCIP_Bool isminsettoinfinity;
9924  SCIP_Bool ismaxsettoinfinity;
9925 
9926  /* check if the constraint becomes redundant after multi-aggregation */
9927  consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
9928  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
9929 
9930  /* do not perform the multi-aggregation due to numerics, if we have huge contributions in the residual
9931  * activity
9932  */
9933  if( minisrelax || maxisrelax )
9934  continue;
9935 
9936  getNewSidesAfterAggregation(scip, consdata, var, val, &newlhs, &newrhs);
9937  removescons = (SCIPisFeasLE(scip, newlhs, minresactivity) && SCIPisFeasLE(scip, maxresactivity, newrhs));
9938 
9939  /* check resactivities for reliability */
9940  if( removescons )
9941  {
9942  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
9943  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
9944 
9945  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity)
9946  && SCIPisFeasLE(scip, newlhs, minresactivity))
9947  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
9948 
9949  removescons = (SCIPisFeasLE(scip, newlhs, minresactivity) && SCIPisFeasLE(scip, maxresactivity, newrhs));
9950  }
9951 
9952  /* if parameter multaggrremove is set to TRUE, only aggregate when this removes constraint */
9953  if( conshdlrdata->multaggrremove && !removescons )
9954  continue;
9955 
9956  /* prefer variables that make the constraints redundant */
9957  if( bestremovescons && !removescons )
9958  continue;
9959 
9960  /* if the constraint does not become redundant, only accept the variable if it does not appear in
9961  * other constraints
9962  */
9963  if( !removescons && nlocks > maxnlocksstay )
9964  continue;
9965 
9966  better = better || (!bestremovescons && removescons);
9967  if( better )
9968  {
9969  bestslackpos = v;
9970  bestslacktype = slacktype;
9971  bestnlocks = nlocks;
9972  bestslackdomrng = slackdomrng;
9973  bestremovescons = removescons;
9974  }
9975  }
9976  }
9977  }
9978 
9979  /* if all coefficients and variables are integral, the right hand side must also be integral */
9980  if( coefsintegral && varsintegral && !SCIPisFeasIntegral(scip, consdata->rhs) )
9981  {
9982  SCIPdebugMsg(scip, "linear equality <%s> is integer infeasible\n", SCIPconsGetName(cons));
9983  SCIPdebugPrintCons(scip, cons, NULL);
9984  *cutoff = TRUE;
9985  return SCIP_OKAY;
9986  }
9987 
9988  supinf = 0;
9989  infinf = 0;
9990  samevar = FALSE;
9991 
9992  /* check whether the the infimum and the supremum of the multi-aggregation can be get infinite */
9993  for( v = 0; v < consdata->nvars; ++v )
9994  {
9995  if( v != bestslackpos )
9996  {
9997  if( SCIPisPositive(scip, consdata->vals[v]) )
9998  {
9999  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
10000  {
10001  ++supinf;
10002  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
10003  {
10004  ++infinf;
10005  samevar = TRUE;
10006  }
10007  }
10008  else if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
10009  ++infinf;
10010  }
10011  else if( SCIPisNegative(scip, consdata->vals[v]) )
10012  {
10013  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
10014  {
10015  ++supinf;
10016  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
10017  {
10018  ++infinf;
10019  samevar = TRUE;
10020  }
10021  }
10022  else if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
10023  ++infinf;
10024  }
10025  }
10026  }
10027  assert(!samevar || (supinf > 0 && infinf > 0));
10028 
10029  /* If the infimum and the supremum of a multi-aggregation are both infinite, then the multi-aggregation might not be resolvable.
10030  * E.g., consider the equality z = x-y. If x and y are both fixed to +infinity, the value for z is not determined */
10031  if( (samevar && (supinf > 1 || infinf > 1)) || (!samevar && supinf > 0 && infinf > 0) )
10032  {
10033  SCIPdebugMsg(scip, "do not perform multi-aggregation: infimum and supremum are both infinite\n");
10034  return SCIP_OKAY;
10035  }
10036 
10037  /* if the slack variable is of integer type, and the constraint itself may take fractional values,
10038  * we cannot aggregate the variable, because the integrality condition would get lost
10039  * Similarly, if there are implicitly integral variables we cannot aggregate, since we might
10040  * loose the integrality condition for this variable.
10041  */
10042  if( bestslackpos >= 0
10043  && (bestslacktype == SCIP_VARTYPE_CONTINUOUS || bestslacktype == SCIP_VARTYPE_IMPLINT
10044  || (coefsintegral && varsintegral && nimplvars == 0)) )
10045  {
10046  SCIP_VAR* slackvar;
10047  SCIP_Real* scalars;
10048  SCIP_Real slackcoef;
10049  SCIP_Real aggrconst;
10050  SCIP_Real newlhs;
10051  SCIP_Real newrhs;
10052  SCIP_Bool aggregated;
10053 
10054  /* we found a slack variable that only occurs in at most one other constraint:
10055  * a_1*x_1 + ... + a_k*x_k + a'*s == rhs -> s == rhs - a_1/a'*x_1 - ... - a_k/a'*x_k
10056  */
10057  assert(bestslackpos < consdata->nvars);
10058 
10059  /* do not multi aggregate binary variables */
10060  if( SCIPvarIsBinary(vars[bestslackpos]) )
10061  return SCIP_OKAY;
10062 
10063  /* convert equality into inequality by deleting the slack variable:
10064  * x + a*s == b, l <= s <= u -> b - a*u <= x <= b - a*l
10065  */
10066  slackvar = vars[bestslackpos];
10067  slackcoef = vals[bestslackpos];
10068  assert(!SCIPisZero(scip, slackcoef));
10069  aggrconst = consdata->rhs/slackcoef;
10070 
10071  getNewSidesAfterAggregation(scip, consdata, slackvar, slackcoef, &newlhs, &newrhs);
10072  assert(SCIPisLE(scip, newlhs, newrhs));
10073  SCIP_CALL( chgLhs(scip, cons, newlhs) );
10074  SCIP_CALL( chgRhs(scip, cons, newrhs) );
10075  SCIP_CALL( delCoefPos(scip, cons, bestslackpos) );
10076 
10077  /* allocate temporary memory */
10078  SCIP_CALL( SCIPallocBufferArray(scip, &scalars, consdata->nvars) );
10079 
10080  /* set up the multi-aggregation */
10081  SCIPdebugMsg(scip, "linear constraint <%s>: multi-aggregate <%s> ==", SCIPconsGetName(cons), SCIPvarGetName(slackvar));
10082  for( v = 0; v < consdata->nvars; ++v )
10083  {
10084  scalars[v] = -consdata->vals[v]/slackcoef;
10085  SCIPdebugMsgPrint(scip, " %+.15g<%s>", scalars[v], SCIPvarGetName(vars[v]));
10086  }
10087  SCIPdebugMsgPrint(scip, " %+.15g, bounds of <%s>: [%.15g,%.15g], nlocks=%d, maxnlocks=%d, removescons=%u\n",
10088  aggrconst, SCIPvarGetName(slackvar), SCIPvarGetLbGlobal(slackvar), SCIPvarGetUbGlobal(slackvar),
10089  bestnlocks, bestremovescons ? maxnlocksremove : maxnlocksstay, bestremovescons);
10090 
10091  /* perform the multi-aggregation */
10092  SCIP_CALL( SCIPmultiaggregateVar(scip, slackvar, consdata->nvars, vars, scalars, aggrconst,
10093  &infeasible, &aggregated) );
10094  assert(aggregated);
10095 
10096  /* free temporary memory */
10097  SCIPfreeBufferArray(scip, &scalars);
10098 
10099  /* check for infeasible aggregation */
10100  if( infeasible )
10101  {
10102  SCIPdebugMsg(scip, "linear constraint <%s>: infeasible multi-aggregation\n", SCIPconsGetName(cons));
10103  *cutoff = TRUE;
10104  return SCIP_OKAY;
10105  }
10106 
10107  (*naggrvars)++;
10108 
10109  /* delete the constraint if it became redundant */
10110  if( bestremovescons )
10111  {
10112  SCIPdebugMsg(scip, "linear constraint <%s>: redundant after multi-aggregation\n", SCIPconsGetName(cons));
10113  SCIP_CALL( SCIPdelCons(scip, cons) );
10114 
10115  if( !consdata->upgraded )
10116  (*ndelconss)++;
10117  }
10118  }
10119  else if( ncontvars == 1 )
10120  {
10121  SCIP_VAR* var;
10122 
10123  assert(0 <= contvarpos && contvarpos < consdata->nvars);
10124  var = vars[contvarpos];
10125  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
10126 
10127  if( coefsintegral && SCIPisFeasIntegral(scip, consdata->rhs) )
10128  {
10129  /* upgrade continuous variable to an implicit one, if the absolute value of the coefficient is one */
10130  if( SCIPisEQ(scip, REALABS(vals[contvarpos]), 1.0) )
10131  {
10132  /* convert the continuous variable with coefficient 1.0 into an implicit integer variable */
10133  SCIPdebugMsg(scip, "linear constraint <%s>: converting continuous variable <%s> to implicit integer variable\n",
10134  SCIPconsGetName(cons), SCIPvarGetName(var));
10135  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
10136  if( infeasible )
10137  {
10138  SCIPdebugMsg(scip, "infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
10139  *cutoff = TRUE;
10140 
10141  return SCIP_OKAY;
10142  }
10143  }
10144  /* aggregate continuous variable to an implicit one, if the absolute value of the coefficient is unequal to one */
10145  /* @todo check if the aggregation coefficient should be in some range(, which is not too big) */
10146  else if( !SCIPdoNotAggr(scip) )
10147  {
10148  SCIP_VAR* newvar;
10149  SCIP_Real absval;
10150  char newvarname[SCIP_MAXSTRLEN];
10151  SCIP_Bool redundant;
10152  SCIP_Bool aggregated;
10153 
10154  absval = REALABS(vals[contvarpos]);
10155 
10156  (void) SCIPsnprintf(newvarname, SCIP_MAXSTRLEN, "%s_impl", SCIPvarGetName(var));
10157 
10158  /* create new implicit variable for aggregation */
10159  SCIP_CALL( SCIPcreateVar(scip, &newvar, newvarname, -SCIPinfinity(scip), SCIPinfinity(scip), 0.0,
10161 
10162  /* add new variable to problem */
10163  SCIP_CALL( SCIPaddVar(scip, newvar) );
10164 
10165 #ifdef WITH_DEBUG_SOLUTION
10166  if( SCIPdebugIsMainscip(scip) )
10167  {
10168  SCIP_Real varval;
10169  SCIP_CALL( SCIPdebugGetSolVal(scip, var, &varval) );
10170  SCIP_CALL( SCIPdebugAddSolVal(scip, newvar, absval * varval) );
10171  }
10172 #endif
10173 
10174  /* convert the continuous variable with coefficient 1.0 into an implicit integer variable */
10175  SCIPdebugMsg(scip, "linear constraint <%s>: aggregating continuous variable <%s> to newly created implicit integer variable <%s>, aggregation factor = %g\n",
10176  SCIPconsGetName(cons), SCIPvarGetName(var), SCIPvarGetName(newvar), absval);
10177 
10178  /* aggregate continuous and implicit variable */
10179  SCIP_CALL( SCIPaggregateVars(scip, var, newvar, absval, -1.0, 0.0, &infeasible, &redundant, &aggregated) );
10180 
10181  if( infeasible )
10182  {
10183  SCIPdebugMsg(scip, "infeasible aggregation of variable <%s> to implicit variable <%s>, domain is empty\n",
10184  SCIPvarGetName(var), SCIPvarGetName(newvar));
10185  *cutoff = TRUE;
10186 
10187  /* release implicit variable */
10188  SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
10189 
10190  return SCIP_OKAY;
10191  }
10192 
10193  /* release implicit variable */
10194  SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
10195 
10196  if( aggregated )
10197  (*naggrvars)++;
10198  else
10199  return SCIP_OKAY;
10200  }
10201 
10202  /* we do not have any event on vartype changes, so we need to manually force this constraint to be presolved
10203  * again
10204  */
10205  consdata->boundstightened = 0;
10206  consdata->rangedrowpropagated = 0;
10207  consdata->presolved = FALSE;
10208  }
10209  }
10210  else if( ncontvars == 0 && nimplvars == 0 && nintvars == 1 && !coefszeroone )
10211  {
10212  SCIP_VAR* var;
10213 
10214  /* this seems to help for rococo instances, but does not for rout (where all coefficients are +/- 1.0)
10215  * -> we don't convert integers into implints if the row is a 0/1-row
10216  */
10217  assert(varsintegral);
10218  assert(0 <= intvarpos && intvarpos < consdata->nvars);
10219  var = vars[intvarpos];
10220  assert(SCIPvarGetType(var) == SCIP_VARTYPE_INTEGER);
10221 
10222  if( coefsintegral
10223  && SCIPisEQ(scip, REALABS(vals[intvarpos]), 1.0)
10224  && SCIPisFeasIntegral(scip, consdata->rhs) )
10225  {
10226  /* convert the integer variable with coefficient 1.0 into an implicit integer variable */
10227  SCIPdebugMsg(scip, "linear constraint <%s>: converting integer variable <%s> to implicit integer variable\n",
10228  SCIPconsGetName(cons), SCIPvarGetName(var));
10229  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
10230  if( infeasible )
10231  {
10232  SCIPdebugMsg(scip, "infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
10233  *cutoff = TRUE;
10234 
10235  return SCIP_OKAY;
10236  }
10237  }
10238  }
10239 
10240  return SCIP_OKAY;
10241 }
10242 
10243 /** checks if the given variables and their coefficient are equal (w.r.t. scaling factor) to the objective function */
10244 static
10246  SCIP* scip, /**< SCIP data structure */
10247  SCIP_CONSDATA* consdata, /**< linear constraint data */
10248  SCIP_Real* scale, /**< pointer to store the scaling factor between the constraint and the
10249  * objective function */
10250  SCIP_Real* offset /**< pointer to store the offset of the objective function resulting by
10251  * this constraint */
10252  )
10253 {
10254  SCIP_VAR** vars;
10255  SCIP_VAR* var;
10256  SCIP_Real objval;
10257  SCIP_Bool negated;
10258  int nvars;
10259  int v;
10260 
10261  vars = consdata->vars;
10262  nvars = consdata->nvars;
10263 
10264  assert(vars != NULL);
10265 
10266  for( v = 0; v < nvars; ++v )
10267  {
10268  negated = FALSE;
10269  var = vars[v];
10270  assert(var != NULL);
10271 
10272  if( SCIPvarIsNegated(var) )
10273  {
10274  negated = TRUE;
10275  var = SCIPvarGetNegatedVar(var);
10276  assert(var != NULL);
10277  }
10278 
10279  objval = SCIPvarGetObj(var);
10280 
10281  /* if a variable has a zero objective coefficient the linear constraint is not a subset of the objective
10282  * function
10283  */
10284  if( SCIPisZero(scip, objval) )
10285  return FALSE;
10286  else
10287  {
10288  SCIP_Real val;
10289 
10290  val = consdata->vals[v];
10291 
10292  if( negated )
10293  {
10294  if( v == 0 )
10295  {
10296  /* the first variable defines the scale */
10297  (*scale) = val / -objval;
10298 
10299  (*offset) += val;
10300  }
10301  else if( SCIPisEQ(scip, -objval * (*scale), val) )
10302  (*offset) += val;
10303  else
10304  return FALSE;
10305  }
10306  else if( v == 0 )
10307  {
10308  /* the first variable defines the scale */
10309  (*scale) = val / objval;
10310  }
10311  else if( !SCIPisEQ(scip, objval * (*scale), val) )
10312  return FALSE;
10313  }
10314  }
10315 
10316  return TRUE;
10317 }
10318 
10319 /** check if the linear equality constraint is equal to a subset of the objective function; if so we can remove the
10320  * objective coefficients and add an objective offset
10321  */
10322 static
10324  SCIP* scip, /**< SCIP data structure */
10325  SCIP_CONS* cons, /**< linear equation constraint */
10326  SCIP_CONSHDLRDATA* conshdlrdata /**< linear constraint handler data */
10327  )
10328 {
10329  SCIP_CONSDATA* consdata;
10330  SCIP_Real offset;
10331  SCIP_Real scale;
10332  SCIP_Bool applicable;
10333  int nobjvars;
10334  int nvars;
10335  int v;
10336 
10337  assert(scip != NULL);
10338  assert(cons != NULL);
10339  assert(conshdlrdata != NULL);
10340 
10341  consdata = SCIPconsGetData(cons);
10342  assert(consdata != NULL);
10343  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
10344 
10345  nvars = consdata->nvars;
10346  nobjvars = SCIPgetNObjVars(scip);
10347 
10348  /* check if the linear equality constraints does not have more variables than the objective function */
10349  if( nvars > nobjvars || nvars == 0 )
10350  return SCIP_OKAY;
10351 
10352  /* check for allowance of algorithm */
10353  if( (nvars < nobjvars && !conshdlrdata->detectpartialobjective) ||
10354  (nvars == nobjvars && (!conshdlrdata->detectcutoffbound || !conshdlrdata->detectlowerbound)) )
10355  return SCIP_OKAY;
10356 
10357  offset = consdata->rhs;
10358  scale = 1.0;
10359 
10360  /* checks if the variables and their coefficients are equal (w.r.t. scaling factor) to the objective function */
10361  applicable = checkEqualObjective(scip, consdata, &scale, &offset);
10362 
10363  if( applicable )
10364  {
10365  SCIP_VAR** vars;
10366 
10367  vars = consdata->vars;
10368  assert(vars != NULL);
10369 
10370  offset /= scale;
10371 
10372  SCIPdebugMsg(scip, "linear equality constraint <%s> == %g (offset %g) is a subset of the objective function\n",
10373  SCIPconsGetName(cons), consdata->rhs, offset);
10374 
10375  /* set all objective coefficient to zero */
10376  for( v = 0; v < nvars; ++v )
10377  {
10378  SCIP_CALL( SCIPchgVarObj(scip, vars[v], 0.0) );
10379  }
10380 
10381  /* add an objective offset */
10382  SCIP_CALL( SCIPaddObjoffset(scip, offset) );
10383  }
10384 
10385  return SCIP_OKAY;
10386 }
10387 
10388 /** updates the cutoff if the given primal bound (which is implied by the given constraint) is better */
10389 static
10391  SCIP* scip, /**< SCIP data structure */
10392  SCIP_CONS* cons, /**< constraint */
10393  SCIP_Real primalbound /**< feasible primal bound */
10394  )
10395 {
10396  SCIP_Real cutoffbound;
10397 
10398  /* increase the cutoff bound value by an epsilon to ensue that solution with the value of the cutoff bound are still
10399  * accepted
10400  */
10401  cutoffbound = primalbound + SCIPcutoffbounddelta(scip);
10402 
10403  if( cutoffbound < SCIPgetCutoffbound(scip) )
10404  {
10405  SCIPdebugMsg(scip, "update cutoff bound <%g>\n", cutoffbound);
10406 
10407  SCIP_CALL( SCIPupdateCutoffbound(scip, cutoffbound) );
10408  }
10409  else
10410  {
10411  SCIP_CONSDATA* consdata;
10412 
10413  consdata = SCIPconsGetData(cons);
10414  assert(consdata != NULL);
10415 
10416  /* we cannot disable the enforcement and propagation on ranged rows, because the cutoffbound could only have
10417  * resulted from one side
10418  */
10419  if( SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, consdata->rhs) )
10420  {
10421  /* in case the cutoff bound is worse then the currently known one, we additionally avoid enforcement and
10422  * propagation
10423  */
10424  SCIP_CALL( SCIPsetConsEnforced(scip, cons, FALSE) );
10425  SCIP_CALL( SCIPsetConsPropagated(scip, cons, FALSE) );
10426  }
10427  }
10428 
10429  return SCIP_OKAY;
10430 }
10431 
10432 /** check if the linear constraint is parallel to objective function; if so update the cutoff bound and avoid that the
10433  * constraint enters the LP by setting the initial and separated flag to FALSE
10434  */
10435 static
10437  SCIP* scip, /**< SCIP data structure */
10438  SCIP_CONS* cons, /**< linear constraint */
10439  SCIP_CONSHDLRDATA* conshdlrdata /**< linear constraint handler data */
10440  )
10441 {
10442  SCIP_CONSDATA* consdata;
10443  SCIP_Real offset;
10444  SCIP_Real scale;
10445  SCIP_Bool applicable;
10446  int nobjvars;
10447  int nvars;
10448 
10449  assert(scip != NULL);
10450  assert(cons != NULL);
10451  assert(conshdlrdata != NULL);
10452 
10453  consdata = SCIPconsGetData(cons);
10454  assert(consdata != NULL);
10456  /* ignore equalities since these are covered by the method checkPartialObjective() */
10457  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
10458  return SCIP_OKAY;
10459 
10460  nvars = consdata->nvars;
10461  nobjvars = SCIPgetNObjVars(scip);
10462 
10463  /* check if the linear inequality constraints has the same number of variables as the objective function and if the
10464  * initial and/or separated flag is set to FALSE
10465  */
10466  if( nvars != nobjvars || (!SCIPconsIsInitial(cons) && !SCIPconsIsSeparated(cons)) )
10467  return SCIP_OKAY;
10468 
10469  offset = 0.0;
10470  scale = 1.0;
10471 
10472  /* There are no variables in the ojective function and in the constraint. Thus, the constraint is redundant or proves
10473  * infeasibility. Since we have a pure feasibility problem, we do not want to set a cutoff or lower bound.
10474  */
10475  if( nobjvars == 0 )
10476  return SCIP_OKAY;
10477 
10478  /* checks if the variables and their coefficients are equal (w.r.t. scaling factor) to the objective function */
10479  applicable = checkEqualObjective(scip, consdata, &scale, &offset);
10480 
10481  if( applicable )
10482  {
10483  SCIP_Bool rhsfinite = !SCIPisInfinity(scip, consdata->rhs);
10484  SCIP_Bool lhsfinite = !SCIPisInfinity(scip, -consdata->lhs);
10485 
10486  if( SCIPisPositive(scip, scale) )
10487  {
10488  if( conshdlrdata->detectcutoffbound && rhsfinite )
10489  {
10490  SCIP_Real primalbound;
10491 
10492  primalbound = (consdata->rhs - offset) / scale;
10493 
10494  SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a cutoff bound <%g>\n",
10495  SCIPconsGetName(cons), primalbound);
10496 
10497  SCIP_CALL( updateCutoffbound(scip, cons, primalbound) );
10498  }
10499 
10500  if( conshdlrdata->detectlowerbound && lhsfinite )
10501  {
10502  SCIP_Real lowerbound;
10503 
10504  lowerbound = (consdata->lhs - offset) / scale;
10505 
10506  SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a lower bound <%g>\n",
10507  SCIPconsGetName(cons), lowerbound);
10508 
10509  SCIP_CALL( SCIPupdateLocalLowerbound(scip, lowerbound) );
10510  }
10511 
10512  if( (conshdlrdata->detectcutoffbound && (conshdlrdata->detectlowerbound || !lhsfinite)) ||
10513  (conshdlrdata->detectlowerbound && !rhsfinite) )
10514  {
10515  /* avoid that the linear constraint enters the LP since it is parallel to the objective function */
10516  SCIP_CALL( SCIPsetConsInitial(scip, cons, FALSE) );
10517  SCIP_CALL( SCIPsetConsSeparated(scip, cons, FALSE) );
10518  }
10519  }
10520  else
10521  {
10522  if( conshdlrdata->detectlowerbound && rhsfinite )
10523  {
10524  SCIP_Real lowerbound;
10525 
10526  lowerbound = (consdata->rhs - offset) / scale;
10527 
10528  SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a lower bound <%g>\n",
10529  SCIPconsGetName(cons), lowerbound);
10530 
10531  SCIP_CALL( SCIPupdateLocalLowerbound(scip, lowerbound) );
10532  }
10533 
10534  if( conshdlrdata->detectcutoffbound && lhsfinite )
10535  {
10536  SCIP_Real primalbound;
10537 
10538  primalbound = (consdata->lhs - offset) / scale;
10539 
10540  SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a cutoff bound <%g>\n",
10541  SCIPconsGetName(cons), primalbound);
10542 
10543  SCIP_CALL( updateCutoffbound(scip, cons, primalbound) );
10544  }
10545 
10546  if( (conshdlrdata->detectcutoffbound && (conshdlrdata->detectlowerbound || !rhsfinite)) ||
10547  (conshdlrdata->detectlowerbound && !lhsfinite) )
10548  {
10549  /* avoid that the linear constraint enters the LP since it is parallel to the objective function */
10550  SCIP_CALL( SCIPsetConsInitial(scip, cons, FALSE) );
10551  SCIP_CALL( SCIPsetConsSeparated(scip, cons, FALSE) );
10552  }
10553  }
10554  }
10555 
10556  return SCIP_OKAY;
10557 }
10558 
10559 /** converts special equalities */
10560 static
10562  SCIP* scip, /**< SCIP data structure */
10563  SCIP_CONS* cons, /**< linear constraint */
10564  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
10565  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
10566  int* nfixedvars, /**< pointer to count number of fixed variables */
10567  int* naggrvars, /**< pointer to count number of aggregated variables */
10568  int* ndelconss /**< pointer to count number of deleted constraints */
10569  )
10570 {
10571  SCIP_CONSDATA* consdata;
10572 
10573  assert(scip != NULL);
10574  assert(cons != NULL);
10575  assert(conshdlrdata != NULL);
10576  assert(cutoff != NULL);
10577  assert(nfixedvars != NULL);
10578  assert(naggrvars != NULL);
10579  assert(ndelconss != NULL);
10581  consdata = SCIPconsGetData(cons);
10582  assert(consdata != NULL);
10583  assert(consdata->removedfixings);
10584 
10585  /* do nothing on inequalities */
10586  if( !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
10587  return SCIP_OKAY;
10588 
10589  /* depending on the number of variables, call a special conversion method */
10590  if( consdata->nvars == 1 )
10591  {
10592  /* fix variable */
10593  SCIP_CALL( convertUnaryEquality(scip, cons, cutoff, nfixedvars, ndelconss) );
10594  }
10595  else if( consdata->nvars == 2 )
10596  {
10597  /* aggregate one of the variables */
10598  SCIP_CALL( convertBinaryEquality(scip, cons, cutoff, naggrvars, ndelconss) );
10599  }
10600  else
10601  {
10602  /* check if the equality is part of the objective function */
10603  SCIP_CALL( checkPartialObjective(scip, cons, conshdlrdata) );
10604 
10605  /* try to multi-aggregate one of the variables */
10606  SCIP_CALL( convertLongEquality(scip, conshdlrdata, cons, cutoff, naggrvars, ndelconss) );
10607  }
10608 
10609  return SCIP_OKAY;
10610 }
10611 
10612 /** returns whether the linear sum of all variables/coefficients except the given one divided by the given value is always
10613  * integral
10614  */
10615 static
10617  SCIP* scip, /**< SCIP data structure */
10618  SCIP_CONSDATA* consdata, /**< linear constraint */
10619  int pos, /**< position of variable to be left out */
10620  SCIP_Real val /**< value to divide the coefficients by */
10621  )
10622 {
10623  int v;
10624 
10625  assert(scip != NULL);
10626  assert(consdata != NULL);
10627  assert(0 <= pos && pos < consdata->nvars);
10628 
10629  for( v = 0; v < consdata->nvars; ++v )
10630  {
10631  if( v != pos && (!SCIPvarIsIntegral(consdata->vars[v]) || !SCIPisIntegral(scip, consdata->vals[v]/val)) )
10632  return FALSE;
10633  }
10634 
10635  return TRUE;
10636 }
10637 
10638 /** check if \f$lhs/a_i - \sum_{j \neq i} a_j/a_i x_j\f$ is always inside the bounds of \f$x_i\f$,
10639  * check if \f$rhs/a_i - \sum_{j \neq i} a_j/a_i x_j\f$ is always inside the bounds of \f$x_i\f$
10640  */
10641 static
10643  SCIP* scip, /**< SCIP data structure */
10644  SCIP_Real side, /**< lhs or rhs */
10645  SCIP_Real val, /**< coefficient */
10646  SCIP_Real minresactivity, /**< minimal residual activity */
10647  SCIP_Real maxresactivity, /**< maximal residual activity */
10648  SCIP_Real* minval, /**< pointer to store calculated minval */
10649  SCIP_Real* maxval /**< pointer to store calculated maxval */
10650  )
10651 {
10652  assert(scip != NULL);
10653  assert(minval != NULL);
10654  assert(maxval != NULL);
10655 
10656  if( val > 0.0 )
10657  {
10658  if( SCIPisInfinity(scip, ABS(maxresactivity)) )
10659  *minval = -maxresactivity;
10660  else
10661  *minval = (side - maxresactivity)/val;
10662 
10663  if( SCIPisInfinity(scip, ABS(minresactivity)) )
10664  *maxval = -minresactivity;
10665  else
10666  *maxval = (side - minresactivity)/val;
10667  }
10668  else
10669  {
10670  if( SCIPisInfinity(scip, ABS(minresactivity)) )
10671  *minval = minresactivity;
10672  else
10673  *minval = (side - minresactivity)/val;
10674 
10675  if( SCIPisInfinity(scip, ABS(maxresactivity)) )
10676  *maxval = maxresactivity;
10677  else
10678  *maxval = (side - maxresactivity)/val;
10679  }
10680 }
10681 
10682 
10683 /** applies dual presolving for variables that are locked only once in a direction, and this locking is due to a
10684  * linear inequality
10685  */
10686 static
10688  SCIP* scip, /**< SCIP data structure */
10689  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
10690  SCIP_CONS* cons, /**< linear constraint */
10691  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
10692  int* nfixedvars, /**< pointer to count number of fixed variables */
10693  int* naggrvars, /**< pointer to count number of aggregated variables */
10694  int* ndelconss /**< pointer to count number of deleted constraints */
10695  )
10696 {
10697  SCIP_CONSDATA* consdata;
10698  SCIP_Bool lhsexists;
10699  SCIP_Bool rhsexists;
10700  SCIP_Bool bestisint;
10701  SCIP_Bool bestislhs;
10702  SCIP_Real minabsval;
10703  SCIP_Real maxabsval;
10704  int bestpos;
10705  int i;
10706  int maxotherlocks;
10707 
10708  assert(scip != NULL);
10709  assert(cons != NULL);
10710  assert(cutoff != NULL);
10711  assert(nfixedvars != NULL);
10712  assert(naggrvars != NULL);
10713  assert(ndelconss != NULL);
10714 
10715  /* only process checked constraints (for which the locks are increased);
10716  * otherwise we would have to check for variables with nlocks == 0, and these are already processed by the
10717  * dualfix presolver
10718  */
10719  if( !SCIPconsIsChecked(cons) )
10720  return SCIP_OKAY;
10721 
10722  consdata = SCIPconsGetData(cons);
10723  assert(consdata != NULL);
10724 
10725  lhsexists = !SCIPisInfinity(scip, -consdata->lhs);
10726  rhsexists = !SCIPisInfinity(scip, consdata->rhs);
10727 
10728  /* search for a single-locked variable which can be multi-aggregated; if a valid continuous variable was found, we
10729  * can use it safely for aggregation and break the search loop
10730  */
10731  bestpos = -1;
10732  bestisint = TRUE;
10733  bestislhs = FALSE;
10734 
10735  /* We only want to multi-aggregate variables, if they appear in maximal one additional constraint,
10736  * everything else would produce fill-in. Exceptions:
10737  * - If there are only two variables in the constraint from which the multi-aggregation arises, no fill-in will be
10738  * produced.
10739  * - If there are three variables in the constraint, multi-aggregation in three additional constraints will remove
10740  * six nonzeros (three from the constraint and the three entries of the multi-aggregated variable) and add
10741  * six nonzeros (two variables per substitution).
10742  * - If there at most four variables in the constraint, multi-aggregation in two additional constraints will remove
10743  * six nonzeros (four from the constraint and the two entries of the multi-aggregated variable) and add
10744  * six nonzeros (three variables per substitution). God exists!
10745  */
10746  if( consdata->nvars <= 2 )
10747  maxotherlocks = INT_MAX;
10748  else if( consdata->nvars == 3 )
10749  maxotherlocks = 3;
10750  else if( consdata->nvars == 4 )
10751  maxotherlocks = 2;
10752  else
10753  maxotherlocks = 1;
10754 
10755  /* if this constraint has both sides, it also provides a lock for the other side and thus we can allow one more lock */
10756  if( lhsexists && rhsexists && maxotherlocks < INT_MAX )
10757  maxotherlocks++;
10758 
10759  minabsval = SCIPinfinity(scip);
10760  maxabsval = -1.0;
10761  for( i = 0; i < consdata->nvars && bestisint; ++i )
10762  {
10763  SCIP_VAR* var;
10764  SCIP_Bool isint;
10765  SCIP_Real val;
10766  SCIP_Real absval;
10767  SCIP_Real obj;
10768  SCIP_Real lb;
10769  SCIP_Real ub;
10770  SCIP_Bool agglhs;
10771  SCIP_Bool aggrhs;
10772 
10773  val = consdata->vals[i];
10774  absval = REALABS(val);
10775 
10776  /* calculate minimal and maximal absolute value */
10777  if( absval < minabsval )
10778  minabsval = absval;
10779  if( absval > maxabsval )
10780  maxabsval = absval;
10781 
10782  /* do not try to multi aggregate, when numerical bad */
10783  if( maxabsval / minabsval > conshdlrdata->maxdualmultaggrquot )
10784  return SCIP_OKAY;
10785 
10786  var = consdata->vars[i];
10788 
10789  /* if we already found a candidate, skip integers */
10790  if( bestpos >= 0 && isint )
10791  continue;
10792 
10793  /* better do not multi-aggregate binary variables, since most plugins rely on their binary variables to be either
10794  * active, fixed, or single-aggregated with another binary variable
10795  */
10796  if( SCIPvarIsBinary(var) && consdata->nvars > 2 )
10797  continue;
10798 
10799  if ( SCIPdoNotMultaggrVar(scip, var) )
10800  continue;
10801 
10802  val = consdata->vals[i];
10803  obj = SCIPvarGetObj(var);
10804  lb = SCIPvarGetLbGlobal(var);
10805  ub = SCIPvarGetUbGlobal(var);
10806 
10807  /* lhs <= a_0 * x_0 + a_1 * x_1 + ... + a_{n-1} * x_{n-1} <= rhs
10808  *
10809  * a_i >= 0, c_i >= 0, lhs exists, nlocksdown(x_i) == 1:
10810  * - constraint is the only one that forbids fixing the variable to its lower bound
10811  * - fix x_i to the smallest value for this constraint: x_i := lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j
10812  *
10813  * a_i <= 0, c_i <= 0, lhs exists, nlocksup(x_i) == 1:
10814  * - constraint is the only one that forbids fixing the variable to its upper bound
10815  * - fix x_i to the largest value for this constraint: x_i := lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j
10816  *
10817  * a_i >= 0, c_i <= 0, rhs exists, nlocksup(x_i) == 1:
10818  * - constraint is the only one that forbids fixing the variable to its upper bound
10819  * - fix x_i to the largest value for this constraint: x_i := rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j
10820  *
10821  * a_i <= 0, c_i >= 0, rhs exists, nlocksdown(x_i) == 1:
10822  * - constraint is the only one that forbids fixing the variable to its lower bound
10823  * - fix x_i to the smallest value for this constraint: x_i := rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j
10824  *
10825  * but: all this is only applicable, if the aggregated value is inside x_i's bounds for all possible values
10826  * of all x_j
10827  * furthermore: we only want to apply this, if no fill-in will be produced
10828  */
10829  agglhs = lhsexists
10830  && ((val > 0.0 && !SCIPisNegative(scip, obj) && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == 1
10831  && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks)
10832  || (val < 0.0 && !SCIPisPositive(scip, obj) && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == 1
10833  && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks));
10834  aggrhs = rhsexists
10835  && ((val > 0.0 && !SCIPisPositive(scip, obj) && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == 1
10836  && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks)
10837  || (val < 0.0 && !SCIPisNegative(scip, obj) && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == 1
10838  && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks));
10839  if( agglhs || aggrhs )
10840  {
10841  SCIP_Real minresactivity;
10842  SCIP_Real maxresactivity;
10843  SCIP_Real minval;
10844  SCIP_Real maxval;
10845  SCIP_Bool minisrelax;
10846  SCIP_Bool maxisrelax;
10847  SCIP_Bool isminsettoinfinity;
10848  SCIP_Bool ismaxsettoinfinity;
10849 
10850  /* calculate bounds for \sum_{j \neq i} a_j * x_j */
10851  consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
10852  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
10853  assert(SCIPisLE(scip, minresactivity, maxresactivity));
10854 
10855  /* We called consdataGetActivityResiduals() saying that we do not need a good relaxation,
10856  * so whenever we have a relaxed activity, it should be relaxed to +/- infinity.
10857  * This is needed, because we do not want to rely on relaxed finite resactivities.
10858  */
10859  assert((!minisrelax || isminsettoinfinity) && (!maxisrelax || ismaxsettoinfinity));
10860 
10861  if( agglhs )
10862  {
10863  /* check if lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10864  calculateMinvalAndMaxval(scip, consdata->lhs, val, minresactivity, maxresactivity, &minval, &maxval);
10865 
10866  assert(SCIPisLE(scip, minval, maxval));
10867  if( (!SCIPisInfinity(scip, -minval) && SCIPisFeasGE(scip, minval, lb)) &&
10868  (!SCIPisInfinity(scip, maxval) && SCIPisFeasLE(scip, maxval, ub)) )
10869  {
10870  SCIP_Real oldmaxresactivity;
10871  SCIP_Real oldminresactivity;
10872  SCIP_Bool recalculated;
10873 
10874  recalculated = FALSE;
10875  oldmaxresactivity = maxresactivity;
10876  oldminresactivity = minresactivity;
10877 
10878  /* check minresactivity for reliability */
10879  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
10880  {
10881  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
10882  recalculated = !SCIPisEQ(scip, oldminresactivity, minresactivity);
10883  isminsettoinfinity = TRUE; /* here it means only that it was even calculated */
10884  }
10885 
10886  /* check maxresactivity for reliability */
10887  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
10888  {
10889  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
10890  recalculated = recalculated || !SCIPisEQ(scip, oldmaxresactivity, maxresactivity);
10891  ismaxsettoinfinity = TRUE; /* here it means only that it was even calculated */
10892  }
10893 
10894  /* minresactivity or maxresactivity wasn't reliable so recalculate min- and maxval*/
10895  if( recalculated )
10896  {
10897  assert(SCIPisLE(scip, minresactivity, maxresactivity));
10898 
10899  /* check again if lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10900  calculateMinvalAndMaxval(scip, consdata->lhs, val, minresactivity, maxresactivity, &minval, &maxval);
10901 
10902  assert(SCIPisLE(scip, minval, maxval));
10903  }
10904 
10905  if( !recalculated || (SCIPisFeasGE(scip, minval, lb) && SCIPisFeasLE(scip, maxval, ub)) )
10906  {
10907  /* if the variable is integer, we have to check whether the integrality condition would always be satisfied
10908  * in the multi-aggregation
10909  */
10910  if( !isint || (SCIPisIntegral(scip, consdata->lhs/val) && consdataIsResidualIntegral(scip, consdata, i, val)) )
10911  {
10912  bestpos = i;
10913  bestisint = isint;
10914  bestislhs = TRUE;
10915  continue; /* no need to also look at the right hand side */
10916  }
10917  }
10918  }
10919  }
10920 
10921  if( aggrhs )
10922  {
10923  /* check if rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10924  calculateMinvalAndMaxval(scip, consdata->rhs, val, minresactivity, maxresactivity, &minval, &maxval);
10925 
10926  assert(SCIPisLE(scip,minval,maxval));
10927  if( (!SCIPisInfinity(scip, -minval) && SCIPisFeasGE(scip, minval, lb)) &&
10928  (!SCIPisInfinity(scip, maxval) && SCIPisFeasLE(scip, maxval, ub)) )
10929  {
10930  SCIP_Real oldmaxresactivity;
10931  SCIP_Real oldminresactivity;
10932  SCIP_Bool recalculated;
10933 
10934  recalculated = FALSE;
10935  oldmaxresactivity = maxresactivity;
10936  oldminresactivity = minresactivity;
10937 
10938  /* check minresactivity for reliability */
10939  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
10940  {
10941  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
10942  recalculated = !SCIPisEQ(scip, oldminresactivity, minresactivity);
10943  }
10944 
10945  /* check maxresactivity for reliability */
10946  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
10947  {
10948  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
10949  recalculated = recalculated || !SCIPisEQ(scip, oldmaxresactivity, maxresactivity);
10950  }
10951 
10952  /* minresactivity or maxresactivity wasn't reliable so recalculate min- and maxval*/
10953  if( recalculated )
10954  {
10955  /* check again if rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10956  calculateMinvalAndMaxval(scip, consdata->rhs, val, minresactivity, maxresactivity, &minval, &maxval);
10957  assert(SCIPisLE(scip,minval,maxval));
10958  }
10959 
10960  if( !recalculated || (SCIPisFeasGE(scip, minval, lb) && SCIPisFeasLE(scip, maxval, ub)) )
10961  {
10962  /* if the variable is integer, we have to check whether the integrality condition would always be satisfied
10963  * in the multi-aggregation
10964  */
10965  if( !isint || (SCIPisIntegral(scip, consdata->rhs/val) && consdataIsResidualIntegral(scip, consdata, i, val)) )
10966  {
10967  bestpos = i;
10968  bestisint = isint;
10969  bestislhs = FALSE;
10970  }
10971  }
10972  }
10973  }
10974  }
10975  }
10976 
10977  if( bestpos >= 0 )
10978  {
10979  SCIP_VAR** aggrvars;
10980  SCIP_Real* aggrcoefs;
10981  SCIP_Real aggrconst;
10982  SCIP_VAR* bestvar;
10983  SCIP_Real bestval;
10984  SCIP_Real epsilon;
10985  int naggrs;
10986  int j;
10987  SCIP_Bool infeasible;
10988  SCIP_Bool aggregated;
10989  SCIP_Bool samevar;
10990  int supinf; /* counter for infinite contributions to the supremum of a possible
10991  * multi-aggregation
10992  */
10993  int infinf; /* counter for infinite contributions to the infimum of a possible
10994  * multi-aggregation
10995  */
10996 
10997  assert(!bestislhs || lhsexists);
10998  assert(bestislhs || rhsexists);
10999 
11000  bestvar = consdata->vars[bestpos];
11001  bestval = consdata->vals[bestpos];
11002  assert(bestisint ==
11004 
11005  /* allocate temporary memory */
11006  SCIP_CALL( SCIPallocBufferArray(scip, &aggrvars, consdata->nvars-1) );
11007  SCIP_CALL( SCIPallocBufferArray(scip, &aggrcoefs, consdata->nvars-1) );
11008 
11009  /* set up the multi-aggregation */
11010  SCIPdebugPrintCons(scip, cons, NULL);
11011  SCIPdebugMsg(scip, "linear constraint <%s> (dual): multi-aggregate <%s> ==", SCIPconsGetName(cons), SCIPvarGetName(bestvar));
11012  naggrs = 0;
11013  supinf = 0;
11014  infinf = 0;
11015  samevar = FALSE;
11016  epsilon = SCIPepsilon(scip);
11017 
11018  for( j = 0; j < consdata->nvars; ++j )
11019  {
11020  if( j != bestpos )
11021  {
11022  SCIP_Real absaggrcoef;
11023 
11024  aggrvars[naggrs] = consdata->vars[j];
11025  aggrcoefs[naggrs] = -consdata->vals[j]/consdata->vals[bestpos];
11026  SCIPdebugMsgPrint(scip, " %+.15g<%s>", aggrcoefs[naggrs], SCIPvarGetName(aggrvars[naggrs]));
11027 
11028  absaggrcoef = REALABS(aggrcoefs[naggrs]);
11029 
11030  /* do not try to multi aggregate, when numerical bad */
11031  if( absaggrcoef < epsilon )
11032  {
11033  SCIPdebugMsg(scip, "do not perform multi-aggregation: too large aggregation coefficients\n");
11034 
11035  /* free temporary memory */
11036  SCIPfreeBufferArray(scip, &aggrcoefs);
11037  SCIPfreeBufferArray(scip, &aggrvars);
11038 
11039  return SCIP_OKAY;
11040  }
11041 
11042  if( bestisint )
11043  {
11044  /* coefficient must be integral: round it to exact integral value */
11045  assert(SCIPisIntegral(scip, aggrcoefs[naggrs]));
11046  aggrcoefs[naggrs] = SCIPfloor(scip, aggrcoefs[naggrs]+0.5);
11047  }
11048 
11049  if( SCIPisPositive(scip, aggrcoefs[naggrs]) )
11050  {
11051  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
11052  {
11053  ++supinf;
11054  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
11055  {
11056  ++infinf;
11057  samevar = TRUE;
11058  }
11059  }
11060  else if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
11061  ++infinf;
11062  }
11063  else if( SCIPisNegative(scip, aggrcoefs[naggrs]) )
11064  {
11065  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
11066  {
11067  ++supinf;
11068  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
11069  {
11070  ++infinf;
11071  samevar = TRUE;
11072  }
11073  }
11074  else if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
11075  ++infinf;
11076  }
11077 
11078  naggrs++;
11079  }
11080  }
11081  assert(!samevar || (supinf > 0 && infinf > 0));
11082 
11083  aggrconst = (bestislhs ? consdata->lhs/bestval : consdata->rhs/bestval);
11084  SCIPdebugMsgPrint(scip, " %+.15g, bounds of <%s>: [%.15g,%.15g]\n", aggrconst, SCIPvarGetName(bestvar),
11085  SCIPvarGetLbGlobal(bestvar), SCIPvarGetUbGlobal(bestvar));
11086  assert(naggrs == consdata->nvars-1);
11087 
11088  /* right hand side must be integral: round it to exact integral value */
11089  if( bestisint )
11090  {
11091  assert(SCIPisIntegral(scip, aggrconst));
11092  aggrconst = SCIPfloor(scip, aggrconst+0.5);
11093  }
11094 
11095  aggregated = FALSE;
11096  infeasible = FALSE;
11097 
11098  /* perform the multi-aggregation */
11099  if( (samevar && supinf == 1 && infinf == 1) || (!samevar && (supinf == 0 || infinf == 0)) )
11100  {
11101  /* @todo if multi-aggregate makes them numerical trouble, avoid them if the coefficients differ to much, see
11102  * also convertLongEquality() early termination due to coefficients
11103  */
11104  SCIP_CALL( SCIPmultiaggregateVar(scip, bestvar, naggrs, aggrvars, aggrcoefs, aggrconst, &infeasible, &aggregated) );
11105  }
11106  else
11107  {
11108  /* If the infimum and the supremum of a multi-aggregation are both infinite, then the multi-aggregation might not be resolvable.
11109  * E.g., consider the equality z = x-y. If x and y are both fixed to +infinity, the value for z is not determined */
11110  SCIPdebugMsg(scip, "do not perform multi-aggregation: infimum and supremum are both infinite\n");
11111  }
11112  /* free temporary memory */
11113  SCIPfreeBufferArray(scip, &aggrcoefs);
11114  SCIPfreeBufferArray(scip, &aggrvars);
11115 
11116  /* check for infeasible aggregation */
11117  if( infeasible )
11118  {
11119  SCIPdebugMsg(scip, "linear constraint <%s>: infeasible multi-aggregation\n", SCIPconsGetName(cons));
11120  *cutoff = TRUE;
11121  return SCIP_OKAY;
11122  }
11123 
11124  /* delete the constraint, if the aggregation was successful */
11125  if( aggregated )
11126  {
11127  SCIP_CALL( SCIPdelCons(scip, cons) );
11128 
11129  if( !consdata->upgraded )
11130  (*ndelconss)++;
11131  (*naggrvars)++;
11132  }
11133  else
11134  {
11135  SCIPdebugMsg(scip, "aggregation non successful!\n");
11136  }
11137  }
11138 
11139  return SCIP_OKAY;
11140 }
11141 
11142 #define BINWEIGHT 1
11143 #define INTWEIGHT 4
11144 #define CONTWEIGHT 8
11145 
11146 /** gets weight for variable in a "weighted number of variables" sum */
11147 static
11148 int getVarWeight(
11149  SCIP_VAR* var /**< variable to get weight for */
11150  )
11151 {
11152  switch( SCIPvarGetType(var) )
11153  {
11154  case SCIP_VARTYPE_BINARY:
11155  return BINWEIGHT;
11156  case SCIP_VARTYPE_INTEGER:
11157  case SCIP_VARTYPE_IMPLINT:
11158  return INTWEIGHT;
11160  return CONTWEIGHT;
11161  default:
11162  SCIPerrorMessage("invalid variable type\n");
11164  return 0; /*lint !e527*/
11165  }
11166 }
11168 /** tries to aggregate variables in equations a^Tx = lhs
11169  * in case there are at most two binary variables with an odd coefficient and all other
11170  * variables are not continuous and have an even coefficient then:
11171  * - exactly one odd binary variables
11172  * this binary variables y can be fixed to 0 if the lhs is even and to 1 if the lhs is odd
11173  * - lhs is odd -> y = 1
11174  * - lhs is even -> y = 0
11175  * - exactly two odd binary variables
11176  * aggregate the two binary variables with odd coefficient
11177  * - lhs is odd -> exactly one of the variable has to be 1 -> var1 + var2 = 1
11178  * - lhs is even -> both have to take the same value -> var1 - var2 = 0
11179  */
11180 static
11182  SCIP* scip, /**< SCIP data structure */
11183  SCIP_CONS* cons, /**< linear constraint */
11184  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
11185  int* nfixedvars, /**< pointer to count number of fixed variables */
11186  int* naggrvars /**< pointer to count number of aggregated variables */
11187  )
11188 { /*lint --e{715}*/
11189  SCIP_CONSDATA* consdata;
11190  SCIP_Bool success;
11191 
11192  assert( scip != NULL );
11193  assert( cons != NULL );
11194 
11195  consdata = SCIPconsGetData(cons);
11196  assert( consdata != NULL );
11197 
11198  /* check if the linear constraint is an equation with integral right hand side */
11199  if( !SCIPisEQ(scip, consdata->lhs, consdata->rhs) || !SCIPisIntegral(scip, consdata->lhs) )
11200  return SCIP_OKAY;
11201 
11202  /* try to fix and aggregated variables until nothing is possible anymore */
11203  do
11204  {
11205  int v;
11206  int nvars;
11207  SCIP_VAR** vars;
11208  SCIP_Real* vals;
11209  SCIP_Real lhs;
11210  SCIP_Bool lhsodd;
11211 
11212  SCIP_Bool infeasible;
11213  SCIP_Bool fixed;
11214  SCIP_Bool aggregated;
11215  SCIP_Bool redundant;
11216 
11217  SCIP_VAR* var1;
11218  SCIP_VAR* var2;
11219  int noddvars;
11220 
11221  success = FALSE;
11222 
11223  lhs = consdata->lhs;
11224  vars = consdata->vars;
11225  vals = consdata->vals;
11226  nvars = consdata->nvars;
11227 
11228  assert( !SCIPisInfinity(scip, ABS(lhs)) );
11229 
11230  var1 = NULL;
11231  var2 = NULL;
11232  noddvars = 0;
11233 
11234  /* search for binary variables with an odd coefficient */
11235  for( v = 0; v < nvars && noddvars < 3; ++v )
11236  {
11237  SCIP_Longint val;
11238 
11239  /* all coefficients and variables have to be integral */
11240  if( !SCIPisIntegral(scip, vals[v]) || SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11241  return SCIP_OKAY;
11242 
11243  val = (SCIP_Longint)SCIPfeasFloor(scip, vals[v]);
11244  if( val % 2 != 0 )
11245  {
11246  /* the odd values have to belong to binary variables */
11247  if( !SCIPvarIsBinary(vars[v]) )
11248  return SCIP_OKAY;
11249 
11250  if( noddvars == 0 )
11251  var1 = vars[v];
11252  else
11253  var2 = vars[v];
11254 
11255  noddvars++;
11256  }
11257  }
11258 
11259  /* check lhs is odd or even */
11260  lhsodd = (((SCIP_Longint)SCIPfeasFloor(scip, lhs)) % 2 != 0);
11261 
11262  if( noddvars == 1 )
11263  {
11264  assert( var1 != NULL );
11265 
11266  SCIPdebugMsg(scip, "linear constraint <%s>: try fixing variable <%s> to <%g>\n",
11267  SCIPconsGetName(cons), SCIPvarGetName(var1), lhsodd ? 1.0 : 0.0);
11268 
11269  SCIP_CALL( SCIPfixVar(scip, var1, lhsodd? 1.0 : 0.0, &infeasible, &fixed) );
11270 
11271  /* check for infeasibility of fixing */
11272  if( infeasible )
11273  {
11274  SCIPdebugMsg(scip, " -> infeasible fixing\n");
11275  *cutoff = TRUE;
11276  return SCIP_OKAY;
11277  }
11278 
11279  if( fixed )
11280  {
11281  SCIPdebugMsg(scip, " -> feasible fixing\n");
11282  (*nfixedvars)++;
11283  success = TRUE;
11284  }
11285  }
11286  else if( noddvars == 2 )
11287  {
11288  assert( var1 != NULL );
11289  assert( var2 != NULL );
11290 
11291  /* aggregate the two variables with odd coefficient
11292  * - lhs is odd -> exactly one of the variable has to be 1 -> var1 + var2 = 1
11293  * - lhs is even -> both have to take the same value -> var1 - var2 = 0
11294  */
11295  SCIPdebugMsg(scip, "linear constraint <%s>: try aggregation of variables <%s> and <%s>\n",
11296  SCIPconsGetName(cons), SCIPvarGetName(var1), SCIPvarGetName(var2));
11297 
11298  SCIP_CALL( SCIPaggregateVars(scip, var1, var2, 1.0, lhsodd ? 1.0 : -1.0,
11299  lhsodd ? 1.0 : 0.0, &infeasible, &redundant, &aggregated) );
11300 
11301  /* check for infeasibility of aggregation */
11302  if( infeasible )
11303  {
11304  SCIPdebugMsg(scip, " -> infeasible aggregation\n");
11305  *cutoff = TRUE;
11306  return SCIP_OKAY;
11307  }
11308 
11309  /* count the aggregation */
11310  if( aggregated )
11311  {
11312  SCIPdebugMsg(scip, " -> feasible aggregation\n");
11313  (*naggrvars)++;
11314  success = TRUE;
11315  }
11316  }
11317 
11318  if( success )
11319  {
11320  /* apply fixings and aggregation to successfully rerun this presolving step */
11321  SCIP_CALL( applyFixings(scip, cons, &infeasible) );
11322 
11323  if( infeasible )
11324  {
11325  SCIPdebugMsg(scip, " -> infeasible fixing\n");
11326  *cutoff = TRUE;
11327  return SCIP_OKAY;
11328  }
11329 
11330  /* normalize constraint */
11331  SCIP_CALL( normalizeCons(scip, cons, &infeasible) );
11332 
11333  if( infeasible )
11334  {
11335  SCIPdebugMsg(scip, " -> infeasible normalization\n");
11336  *cutoff = TRUE;
11337  return SCIP_OKAY;
11338  }
11339  }
11340  }
11341  while( success );
11342 
11343  return SCIP_OKAY;
11344 }
11345 
11346 
11347 
11348 /** sorting method for constraint data, compares two variables on given indices, continuous variables will be sorted to
11349  * the end and for all other variables the sortation will be in non-increasing order of their absolute value of the
11350  * coefficients
11351  */
11352 static
11353 SCIP_DECL_SORTINDCOMP(consdataCompSim)
11354 { /*lint --e{715}*/
11355  SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
11356  SCIP_VARTYPE vartype1;
11357  SCIP_VARTYPE vartype2;
11358  SCIP_Real value;
11359 
11360  assert(consdata != NULL);
11361  assert(0 <= ind1 && ind1 < consdata->nvars);
11362  assert(0 <= ind2 && ind2 < consdata->nvars);
11363 
11364  vartype1 = SCIPvarGetType(consdata->vars[ind1]);
11365  vartype2 = SCIPvarGetType(consdata->vars[ind2]);
11366 
11367  if( vartype1 == SCIP_VARTYPE_CONTINUOUS )
11368  {
11369  /* continuous varibles will be sorted to the back */
11370  if( vartype2 != vartype1 )
11371  return +1;
11372  /* both variables are continuous */
11373  else
11374  return 0;
11375  }
11376  /* continuous variables will be sorted to the back */
11377  else if( vartype2 == SCIP_VARTYPE_CONTINUOUS )
11378  return -1;
11379 
11380  value = REALABS(consdata->vals[ind2]) - REALABS(consdata->vals[ind1]);
11381 
11382  /* for all non-continuous variables, the variables are sorted after decreasing absolute coefficients */
11383  return (value > 0 ? +1 : (value < 0 ? -1 : 0));
11384 }
11385 
11386 /** tries to simplify coefficients and delete variables in ranged row of the form lhs <= a^Tx <= rhs, e.g. using the greatest
11387  * common divisor
11388  *
11389  * 1. lhs <= a^Tx <= rhs, forall a_i >= lhs, a_i <= rhs, and forall pairs a_i + a_j > rhs then we can change this
11390  * constraint to 1^Tx = 1
11391  */
11392 static
11394  SCIP* scip, /**< SCIP data structure */
11395  SCIP_CONS* cons, /**< linear constraint */
11396  int* nchgcoefs, /**< pointer to store the amount of changed coefficients */
11397  int* nchgsides /**< pointer to store the amount of changed sides */
11398  )
11399 {
11400  SCIP_CONSDATA* consdata;
11401  SCIP_VAR** vars;
11402  SCIP_Real* vals;
11403  SCIP_Real minval;
11404  SCIP_Real secondminval;
11405  SCIP_Real maxval;
11406  SCIP_Real lhs;
11407  SCIP_Real rhs;
11408  int nvars;
11409  int v;
11410 
11411  /* we must not change a modifiable constraint in any way */
11413  return SCIP_OKAY;
11414 
11415  if( SCIPconsIsDeleted(cons) )
11416  return SCIP_OKAY;
11417 
11418  consdata = SCIPconsGetData(cons);
11419  assert(consdata != NULL);
11420 
11421  nvars = consdata->nvars;
11422 
11423  /* do not check empty or bound-constraints */
11424  if( nvars < 2 )
11425  return SCIP_OKAY;
11426 
11427  vals = consdata->vals;
11428  vars = consdata->vars;
11429  assert(vars != NULL);
11430  assert(vals != NULL);
11431 
11432  lhs = consdata->lhs;
11433  rhs = consdata->rhs;
11434  assert(!SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs));
11435  assert(!SCIPisNegative(scip, rhs));
11436 
11437  minval = SCIP_INVALID;
11438  secondminval = SCIP_INVALID;
11439  maxval = -SCIP_INVALID;
11440 
11441  for( v = nvars - 1; v >= 0; --v )
11442  {
11443  if( SCIPvarIsBinary(vars[v]) )
11444  {
11445  if( minval > vals[v] || minval == SCIP_INVALID ) /*lint !e777*/
11446  {
11447  secondminval = minval;
11448  minval = vals[v];
11449  }
11450  else if( secondminval > vals[v] || secondminval == SCIP_INVALID ) /*lint !e777*/
11451  secondminval = vals[v];
11452 
11453  if( maxval < vals[v] || maxval == -SCIP_INVALID ) /*lint !e777*/
11454  maxval = vals[v];
11455  }
11456  else
11457  break;
11458  }
11459 
11460  /* check if all variables are binary */
11461  if( v == -1 )
11462  {
11463  if( SCIPisEQ(scip, minval, maxval) && SCIPisEQ(scip, lhs, rhs) )
11464  return SCIP_OKAY;
11465 
11466  /* check if we can and need to choose exactly one binary variable */
11467  if( SCIPisGE(scip, minval, lhs) && SCIPisLE(scip, maxval, rhs) && SCIPisGT(scip, minval + secondminval, rhs) )
11468  {
11469  /* change all coefficients to 1.0 */
11470  for( v = nvars - 1; v >= 0; --v )
11471  {
11472  SCIP_CALL( chgCoefPos(scip, cons, v, 1.0) );
11473  }
11474  (*nchgcoefs) += nvars;
11475 
11476  /* replace old right and left hand side with 1.0 */
11477  SCIP_CALL( chgRhs(scip, cons, 1.0) );
11478  SCIP_CALL( chgLhs(scip, cons, 1.0) );
11479  (*nchgsides) += 2;
11480  }
11481  }
11482 
11483  return SCIP_OKAY;
11484 }
11485 
11486 /** tries to simplify coefficients and delete variables in constraints of the form lhs <= a^Tx <= rhs
11487  * for equations @see rangedRowSimplify() will be called
11488  *
11489  * there are several different coefficient reduction steps which will be applied
11490  *
11491  * 1. We try to determine parts of the constraint which will not change anything on (in-)feasibility of the constraint
11492  *
11493  * e.g. 5x1 + 5x2 + 3z1 <= 8 => 3z1 is redundant if all x are binary and -2 < 3z1 <= 3
11494  *
11495  * 2. We try to remove redundant fractional parts in a constraint
11496  *
11497  * e.g. 5.2x1 + 5.1x2 + 3x3 <= 8.3 => will be changed to 5x1 + 5x2 + 3x3 <= 8 if all x are binary
11498  *
11499  * 3. We are using the greatest common divisor for further reductions
11500  *
11501  * e.g. 10x1 + 5y2 + 5x3 + 3x4 <= 15 => will be changed to 2x1 + y2 + x3 + x4 <= 3 if all xi are binary and y2 is
11502  * integral
11503  */
11504 static
11506  SCIP* scip, /**< SCIP data structure */
11507  SCIP_CONS* cons, /**< linear constraint */
11508  int* nchgcoefs, /**< pointer to store the amount of changed coefficients */
11509  int* nchgsides, /**< pointer to store the amount of changed sides */
11510  SCIP_Bool* infeasible /**< pointer to store whether infeasibility was detected */
11511  )
11512 {
11513  SCIP_CONSDATA* consdata;
11514  SCIP_VAR** vars;
11515  SCIP_Real* vals;
11516  int* perm;
11517  SCIP_Real minactsub;
11518  SCIP_Real maxactsub;
11519  SCIP_Real siderest;
11520  SCIP_Real feastol;
11521  SCIP_Real newcoef;
11522  SCIP_Real absval;
11523  SCIP_Real minact;
11524  SCIP_Real maxact;
11525  SCIP_Real side;
11526  SCIP_Real lhs;
11527  SCIP_Real rhs;
11528  SCIP_Real lb;
11529  SCIP_Real ub;
11530  SCIP_Longint restcoef;
11531  SCIP_Longint oldgcd;
11532  SCIP_Longint rest;
11533  SCIP_Longint gcd;
11534  SCIP_Bool isminsettoinfinity;
11535  SCIP_Bool ismaxsettoinfinity;
11536  SCIP_Bool isminrelax;
11537  SCIP_Bool ismaxrelax;
11538  SCIP_Bool allcoefintegral;
11539  SCIP_Bool onlybin;
11540  SCIP_Bool hasrhs;
11541  SCIP_Bool haslhs;
11542  int oldnchgcoefs;
11543  int oldnchgsides;
11544  int foundbin;
11545  int candpos;
11546  int candpos2;
11547  int offsetv;
11548  int nvars;
11549  int v;
11550  int w;
11551 
11552  assert(scip != NULL);
11553  assert(cons != NULL);
11554  assert(nchgcoefs != NULL);
11555  assert(nchgsides != NULL);
11556 
11557  *infeasible = FALSE;
11558 
11559  /* we must not change a modifiable constraint in any way */
11560  if( SCIPconsIsModifiable(cons) )
11561  return SCIP_OKAY;
11562 
11563  if( SCIPconsIsDeleted(cons) )
11564  return SCIP_OKAY;
11565 
11566  consdata = SCIPconsGetData(cons);
11567  assert(consdata != NULL);
11568 
11569  nvars = consdata->nvars;
11570 
11571  /* do not check empty or bound-constraints */
11572  if( nvars <= 2 )
11573  return SCIP_OKAY;
11574 
11575  /* update maximal activity delta if necessary */
11576  if( consdata->maxactdelta == SCIP_INVALID ) /*lint !e777*/
11577  consdataRecomputeMaxActivityDelta(scip, consdata);
11578 
11579  assert(consdata->maxactdelta != SCIP_INVALID); /*lint !e777*/
11580  assert(!SCIPisFeasNegative(scip, consdata->maxactdelta));
11581  checkMaxActivityDelta(scip, consdata);
11582 
11583  /* @todo the following might be too hard, check which steps can be applied and what code must be corrected
11584  * accordingly
11585  */
11586  /* can only work with valid non-infinity activities per variable */
11587  if( SCIPisInfinity(scip, consdata->maxactdelta) )
11588  return SCIP_OKAY;
11589 
11590  /* @todo: change the following: due to vartype changes, the status of the normalization can be wrong, need an event
11591  * but the eventsystem seems to be full
11592  */
11593  consdata->normalized = FALSE;
11594 
11595  /* normalize constraint */
11596  SCIP_CALL( normalizeCons(scip, cons, infeasible) );
11597  assert(nvars == consdata->nvars);
11598 
11599  if( *infeasible )
11600  return SCIP_OKAY;
11601 
11602  if( !consdata->normalized )
11603  return SCIP_OKAY;
11604 
11605  lhs = consdata->lhs;
11606  rhs = consdata->rhs;
11607  assert(!SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs));
11608  assert(!SCIPisNegative(scip, rhs));
11609 
11610  if( !SCIPisInfinity(scip, -lhs) )
11611  haslhs = TRUE;
11612  else
11613  haslhs = FALSE;
11614 
11615  if( !SCIPisInfinity(scip, rhs) )
11616  hasrhs = TRUE;
11617  else
11618  hasrhs = FALSE;
11619 
11620  SCIPdebug( oldnchgcoefs = *nchgcoefs; )
11621  SCIPdebug( oldnchgsides = *nchgsides; )
11622 
11623  /* @todo also work on ranged rows */
11624  if( haslhs && hasrhs )
11625  {
11626  SCIP_CALL( rangedRowSimplify(scip, cons, nchgcoefs, nchgsides ) );
11627 
11628  return SCIP_OKAY;
11629  }
11630  assert(haslhs != hasrhs);
11631 
11632  /* if we have a normalized inequality (not ranged) the one side should be positive, @see normalizeCons() */
11633  assert(!hasrhs || !SCIPisNegative(scip, rhs));
11634  assert(!haslhs || !SCIPisNegative(scip, lhs));
11635 
11636  /* get temporary memory to store the sorted permutation */
11637  SCIP_CALL( SCIPallocBufferArray(scip, &perm, nvars) );
11638 
11639  /* call sorting method, order continuous variables to the end and all other variables after non-increasing absolute
11640  * value of their coefficients
11641  */
11642  SCIPsort(perm, consdataCompSim, (void*)consdata, nvars);
11643 
11644  /* perform sorting after permutation array */
11645  permSortConsdata(consdata, perm, nvars);
11646  consdata->indexsorted = FALSE;
11647  consdata->coefsorted = FALSE;
11648 
11649  vars = consdata->vars;
11650  vals = consdata->vals;
11651  assert(vars != NULL);
11652  assert(vals != NULL);
11653  assert(consdata->validmaxabsval ? (SCIPisFeasEQ(scip, consdata->maxabsval, REALABS(vals[0])) || SCIPvarGetType(vars[nvars - 1]) == SCIP_VARTYPE_CONTINUOUS) : TRUE);
11654 
11655  /* free temporary memory */
11656  SCIPfreeBufferArray(scip, &perm);
11657 
11658  /* only check constraints with at least two non continuous variables */
11659  if( SCIPvarGetType(vars[1]) == SCIP_VARTYPE_CONTINUOUS )
11660  return SCIP_OKAY;
11661 
11662  /* do not process constraints when all coefficients are 1.0 */
11663  if( SCIPisEQ(scip, REALABS(vals[0]), 1.0) && ((hasrhs && SCIPisIntegral(scip, rhs)) || (haslhs && SCIPisIntegral(scip, lhs))) )
11664  return SCIP_OKAY;
11665 
11666  feastol = SCIPfeastol(scip);
11667 
11668  SCIPdebugMsg(scip, "starting simplification of coefficients\n");
11669  SCIPdebugPrintCons(scip, cons, NULL);
11670 
11671  /* get global activities */
11672  consdataGetGlbActivityBounds(scip, consdata, FALSE, &minact, &maxact,
11673  &isminrelax, &ismaxrelax, &isminsettoinfinity, &ismaxsettoinfinity);
11674 
11675  /* cannot work with infinite activities */
11676  if( isminsettoinfinity || ismaxsettoinfinity )
11677  return SCIP_OKAY;
11678 
11679  assert(!isminrelax);
11680  assert(!ismaxrelax);
11681  assert(maxact > minact);
11682  assert(!SCIPisInfinity(scip, -minact));
11683  assert(!SCIPisInfinity(scip, maxact));
11684 
11685  v = 0;
11686  offsetv = -1;
11687  side = haslhs ? lhs : rhs;
11688  minactsub = minact;
11689  maxactsub = maxact;
11690 
11691  /* we now determine coefficients as large as the side of the constraint to retrieve a better reduction where we
11692  * do not need to look at the large coefficients
11693  *
11694  * e.g. all x are binary, z are positive integer
11695  * c1: +5x1 + 5x2 + 3x3 + 3x4 + x5 >= 5 (x5 is redundant and does not change (in-)feasibility of this constraint)
11696  * c2: +4x1 + 4x2 + 3x3 + 3x4 + x5 >= 4 (gcd (without the coefficient of x5) after the large coefficients is 3
11697  * c3: +30x1 + 29x2 + 14x3 + 14z1 + 7x5 + 7x6 <= 30 (gcd (without the coefficient of x2) after the large coefficients is 7
11698  *
11699  * can be changed to
11700  *
11701  * c1: +6x1 + 6x2 + 3x3 + 3x4 >= 6 (will be changed to c1: +2x1 + 2x2 + x3 + x4 >= 2)
11702  * c2: +6x1 + 6x2 + 3x3 + 3x4 + 3x5 >= 6 (will be changed to c2: +2x1 + 2x2 + x3 + x4 + x5 >= 2)
11703  * c3: +28x1 + 28x2 + 14x3 + 14z1 + 7x5 + 7x6 <= 28 (will be changed to c3: +4x1 + 4x2 + 2x3 + 2z1 + x5 + x6 <= 4)
11704  */
11705 
11706  /* if the minimal activity is negative and we found more than one variable with a coefficient bigger than the left
11707  * hand side, we cannot apply the extra reduction step and need to reset v
11708  *
11709  * e.g. 7x1 + 7x2 - 4x3 - 4x4 >= 7 => xi = 1 for all i is not a solution, but if we would do a change on the
11710  * coefficients due to the gcd on the "small" coefficients we would get 8x1 + 8x2 - 4x3 - 4x4 >= 8 were xi = 1
11711  * for all i is a solution
11712  *
11713  * also redundancy of variables would not be correctly determined in such a case
11714  */
11715  if( nvars > 2 && SCIPisEQ(scip, vals[0], side) && !SCIPisNegative(scip, minactsub) )
11716  {
11717  v = 1;
11718 
11719  while( v < nvars && SCIPisEQ(scip, side, vals[v]) )
11720  {
11721  /* if we have integer variable with "side"-coefficients but also with a lower bound greater than 0 we stop this
11722  * extra step, which might have worked
11723  */
11724  if( SCIPvarGetLbGlobal(vars[v]) > 0.5 )
11725  {
11726  v = 0;
11727  break;
11728  }
11729 
11730  ++v;
11731  }
11732 
11733  /* easy and quick fix: if all coefficients were equal to the side, we cannot apply further simplifications */
11734  /* todo find numerically stable normalization conditions to scale this cons to have coefficients almost equal to 1 */
11735  if( v == nvars )
11736  return SCIP_OKAY;
11737 
11738  /* cannot work with continuous variables which have a big coefficient */
11739  if( v > 0 && SCIPvarGetType(vars[v - 1]) == SCIP_VARTYPE_CONTINUOUS )
11740  return SCIP_OKAY;
11741 
11742  /* big negative coefficient, do not try to use the extra coefficient reduction step */
11743  if( SCIPisEQ(scip, side, -vals[v]) )
11744  v = 0;
11745 
11746  /* all but one variable are processed or the next variable is continuous we cannot perform the extra coefficient
11747  * reduction
11748  */
11749  if( v == nvars - 1 || SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11750  v = 0;
11751 
11752  if( v > 0 )
11753  {
11754  assert(v < nvars);
11755 
11756  offsetv = v - 1;
11757 
11758  for( w = 0; w < v; ++w )
11759  {
11760  lb = SCIPvarGetLbGlobal(vars[w]);
11761  ub = SCIPvarGetUbGlobal(vars[w]);
11762 
11763  assert(vals[w] > 0);
11764 
11765  /* update residual activities */
11766  maxactsub -= ub * vals[w];
11767  minactsub -= lb * vals[w];
11768  assert(maxactsub > minactsub);
11769  }
11770  }
11771  }
11772 
11773  /* find and remove redundant variables which do not interact with the (in-)feasibility of this constraint
11774  *
11775  * e.g. let all x are binary and y1 is continuous with bounds [-3,1] then we can reduce
11776  *
11777  * 15x1 + 15x2 + 7x3 + 3x4 + y1 <= 26
11778  * to
11779  * 15x1 + 15x2 <= 26 <=> x1 + x2 <= 1
11780  */
11781  if( nvars > 2 && SCIPisIntegral(scip, vals[v]) )
11782  {
11783  SCIP_Bool redundant = FALSE;
11784  SCIP_Bool numericsok;
11785  SCIP_Bool rredundant;
11786  SCIP_Bool lredundant;
11787 
11788 
11789  gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
11790  assert(gcd >= 1);
11791 
11792  if( v == 0 )
11793  {
11794  lb = SCIPvarGetLbGlobal(vars[0]);
11795  ub = SCIPvarGetUbGlobal(vars[0]);
11796 
11797  /* update residual activities */
11798  if( vals[0] > 0 )
11799  {
11800  maxactsub -= ub * vals[0];
11801  minactsub -= lb * vals[0];
11802  }
11803  else
11804  {
11805  maxactsub -= lb * vals[0];
11806  minactsub -= ub * vals[0];
11807  }
11808  assert(maxactsub > minactsub);
11809  ++v;
11810  }
11811 
11812  siderest = -SCIP_INVALID;
11813  allcoefintegral = TRUE;
11814 
11815  /* check if some variables always fit into the given constraint */
11816  for( ; v < nvars - 1; ++v )
11817  {
11818  if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11819  break;
11820 
11821  if( !SCIPisIntegral(scip, vals[v]) )
11822  {
11823  allcoefintegral = FALSE;
11824  break;
11825  }
11826 
11827  /* calculate greatest common divisor for all general and binary variables */
11828  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
11829 
11830  if( gcd == 1 )
11831  break;
11832 
11833  lb = SCIPvarGetLbGlobal(vars[v]);
11834  ub = SCIPvarGetUbGlobal(vars[v]);
11835 
11836  assert(!SCIPisInfinity(scip, -lb));
11837  assert(!SCIPisInfinity(scip, ub));
11838 
11839  /* update residual activities */
11840  if( vals[v] > 0 )
11841  {
11842  maxactsub -= ub * vals[v];
11843  minactsub -= lb * vals[v];
11844  }
11845  else
11846  {
11847  maxactsub -= lb * vals[v];
11848  minactsub -= ub * vals[v];
11849  }
11850  assert(SCIPisGE(scip, maxactsub, minactsub));
11851 
11852  if( hasrhs )
11853  {
11854  /* determine the remainder of the right hand side and the gcd */
11855  siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11856  }
11857  else
11858  {
11859  /* determine the remainder of the left hand side and the gcd */
11860  siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11861  if( SCIPisZero(scip, siderest) )
11862  siderest = gcd;
11863  }
11864 
11865  rredundant = hasrhs && maxactsub <= siderest && SCIPisFeasGT(scip, minactsub, siderest - gcd);
11866  lredundant = haslhs && SCIPisFeasLT(scip, maxactsub, siderest) && minactsub >= siderest - gcd;
11867 
11868  /* early termination if the activities deceed the gcd */
11869  if( offsetv == -1 && (rredundant || lredundant) )
11870  {
11871  redundant = TRUE;
11872  break;
11873  }
11874  }
11875  assert(v < nvars || (offsetv >= 0 && gcd > 1));
11876 
11877  if( !redundant )
11878  {
11879  if( hasrhs )
11880  {
11881  /* determine the remainder of the right hand side and the gcd */
11882  siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11883  }
11884  else
11885  {
11886  /* determine the remainder of the left hand side and the gcd */
11887  siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11888  if( SCIPisZero(scip, siderest) )
11889  siderest = gcd;
11890  }
11891  }
11892  else
11893  ++v;
11894 
11895  SCIPdebugMsg(scip, "stopped at pos %d (of %d), subactivities [%g, %g], redundant = %u, hasrhs = %u, siderest = %g, gcd = %" SCIP_LONGINT_FORMAT ", offset position for 'side' coefficients = %d\n",
11896  v, nvars, minactsub, maxactsub, redundant, hasrhs, siderest, gcd, offsetv);
11897 
11898  /* to avoid inconsistencies due to numerics, check that the full and partial activities have
11899  * reasonable absolute values */
11900  numericsok = REALABS(maxact) < MAXACTVAL && REALABS(maxactsub) < MAXACTVAL && REALABS(minact) < MAXACTVAL &&
11901  REALABS(minactsub) < MAXACTVAL;
11902 
11903  rredundant = hasrhs && maxactsub <= siderest && SCIPisFeasGT(scip, minactsub, siderest - gcd);
11904  lredundant = haslhs && SCIPisFeasLT(scip, maxactsub, siderest) && minactsub >= siderest - gcd;
11905 
11906  /* check if we can remove redundant variables */
11907  if( v < nvars && numericsok && (redundant || (offsetv == -1 && (rredundant || lredundant))) )
11908  {
11909  SCIP_Real oldcoef;
11910 
11911  /* double check the redundancy */
11912 #ifndef NDEBUG
11913  SCIP_Real tmpminactsub = 0.0;
11914  SCIP_Real tmpmaxactsub = 0.0;
11915 
11916  /* recompute residual activities */
11917  for( w = v; w < nvars; ++w )
11918  {
11919  lb = SCIPvarGetLbGlobal(vars[w]);
11920  ub = SCIPvarGetUbGlobal(vars[w]);
11921 
11922  assert(!SCIPisInfinity(scip, -lb));
11923  assert(!SCIPisInfinity(scip, ub));
11924 
11925  /* update residual activities */
11926  if( vals[w] > 0 )
11927  {
11928  tmpmaxactsub += ub * vals[w];
11929  tmpminactsub += lb * vals[w];
11930  }
11931  else
11932  {
11933  tmpmaxactsub += lb * vals[w];
11934  tmpminactsub += ub * vals[w];
11935  }
11936  assert(tmpmaxactsub >= tmpminactsub);
11937  }
11938 
11939  if( hasrhs )
11940  {
11941  assert(offsetv == -1);
11942 
11943  /* determine the remainder of the right hand side and the gcd */
11944  siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11945  }
11946  else
11947  {
11948  /* determine the remainder of the left hand side and the gcd */
11949  siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11950  if( SCIPisZero(scip, siderest) )
11951  siderest = gcd;
11952  }
11953 
11954  /* is the redundancy really fulfilled */
11955  assert((hasrhs && SCIPisFeasLE(scip, tmpmaxactsub, siderest) && tmpminactsub > siderest - gcd) ||
11956  (haslhs && tmpmaxactsub < siderest && SCIPisFeasGE(scip, tmpminactsub, siderest - gcd)));
11957 #endif
11958 
11959  SCIPdebugMsg(scip, "removing %d last variables from constraint <%s>, because they never change anything on the feasibility of this constraint\n",
11960  nvars - v, SCIPconsGetName(cons));
11961 
11962  /* remove redundant variables */
11963  for( w = nvars - 1; w >= v; --w )
11964  {
11965  SCIP_CALL( delCoefPos(scip, cons, w) );
11966  }
11967  (*nchgcoefs) += (nvars - v);
11968 
11969  assert(w >= 0);
11970 
11971  oldcoef = vals[w];
11972 
11973  /* normalize constraint */
11974  SCIP_CALL( normalizeCons(scip, cons, infeasible) );
11975  assert(vars == consdata->vars);
11976  assert(vals == consdata->vals);
11977  assert(w < consdata->nvars);
11978 
11979  if( *infeasible )
11980  return SCIP_OKAY;
11981 
11982  /* compute new greatest common divisor due to normalization */
11983  gcd = (SCIP_Longint)(gcd / (oldcoef/vals[w]) + feastol);
11984  assert(gcd >= 1);
11985 
11986  /* update side */
11987  if( hasrhs )
11988  {
11989  /* replace old with new right hand side */
11990  SCIP_CALL( chgRhs(scip, cons, SCIPfeasFloor(scip, consdata->rhs)) );
11991  rhs = consdata->rhs;
11992  }
11993  else
11994  {
11995  if( SCIPisFeasGT(scip, oldcoef/vals[w], 1.0) )
11996  {
11997  SCIP_CALL( chgLhs(scip, cons, SCIPfeasCeil(scip, consdata->lhs)) );
11998  lhs = consdata->lhs;
11999  }
12000  else
12001  assert(offsetv == -1 || SCIPisEQ(scip, vals[offsetv], consdata->lhs));
12002  }
12003  ++(*nchgsides);
12004 
12005  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12006  assert(!haslhs || !SCIPisNegative(scip, lhs));
12007 
12008  /* get new constraint data */
12009  nvars = consdata->nvars;
12010  assert(nvars > 0);
12011 
12012  allcoefintegral = TRUE;
12013 
12014 #ifndef NDEBUG
12015  /* check integrality */
12016  for( w = offsetv + 1; w < nvars; ++w )
12017  {
12018  assert(SCIPisIntegral(scip, vals[w]));
12019  }
12020 #endif
12021  SCIPdebugPrintCons(scip, cons, NULL);
12022  }
12023 
12024  /* try to find a better gcd, when having large coefficients */
12025  if( offsetv >= 0 && gcd == 1 )
12026  {
12027  /* calculate greatest common divisor for all general variables */
12028  gcd = (SCIP_Longint)(REALABS(vals[nvars - 1]) + feastol);
12029 
12030  if( gcd > 1 )
12031  {
12032  gcd = -1;
12033  candpos = -1;
12034 
12035  for( v = nvars - 1; v > offsetv; --v )
12036  {
12037  assert(!SCIPisZero(scip, vals[v]));
12038  if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
12039  break;
12040 
12041  if( !SCIPisIntegral(scip, vals[v]) )
12042  {
12043  allcoefintegral = FALSE;
12044  break;
12045  }
12046 
12047  oldgcd = gcd;
12048 
12049  if( gcd == -1 )
12050  {
12051  gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
12052  assert(gcd >= 1);
12053  }
12054  else
12055  {
12056  /* calculate greatest common divisor for all general and binary variables */
12057  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
12058  }
12059 
12060  /* if the greatest commmon divisor has become 1, we might have found the possible coefficient to change or we
12061  * can stop searching
12062  */
12063  if( gcd == 1 )
12064  {
12065  if( !SCIPvarIsBinary(vars[v]) )
12066  break;
12067 
12068  /* found candidate */
12069  if( candpos == -1 )
12070  {
12071  gcd = oldgcd;
12072  candpos = v;
12073  }
12074  /* two different binary variables lead to a gcd of one, so we cannot change a coefficient */
12075  else
12076  break;
12077  }
12078  }
12079  assert(v > offsetv || candpos > offsetv);
12080  }
12081  else
12082  candpos = -1;
12083  }
12084  else
12085  candpos = nvars - 1;
12086 
12087  /* check last coefficient for integrality */
12088  if( gcd > 1 && allcoefintegral && !redundant )
12089  {
12090  if( !SCIPisIntegral(scip, vals[nvars - 1]) )
12091  allcoefintegral = FALSE;
12092  }
12093 
12094  /* check for further necessary coefficient adjustments */
12095  if( offsetv >= 0 && gcd > 1 && allcoefintegral )
12096  {
12097  assert(offsetv + 1 < nvars);
12098  assert(0 <= candpos && candpos < nvars);
12099 
12100  if( SCIPvarGetType(vars[candpos]) != SCIP_VARTYPE_CONTINUOUS )
12101  {
12102  SCIP_Bool notchangable = FALSE;
12103 
12104 #ifndef NDEBUG
12105  /* check integrality */
12106  for( w = offsetv + 1; w < nvars; ++w )
12107  {
12108  assert(SCIPisIntegral(scip, vals[w]));
12109  }
12110 #endif
12111 
12112  if( vals[candpos] > 0 && SCIPvarIsBinary(vars[candpos]) &&
12113  SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) < gcd )
12114  {
12115  /* determine the remainder of the side and the gcd */
12116  if( hasrhs )
12117  rest = ((SCIP_Longint)(rhs + feastol)) % gcd;
12118  else
12119  rest = ((SCIP_Longint)(lhs + feastol)) % gcd;
12120  assert(rest >= 0);
12121  assert(rest < gcd);
12122 
12123  /* determine the remainder of the coefficient candidate and the gcd */
12124  restcoef = ((SCIP_Longint)(vals[candpos] + feastol)) % gcd;
12125  assert(restcoef >= 1);
12126  assert(restcoef < gcd);
12127 
12128  if( hasrhs )
12129  {
12130  /* calculate new coefficient */
12131  if( restcoef > rest )
12132  newcoef = vals[candpos] - restcoef + gcd;
12133  else
12134  newcoef = vals[candpos] - restcoef;
12135  }
12136  else
12137  {
12138  /* calculate new coefficient */
12139  if( rest == 0 || restcoef < rest )
12140  newcoef = vals[candpos] - restcoef;
12141  else
12142  newcoef = vals[candpos] - restcoef + gcd;
12143  }
12144 
12145  /* done */
12146 
12147  /* new coeffcient must not be zero if we would loose the implication that a variable needs to be 0 if
12148  * another with the big coefficient was set to 1
12149  */
12150  if( hasrhs && SCIPisZero(scip, newcoef) )
12151  {
12152  notchangable = TRUE;
12153  }
12154  else if( SCIPisZero(scip, newcoef) )
12155  {
12156  /* delete old redundant coefficient */
12157  SCIP_CALL( delCoefPos(scip, cons, candpos) );
12158  ++(*nchgcoefs);
12159  }
12160  else
12161  {
12162  /* replace old with new coefficient */
12163  SCIP_CALL( chgCoefPos(scip, cons, candpos, newcoef) );
12164  ++(*nchgcoefs);
12165  }
12166  }
12167  else if( vals[candpos] < 0 || !SCIPvarIsBinary(vars[candpos]) )
12168  {
12169  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol));
12170  }
12171 
12172  /* correct side and big coefficients */
12173  if( (!notchangable && hasrhs && ((!SCIPisFeasIntegral(scip, rhs) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(rhs + feastol)) < gcd) && (SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) == gcd))) ||
12174  ( haslhs && (!SCIPisFeasIntegral(scip, lhs) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(lhs + feastol)) < gcd) && (SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) == gcd)) )
12175  {
12176  if( haslhs )
12177  {
12178  newcoef = (SCIP_Real)((SCIP_Longint)(SCIPfeasCeil(scip, lhs/gcd) * gcd + feastol));
12179 
12180  SCIP_CALL( chgLhs(scip, cons, newcoef) );
12181  ++(*nchgsides);
12182  }
12183  else
12184  {
12185  assert(hasrhs);
12186  newcoef = (SCIP_Real)((SCIP_Longint)(SCIPfeasFloor(scip, rhs/gcd) * gcd + feastol));
12187 
12188  SCIP_CALL( chgRhs(scip, cons, newcoef) );
12189  ++(*nchgsides);
12190  }
12191 
12192  /* correct coefficients up front */
12193  for( w = offsetv; w >= 0; --w )
12194  {
12195  assert(vals[w] > 0);
12196 
12197  SCIP_CALL( chgCoefPos(scip, cons, w, newcoef) );
12198  }
12199  (*nchgcoefs) += (offsetv + 1);
12200  }
12201 
12202  if( !notchangable )
12203  {
12204  /* normalize constraint */
12205  SCIP_CALL( normalizeCons(scip, cons, infeasible) );
12206  assert(vars == consdata->vars);
12207  assert(vals == consdata->vals);
12208 
12209  if( *infeasible )
12210  return SCIP_OKAY;
12211 
12212  /* get new constraint data */
12213  nvars = consdata->nvars;
12214  assert(nvars >= 2);
12215 
12216  SCIPdebugPrintCons(scip, cons, NULL);
12217 
12218  lhs = consdata->lhs;
12219  rhs = consdata->rhs;
12220  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12221  assert(!haslhs || !SCIPisNegative(scip, lhs));
12222  }
12223  }
12224  }
12225  }
12226 
12227  /* @todo we still can remove continuous variables if they are redundant due to the non-integrality argument */
12228  /* no continuous variables are left over */
12229  if( SCIPvarGetType(vars[nvars - 1]) == SCIP_VARTYPE_CONTINUOUS )
12230  return SCIP_OKAY;
12231 
12232  onlybin = TRUE;
12233  allcoefintegral = TRUE;
12234  /* check if all variables are of binary type */
12235  for( v = nvars - 1; v >= 0; --v )
12236  {
12237  if( !SCIPvarIsBinary(vars[v]) )
12238  onlybin = FALSE;
12239  if( !SCIPisIntegral(scip, vals[v]) )
12240  allcoefintegral = FALSE;
12241  }
12242 
12243  /* check if the non-integrality part of all integral variables is smaller than the non-inegrality part of the right
12244  * hand side or bigger than the left hand side respectively, so we can make all of them integral
12245  *
12246  * @todo there are some steps missing ....
12247  */
12248  if( (hasrhs && !SCIPisFeasIntegral(scip, rhs)) || (haslhs && !SCIPisFeasIntegral(scip, lhs)) )
12249  {
12250  SCIP_Real val;
12251  SCIP_Real newval;
12252  SCIP_Real frac = 0.0;
12253  SCIP_Bool found = FALSE;
12254 
12255  if( hasrhs )
12256  {
12257  if( allcoefintegral )
12258  {
12259  /* replace old with new right hand side */
12260  SCIP_CALL( chgRhs(scip, cons, SCIPfloor(scip, rhs)) );
12261  ++(*nchgsides);
12262  }
12263  else
12264  {
12265  siderest = rhs - SCIPfloor(scip, rhs);
12266 
12267  /* try to round down all non-integral coefficients */
12268  for( v = nvars - 1; v >= 0; --v )
12269  {
12270  val = vals[v];
12271 
12272  /* add up all possible fractional parts */
12273  if( !SCIPisIntegral(scip, val) )
12274  {
12275  lb = SCIPvarGetLbGlobal(vars[v]);
12276  ub = SCIPvarGetUbGlobal(vars[v]);
12277 
12278  /* at least one bound need to be at zero */
12279  if( !onlybin && !SCIPisFeasZero(scip, lb) && !SCIPisFeasZero(scip, ub) )
12280  return SCIP_OKAY;
12281 
12282  /* swap bounds for 'standard' form */
12283  if( !SCIPisFeasZero(scip, lb) )
12284  {
12285  ub = lb;
12286  val *= -1;
12287  }
12288 
12289  found = TRUE;
12290 
12291  frac += (val - SCIPfloor(scip, val)) * ub;
12292 
12293  /* if we exceed the fractional part of the right hand side, we cannot tighten the coefficients
12294  *
12295  * e.g. 1.1x1 + 1.1x2 + 1.4x3 + 1.02x4 <= 2.4, here we cannot floor all fractionals because
12296  * x3, x4 set to 1 would be infeasible but feasible after flooring
12297  */
12298  if( SCIPisGT(scip, frac, siderest) )
12299  return SCIP_OKAY;
12300  }
12301  }
12302  assert(v == -1);
12303 
12304  SCIPdebugMsg(scip, "rounding all non-integral coefficients and the right hand side down\n");
12305 
12306  /* round rhs and coefficients to integral values */
12307  if( found )
12308  {
12309  for( v = nvars - 1; v >= 0; --v )
12310  {
12311  val = vals[v];
12312 
12313  /* add the whole fractional part */
12314  if( !SCIPisIntegral(scip, val) )
12315  {
12316  lb = SCIPvarGetLbGlobal(vars[v]);
12317 
12318  if( SCIPisFeasZero(scip, lb) )
12319  newval = SCIPfloor(scip, val);
12320  else
12321  newval = SCIPceil(scip, val);
12322 
12323  if( SCIPisZero(scip, newval) )
12324  {
12325  /* delete old redundant coefficient */
12326  SCIP_CALL( delCoefPos(scip, cons, v) );
12327  ++(*nchgcoefs);
12328  }
12329  else
12330  {
12331  /* replace old with new coefficient */
12332  SCIP_CALL( chgCoefPos(scip, cons, v, newval) );
12333  ++(*nchgcoefs);
12334  }
12335  }
12336  }
12337  }
12338 
12339  /* replace old with new right hand side */
12340  SCIP_CALL( chgRhs(scip, cons, SCIPfloor(scip, rhs)) );
12341  ++(*nchgsides);
12342  }
12343  }
12344  else
12345  {
12346  if( allcoefintegral )
12347  {
12348  /* replace old with new left hand side */
12349  SCIP_CALL( chgLhs(scip, cons, SCIPceil(scip, lhs)) );
12350  ++(*nchgsides);
12351  }
12352  else
12353  {
12354  /* cannot floor left hand side to zero */
12355  if( SCIPisLT(scip, lhs, 1.0) )
12356  return SCIP_OKAY;
12357 
12358  siderest = lhs - SCIPfloor(scip, lhs);
12359 
12360  /* try to round down all non-integral coefficients */
12361  for( v = nvars - 1; v >= 0; --v )
12362  {
12363  val = vals[v];
12364 
12365  /* add up all possible fractional parts */
12366  if( !SCIPisIntegral(scip, val) )
12367  {
12368  lb = SCIPvarGetLbGlobal(vars[v]);
12369  ub = SCIPvarGetUbGlobal(vars[v]);
12370 
12371  /* at least one bound need to be at zero */
12372  if( !SCIPisFeasZero(scip, lb) && !SCIPisFeasZero(scip, ub) )
12373  return SCIP_OKAY;
12374 
12375  /* swap bounds for 'standard' form */
12376  if( !SCIPisFeasZero(scip, lb) )
12377  {
12378  ub = lb;
12379  val *= -1;
12380  }
12381 
12382  /* cannot floor to zero */
12383  if( SCIPisLT(scip, val, 1.0) )
12384  return SCIP_OKAY;
12385 
12386  /* the fractional part on each variable need to exceed the fractional part on the left hand side */
12387  if( SCIPisLT(scip, val - SCIPfloor(scip, val), siderest) )
12388  return SCIP_OKAY;
12389 
12390  found = TRUE;
12391 
12392  frac += (val - SCIPfloor(scip, val)) * ub;
12393 
12394  /* if we exceed the fractional part of the left hand side plus one by summing up all maximal
12395  * fractional parts of the variables, we cannot tighten the coefficients
12396  *
12397  * e.g. 4.3x1 + 1.3x2 + 1.3x3 + 1.6x4 >= 4.2, here we cannot floor all fractionals because
12398  * x2-x4 set to 1 would be feasible but not after flooring
12399  */
12400  if( SCIPisGE(scip, frac, 1 + siderest) )
12401  return SCIP_OKAY;
12402  }
12403  /* all coefficients need to be integral, otherwise we might do an invalid reduction */
12404  else
12405  return SCIP_OKAY;
12406  }
12407  assert(v == -1);
12408 
12409  SCIPdebugMsg(scip, "rounding all non-integral coefficients and the left hand side down\n");
12410 
12411  /* round lhs and coefficients to integral values */
12412  if( found )
12413  {
12414  for( v = nvars - 1; v >= 0; --v )
12415  {
12416  val = vals[v];
12417 
12418  /* add the whole fractional part */
12419  if( !SCIPisIntegral(scip, val) )
12420  {
12421  lb = SCIPvarGetLbGlobal(vars[v]);
12422 
12423  if( SCIPisFeasZero(scip, lb) )
12424  newval = SCIPfloor(scip, val);
12425  else
12426  newval = SCIPceil(scip, val);
12427 
12428  if( SCIPisZero(scip, newval) )
12429  {
12430  /* delete old redundant coefficient */
12431  SCIP_CALL( delCoefPos(scip, cons, v) );
12432  ++(*nchgcoefs);
12433  }
12434  else
12435  {
12436  /* replace old with new coefficient */
12437  SCIP_CALL( chgCoefPos(scip, cons, v, newval) );
12438  ++(*nchgcoefs);
12439  }
12440  }
12441  }
12442  }
12443 
12444  /* replace old with new left hand side */
12445  SCIP_CALL( chgLhs(scip, cons, SCIPfloor(scip, lhs)) );
12446  ++(*nchgsides);
12447  }
12448  }
12449 
12450  /* normalize constraint */
12451  SCIP_CALL( normalizeCons(scip, cons, infeasible) );
12452  assert(vars == consdata->vars);
12453  assert(vals == consdata->vals);
12454 
12455  if( *infeasible )
12456  return SCIP_OKAY;
12457 
12458  rhs = consdata->rhs;
12459  lhs = consdata->lhs;
12460 
12461  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12462  assert(!haslhs || !SCIPisNegative(scip, lhs));
12463 
12464  SCIPdebugPrintCons(scip, cons, NULL);
12465 
12466  nvars = consdata->nvars;
12467  if( nvars < 2 )
12468  return SCIP_OKAY;
12469 
12470  allcoefintegral = TRUE;
12471 #ifndef NDEBUG
12472  /* debug check if all coefficients are really integral */
12473  for( v = nvars - 1; v >= 0; --v )
12474  assert(SCIPisIntegral(scip, vals[v]));
12475 #endif
12476  }
12477 
12478  /* @todo following can also work on non integral coefficients, need more investigation */
12479  /* only check constraints with integral coefficients on all integral variables */
12480  if( !allcoefintegral )
12481  return SCIP_OKAY;
12482 
12483  /* we want to avoid numerical troubles, therefore we do not change non-integral sides */
12484  if( (hasrhs && !SCIPisIntegral(scip, rhs)) || (haslhs && !SCIPisIntegral(scip, lhs)) )
12485  return SCIP_OKAY;
12486 
12487  /* maximal absolute value of coefficients in constraint is one, so we cannot tighten it further */
12488  if( SCIPisEQ(scip, REALABS(vals[0]), 1.0) )
12489  return SCIP_OKAY;
12490 
12491  /* stop if the last coeffcients is one in absolute value and the variable is not binary */
12492  if( !SCIPvarIsBinary(vars[nvars - 1]) && SCIPisEQ(scip, REALABS(vals[nvars - 1]), 1.0) )
12493  return SCIP_OKAY;
12494 
12495  assert(nvars >= 2);
12496 
12497  /* start gcd procedure for all variables */
12498  do
12499  {
12500  SCIPdebug( oldnchgcoefs = *nchgcoefs; )
12501  SCIPdebug( oldnchgsides = *nchgsides; )
12502 
12503  /* stop if we have two coeffcients which are one in absolute value */
12504  if( SCIPisEQ(scip, REALABS(vals[nvars - 1]), 1.0) && SCIPisEQ(scip, REALABS(vals[nvars - 2]), 1.0) )
12505  return SCIP_OKAY;
12506 
12507  gcd = -1;
12508 
12509  /* calculate greatest common divisor over all integer variables; note that the onlybin flag needs to be recomputed
12510  * because coefficients of non-binary variables might have changed to zero */
12511  if( !onlybin )
12512  {
12513  foundbin = -1;
12514  onlybin = TRUE;
12515 
12516  for( v = nvars - 1; v >= 0; --v )
12517  {
12518  assert(!SCIPisZero(scip, vals[v]));
12519  assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_CONTINUOUS);
12520 
12521  if( SCIPvarIsBinary(vars[v]) )
12522  {
12523  if( foundbin == -1 )
12524  foundbin = v;
12525  continue;
12526  }
12527  else
12528  onlybin = FALSE;
12529 
12530  absval = REALABS(vals[v]);
12531  /* arithmetic precision can lead to the absolute value only being integral up to feasibility tolerance,
12532  * even though the value itself is feasible up to epsilon, but since we add feastol later, this is enough
12533  */
12534  assert(SCIPisFeasIntegral(scip, absval));
12535 
12536  if( gcd == -1 )
12537  {
12538  gcd = (SCIP_Longint)(absval + feastol);
12539  assert(gcd >= 1);
12540  }
12541  else
12542  {
12543  /* calculate greatest common divisor for all general variables */
12544  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(absval + feastol));
12545  }
12546  if( gcd == 1 )
12547  break;
12548  }
12549  }
12550  else
12551  foundbin = nvars - 1;
12552 
12553  /* we need at least one binary variable and a gcd greater than 1 to try to perform further coefficient changes */
12554  if( gcd == 1 || foundbin == -1)
12555  return SCIP_OKAY;
12556 
12557  assert((onlybin && gcd == -1) || (!onlybin && gcd > 1));
12558 
12559  candpos = -1;
12560  candpos2 = -1;
12561 
12562  /* calculate greatest common divisor over all integer and binary variables and determine the candidate where we might
12563  * change the coefficient
12564  */
12565  for( v = foundbin; v >= 0; --v )
12566  {
12567  if( onlybin || SCIPvarIsBinary(vars[v]) )
12568  {
12569  absval = REALABS(vals[v]);
12570  /* arithmetic precision can lead to the absolute value only being integral up to feasibility tolerance,
12571  * even though the value itself is feasible up to epsilon, but since we add feastol later, this is enough
12572  */
12573  assert(SCIPisFeasIntegral(scip, absval));
12574 
12575  oldgcd = gcd;
12576 
12577  if( gcd == -1 )
12578  {
12579  gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
12580  assert(gcd >= 1);
12581  }
12582  else
12583  {
12584  /* calculate greatest common divisor for all general and binary variables */
12585  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
12586  }
12587 
12588  /* if the greatest commmon divisor has become 1, we might have found the possible coefficient to change or we
12589  * can terminate
12590  */
12591  if( gcd == 1 )
12592  {
12593  /* found candidate */
12594  if( candpos == -1 )
12595  {
12596  gcd = oldgcd;
12597  candpos = v;
12598 
12599  /* if we have only binary variables and both first coefficients have a gcd of 1, both are candidates for
12600  * the coefficient change
12601  */
12602  if( onlybin && v == foundbin - 1 )
12603  candpos2 = foundbin;
12604  }
12605  /* two different binary variables lead to a gcd of one, so we cannot change a coefficient */
12606  else
12607  {
12608  if( onlybin && candpos == v + 1 && candpos2 == v + 2 )
12609  {
12610  assert(candpos2 == nvars - 1);
12611 
12612  /* take new candidates */
12613  candpos = candpos2;
12614 
12615  /* recalculate gcd from scratch */
12616  gcd = (SCIP_Longint)(REALABS(vals[v+1]) + feastol);
12617  assert(gcd >= 1);
12618 
12619  /* calculate greatest common divisor for all general and binary variables */
12620  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
12621  if( gcd == 1 )
12622  return SCIP_OKAY;
12623  }
12624  else
12625  /* cannot determine a possible coefficient for reduction */
12626  return SCIP_OKAY;
12627  }
12628  }
12629  }
12630  }
12631  assert(gcd >= 2);
12632 
12633  /* we should have found one coefficient, that led to a gcd of 1, otherwise we could normalize the constraint
12634  * further
12635  */
12636  assert(candpos >= 0 && candpos < nvars);
12637 
12638  /* all variables and all coefficients are integral, so the side should be too */
12639  assert((hasrhs && SCIPisIntegral(scip, rhs)) || (haslhs && SCIPisIntegral(scip, lhs)));
12640 
12641  /* check again, if we have a normalized inequality (not ranged) the one side should be positive,
12642  * @see normalizeCons()
12643  */
12644  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12645  assert(!haslhs || !SCIPisNegative(scip, lhs));
12646 
12647  /* determine the remainder of the side and the gcd */
12648  if( hasrhs )
12649  rest = ((SCIP_Longint)(rhs + feastol)) % gcd;
12650  else
12651  rest = ((SCIP_Longint)(lhs + feastol)) % gcd;
12652  assert(rest >= 0);
12653  assert(rest < gcd);
12654 
12655  /* determine the remainder of the coefficient candidate and the gcd */
12656  if( vals[candpos] < 0 )
12657  {
12658  restcoef = ((SCIP_Longint)(vals[candpos] - feastol)) % gcd;
12659  assert(restcoef <= -1);
12660  restcoef += gcd;
12661  }
12662  else
12663  restcoef = ((SCIP_Longint)(vals[candpos] + feastol)) % gcd;
12664  assert(restcoef >= 1);
12665  assert(restcoef < gcd);
12666 
12667  if( hasrhs )
12668  {
12669  if( rest > 0 )
12670  {
12671  /* replace old with new right hand side */
12672  SCIP_CALL( chgRhs(scip, cons, rhs - rest) );
12673  ++(*nchgsides);
12674  }
12675 
12676  /* calculate new coefficient */
12677  if( restcoef > rest )
12678  newcoef = vals[candpos] - restcoef + gcd;
12679  else
12680  newcoef = vals[candpos] - restcoef;
12681  }
12682  else
12683  {
12684  if( rest > 0 )
12685  {
12686  /* replace old with new left hand side */
12687  SCIP_CALL( chgLhs(scip, cons, lhs - rest + gcd) );
12688  ++(*nchgsides);
12689  }
12690 
12691  /* calculate new coefficient */
12692  if( rest == 0 || restcoef < rest )
12693  newcoef = vals[candpos] - restcoef;
12694  else
12695  newcoef = vals[candpos] - restcoef + gcd;
12696  }
12697  assert(SCIPisZero(scip, newcoef) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(newcoef) + feastol)) == gcd);
12698 
12699  SCIPdebugMsg(scip, "gcd = %" SCIP_LONGINT_FORMAT ", rest = %" SCIP_LONGINT_FORMAT ", restcoef = %" SCIP_LONGINT_FORMAT "; changing coef of variable <%s> to %g and %s by %" SCIP_LONGINT_FORMAT "\n", gcd, rest, restcoef, SCIPvarGetName(vars[candpos]), newcoef, hasrhs ? "reduced rhs" : "increased lhs", hasrhs ? rest : (rest > 0 ? gcd - rest : 0));
12700 
12701  if( SCIPisZero(scip, newcoef) )
12702  {
12703  /* delete redundant coefficient */
12704  SCIP_CALL( delCoefPos(scip, cons, candpos) );
12705  }
12706  else
12707  {
12708  /* replace old with new coefficient */
12709  SCIP_CALL( chgCoefPos(scip, cons, candpos, newcoef) );
12710  }
12711  ++(*nchgcoefs);
12712 
12713  /* now constraint can be normalized, might be directly done by dividing it by the gcd */
12714  SCIP_CALL( normalizeCons(scip, cons, infeasible) );
12715  assert(vars == consdata->vars);
12716  assert(vals == consdata->vals);
12717 
12718  if( *infeasible )
12719  return SCIP_OKAY;
12720 
12721  SCIPdebugPrintCons(scip, cons, NULL);
12722 
12723  rhs = consdata->rhs;
12724  lhs = consdata->lhs;
12725  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12726  assert(!haslhs || !SCIPisNegative(scip, lhs));
12727 
12728  nvars = consdata->nvars;
12729 
12730  SCIPdebugMsg(scip, "we did %d coefficient changes and %d side changes on constraint %s when applying one round of the gcd algorithm\n", *nchgcoefs - oldnchgcoefs, *nchgsides - oldnchgsides, SCIPconsGetName(cons));
12731  }
12732  while( nvars >= 2 );
12733 
12734  return SCIP_OKAY;
12735 }
12736 
12737 
12738 /** tries to aggregate an (in)equality and an equality in order to decrease the number of variables in the (in)equality:
12739  * cons0 := a * cons0 + b * cons1,
12740  * where a = val1[v] and b = -val0[v] for common variable v which removes most variable weight;
12741  * for numerical stability, we will only accept integral a and b;
12742  * the variable weight is a weighted sum over all included variables, where each binary variable weighs BINWEIGHT,
12743  * each integer or implicit integer variable weighs INTWEIGHT and each continuous variable weighs CONTWEIGHT
12744  */
12745 static
12747  SCIP* scip, /**< SCIP data structure */
12748  SCIP_CONS* cons0, /**< (in)equality to modify */
12749  SCIP_CONS* cons1, /**< equality to use for aggregation of cons0 */
12750  int* commonidx0, /**< array with indices of variables in cons0, that appear also in cons1 */
12751  int* commonidx1, /**< array with indices of variables in cons1, that appear also in cons0 */
12752  int* diffidx0minus1, /**< array with indices of variables in cons0, that don't appear in cons1 */
12753  int* diffidx1minus0, /**< array with indices of variables in cons1, that don't appear in cons0 */
12754  int nvarscommon, /**< number of variables, that appear in both constraints */
12755  int commonidxweight, /**< variable weight sum of common variables */
12756  int diffidx0minus1weight, /**< variable weight sum of variables in cons0, that don't appear in cons1 */
12757  int diffidx1minus0weight, /**< variable weight sum of variables in cons1, that don't appear in cons0 */
12758  SCIP_Real maxaggrnormscale, /**< maximal allowed relative gain in maximum norm for constraint aggregation */
12759  int* nchgcoefs, /**< pointer to count the number of changed coefficients */
12760  SCIP_Bool* aggregated, /**< pointer to store whether an aggregation was made */
12761  SCIP_Bool* infeasible /**< pointer to store whether infeasibility was detected */
12762  )
12763 {
12764  SCIP_CONSDATA* consdata0;
12765  SCIP_CONSDATA* consdata1;
12766  SCIP_Real a;
12767  SCIP_Real b;
12768  SCIP_Real aggrcoef;
12769  SCIP_Real scalarsum;
12770  SCIP_Real bestscalarsum;
12771  SCIP_Bool betterscalarsum;
12772  SCIP_Bool commonvarlindependent; /* indicates whether coefficient vector of common variables in linearly dependent */
12773  int varweight;
12774  int nvars;
12775  int bestvarweight;
12776  int bestnvars;
12777  int bestv;
12778  int v;
12779  int i;
12780 
12781  assert(scip != NULL);
12782  assert(cons0 != NULL);
12783  assert(cons1 != NULL);
12784  assert(commonidx0 != NULL);
12785  assert(commonidx1 != NULL);
12786  assert(diffidx0minus1 != NULL);
12787  assert(diffidx1minus0 != NULL);
12788  assert(nvarscommon >= 1);
12789  assert(commonidxweight >= nvarscommon);
12790  assert(nchgcoefs != NULL);
12791  assert(aggregated != NULL);
12792 
12793  assert(SCIPconsIsActive(cons0));
12794  assert(SCIPconsIsActive(cons1));
12795 
12796  *infeasible = FALSE;
12797 
12798  SCIPdebugMsg(scip, "try aggregation of <%s> and <%s>\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
12799 
12800  /* cons0 is an (in)equality */
12801  consdata0 = SCIPconsGetData(cons0);
12802  assert(consdata0 != NULL);
12803  assert(consdata0->nvars >= 1);
12804  assert(SCIPisLE(scip, consdata0->lhs, consdata0->rhs));
12805  assert(diffidx0minus1weight >= consdata0->nvars - nvarscommon);
12806 
12807  /* cons1 is an equality */
12808  consdata1 = SCIPconsGetData(cons1);
12809  assert(consdata1 != NULL);
12810  assert(consdata1->nvars >= 1);
12811  assert(SCIPisEQ(scip, consdata1->lhs, consdata1->rhs));
12812  assert(diffidx1minus0weight >= consdata1->nvars - nvarscommon);
12813 
12814  *aggregated = FALSE;
12815 
12816  /* search for the best common variable such that
12817  * val1[var] * consdata0 - val0[var] * consdata1
12818  * has least weighted number of variables
12819  */
12820  bestvarweight = commonidxweight + diffidx0minus1weight;
12821  bestnvars = consdata0->nvars;
12822  bestv = -1;
12823  bestscalarsum = 0.0;
12824  commonvarlindependent = TRUE;
12825  for( v = 0; v < nvarscommon; ++v )
12826  {
12827  assert(consdata0->vars[commonidx0[v]] == consdata1->vars[commonidx1[v]]);
12828  a = consdata1->vals[commonidx1[v]];
12829  b = -consdata0->vals[commonidx0[v]];
12830 
12831  /* only try aggregation, if coefficients are integral (numerical stability) */
12832  if( SCIPisIntegral(scip, a) && SCIPisIntegral(scip, b) )
12833  {
12834  /* count the number of variables in the potential new constraint a * consdata0 + b * consdata1 */
12835  varweight = diffidx0minus1weight + diffidx1minus0weight;
12836  nvars = consdata0->nvars + consdata1->nvars - 2*nvarscommon;
12837  scalarsum = REALABS(a) + REALABS(b);
12838  betterscalarsum = (scalarsum < bestscalarsum);
12839  for( i = 0; i < nvarscommon
12840  && (varweight < bestvarweight || (varweight == bestvarweight && betterscalarsum)); ++i )
12841  {
12842  aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
12843  if( !SCIPisZero(scip, aggrcoef) )
12844  {
12845  varweight += getVarWeight(consdata0->vars[commonidx0[i]]);
12846  nvars++;
12847  }
12848  }
12849  if( varweight < bestvarweight || (varweight == bestvarweight && betterscalarsum) )
12850  {
12851  bestv = v;
12852  bestvarweight = varweight;
12853  bestnvars = nvars;
12854  bestscalarsum = scalarsum;
12855  }
12856  }
12857 
12858  /* update commonvarlindependent flag, if still TRUE:
12859  * v's common coefficient in cons1 / v's common coefficient in cons0 should be constant, i.e., equal 0's common coefficient in cons1 / 0's common coefficient in cons0
12860  */
12861  if( commonvarlindependent && v > 0 )
12862  commonvarlindependent = SCIPisEQ(scip,
12863  consdata1->vals[commonidx1[v]] * consdata0->vals[commonidx0[0]],
12864  consdata1->vals[commonidx1[0]] * consdata0->vals[commonidx0[v]]);
12865  }
12866 
12867  /* if better aggregation was found, create new constraint and delete old one */
12868  if( (bestv != -1 || commonvarlindependent) && SCIPconsGetNUpgradeLocks(cons0) == 0 )
12869  {
12870  SCIP_CONS* newcons;
12871  SCIP_CONSDATA* newconsdata;
12872  SCIP_VAR** newvars;
12873  SCIP_Real* newvals;
12874  SCIP_Real newlhs;
12875  SCIP_Real newrhs;
12876  int newnvars;
12877 
12878  if( bestv != -1 )
12879  {
12880  /* choose multipliers such that the multiplier for the (in)equality cons0 is positive */
12881  if( consdata1->vals[commonidx1[bestv]] > 0.0 )
12882  {
12883  a = consdata1->vals[commonidx1[bestv]];
12884  b = -consdata0->vals[commonidx0[bestv]];
12885  }
12886  else
12887  {
12888  a = -consdata1->vals[commonidx1[bestv]];
12889  b = consdata0->vals[commonidx0[bestv]];
12890  }
12891  assert(SCIPisIntegral(scip, a));
12892  assert(SCIPisPositive(scip, a));
12893  assert(SCIPisIntegral(scip, b));
12894  assert(!SCIPisZero(scip, b));
12895  }
12896  else
12897  {
12898  assert(commonvarlindependent);
12899  if( consdata1->vals[commonidx1[0]] > 0.0 )
12900  {
12901  a = consdata1->vals[commonidx1[0]];
12902  b = -consdata0->vals[commonidx0[0]];
12903  }
12904  else
12905  {
12906  a = -consdata1->vals[commonidx1[0]];
12907  b = consdata0->vals[commonidx0[0]];
12908  }
12909  assert(SCIPisPositive(scip, a));
12910  assert(!SCIPisZero(scip, b));
12911 
12912  /* if a/b is integral, then we can easily choose integer multipliers */
12913  if( SCIPisIntegral(scip, a/b) )
12914  {
12915  if( a/b > 0 )
12916  {
12917  a /= b;
12918  b = 1.0;
12919  }
12920  else
12921  {
12922  a /= -b;
12923  b = -1.0;
12924  }
12925  }
12926 
12927  /* setup best* variables that were not setup above because we are in the commonvarlindependent case */
12928  SCIPdebug( bestvarweight = diffidx0minus1weight + diffidx1minus0weight; )
12929  bestnvars = consdata0->nvars + consdata1->nvars - 2*nvarscommon;
12930  }
12931 
12932  SCIPdebugMsg(scip, "aggregate linear constraints <%s> := %.15g*<%s> + %.15g*<%s> -> nvars: %d -> %d, weight: %d -> %d\n",
12933  SCIPconsGetName(cons0), a, SCIPconsGetName(cons0), b, SCIPconsGetName(cons1),
12934  consdata0->nvars, bestnvars, commonidxweight + diffidx0minus1weight, bestvarweight);
12935  SCIPdebugPrintCons(scip, cons0, NULL);
12936  SCIPdebugPrintCons(scip, cons1, NULL);
12937 
12938  /* get temporary memory for creating the new linear constraint */
12939  SCIP_CALL( SCIPallocBufferArray(scip, &newvars, bestnvars) );
12940  SCIP_CALL( SCIPallocBufferArray(scip, &newvals, bestnvars) );
12941 
12942  /* calculate the common coefficients, if we have not recognized linear dependency */
12943  newnvars = 0;
12944  if( !commonvarlindependent )
12945  {
12946  for( i = 0; i < nvarscommon; ++i )
12947  {
12948  assert(0 <= commonidx0[i] && commonidx0[i] < consdata0->nvars);
12949  assert(0 <= commonidx1[i] && commonidx1[i] < consdata1->nvars);
12950 
12951  aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
12952  if( !SCIPisZero(scip, aggrcoef) )
12953  {
12954  assert(newnvars < bestnvars);
12955  newvars[newnvars] = consdata0->vars[commonidx0[i]];
12956  newvals[newnvars] = aggrcoef;
12957  newnvars++;
12958  }
12959  }
12960  }
12961  else
12962  {
12963  /* if we recognized linear dependency of the common coefficients, then the aggregation coefficient should be 0.0 for every common variable */
12964 #ifndef NDEBUG
12965  for( i = 0; i < nvarscommon; ++i )
12966  {
12967  assert(0 <= commonidx0[i] && commonidx0[i] < consdata0->nvars);
12968  assert(0 <= commonidx1[i] && commonidx1[i] < consdata1->nvars);
12969 
12970  aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
12971  assert(SCIPisZero(scip, aggrcoef));
12972  }
12973 #endif
12974  }
12975 
12976  /* calculate the coefficients appearing in cons0 but not in cons1 */
12977  for( i = 0; i < consdata0->nvars - nvarscommon; ++i )
12978  {
12979  assert(0 <= diffidx0minus1[i] && diffidx0minus1[i] < consdata0->nvars);
12980 
12981  aggrcoef = a * consdata0->vals[diffidx0minus1[i]];
12982  assert(!SCIPisZero(scip, aggrcoef));
12983  assert(newnvars < bestnvars);
12984  newvars[newnvars] = consdata0->vars[diffidx0minus1[i]];
12985  newvals[newnvars] = aggrcoef;
12986  newnvars++;
12987  }
12988 
12989  /* calculate the coefficients appearing in cons1 but not in cons0 */
12990  for( i = 0; i < consdata1->nvars - nvarscommon; ++i )
12991  {
12992  assert(0 <= diffidx1minus0[i] && diffidx1minus0[i] < consdata1->nvars);
12993 
12994  aggrcoef = b * consdata1->vals[diffidx1minus0[i]];
12995  assert(!SCIPisZero(scip, aggrcoef));
12996  assert(newnvars < bestnvars);
12997  newvars[newnvars] = consdata1->vars[diffidx1minus0[i]];
12998  newvals[newnvars] = aggrcoef;
12999  newnvars++;
13000  }
13001  assert(newnvars == bestnvars);
13002 
13003  /* calculate the new left and right hand side of the (in)equality */
13004  assert(!SCIPisInfinity(scip, -consdata1->lhs));
13005  assert(!SCIPisInfinity(scip, consdata1->rhs));
13006  if( SCIPisInfinity(scip, -consdata0->lhs) )
13007  newlhs = -SCIPinfinity(scip);
13008  else
13009  newlhs = a * consdata0->lhs + b * consdata1->lhs;
13010  if( SCIPisInfinity(scip, consdata0->rhs) )
13011  newrhs = SCIPinfinity(scip);
13012  else
13013  newrhs = a * consdata0->rhs + b * consdata1->rhs;
13014 
13015  /* create the new linear constraint */
13016  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, SCIPconsGetName(cons0), newnvars, newvars, newvals, newlhs, newrhs,
13018  SCIPconsIsChecked(cons0), SCIPconsIsPropagated(cons0),
13019  SCIPconsIsLocal(cons0), SCIPconsIsModifiable(cons0),
13021 
13022  newconsdata = SCIPconsGetData(newcons);
13023  assert(newconsdata != NULL);
13024 
13025  /* copy the upgraded flag from the old cons0 to the new constraint */
13026  newconsdata->upgraded = consdata0->upgraded;
13027 
13028  /* normalize the new constraint */
13029  SCIP_CALL( normalizeCons(scip, newcons, infeasible) );
13030 
13031  if( *infeasible )
13032  goto TERMINATE;
13033 
13034  /* check, if we really want to use the new constraint instead of the old one:
13035  * use the new one, if the maximum norm doesn't grow too much
13036  */
13037  if( consdataGetMaxAbsval(SCIPconsGetData(newcons)) <= maxaggrnormscale * consdataGetMaxAbsval(consdata0) )
13038  {
13039  SCIPdebugMsg(scip, " -> aggregated to <%s>\n", SCIPconsGetName(newcons));
13040  SCIPdebugPrintCons(scip, newcons, NULL);
13041 
13042  /* update the statistics: we changed all coefficients */
13043  if( !consdata0->upgraded )
13044  (*nchgcoefs) += consdata0->nvars + consdata1->nvars - nvarscommon;
13045  *aggregated = TRUE;
13046 
13047  /* delete the old constraint, and add the new linear constraint to the problem */
13048  SCIP_CALL( SCIPdelCons(scip, cons0) );
13049  SCIP_CALL( SCIPaddCons(scip, newcons) );
13050  }
13051 
13052  TERMINATE:
13053  /* release the new constraint */
13054  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
13055 
13056  /* free temporary memory */
13057  SCIPfreeBufferArray(scip, &newvals);
13058  SCIPfreeBufferArray(scip, &newvars);
13059  }
13060 
13061  return SCIP_OKAY;
13062 }
13063 
13064 /** gets the key of the given element */
13065 static
13066 SCIP_DECL_HASHGETKEY(hashGetKeyLinearcons)
13067 { /*lint --e{715}*/
13068  /* the key is the element itself */
13069  return elem;
13070 }
13071 
13072 /** returns TRUE iff both keys are equal; two constraints are equal if they have the same variables and the
13073  * coefficients are either equal or negated
13074  */
13075 static
13076 SCIP_DECL_HASHKEYEQ(hashKeyEqLinearcons)
13077 {
13078  SCIP* scip;
13079  SCIP_CONSDATA* consdata1;
13080  SCIP_CONSDATA* consdata2;
13081  SCIP_Real cons1scale;
13082  SCIP_Real cons2scale;
13083  int i;
13084 
13085  assert(key1 != NULL);
13086  assert(key2 != NULL);
13087  consdata1 = SCIPconsGetData((SCIP_CONS*)key1);
13088  consdata2 = SCIPconsGetData((SCIP_CONS*)key2);
13089  assert(consdata1->indexsorted);
13090  assert(consdata2->indexsorted);
13091 
13092  scip = (SCIP*)userptr;
13093  assert(scip != NULL);
13094 
13095  /* if it is the same constraint we dont need to check anything */
13096  if( key1 == key2 )
13097  return TRUE;
13098 
13099  /* checks trivial case */
13100  if( consdata1->nvars != consdata2->nvars )
13101  return FALSE;
13102 
13103  /* tests if variables are equal */
13104  for( i = 0; i < consdata1->nvars; ++i )
13105  {
13106  if( consdata1->vars[i] != consdata2->vars[i] )
13107  {
13108  assert(SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == 1 ||
13109  SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == -1);
13110  return FALSE;
13111  }
13112  assert(SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == 0);
13113  }
13114 
13115  /* compute scale before comparing coefficients of constraints */
13116  cons1scale = COPYSIGN(1.0/consdata1->maxabsval, consdata1->vals[0]);
13117  cons2scale = COPYSIGN(1.0/consdata2->maxabsval, consdata2->vals[0]);
13118 
13119  /* tests if coefficients are equal with the computed scale */
13120  for( i = 0; i < consdata1->nvars; ++i )
13121  {
13122  SCIP_Real val1;
13123  SCIP_Real val2;
13124 
13125  val1 = consdata1->vals[i] * cons1scale;
13126  val2 = consdata2->vals[i] * cons2scale;
13127 
13128  if( !SCIPisEQ(scip, val1, val2) )
13129  return FALSE;
13130  }
13131 
13132  return TRUE;
13133 }
13134 
13135 /** returns the hash value of the key */
13136 static
13137 SCIP_DECL_HASHKEYVAL(hashKeyValLinearcons)
13138 {
13139  SCIP_CONSDATA* consdata;
13140  int minidx;
13141  int mididx;
13142  int maxidx;
13143  SCIP_Real scale;
13144 #ifndef NDEBUG
13145  SCIP* scip;
13146 
13147  scip = (SCIP*)userptr;
13148  assert(scip != NULL);
13149 #endif
13150 
13151  assert(key != NULL);
13152  consdata = SCIPconsGetData((SCIP_CONS*)key);
13153  assert(consdata != NULL);
13154  assert(consdata->nvars > 0);
13155 
13156  assert(consdata->indexsorted);
13157 
13158  minidx = SCIPvarGetIndex(consdata->vars[0]);
13159  mididx = SCIPvarGetIndex(consdata->vars[consdata->nvars / 2]);
13160  maxidx = SCIPvarGetIndex(consdata->vars[consdata->nvars - 1]);
13161  scale = COPYSIGN(1.0/consdata->maxabsval, consdata->vals[0]);
13162 
13163  /* using only the variable indices as hash, since the values are compared by epsilon */
13164  return SCIPhashSeven(consdata->nvars, minidx, SCIPrealHashCode(consdata->vals[0] * scale),
13165  mididx, SCIPrealHashCode(consdata->vals[consdata->nvars / 2] * scale),
13166  maxidx, SCIPrealHashCode(consdata->vals[consdata->nvars - 1] * scale));
13167 }
13168 
13169 /** returns the key for deciding which of two parallel constraints should be kept (smaller key should be kept);
13170  * prefers non-upgraded constraints and as second criterion the constraint with the smallest position
13171  */
13172 static
13173 unsigned int getParallelConsKey(
13174  SCIP_CONS* cons /**< linear constraint */
13175  )
13176 {
13177  SCIP_CONSDATA* consdata;
13178 
13179  assert(cons != NULL);
13180 
13181  consdata = SCIPconsGetData(cons);
13182  assert(consdata != NULL);
13183 
13184  return (((unsigned int)consdata->upgraded)<<31) + (unsigned int)SCIPconsGetPos(cons); /*lint !e571*/
13185 }
13186 
13187 /** updates the hashtable such that out of all constraints in the hashtable that are detected
13188  * to be parallel to *querycons, only one is kept in the hashtable and stored into *querycons,
13189  * and all others are removed from the hashtable and stored in the given array
13190  */
13191 static
13193  SCIP_HASHTABLE* hashtable, /**< hashtable containing linear constraints */
13194  SCIP_CONS** querycons, /**< pointer to linear constraint used to look for duplicates in the hash table;
13195  * upon return will contain the constraint that should be kept */
13196  SCIP_CONS** parallelconss, /**< array to return constraints that are parallel to the given;
13197  * these constraints where removed from the hashtable */
13198  int* nparallelconss /**< pointer to return number of parallel constraints */
13199  )
13200 {
13201  SCIP_CONS* parallelcons;
13202  unsigned int querykey;
13203 
13204  *nparallelconss = 0;
13205  querykey = getParallelConsKey(*querycons);
13206 
13207  while( (parallelcons = (SCIP_CONS*)SCIPhashtableRetrieve(hashtable, (void*)(*querycons))) != NULL )
13208  {
13209  unsigned int conskey = getParallelConsKey(parallelcons);
13210 
13211  if( conskey < querykey )
13212  {
13213  parallelconss[(*nparallelconss)++] = *querycons;
13214  *querycons = parallelcons;
13215  querykey = conskey;
13216  }
13217  else
13218  {
13219  parallelconss[(*nparallelconss)++] = parallelcons;
13220  }
13221 
13222  /* if the constraint that just came out of the hash table is the one that is kept,
13223  * we do not need to look into the hashtable again, since the invariant is that
13224  * in the hashtable only pair-wise non-parallel constraints are contained.
13225  * For the original querycons, however, multiple constraints that compare equal (=parallel)
13226  * could be contained due to non-transitivity of the equality comparison.
13227  * Also we can return immediately, since parallelcons is already contained in the
13228  * hashtable and we do not need to remove and reinsert it.
13229  */
13230  if( *querycons == parallelcons )
13231  return SCIP_OKAY;
13232 
13233  /* remove parallelcons from the hashtable, since it will be replaced by querycons */
13234  SCIP_CALL( SCIPhashtableRemove(hashtable, (void*) parallelcons) );
13235  }
13236 
13237  /* in debug mode we make sure, that the hashtable cannot contain a constraint that
13238  * comnpares equal to querycons at this point
13239  */
13240 #ifndef NDEBUG
13241  SCIP_CALL_ABORT( SCIPhashtableSafeInsert(hashtable, *querycons) );
13242 #else
13243  SCIP_CALL( SCIPhashtableInsert(hashtable, *querycons) );
13244 #endif
13245 
13246  return SCIP_OKAY;
13247 }
13248 
13249 /** compares each constraint with all other constraints for possible redundancy and removes or changes constraint
13250  * accordingly; in contrast to preprocessConstraintPairs(), it uses a hash table
13251  */
13252 static
13254  SCIP* scip, /**< SCIP data structure */
13255  BMS_BLKMEM* blkmem, /**< block memory */
13256  SCIP_CONS** conss, /**< constraint set */
13257  int nconss, /**< number of constraints in constraint set */
13258  int* firstchange, /**< pointer to store first changed constraint */
13259  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
13260  int* ndelconss, /**< pointer to count number of deleted constraints */
13261  int* nchgsides /**< pointer to count number of changed left/right hand sides */
13262  )
13263 {
13264  SCIP_HASHTABLE* hashtable;
13265  SCIP_CONS** parallelconss;
13266  int nparallelconss;
13267  int hashtablesize;
13268  int c;
13269 
13270  assert(scip != NULL);
13271  assert(blkmem != NULL);
13272  assert(conss != NULL);
13273  assert(firstchange != NULL);
13274  assert(cutoff != NULL);
13275  assert(ndelconss != NULL);
13276  assert(nchgsides != NULL);
13277 
13278  /* create a hash table for the constraint set */
13279  hashtablesize = nconss;
13280  SCIP_CALL( SCIPhashtableCreate(&hashtable, blkmem, hashtablesize,
13281  hashGetKeyLinearcons, hashKeyEqLinearcons, hashKeyValLinearcons, (void*) scip) );
13282 
13283  SCIP_CALL( SCIPallocBufferArray(scip, &parallelconss, nconss) );
13284 
13285  /* check all constraints in the given set for redundancy */
13286  for( c = 0; c < nconss; ++c )
13287  {
13288  SCIP_CONS* cons0;
13289  SCIP_CONSDATA* consdata0;
13290 
13291  cons0 = conss[c];
13292 
13293  if( !SCIPconsIsActive(cons0) || SCIPconsIsModifiable(cons0) )
13294  continue;
13295 
13296  /* check for interuption */
13297  if( c % 1000 == 0 && SCIPisStopped(scip) )
13298  break;
13299 
13300  /* sorts the constraint */
13301  consdata0 = SCIPconsGetData(cons0);
13302  assert(consdata0 != NULL);
13303  SCIP_CALL( consdataSort(scip, consdata0) );
13304  assert(consdata0->indexsorted);
13305 
13306  /* get constraints from current hash table with same variables as cons0 and with coefficients equal
13307  * to the ones of cons0 when both are scaled such that maxabsval is 1.0 and the coefficient of the
13308  * first variable is positive
13309  * Also inserts cons0 into the hashtable.
13310  */
13311  SCIP_CALL( retrieveParallelConstraints(hashtable, &cons0, parallelconss, &nparallelconss) );
13312 
13313  if( nparallelconss != 0 )
13314  {
13315  SCIP_Real lhs;
13316  SCIP_Real rhs;
13317 
13318  int i;
13319 
13320  /* cons0 may have been changed in retrieveParallelConstraints() */
13321  consdata0 = SCIPconsGetData(cons0);
13322 
13323  lhs = consdata0->lhs;
13324  rhs = consdata0->rhs;
13325 
13326  for( i = 0; i < nparallelconss; ++i )
13327  {
13328  SCIP_CONS* consdel;
13329  SCIP_CONSDATA* consdatadel;
13330  SCIP_Real scale;
13331 
13332  consdel = parallelconss[i];
13333  consdatadel = SCIPconsGetData(consdel);
13334 
13335  assert(SCIPconsIsActive(consdel));
13336  assert(!SCIPconsIsModifiable(consdel));
13337 
13338  /* constraint found: create a new constraint with same coefficients and best left and right hand side;
13339  * delete old constraints afterwards
13340  */
13341  assert(consdatadel != NULL);
13342  assert(consdata0->nvars >= 1 && consdata0->nvars == consdatadel->nvars);
13343 
13344  assert(consdatadel->indexsorted);
13345  assert(consdata0->vars[0] == consdatadel->vars[0]);
13346 
13347  scale = consdata0->vals[0] / consdatadel->vals[0];
13348  assert(scale != 0.0);
13349 
13350  /* in debug mode, check that all coefficients are equal with respect to epsilon
13351  * if the constraints are in equilibrium scale
13352  */
13353 #ifndef NDEBUG
13354  {
13355  int k;
13356  SCIP_Real scale0 = 1.0 / consdata0->maxabsval;
13357  SCIP_Real scaledel = COPYSIGN(1.0 / consdatadel->maxabsval, scale);
13358 
13359  for( k = 0; k < consdata0->nvars; ++k )
13360  {
13361  assert(SCIPisEQ(scip, scale0 * consdata0->vals[k], scaledel * consdatadel->vals[k]));
13362  }
13363  }
13364 #endif
13365 
13366  if( scale > 0.0 )
13367  {
13368  /* the coefficients of both constraints are parallel with a positive scale */
13369  SCIPdebugMsg(scip, "aggregate linear constraints <%s> and <%s> with equal coefficients into single ranged row\n",
13370  SCIPconsGetName(cons0), SCIPconsGetName(consdel));
13371  SCIPdebugPrintCons(scip, cons0, NULL);
13372  SCIPdebugPrintCons(scip, consdel, NULL);
13373 
13374  if( ! SCIPisInfinity(scip, -consdatadel->lhs) )
13375  lhs = MAX(scale * consdatadel->lhs, lhs);
13376 
13377  if( ! SCIPisInfinity(scip, consdatadel->rhs) )
13378  rhs = MIN(scale * consdatadel->rhs, rhs);
13379  }
13380  else
13381  {
13382  /* the coefficients of both rows are negations */
13383  SCIPdebugMsg(scip, "aggregate linear constraints <%s> and <%s> with negated coefficients into single ranged row\n",
13384  SCIPconsGetName(cons0), SCIPconsGetName(consdel));
13385  SCIPdebugPrintCons(scip, cons0, NULL);
13386  SCIPdebugPrintCons(scip, consdel, NULL);
13387 
13388  if( ! SCIPisInfinity(scip, consdatadel->rhs) )
13389  lhs = MAX(scale * consdatadel->rhs, lhs);
13390 
13391  if( ! SCIPisInfinity(scip, -consdatadel->lhs) )
13392  rhs = MIN(scale * consdatadel->lhs, rhs);
13393  }
13394 
13395  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13396  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, consdel) );
13397 
13398  /* delete consdel */
13399  assert( ! consdata0->upgraded || consdatadel->upgraded );
13400  SCIP_CALL( SCIPdelCons(scip, consdel) );
13401  if( !consdatadel->upgraded )
13402  (*ndelconss)++;
13403  }
13404 
13405  if( SCIPisFeasLT(scip, rhs, lhs) )
13406  {
13407  SCIPdebugMsg(scip, "aggregated linear constraint <%s> is infeasible\n", SCIPconsGetName(cons0));
13408  *cutoff = TRUE;
13409  break;
13410  }
13411 
13412  /* ensure that lhs <= rhs holds without tolerances as we only allow such rows to enter the LP */
13413  if( lhs > rhs )
13414  {
13415  rhs = (lhs + rhs)/2;
13416  lhs = rhs;
13417  }
13418 
13419  /* update lhs and rhs of cons0 */
13420  SCIP_CALL( chgLhs(scip, cons0, lhs) );
13421  SCIP_CALL( chgRhs(scip, cons0, rhs) );
13422 
13423  /* update the first changed constraint to begin the next aggregation round with */
13424  if( consdata0->changed && SCIPconsGetPos(cons0) < *firstchange )
13425  *firstchange = SCIPconsGetPos(cons0);
13426 
13427  assert(SCIPconsIsActive(cons0));
13428  }
13429  }
13430 #ifdef SCIP_MORE_DEBUG
13431  SCIPinfoMessage(scip, NULL, "linear pairwise comparison hashtable statistics:\n");
13433 #endif
13434 
13435  SCIPfreeBufferArray(scip, &parallelconss);
13436 
13437  /* free hash table */
13438  SCIPhashtableFree(&hashtable);
13439 
13440  return SCIP_OKAY;
13441 }
13442 
13443 /** compares constraint with all prior constraints for possible redundancy or aggregation,
13444  * and removes or changes constraint accordingly
13445  */
13446 static
13448  SCIP* scip, /**< SCIP data structure */
13449  SCIP_CONS** conss, /**< constraint set */
13450  int firstchange, /**< first constraint that changed since last pair preprocessing round */
13451  int chkind, /**< index of constraint to check against all prior indices upto startind */
13452  SCIP_Real maxaggrnormscale, /**< maximal allowed relative gain in maximum norm for constraint aggregation */
13453  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
13454  int* ndelconss, /**< pointer to count number of deleted constraints */
13455  int* nchgsides, /**< pointer to count number of changed left/right hand sides */
13456  int* nchgcoefs /**< pointer to count number of changed coefficients */
13457  )
13458 {
13459  SCIP_CONS* cons0;
13460  SCIP_CONSDATA* consdata0;
13461  int* commonidx0;
13462  int* commonidx1;
13463  int* diffidx0minus1;
13464  int* diffidx1minus0;
13465  uint64_t possignature0;
13466  uint64_t negsignature0;
13467  SCIP_Bool cons0changed;
13468  SCIP_Bool cons0isequality;
13469  int diffidx1minus0size;
13470  int c;
13471  SCIP_Real cons0lhs;
13472  SCIP_Real cons0rhs;
13473  SCIP_Bool cons0upgraded;
13474 
13475  assert(scip != NULL);
13476  assert(conss != NULL);
13477  assert(firstchange <= chkind);
13478  assert(cutoff != NULL);
13479  assert(ndelconss != NULL);
13480  assert(nchgsides != NULL);
13481  assert(nchgcoefs != NULL);
13482 
13483  /* get the constraint to be checked against all prior constraints */
13484  cons0 = conss[chkind];
13485  assert(cons0 != NULL);
13486  assert(SCIPconsIsActive(cons0));
13487  assert(!SCIPconsIsModifiable(cons0));
13488 
13489  consdata0 = SCIPconsGetData(cons0);
13490  assert(consdata0 != NULL);
13491  assert(consdata0->nvars >= 1);
13492  cons0isequality = SCIPisEQ(scip, consdata0->lhs, consdata0->rhs);
13493 
13494  /* sort the constraint */
13495  SCIP_CALL( consdataSort(scip, consdata0) );
13496 
13497  /* calculate bit signatures of cons0 for potentially positive and negative coefficients */
13498  consdataCalcSignatures(consdata0);
13499  possignature0 = consdata0->possignature;
13500  negsignature0 = consdata0->negsignature;
13501 
13502  /* get temporary memory for indices of common variables */
13503  SCIP_CALL( SCIPallocBufferArray(scip, &commonidx0, consdata0->nvars) );
13504  SCIP_CALL( SCIPallocBufferArray(scip, &commonidx1, consdata0->nvars) );
13505  SCIP_CALL( SCIPallocBufferArray(scip, &diffidx0minus1, consdata0->nvars) );
13506  SCIP_CALL( SCIPallocBufferArray(scip, &diffidx1minus0, consdata0->nvars) );
13507  diffidx1minus0size = consdata0->nvars;
13508 
13509  cons0lhs = consdata0->lhs;
13510  cons0rhs = consdata0->rhs;
13511  cons0upgraded = consdata0->upgraded;
13512 
13513  /* check constraint against all prior constraints */
13514  cons0changed = consdata0->changed;
13515  consdata0->changed = FALSE;
13516  for( c = (cons0changed ? 0 : firstchange); c < chkind && !(*cutoff) && conss[chkind] != NULL; ++c )
13517  {
13518  SCIP_CONS* cons1;
13519  SCIP_CONSDATA* consdata1;
13520  uint64_t possignature1;
13521  uint64_t negsignature1;
13522  SCIP_Bool cons0dominateslhs;
13523  SCIP_Bool cons1dominateslhs;
13524  SCIP_Bool cons0dominatesrhs;
13525  SCIP_Bool cons1dominatesrhs;
13526  SCIP_Bool cons1isequality;
13527  SCIP_Bool coefsequal;
13528  SCIP_Bool coefsnegated;
13529  SCIP_Bool tryaggregation;
13530  int nvarscommon;
13531  int nvars0minus1;
13532  int nvars1minus0;
13533  int commonidxweight;
13534  int diffidx0minus1weight;
13535  int diffidx1minus0weight;
13536  int v0;
13537  int v1;
13538 
13539  assert(cons0lhs == consdata0->lhs); /*lint !e777*/
13540  assert(cons0rhs == consdata0->rhs); /*lint !e777*/
13541  assert(cons0upgraded == consdata0->upgraded);
13542 
13543  cons1 = conss[c];
13544 
13545  /* cons1 has become inactive during presolving of constraint pairs */
13546  if( cons1 == NULL )
13547  continue;
13548 
13549  assert(SCIPconsIsActive(cons0) && !SCIPconsIsModifiable(cons0));
13550  assert(SCIPconsIsActive(cons1) && !SCIPconsIsModifiable(cons1));
13551 
13552  consdata1 = SCIPconsGetData(cons1);
13553  assert(consdata1 != NULL);
13554 
13555  /* SCIPdebugMsg(scip, "preprocess linear constraint pair <%s>[chgd:%d, upgd:%d] and <%s>[chgd:%d, upgd:%d]\n",
13556  SCIPconsGetName(cons0), cons0changed, cons0upgraded,
13557  SCIPconsGetName(cons1), consdata1->changed, consdata1->upgraded); */
13558 
13559  /* if both constraints didn't change since last pair processing, we can ignore the pair */
13560  if( !cons0changed && !consdata1->changed )
13561  continue;
13562 
13563  /* if both constraints are already upgraded, skip the pair;
13564  * because changes on these constraints cannot be applied to the instance anymore */
13565  if( cons0upgraded && consdata1->upgraded )
13566  continue;
13567 
13568  assert(consdata1->nvars >= 1);
13569 
13570  /* sort the constraint */
13571  SCIP_CALL( consdataSort(scip, consdata1) );
13572 
13573  /* calculate bit signatures of cons1 for potentially positive and negative coefficients */
13574  consdataCalcSignatures(consdata1);
13575  possignature1 = consdata1->possignature;
13576  negsignature1 = consdata1->negsignature;
13577 
13578  /* the signatures give a quick test to check for domination and equality of coefficients */
13579  coefsequal = (possignature0 == possignature1) && (negsignature0 == negsignature1);
13580  coefsnegated = (possignature0 == negsignature1) && (negsignature0 == possignature1);
13581  cons0dominateslhs = SCIPisGE(scip, cons0lhs, consdata1->lhs)
13582  && ((possignature0 | possignature1) == possignature1) /* possignature0 <= possignature1 (as bit vector) */
13583  && ((negsignature0 | negsignature1) == negsignature0); /* negsignature0 >= negsignature1 (as bit vector) */
13584  cons1dominateslhs = SCIPisGE(scip, consdata1->lhs, cons0lhs)
13585  && ((possignature0 | possignature1) == possignature0) /* possignature0 >= possignature1 (as bit vector) */
13586  && ((negsignature0 | negsignature1) == negsignature1); /* negsignature0 <= negsignature1 (as bit vector) */
13587  cons0dominatesrhs = SCIPisLE(scip, cons0rhs, consdata1->rhs)
13588  && ((possignature0 | possignature1) == possignature0) /* possignature0 >= possignature1 (as bit vector) */
13589  && ((negsignature0 | negsignature1) == negsignature1); /* negsignature0 <= negsignature1 (as bit vector) */
13590  cons1dominatesrhs = SCIPisLE(scip, consdata1->rhs, cons0rhs)
13591  && ((possignature0 | possignature1) == possignature1) /* possignature0 <= possignature1 (as bit vector) */
13592  && ((negsignature0 | negsignature1) == negsignature0); /* negsignature0 >= negsignature1 (as bit vector) */
13593  cons1isequality = SCIPisEQ(scip, consdata1->lhs, consdata1->rhs);
13594  tryaggregation = (cons0isequality || cons1isequality) && (maxaggrnormscale > 0.0);
13595  if( !cons0dominateslhs && !cons1dominateslhs && !cons0dominatesrhs && !cons1dominatesrhs
13596  && !coefsequal && !coefsnegated && !tryaggregation )
13597  continue;
13598 
13599  /* make sure, we have enough memory for the index set of V_1 \ V_0 */
13600  if( tryaggregation && consdata1->nvars > diffidx1minus0size )
13601  {
13602  SCIP_CALL( SCIPreallocBufferArray(scip, &diffidx1minus0, consdata1->nvars) );
13603  diffidx1minus0size = consdata1->nvars;
13604  }
13605 
13606  /* check consdata0 against consdata1:
13607  * - if lhs0 >= lhs1 and for each variable v and each solution value x_v val0[v]*x_v <= val1[v]*x_v,
13608  * consdata0 dominates consdata1 w.r.t. left hand side
13609  * - if rhs0 <= rhs1 and for each variable v and each solution value x_v val0[v]*x_v >= val1[v]*x_v,
13610  * consdata0 dominates consdata1 w.r.t. right hand side
13611  * - if val0[v] == -val1[v] for all variables v, the two inequalities can be replaced by a single
13612  * ranged row (or equality)
13613  * - if at least one constraint is an equality, count the weighted number of common variables W_c
13614  * and the weighted number of variable in the difference sets W_0 = w(V_0 \ V_1), W_1 = w(V_1 \ V_0),
13615  * where the weight of each variable depends on its type, such that aggregations in order to remove the
13616  * number of continuous and integer variables are preferred:
13617  * - if W_c > W_1, try to aggregate consdata0 := a * consdata0 + b * consdata1 in order to decrease the
13618  * variable weight in consdata0, where a = +/- val1[v] and b = -/+ val0[v] for common v which leads to
13619  * the smallest weight; for numerical stability, we will only accept integral a and b; the sign of a has
13620  * to be positive to not switch the sense of the (in)equality cons0
13621  * - if W_c > W_0, try to aggregate consdata1 := a * consdata1 + b * consdata0 in order to decrease the
13622  * variable weight in consdata1, where a = +/- val0[v] and b = -/+ val1[v] for common v which leads to
13623  * the smallest weight; for numerical stability, we will only accept integral a and b; the sign of a has
13624  * to be positive to not switch the sense of the (in)equality cons1
13625  */
13626 
13627  /* check consdata0 against consdata1 for redundancy, or ranged row accumulation */
13628  nvarscommon = 0;
13629  commonidxweight = 0;
13630  nvars0minus1 = 0;
13631  diffidx0minus1weight = 0;
13632  nvars1minus0 = 0;
13633  diffidx1minus0weight = 0;
13634  v0 = 0;
13635  v1 = 0;
13636  while( (v0 < consdata0->nvars || v1 < consdata1->nvars)
13637  && (cons0dominateslhs || cons1dominateslhs || cons0dominatesrhs || cons1dominatesrhs
13638  || coefsequal || coefsnegated || tryaggregation) )
13639  {
13640  SCIP_VAR* var;
13641  SCIP_Real val0;
13642  SCIP_Real val1;
13643  int varcmp;
13644 
13645  /* test, if variable appears in only one or in both constraints */
13646  if( v0 < consdata0->nvars && v1 < consdata1->nvars )
13647  varcmp = SCIPvarCompare(consdata0->vars[v0], consdata1->vars[v1]);
13648  else if( v0 < consdata0->nvars )
13649  varcmp = -1;
13650  else
13651  varcmp = +1;
13652 
13653  switch( varcmp )
13654  {
13655  case -1:
13656  /* variable doesn't appear in consdata1 */
13657  var = consdata0->vars[v0];
13658  val0 = consdata0->vals[v0];
13659  val1 = 0.0;
13660  if( tryaggregation )
13661  {
13662  diffidx0minus1[nvars0minus1] = v0;
13663  nvars0minus1++;
13664  diffidx0minus1weight += getVarWeight(var);
13665  }
13666  v0++;
13667  coefsequal = FALSE;
13668  coefsnegated = FALSE;
13669  break;
13670 
13671  case +1:
13672  /* variable doesn't appear in consdata0 */
13673  var = consdata1->vars[v1];
13674  val0 = 0.0;
13675  val1 = consdata1->vals[v1];
13676  if( tryaggregation )
13677  {
13678  diffidx1minus0[nvars1minus0] = v1;
13679  nvars1minus0++;
13680  diffidx1minus0weight += getVarWeight(var);
13681  }
13682  v1++;
13683  coefsequal = FALSE;
13684  coefsnegated = FALSE;
13685  break;
13686 
13687  case 0:
13688  /* variable appears in both constraints */
13689  assert(consdata0->vars[v0] == consdata1->vars[v1]);
13690  var = consdata0->vars[v0];
13691  val0 = consdata0->vals[v0];
13692  val1 = consdata1->vals[v1];
13693  if( tryaggregation )
13694  {
13695  commonidx0[nvarscommon] = v0;
13696  commonidx1[nvarscommon] = v1;
13697  nvarscommon++;
13698  commonidxweight += getVarWeight(var);
13699  }
13700  v0++;
13701  v1++;
13702  coefsequal = coefsequal && (SCIPisEQ(scip, val0, val1));
13703  coefsnegated = coefsnegated && (SCIPisEQ(scip, val0, -val1));
13704  break;
13705 
13706  default:
13707  SCIPerrorMessage("invalid comparison result\n");
13708  SCIPABORT();
13709  var = NULL;
13710  val0 = 0.0;
13711  val1 = 0.0;
13712  }
13713  assert(var != NULL);
13714 
13715  /* update domination criteria w.r.t. the coefficient and the variable's bounds */
13716  if( SCIPisGT(scip, val0, val1) )
13717  {
13718  if( SCIPisNegative(scip, SCIPvarGetLbGlobal(var)) )
13719  {
13720  cons0dominatesrhs = FALSE;
13721  cons1dominateslhs = FALSE;
13722  }
13723  if( SCIPisPositive(scip, SCIPvarGetUbGlobal(var)) )
13724  {
13725  cons0dominateslhs = FALSE;
13726  cons1dominatesrhs = FALSE;
13727  }
13728  }
13729  else if( SCIPisLT(scip, val0, val1) )
13730  {
13731  if( SCIPisNegative(scip, SCIPvarGetLbGlobal(var)) )
13732  {
13733  cons0dominateslhs = FALSE;
13734  cons1dominatesrhs = FALSE;
13735  }
13736  if( SCIPisPositive(scip, SCIPvarGetUbGlobal(var)) )
13737  {
13738  cons0dominatesrhs = FALSE;
13739  cons1dominateslhs = FALSE;
13740  }
13741  }
13742  }
13743 
13744  /* check for disaggregated ranged rows */
13745  if( coefsequal || coefsnegated )
13746  {
13747  SCIP_CONS* consstay;
13748  SCIP_CONS* consdel;
13749 #ifndef NDEBUG
13750  SCIP_CONSDATA* consdatastay;
13751 #endif
13752  SCIP_CONSDATA* consdatadel;
13753  SCIP_Real lhs;
13754  SCIP_Real rhs;
13755  int consinddel;
13756 
13757  /* the coefficients in both rows are either equal or negated: create a new constraint with same coefficients and
13758  * best left and right hand sides; delete the old constraints afterwards
13759  */
13760  SCIPdebugMsg(scip, "aggregate linear constraints <%s> and <%s> with %s coefficients into single ranged row\n",
13761  SCIPconsGetName(cons0), SCIPconsGetName(cons1), coefsequal ? "equal" : "negated");
13762  SCIPdebugPrintCons(scip, cons0, NULL);
13763  SCIPdebugPrintCons(scip, cons1, NULL);
13764 
13765  if( coefsequal )
13766  {
13767  /* the coefficients of both rows are equal */
13768  lhs = MAX(consdata0->lhs, consdata1->lhs);
13769  rhs = MIN(consdata0->rhs, consdata1->rhs);
13770  }
13771  else
13772  {
13773  /* the coefficients of both rows are negations */
13774  lhs = MAX(consdata0->lhs, -consdata1->rhs);
13775  rhs = MIN(consdata0->rhs, -consdata1->lhs);
13776  }
13777  if( SCIPisFeasLT(scip, rhs, lhs) )
13778  {
13779  SCIPdebugMsg(scip, "aggregated linear constraint <%s> is infeasible\n", SCIPconsGetName(cons0));
13780  *cutoff = TRUE;
13781  break;
13782  }
13783 
13784  /* check which constraint has to stay;
13785  * changes applied to an upgraded constraint will not be considered in the instance */
13786  if( consdata0->upgraded )
13787  {
13788  assert(!consdata1->upgraded);
13789  consstay = cons1;
13790 #ifndef NDEBUG
13791  consdatastay = consdata1;
13792 #endif
13793 
13794  consdel = cons0;
13795  consdatadel = consdata0;
13796  consinddel = chkind;
13797  }
13798  else
13799  {
13800  consstay = cons0;
13801 #ifndef NDEBUG
13802  consdatastay = consdata0;
13803 #endif
13804 
13805  consdel = cons1;
13806  consdatadel = consdata1;
13807  consinddel = c;
13808  }
13809 
13810  /* update the sides of consstay */
13811  SCIP_CALL( chgLhs(scip, consstay, lhs) );
13812  SCIP_CALL( chgRhs(scip, consstay, rhs) );
13813  if( !consdata0->upgraded )
13814  {
13815  assert(consstay == cons0);
13816  cons0lhs = consdata0->lhs;
13817  cons0rhs = consdata0->rhs;
13818  }
13819 
13820  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13821  SCIP_CALL( SCIPupdateConsFlags(scip, consstay, consdel) );
13822 
13823  assert( !consdatastay->upgraded );
13824  /* delete consdel */
13825  SCIP_CALL( SCIPdelCons(scip, consdel) );
13826  conss[consinddel] = NULL;
13827  if( !consdatadel->upgraded )
13828  (*ndelconss)++;
13829  continue;
13830  }
13831 
13832  /* check for domination: remove dominated sides, but don't touch equalities as long as they are not totally
13833  * redundant
13834  */
13835  if( cons1dominateslhs && (!cons0isequality || cons1dominatesrhs || SCIPisInfinity(scip, consdata0->rhs) ) )
13836  {
13837  /* left hand side is dominated by consdata1: delete left hand side of consdata0 */
13838  SCIPdebugMsg(scip, "left hand side of linear constraint <%s> is dominated by <%s>:\n",
13839  SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13840  SCIPdebugPrintCons(scip, cons0, NULL);
13841  SCIPdebugPrintCons(scip, cons1, NULL);
13842 
13843  /* check for infeasibility */
13844  if( SCIPisFeasGT(scip, consdata1->lhs, consdata0->rhs) )
13845  {
13846  SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13847  *cutoff = TRUE;
13848  break;
13849  }
13850 
13851  /* remove redundant left hand side */
13852  if( !SCIPisInfinity(scip, -consdata0->lhs) )
13853  {
13854  SCIP_CALL( chgLhs(scip, cons0, -SCIPinfinity(scip)) );
13855  cons0lhs = consdata0->lhs;
13856  cons0isequality = FALSE;
13857  if( !consdata0->upgraded )
13858  {
13859  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13860  SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
13861 
13862  (*nchgsides)++;
13863  }
13864  }
13865  }
13866  else if( cons0dominateslhs && (!cons1isequality || cons0dominatesrhs || SCIPisInfinity(scip, consdata1->rhs)) )
13867  {
13868  /* left hand side is dominated by consdata0: delete left hand side of consdata1 */
13869  SCIPdebugMsg(scip, "left hand side of linear constraint <%s> is dominated by <%s>:\n",
13870  SCIPconsGetName(cons1), SCIPconsGetName(cons0));
13871  SCIPdebugPrintCons(scip, cons1, NULL);
13872  SCIPdebugPrintCons(scip, cons0, NULL);
13873 
13874  /* check for infeasibility */
13875  if( SCIPisFeasGT(scip, consdata0->lhs, consdata1->rhs) )
13876  {
13877  SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13878  *cutoff = TRUE;
13879  break;
13880  }
13881 
13882  /* remove redundant left hand side */
13883  if( !SCIPisInfinity(scip, -consdata1->lhs) )
13884  {
13885  SCIP_CALL( chgLhs(scip, cons1, -SCIPinfinity(scip)) );
13886  cons1isequality = FALSE;
13887  if( !consdata1->upgraded )
13888  {
13889  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13890  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
13891 
13892  (*nchgsides)++;
13893  }
13894  }
13895  }
13896  if( cons1dominatesrhs && (!cons0isequality || cons1dominateslhs || SCIPisInfinity(scip, -consdata0->lhs)) )
13897  {
13898  /* right hand side is dominated by consdata1: delete right hand side of consdata0 */
13899  SCIPdebugMsg(scip, "right hand side of linear constraint <%s> is dominated by <%s>:\n",
13900  SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13901  SCIPdebugPrintCons(scip, cons0, NULL);
13902  SCIPdebugPrintCons(scip, cons1, NULL);
13903 
13904  /* check for infeasibility */
13905  if( SCIPisFeasLT(scip, consdata1->rhs, consdata0->lhs) )
13906  {
13907  SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13908  *cutoff = TRUE;
13909  break;
13910  }
13911 
13912  /* remove redundant right hand side */
13913  if( !SCIPisInfinity(scip, consdata0->rhs) )
13914  {
13915  SCIP_CALL( chgRhs(scip, cons0, SCIPinfinity(scip)) );
13916  cons0rhs = consdata0->rhs;
13917  cons0isequality = FALSE;
13918  if( !consdata0->upgraded )
13919  {
13920  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13921  SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
13922 
13923  (*nchgsides)++;
13924  }
13925  }
13926  }
13927  else if( cons0dominatesrhs && (!cons1isequality || cons0dominateslhs || SCIPisInfinity(scip, -consdata1->lhs)) )
13928  {
13929  /* right hand side is dominated by consdata0: delete right hand side of consdata1 */
13930  SCIPdebugMsg(scip, "right hand side of linear constraint <%s> is dominated by <%s>:\n",
13931  SCIPconsGetName(cons1), SCIPconsGetName(cons0));
13932  SCIPdebugPrintCons(scip, cons1, NULL);
13933  SCIPdebugPrintCons(scip, cons0, NULL);
13934 
13935  /* check for infeasibility */
13936  if( SCIPisFeasLT(scip, consdata0->rhs, consdata1->lhs) )
13937  {
13938  SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13939  *cutoff = TRUE;
13940  break;
13941  }
13942 
13943  /* remove redundant right hand side */
13944  if( !SCIPisInfinity(scip, consdata1->rhs) )
13945  {
13946  SCIP_CALL( chgRhs(scip, cons1, SCIPinfinity(scip)) );
13947  cons1isequality = FALSE;
13948  if( !consdata1->upgraded )
13949  {
13950  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13951  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
13952 
13953  (*nchgsides)++;
13954  }
13955  }
13956  }
13957 
13958  /* check for now redundant constraints */
13959  if( SCIPisInfinity(scip, -consdata0->lhs) && SCIPisInfinity(scip, consdata0->rhs) )
13960  {
13961  /* consdata0 became redundant */
13962  SCIPdebugMsg(scip, "linear constraint <%s> is redundant\n", SCIPconsGetName(cons0));
13963  SCIP_CALL( SCIPdelCons(scip, cons0) );
13964  conss[chkind] = NULL;
13965  if( !consdata0->upgraded )
13966  {
13967  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13968  SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
13969 
13970  (*ndelconss)++;
13971  }
13972  continue;
13973  }
13974  if( SCIPisInfinity(scip, -consdata1->lhs) && SCIPisInfinity(scip, consdata1->rhs) )
13975  {
13976  /* consdata1 became redundant */
13977  SCIPdebugMsg(scip, "linear constraint <%s> is redundant\n", SCIPconsGetName(cons1));
13978  SCIP_CALL( SCIPdelCons(scip, cons1) );
13979  conss[c] = NULL;
13980  if( !consdata1->upgraded )
13981  {
13982  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13983  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
13984 
13985  (*ndelconss)++;
13986  }
13987  continue;
13988  }
13989 
13990  /* check, if we want to aggregate an (in)equality with an equality:
13991  * consdata0 := a * consdata0 + b * consdata1 or consdata1 := a * consdata1 + b * consdata0
13992  */
13993  if( tryaggregation )
13994  {
13995  SCIP_Bool aggregated;
13996 
13997  assert(consdata0->nvars == nvarscommon + nvars0minus1);
13998  assert(consdata1->nvars == nvarscommon + nvars1minus0);
13999 
14000  aggregated = FALSE;
14001  if( cons1isequality && !consdata0->upgraded && commonidxweight > diffidx1minus0weight )
14002  {
14003  /* W_c > W_1: try to aggregate consdata0 := a * consdata0 + b * consdata1 */
14004  SCIP_CALL( aggregateConstraints(scip, cons0, cons1, commonidx0, commonidx1, diffidx0minus1, diffidx1minus0,
14005  nvarscommon, commonidxweight, diffidx0minus1weight, diffidx1minus0weight, maxaggrnormscale,
14006  nchgcoefs, &aggregated, cutoff) );
14007 
14008  if( *cutoff )
14009  break;
14010 
14011  /* update array of active constraints */
14012  if( aggregated )
14013  {
14014  assert(!SCIPconsIsActive(cons0));
14015  assert(SCIPconsIsActive(cons1));
14016  conss[chkind] = NULL;
14017  }
14018  }
14019  if( !aggregated && cons0isequality && !consdata1->upgraded && commonidxweight > diffidx0minus1weight )
14020  {
14021  /* W_c > W_0: try to aggregate consdata1 := a * consdata1 + b * consdata0 */
14022  SCIP_CALL( aggregateConstraints(scip, cons1, cons0, commonidx1, commonidx0, diffidx1minus0, diffidx0minus1,
14023  nvarscommon, commonidxweight, diffidx1minus0weight, diffidx0minus1weight, maxaggrnormscale,
14024  nchgcoefs, &aggregated, cutoff) );
14025 
14026  if( *cutoff )
14027  break;
14028 
14029  /* update array of active constraints */
14030  if( aggregated )
14031  {
14032  assert(!SCIPconsIsActive(cons1));
14033  assert(SCIPconsIsActive(cons0));
14034  conss[c] = NULL;
14035  }
14036  }
14037  }
14038  }
14039 
14040  /* free temporary memory */
14041  SCIPfreeBufferArray(scip, &diffidx1minus0);
14042  SCIPfreeBufferArray(scip, &diffidx0minus1);
14043  SCIPfreeBufferArray(scip, &commonidx1);
14044  SCIPfreeBufferArray(scip, &commonidx0);
14045 
14046  return SCIP_OKAY;
14047 }
14048 
14049 /** do stuffing presolving on a single constraint */
14050 static
14052  SCIP* scip, /**< SCIP data structure */
14053  SCIP_CONS* cons, /**< linear constraint */
14054  SCIP_Bool singletonstuffing, /**< should stuffing of singleton continuous variables be performed? */
14055  SCIP_Bool singlevarstuffing, /**< should single variable stuffing be performed, which tries to fulfill
14056  * constraints using the cheapest variable? */
14057  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
14058  int* nfixedvars, /**< pointer to count the total number of fixed variables */
14059  int* nchgbds /**< pointer to count the total number of tightened bounds */
14060  )
14061 {
14062  SCIP_CONSDATA* consdata;
14063  SCIP_Real* ratios;
14064  int* varpos;
14065  SCIP_Bool* swapped;
14066  SCIP_VAR** vars;
14067  SCIP_Real* vals;
14068  SCIP_VAR* var;
14069  SCIP_Real lb;
14071  SCIP_Real minactivity;
14072  SCIP_Real maxactivity;
14073  SCIP_Real maxcondactivity;
14074  SCIP_Real mincondactivity;
14075  SCIP_Real rhs;
14076  SCIP_Real val;
14077  SCIP_Real obj;
14078  SCIP_Real factor;
14079  SCIP_Bool minactisrelax;
14080  SCIP_Bool maxactisrelax;
14081  SCIP_Bool isminsettoinfinity;
14082  SCIP_Bool ismaxsettoinfinity;
14083  SCIP_Bool tryfixing;
14084  int nsingletons;
14085  int idx;
14086  int v;
14087  int nvars;
14088 
14089  assert(scip != NULL);
14090  assert(cons != NULL);
14091  assert(nfixedvars != NULL);
14092 
14093  consdata = SCIPconsGetData(cons);
14094 
14095  /* we only want to run for inequalities */
14096  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, -consdata->lhs) )
14097  return SCIP_OKAY;
14098 
14099  if( singlevarstuffing )
14100  {
14101  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
14102  &isminsettoinfinity, &ismaxsettoinfinity);
14103  }
14104  else
14105  {
14106  minactivity = SCIP_INVALID;
14107  maxactivity = SCIP_INVALID;
14108  isminsettoinfinity = FALSE;
14109  ismaxsettoinfinity = FALSE;
14110  }
14111 
14112  /* we want to have a <= constraint, if the rhs is infinite, we implicitly multiply the constraint by -1,
14113  * the new maxactivity is minus the old minactivity then
14114  */
14115  if( SCIPisInfinity(scip, consdata->rhs) )
14116  {
14117  rhs = -consdata->lhs;
14118  factor = -1.0;
14119  maxactivity = -minactivity;
14120  ismaxsettoinfinity = isminsettoinfinity;
14121  }
14122  else
14123  {
14124  assert(SCIPisInfinity(scip, -consdata->lhs));
14125  rhs = consdata->rhs;
14126  factor = 1.0;
14127  }
14128 
14129  nvars = consdata->nvars;
14130  vars = consdata->vars;
14131  vals = consdata->vals;
14132 
14133  /* check for continuous singletons */
14134  if( singletonstuffing )
14135  {
14136  for( v = 0; v < nvars; ++v )
14137  {
14138  var = vars[v];
14139 
14142  break;
14143  }
14144  }
14145  else
14146  /* we don't want to go into the next block */
14147  v = nvars;
14148 
14149  /* a singleton was found -> perform singleton variable stuffing */
14150  if( v < nvars )
14151  {
14152  assert(singletonstuffing);
14153 
14154  SCIP_CALL( SCIPallocBufferArray(scip, &varpos, nvars) );
14155  SCIP_CALL( SCIPallocBufferArray(scip, &ratios, nvars) );
14156  SCIP_CALL( SCIPallocBufferArray(scip, &swapped, nvars) );
14157 
14158  tryfixing = TRUE;
14159  nsingletons = 0;
14160  mincondactivity = 0.0;
14161  maxcondactivity = 0.0;
14162 
14163  for( v = 0; v < nvars; ++v )
14164  {
14165  var = vars[v];
14166  lb = SCIPvarGetLbGlobal(var);
14167  ub = SCIPvarGetUbGlobal(var);
14168  obj = SCIPvarGetObj(var);
14169  val = factor * vals[v];
14170 
14171  assert(!SCIPisZero(scip, val));
14172 
14173  /* the variable is a singleton and continuous */
14176  {
14177  if( SCIPisNegative(scip, obj) && val > 0 )
14178  {
14179  /* case 1: obj < 0 and coef > 0 */
14180  if( SCIPisInfinity(scip, -lb) )
14181  {
14182  tryfixing = FALSE;
14183  break;
14184  }
14185 
14186  maxcondactivity += val * lb;
14187  mincondactivity += val * lb;
14188  swapped[v] = FALSE;
14189  ratios[nsingletons] = obj / val;
14190  varpos[nsingletons] = v;
14191  nsingletons++;
14192  }
14193  else if( SCIPisPositive(scip, obj) && val < 0 )
14194  {
14195  /* case 2: obj > 0 and coef < 0 */
14196  if( SCIPisInfinity(scip, ub) )
14197  {
14198  tryfixing = FALSE;
14199  break;
14200  }
14201  /* multiply column by (-1) to become case 1.
14202  * now bounds are swapped: ub := -lb, lb := -ub
14203  */
14204 
14205  maxcondactivity += val * ub;
14206  mincondactivity += val * ub;
14207  swapped[v] = TRUE;
14208  ratios[nsingletons] = obj / val;
14209  varpos[nsingletons] = v;
14210  nsingletons++;
14211  }
14212  else if( val > 0 )
14213  {
14214  /* case 3: obj >= 0 and coef >= 0 is handled by duality fixing.
14215  * we only consider the lower bound for the constants
14216  */
14217  assert(!SCIPisNegative(scip, obj));
14218 
14219  if( SCIPisInfinity(scip, -lb) )
14220  {
14221  /* maybe unbounded */
14222  tryfixing = FALSE;
14223  break;
14224  }
14225 
14226  maxcondactivity += val * lb;
14227  mincondactivity += val * lb;
14228  }
14229  else
14230  {
14231  /* case 4: obj <= 0 and coef <= 0 is also handled by duality fixing.
14232  * we only consider the upper bound for the constants
14233  */
14234  assert(!SCIPisPositive(scip, obj));
14235  assert(val < 0);
14236 
14237  if( SCIPisInfinity(scip, ub) )
14238  {
14239  /* maybe unbounded */
14240  tryfixing = FALSE;
14241  break;
14242  }
14243 
14244  maxcondactivity += val * ub;
14245  mincondactivity += val * ub;
14246  }
14247  }
14248  else
14249  {
14250  /* consider contribution of discrete variables, non-singleton
14251  * continuous variables and variables with more than one lock
14252  */
14253  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
14254  {
14255  tryfixing = FALSE;
14256  break;
14257  }
14258 
14259  if( val > 0 )
14260  {
14261  maxcondactivity += val * ub;
14262  mincondactivity += val * lb;
14263  }
14264  else
14265  {
14266  maxcondactivity += val * lb;
14267  mincondactivity += val * ub;
14268  }
14269  }
14270  }
14271  if( tryfixing && nsingletons > 0 && (SCIPisGT(scip, rhs, maxcondactivity) || SCIPisLE(scip, rhs, mincondactivity)) )
14272  {
14273  SCIP_Real delta;
14274  SCIP_Bool tightened;
14275 #ifdef SCIP_DEBUG
14276  int oldnfixedvars = *nfixedvars;
14277  int oldnchgbds = *nchgbds;
14278 #endif
14279 
14280  SCIPsortRealInt(ratios, varpos, nsingletons);
14281 
14282  /* verify which singleton continuous variables can be fixed */
14283  for( v = 0; v < nsingletons; ++v )
14284  {
14285  idx = varpos[v];
14286  var = vars[idx];
14287  val = factor * vals[idx];
14288  lb = SCIPvarGetLbGlobal(var);
14289  ub = SCIPvarGetUbGlobal(var);
14290 
14291  assert(val > 0 || SCIPisPositive(scip, SCIPvarGetObj(var)));
14292  assert((val < 0) == swapped[idx]);
14293  val = REALABS(val);
14294 
14295  /* stop fixing if variable bounds are not finite */
14296  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
14297  break;
14298 
14301  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
14302 
14303  /* calculate the change in the row activities if this variable changes
14304  * its value from its worst to its best bound
14305  */
14306  if( swapped[idx] )
14307  delta = -(lb - ub) * val;
14308  else
14309  delta = (ub - lb) * val;
14310 
14311  assert(!SCIPisNegative(scip, delta));
14312 
14313  if( SCIPisLE(scip, delta, rhs - maxcondactivity) )
14314  {
14315  if( swapped[idx] )
14316  {
14317  SCIPdebugMsg(scip, "fix <%s> to its lower bound %g\n", SCIPvarGetName(var), lb);
14318  SCIP_CALL( SCIPfixVar(scip, var, lb, cutoff, &tightened) );
14319  }
14320  else
14321  {
14322  SCIPdebugMsg(scip, "fix <%s> to its upper bound %g\n", SCIPvarGetName(var), ub);
14323  SCIP_CALL( SCIPfixVar(scip, var, ub, cutoff, &tightened) );
14324  }
14325 
14326  if( *cutoff )
14327  break;
14328  if( tightened )
14329  {
14330  (*nfixedvars)++;
14331  }
14332  }
14333  /* @note: we could in theory tighten the bound of the first singleton variable which does not fall into the above case,
14334  * since it cannot be fully fixed. However, this is not needed and should be done by activity-based bound tightening
14335  * anyway after all other continuous singleton columns were fixed; doing it here may introduce numerical
14336  * troubles in case of large bounds.
14337  */
14338  else if( SCIPisLE(scip, rhs, mincondactivity) )
14339  {
14340  if( swapped[idx] )
14341  {
14342  SCIPdebugMsg(scip, "fix <%s> to its upper bound %g\n", SCIPvarGetName(var), ub);
14343  SCIP_CALL( SCIPfixVar(scip, var, ub, cutoff, &tightened) );
14344  }
14345  else
14346  {
14347  SCIPdebugMsg(scip, "fix <%s> to its lower bound %g\n", SCIPvarGetName(var), lb);
14348  SCIP_CALL( SCIPfixVar(scip, var, lb, cutoff, &tightened) );
14349  }
14350 
14351  if( *cutoff )
14352  break;
14353  if( tightened )
14354  {
14355  (*nfixedvars)++;
14356  }
14357  }
14358 
14359  maxcondactivity += delta;
14360  mincondactivity += delta;
14361  }
14362 
14363 #ifdef SCIP_DEBUG
14364  if( *nfixedvars - oldnfixedvars > 0 || *nchgbds - oldnchgbds > 0 )
14365  {
14366  SCIPdebugMsg(scip, "### stuffing fixed %d variables and changed %d bounds\n", *nfixedvars - oldnfixedvars, *nchgbds - oldnchgbds);
14367  }
14368 #endif
14369  }
14370 
14371  SCIPfreeBufferArray(scip, &swapped);
14372  SCIPfreeBufferArray(scip, &ratios);
14373  SCIPfreeBufferArray(scip, &varpos);
14374  }
14375 
14376  /* perform single-variable stuffing:
14377  * for a linear inequality
14378  * a_1 x_1 + a_2 x_2 + ... + a_n x_n <= b
14379  * with a_i > 0 and objective coefficients c_i < 0,
14380  * setting all variables to their upper bound (giving us the maximal activity of the constraint) is worst w.r.t.
14381  * feasibility of the constraint. On the other hand, this gives the best objective function contribution of the
14382  * variables contained in the constraint. The maximal activity should be larger than the rhs, otherwise the constraint
14383  * is redundant.
14384  * Now we are searching for a variable x_k with maximal ratio c_k / a_k (note that all these ratios are negative), so
14385  * that by reducing the value of this variable we reduce the activity of the constraint while having the smallest
14386  * objective deterioration per activity unit. If x_k has no downlocks, is continuous, and can be reduced enough to
14387  * render the constraint feasible, and ALL other variables have only the one uplock installed by the current constraint,
14388  * we can reduce the upper bound of x_k such that the maxactivity equals the rhs and fix all other variables to their
14389  * upper bound.
14390  * Note that the others variables may have downlocks from other constraints, which we do not need to care
14391  * about since we are setting them to the highest possible value. Also, they may be integer or binary, because the
14392  * computed ratio is still a lower bound on the change in the objective caused by reducing those variable to reach
14393  * constraint feasibility. On the other hand, uplocks on x_k from other constraint do no interfer with the method.
14394  * With a slight adjustment, the procedure even works for integral x_k. If (maxactivity - rhs)/val is integral,
14395  * the variable gets an integral value in order to fulfill the constraint tightly, and we can just apply the procedure.
14396  * If (maxactivity - rhs)/val is fractional, we need to check, if overfulfilling the constraint by setting x_k to
14397  * ceil((maxactivity - rhs)/val) is still better than setting x_k to ceil((maxactivity - rhs)/val) - 1 and
14398  * filling the remaining gap in the constraint with the next-best variable. For this, we check that
14399  * c_k * ceil((maxactivity - rhs)/val) is still better than
14400  * c_k * floor((maxactivity - rhs)/val) + c_j * ((maxactivity - rhs) - (floor((maxactivity - rhs)/val) * val))/a_j.
14401  * In this case, the upper bound of x_k is decreased to ub_k - ceil(maxactivity - rhs).
14402  * If there are variables with a_i < 0 and c_i > 0, they are negated to obtain the above form, variables with same
14403  * sign of coefficients in constraint and objective prevent the use of this method.
14404  */
14405  if( singlevarstuffing && !ismaxsettoinfinity )
14406  {
14407  SCIP_Real bestratio = -SCIPinfinity(scip);
14408  SCIP_Real secondbestratio = -SCIPinfinity(scip);
14409  SCIP_Real ratio;
14410  int bestindex = -1;
14411  int bestuplocks = 0;
14412  int bestdownlocks = 1;
14413  int downlocks;
14414  int uplocks;
14415  SCIPdebug( int oldnfixedvars = *nfixedvars; )
14416  SCIPdebug( int oldnchgbds = *nchgbds; )
14417 
14418  /* loop over all variables to identify the best and second-best ratio */
14419  for( v = 0; v < nvars; ++v )
14420  {
14421  var = vars[v];
14422  obj = SCIPvarGetObj(var);
14423  val = factor * vals[v];
14424 
14425  assert(!SCIPisZero(scip, val));
14426 
14427  ratio = obj / val;
14428 
14429  /* if both objective and constraint push the variable to the same direction, we can do nothing here */
14430  if( !SCIPisNegative(scip, ratio) )
14431  {
14432  bestindex = -1;
14433  break;
14434  }
14435 
14436  if( val > 0 )
14437  {
14440  }
14441  else
14442  {
14443  downlocks = SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL);
14445  }
14446 
14447  /* better ratio, update best candidate
14448  * @todo use some tolerance
14449  * @todo check size of domain and updated ratio for integer variables already?
14450  */
14451  if( ratio > bestratio || ((ratio == bestratio) && downlocks == 0 && (bestdownlocks > 0 /*lint !e777*/
14452  || (SCIPvarGetType(vars[bestindex]) != SCIP_VARTYPE_CONTINUOUS
14453  && SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS))) )
14454  {
14455  /* best index becomes second-best*/
14456  if( bestindex != -1 )
14457  {
14458  /* second-best index must not have more than 1 uplock */
14459  if( bestuplocks > 1 )
14460  {
14461  bestindex = -1;
14462  break;
14463  }
14464  else
14465  {
14466  secondbestratio = bestratio;
14467  }
14468  }
14469  bestdownlocks = downlocks;
14470  bestuplocks = uplocks;
14471  bestratio = ratio;
14472  bestindex = v;
14473 
14474  /* if this variable is the best in the end, we cannot do reductions since it has a downlocks,
14475  * if it is not the best, it has too many uplocks -> not applicable
14476  */
14477  if( bestdownlocks > 0 && bestuplocks > 1 )
14478  {
14479  bestindex = -1;
14480  break;
14481  }
14482  }
14483  else
14484  {
14485  /* non-best index must not have more than 1 uplock */
14486  if( uplocks > 1 )
14487  {
14488  bestindex = -1;
14489  break;
14490  }
14491  /* update second-best ratio */
14492  if( ratio > secondbestratio )
14493  {
14494  secondbestratio = ratio;
14495  }
14496  }
14497  }
14498 
14499  /* check if we can apply single variable stuffing */
14500  if( bestindex != -1 && bestdownlocks == 0 )
14501  {
14502  SCIP_Bool tightened = FALSE;
14503  SCIP_Real bounddelta;
14504 
14505  var = vars[bestindex];
14506  obj = SCIPvarGetObj(var);
14507  val = factor * vals[bestindex];
14508  lb = SCIPvarGetLbGlobal(var);
14509  ub = SCIPvarGetUbGlobal(var);
14510  tryfixing = TRUE;
14511 
14512  if( val < 0 )
14513  {
14514  assert(!SCIPisNegative(scip, obj));
14515 
14516  /* the best variable is integer, and we need to overfulfill the constraint when using just the variable */
14517  if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisIntegral(scip, (maxactivity - rhs)/-val) )
14518  {
14519  SCIP_Real bestvarfloor = SCIPfloor(scip, (maxactivity - rhs)/-val);
14520  SCIP_Real activitydelta = (maxactivity - rhs) - (bestvarfloor * -val);
14521  assert(SCIPisPositive(scip, activitydelta));
14522 
14523  tryfixing = SCIPisLE(scip, obj, -activitydelta * secondbestratio);
14524 
14525  bounddelta = SCIPceil(scip, (maxactivity - rhs)/-val);
14526  assert(SCIPisPositive(scip, bounddelta));
14527  }
14528  else
14529  bounddelta = (maxactivity - rhs)/-val;
14530 
14531  tryfixing = tryfixing && SCIPisLE(scip, bounddelta, ub - lb);
14532 
14533  if( tryfixing )
14534  {
14535  assert(SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == 0);
14536 
14537  if( SCIPisEQ(scip, lb + bounddelta, ub) )
14538  {
14539  SCIPdebugMsg(scip, "fix var <%s> to %g\n", SCIPvarGetName(var), lb + bounddelta);
14540  SCIP_CALL( SCIPfixVar(scip, var, lb + bounddelta, cutoff, &tightened) );
14541  }
14542  else
14543  {
14544  SCIPdebugMsg(scip, "tighten the lower bound of <%s> from %g to %g (ub=%g)\n", SCIPvarGetName(var), lb, lb + bounddelta, ub);
14545  SCIP_CALL( SCIPtightenVarLb(scip, var, lb + bounddelta, FALSE, cutoff, &tightened) );
14546  }
14547  }
14548  }
14549  else
14550  {
14551  assert(!SCIPisPositive(scip, obj));
14552 
14553  /* the best variable is integer, and we need to overfulfill the constraint when using just the variable */
14554  if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisIntegral(scip, (maxactivity - rhs)/val))
14555  {
14556  SCIP_Real bestvarfloor = SCIPfloor(scip, (maxactivity - rhs)/val);
14557  SCIP_Real activitydelta = (maxactivity - rhs) - (bestvarfloor * val);
14558  assert(SCIPisPositive(scip, activitydelta));
14559 
14560  tryfixing = SCIPisLE(scip, -obj, activitydelta * secondbestratio);
14561 
14562  bounddelta = SCIPceil(scip, (maxactivity - rhs)/val);
14563  assert(SCIPisPositive(scip, bounddelta));
14564  }
14565  else
14566  bounddelta = (maxactivity - rhs)/val;
14567 
14568  tryfixing = tryfixing && SCIPisLE(scip, bounddelta, ub - lb);
14569 
14570  if( tryfixing )
14571  {
14572  assert(SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == 0);
14573 
14574  if( SCIPisEQ(scip, ub - bounddelta, lb) )
14575  {
14576  SCIPdebugMsg(scip, "fix var <%s> to %g\n", SCIPvarGetName(var), ub - bounddelta);
14577  SCIP_CALL( SCIPfixVar(scip, var, ub - bounddelta, cutoff, &tightened) );
14578  }
14579  else
14580  {
14581  SCIPdebugMsg(scip, "tighten the upper bound of <%s> from %g to %g (lb=%g)\n", SCIPvarGetName(var), ub, ub - bounddelta, lb);
14582  SCIP_CALL( SCIPtightenVarUb(scip, var, ub - bounddelta, FALSE, cutoff, &tightened) );
14583  }
14584  }
14585  }
14586 
14587  if( *cutoff )
14588  return SCIP_OKAY;
14589  if( tightened )
14590  {
14591  if( SCIPisEQ(scip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)) )
14592  ++(*nfixedvars);
14593  else
14594  ++(*nchgbds);
14595 
14596  SCIPdebugMsg(scip, "cons <%s>: %g <=\n", SCIPconsGetName(cons), factor > 0 ? consdata->lhs : -consdata->rhs);
14597  for( v = 0; v < nvars; ++v )
14598  {
14599  SCIPdebugMsg(scip, "%+g <%s>([%g,%g],%g,[%d,%d],%s)\n", factor * vals[v], SCIPvarGetName(vars[v]),
14600  SCIPvarGetLbGlobal(vars[v]), SCIPvarGetUbGlobal(vars[v]), SCIPvarGetObj(vars[v]),
14603  SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS ? "C" : "I");
14604  }
14605  SCIPdebugMsg(scip, "<= %g\n", factor > 0 ? consdata->rhs : -consdata->lhs);
14606 
14607  for( v = 0; v < nvars; ++v )
14608  {
14609  if( v == bestindex )
14610  continue;
14611 
14612  if( factor * vals[v] < 0 )
14613  {
14614  assert(SCIPvarGetNLocksDownType(vars[v], SCIP_LOCKTYPE_MODEL) == 1);
14615  SCIPdebugMsg(scip, "fix <%s> to its lower bound (%g)\n",
14616  SCIPvarGetName(vars[v]), SCIPvarGetLbGlobal(vars[v]));
14617  SCIP_CALL( SCIPfixVar(scip, vars[v], SCIPvarGetLbGlobal(vars[v]), cutoff, &tightened) );
14618  }
14619  else
14620  {
14621  assert(SCIPvarGetNLocksUpType(vars[v], SCIP_LOCKTYPE_MODEL) == 1);
14622  SCIPdebugMsg(scip, "fix <%s> to its upper bound (%g)\n",
14623  SCIPvarGetName(vars[v]), SCIPvarGetUbGlobal(vars[v]));
14624  SCIP_CALL( SCIPfixVar(scip, vars[v], SCIPvarGetUbGlobal(vars[v]), cutoff, &tightened) );
14625  }
14626 
14627  if( *cutoff )
14628  return SCIP_OKAY;
14629  if( tightened )
14630  ++(*nfixedvars);
14631  }
14632  SCIPdebug( SCIPdebugMsg(scip, "### new stuffing fixed %d vars, tightened %d bounds\n", *nfixedvars - oldnfixedvars, *nchgbds - oldnchgbds); )
14633  }
14634  }
14635  }
14636 
14637  return SCIP_OKAY;
14638 }
14639 
14640 /** applies full dual presolving on variables that only appear in linear constraints */
14641 static
14643  SCIP* scip, /**< SCIP data structure */
14644  SCIP_CONS** conss, /**< constraint set */
14645  int nconss, /**< number of constraints */
14646  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
14647  int* nchgbds /**< pointer to count the number of bound changes */
14648  )
14649 {
14650  SCIP_Real* redlb;
14651  SCIP_Real* redub;
14652  int* nlocksdown;
14653  int* nlocksup;
14654  SCIP_Bool* isimplint;
14655  SCIP_VAR** origvars;
14656  SCIP_VAR** vars;
14657  SCIP_VAR** conscontvars;
14658  int nvars;
14659  int nbinvars;
14660  int nintvars;
14661  int ncontvars;
14662  int v;
14663  int c;
14664 
14665  /* we calculate redundancy bounds with the following meaning:
14666  * redlb[v] == k : if x_v >= k, we can always round x_v down to x_v == k without violating any constraint
14667  * redub[v] == k : if x_v <= k, we can always round x_v up to x_v == k without violating any constraint
14668  * then:
14669  * c_v >= 0 : x_v <= redlb[v] is feasible due to optimality
14670  * c_v <= 0 : x_v >= redub[v] is feasible due to optimality
14671  */
14672 
14673  /* Additionally, we detect continuous variables that are implicitly integral.
14674  * A continuous variable j is implicit integral if it only has only +/-1 coefficients,
14675  * and all constraints (including the bounds as trivial constraints) in which:
14676  * c_j > 0: the variable is down-locked,
14677  * c_j < 0: the variable is up-locked,
14678  * c_j = 0: the variable appears
14679  * have, apart from j, only integer variables with integral coefficients and integral sides.
14680  * This is because then, the value of the variable is either determined by one of its bounds or
14681  * by one of these constraints, and in all cases, the value of the variable is integral.
14682  */
14683 
14684  assert(scip != NULL);
14685  assert(nconss == 0 || conss != NULL);
14686  assert(nchgbds != NULL);
14687  assert(!SCIPinProbing(scip));
14688 
14689  /* get active variables */
14690  nvars = SCIPgetNVars(scip);
14691  origvars = SCIPgetVars(scip);
14692 
14693  /* if the problem is a pure binary program, nothing can be achieved by full dual presolve */
14694  nbinvars = SCIPgetNBinVars(scip);
14695  if( nbinvars == nvars )
14696  return SCIP_OKAY;
14697 
14698  /* get number of continuous variables */
14699  ncontvars = SCIPgetNContVars(scip);
14700  nintvars = nvars - ncontvars;
14701 
14702  /* copy the variable array since this array might change during the curse of this algorithm */
14703  nvars = nvars - nbinvars;
14704  SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, &(origvars[nbinvars]), nvars) );
14705 
14706  /* allocate temporary memory */
14707  SCIP_CALL( SCIPallocBufferArray(scip, &redlb, nvars) );
14708  SCIP_CALL( SCIPallocBufferArray(scip, &redub, nvars) );
14709  SCIP_CALL( SCIPallocBufferArray(scip, &nlocksdown, nvars) );
14710  SCIP_CALL( SCIPallocBufferArray(scip, &nlocksup, nvars) );
14711  SCIP_CALL( SCIPallocBufferArray(scip, &isimplint, ncontvars) );
14712  SCIP_CALL( SCIPallocBufferArray(scip, &conscontvars, ncontvars) );
14713 
14714  /* initialize redundancy bounds */
14715  for( v = 0; v < nvars; ++v )
14716  {
14717  assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_BINARY);
14718  redlb[v] = SCIPvarGetLbGlobal(vars[v]);
14719  redub[v] = SCIPvarGetUbGlobal(vars[v]);
14720  }
14721  BMSclearMemoryArray(nlocksdown, nvars);
14722  BMSclearMemoryArray(nlocksup, nvars);
14723 
14724  /* Initialize isimplint array: variable may be implied integer if rounded to their best bound they are integral.
14725  * We better not use SCIPisFeasIntegral() in these checks.
14726  */
14727  for( v = 0; v < ncontvars; v++ )
14728  {
14729  SCIP_VAR* var;
14730  SCIP_Real obj;
14731  SCIP_Real lb;
14732  SCIP_Real ub;
14733 
14734  var = vars[v + nintvars - nbinvars];
14735  lb = SCIPvarGetLbGlobal(var);
14736  ub = SCIPvarGetUbGlobal(var);
14737 
14738  obj = SCIPvarGetObj(var);
14739  if( SCIPisZero(scip, obj) )
14740  isimplint[v] = (SCIPisInfinity(scip, -lb) || SCIPisIntegral(scip, lb)) && (SCIPisInfinity(scip, ub) || SCIPisIntegral(scip, ub));
14741  else
14742  {
14743  if( SCIPisPositive(scip, obj) )
14744  isimplint[v] = (SCIPisInfinity(scip, -lb) || SCIPisIntegral(scip, lb));
14745  else
14746  {
14747  assert(SCIPisNegative(scip, obj));
14748  isimplint[v] = (SCIPisInfinity(scip, ub) || SCIPisIntegral(scip, ub));
14749  }
14750  }
14751  }
14752 
14753  /* scan all constraints */
14754  for( c = 0; c < nconss; ++c )
14755  {
14756  /* we only need to consider constraints that have been locked (i.e., checked constraints or constraints that are
14757  * part of checked disjunctions)
14758  */
14759  if( SCIPconsIsLocked(conss[c]) )
14760  {
14761  SCIP_CONSDATA* consdata;
14762  SCIP_Bool lhsexists;
14763  SCIP_Bool rhsexists;
14764  SCIP_Bool hasimpliedpotential;
14765  SCIP_Bool integralcoefs;
14766  int nlockspos;
14767  int contvarpos;
14768  int nconscontvars;
14769  int i;
14770 
14771  consdata = SCIPconsGetData(conss[c]);
14772  assert(consdata != NULL);
14773 
14774  /* get number of times the constraint was locked */
14775  nlockspos = SCIPconsGetNLocksPos(conss[c]);
14776 
14777  /* we do not want to include constraints with locked negation (this would be too weird) */
14778  if( SCIPconsGetNLocksNeg(conss[c]) > 0 )
14779  {
14780  /* mark all continuous variables as not being implicit integral */
14781  for( i = 0; i < consdata->nvars; ++i )
14782  {
14783  SCIP_VAR* var;
14784 
14785  var = consdata->vars[i];
14787  {
14788  int contv;
14789  contv = SCIPvarGetProbindex(var) - nintvars;
14790  assert(0 <= contv && contv < ncontvars); /* variable should be active due to applyFixings() */
14791  isimplint[contv] = FALSE;
14792  }
14793  }
14794  continue;
14795  }
14796 
14797  /* check for existing sides */
14798  lhsexists = !SCIPisInfinity(scip, -consdata->lhs);
14799  rhsexists = !SCIPisInfinity(scip, consdata->rhs);
14800 
14801  /* count locks and update redundancy bounds */
14802  contvarpos = -1;
14803  nconscontvars = 0;
14804  hasimpliedpotential = FALSE;
14805  integralcoefs = !SCIPconsIsModifiable(conss[c]);
14806 
14807  for( i = 0; i < consdata->nvars; ++i )
14808  {
14809  SCIP_VAR* var;
14810  SCIP_Real val;
14811  SCIP_Real minresactivity;
14812  SCIP_Real maxresactivity;
14813  SCIP_Real newredlb;
14814  SCIP_Real newredub;
14815  SCIP_Bool minisrelax;
14816  SCIP_Bool maxisrelax;
14817  SCIP_Bool isminsettoinfinity;
14818  SCIP_Bool ismaxsettoinfinity;
14819  int arrayindex;
14820 
14821  var = consdata->vars[i];
14822  val = consdata->vals[i];
14823 
14824  /* check if still all integer variables have integral coefficients */
14825  if( SCIPvarIsIntegral(var) )
14826  integralcoefs = integralcoefs && SCIPisIntegral(scip, val);
14827 
14828  /* we do not need to process binary variables */
14829  if( SCIPvarIsBinary(var) )
14830  continue;
14831 
14832  if( SCIPconsIsModifiable(conss[c]) )
14833  {
14834  minresactivity = -SCIPinfinity(scip);
14835  maxresactivity = SCIPinfinity(scip);
14836  isminsettoinfinity = TRUE;
14837  ismaxsettoinfinity = TRUE;
14838  }
14839  else
14840  {
14841  /* calculate residual activity bounds if variable would be fixed to zero */
14842  consdataGetGlbActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
14843  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
14844 
14845  /* We called consdataGetGlbActivityResiduals() saying that we do not need a good relaxation,
14846  * so whenever we have a relaxed activity, it should be relaxed to +/- infinity.
14847  * This is needed, because we do not want to rely on relaxed finite resactivities.
14848  */
14849  assert((!minisrelax || isminsettoinfinity) && (!maxisrelax || ismaxsettoinfinity));
14850 
14851  /* check minresactivity for reliability */
14852  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastglbminactivity) )
14853  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, TRUE);
14854 
14855  /* check maxresactivity for reliability */
14856  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastglbmaxactivity) )
14857  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, TRUE);
14858  }
14859 
14860  arrayindex = SCIPvarGetProbindex(var) - nbinvars;
14861 
14862  assert(0 <= arrayindex && arrayindex < nvars); /* variable should be active due to applyFixings() */
14863 
14864  newredlb = redlb[arrayindex];
14865  newredub = redub[arrayindex];
14866  if( val > 0.0 )
14867  {
14868  if( lhsexists )
14869  {
14870  /* lhs <= d*x + a*y, d > 0 -> redundant in y if x >= (lhs - min{a*y})/d */
14871  nlocksdown[arrayindex] += nlockspos;
14872  newredlb = (isminsettoinfinity ? SCIPinfinity(scip) : (consdata->lhs - minresactivity)/val);
14873  }
14874  if( rhsexists )
14875  {
14876  /* d*x + a*y <= rhs, d > 0 -> redundant in y if x <= (rhs - max{a*y})/d */
14877  nlocksup[arrayindex] += nlockspos;
14878  newredub = (ismaxsettoinfinity ? -SCIPinfinity(scip) : (consdata->rhs - maxresactivity)/val);
14879  }
14880  }
14881  else
14882  {
14883  if( lhsexists )
14884  {
14885  /* lhs <= d*x + a*y, d < 0 -> redundant in y if x <= (lhs - min{a*y})/d */
14886  nlocksup[arrayindex] += nlockspos;
14887  newredub = (isminsettoinfinity ? -SCIPinfinity(scip) : (consdata->lhs - minresactivity)/val);
14888  }
14889  if( rhsexists )
14890  {
14891  /* d*x + a*y <= rhs, d < 0 -> redundant in y if x >= (rhs - max{a*y})/d */
14892  nlocksdown[arrayindex] += nlockspos;
14893  newredlb = (ismaxsettoinfinity ? SCIPinfinity(scip) : (consdata->rhs - maxresactivity)/val);
14894  }
14895  }
14896 
14897  /* if the variable is integer, we have to round the value to the next integral value */
14898  if( SCIPvarIsIntegral(var) )
14899  {
14900  if( !SCIPisInfinity(scip, newredlb) )
14901  newredlb = SCIPceil(scip, newredlb);
14902  if( !SCIPisInfinity(scip, -newredub) )
14903  newredub = SCIPfloor(scip, newredub);
14904  }
14905 
14906  /* update redundancy bounds */
14907  redlb[arrayindex] = MAX(redlb[arrayindex], newredlb);
14908  redub[arrayindex] = MIN(redub[arrayindex], newredub);
14909 
14910  /* collect the continuous variables of the constraint */
14912  {
14913  int contv;
14914 
14915  assert(nconscontvars < ncontvars);
14916  contvarpos = i;
14917  conscontvars[nconscontvars] = var;
14918  nconscontvars++;
14919 
14920  contv = SCIPvarGetProbindex(var) - nintvars;
14921  assert(0 <= contv && contv < ncontvars);
14922  hasimpliedpotential = hasimpliedpotential || isimplint[contv];
14923  }
14924  }
14925 
14926  /* update implied integer status of continuous variables */
14927  if( hasimpliedpotential )
14928  {
14929  if( nconscontvars > 1 || !integralcoefs )
14930  {
14931  /* there is more than one continuous variable or the integer variables have fractional coefficients:
14932  * none of the continuous variables is implied integer
14933  */
14934  for( i = 0; i < nconscontvars; i++ )
14935  {
14936  int contv;
14937  contv = SCIPvarGetProbindex(conscontvars[i]) - nintvars;
14938  assert(0 <= contv && contv < ncontvars);
14939  isimplint[contv] = FALSE;
14940  }
14941  }
14942  else
14943  {
14944  SCIP_VAR* var;
14945  SCIP_Real val;
14946  SCIP_Real absval;
14947  int contv;
14948 
14949  /* there is exactly one continuous variable and the integer variables have integral coefficients:
14950  * this is the interesting case, and we have to check whether the coefficient is +/-1 and the corresponding
14951  * side(s) of the constraint is integral
14952  */
14953  assert(nconscontvars == 1);
14954  assert(0 <= contvarpos && contvarpos < consdata->nvars);
14955  var = consdata->vars[contvarpos];
14956  val = consdata->vals[contvarpos];
14957  contv = SCIPvarGetProbindex(var) - nintvars;
14958  assert(0 <= contv && contv < ncontvars);
14959  assert(isimplint[contv]);
14960 
14961  absval = REALABS(val);
14962  if( !SCIPisEQ(scip, absval, 1.0) )
14963  isimplint[contv] = FALSE;
14964  else
14965  {
14966  SCIP_Real obj;
14967 
14968  obj = SCIPvarGetObj(var);
14969  if( obj * val >= 0.0 && lhsexists )
14970  {
14971  /* the variable may be blocked by the constraint's left hand side */
14972  isimplint[contv] = isimplint[contv] && SCIPisIntegral(scip, consdata->lhs);
14973  }
14974  if( obj * val <= 0.0 && rhsexists )
14975  {
14976  /* the variable may be blocked by the constraint's left hand side */
14977  isimplint[contv] = isimplint[contv] && SCIPisIntegral(scip, consdata->rhs);
14978  }
14979  }
14980  }
14981  }
14982  }
14983  }
14984 
14985  /* check if any bounds can be tightened due to optimality */
14986  for( v = 0; v < nvars; ++v )
14987  {
14988  SCIP_VAR* var;
14989  SCIP_Real obj;
14990  SCIP_Bool infeasible;
14991  SCIP_Bool tightened;
14992 
14993  assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_BINARY);
14994  assert(SCIPvarGetNLocksDownType(vars[v], SCIP_LOCKTYPE_MODEL) >= nlocksdown[v]);
14995  assert(SCIPvarGetNLocksUpType(vars[v], SCIP_LOCKTYPE_MODEL) >= nlocksup[v]);
14996 
14997  var = vars[v];
14998  obj = SCIPvarGetObj(var);
14999  if( obj >= 0.0 )
15000  {
15001  /* making the variable as small as possible does not increase the objective:
15002  * check if all down locks of the variables are due to linear constraints;
15003  * if largest bound to make constraints redundant is -infinity, we better do nothing for numerical reasons
15004  */
15005  if( SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == nlocksdown[v]
15006  && !SCIPisInfinity(scip, -redlb[v])
15007  && redlb[v] < SCIPvarGetUbGlobal(var) )
15008  {
15009  SCIP_Real ub;
15010 
15011  /* if x_v >= redlb[v], we can always round x_v down to x_v == redlb[v] without violating any constraint
15012  * -> tighten upper bound to x_v <= redlb[v]
15013  */
15014  SCIPdebugMsg(scip, "variable <%s> only locked down in linear constraints: dual presolve <%s>[%.15g,%.15g] <= %.15g\n",
15016  redlb[v]);
15017  SCIP_CALL( SCIPtightenVarUb(scip, var, redlb[v], FALSE, &infeasible, &tightened) );
15018  assert(!infeasible);
15019 
15020  ub = SCIPvarGetUbGlobal(var);
15021  redub[v] = MIN(redub[v], ub);
15022  if( tightened )
15023  (*nchgbds)++;
15024  }
15025  }
15026  if( obj <= 0.0 )
15027  {
15028  /* making the variable as large as possible does not increase the objective:
15029  * check if all up locks of the variables are due to linear constraints;
15030  * if smallest bound to make constraints redundant is +infinity, we better do nothing for numerical reasons
15031  */
15032  if( SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == nlocksup[v]
15033  && !SCIPisInfinity(scip, redub[v])
15034  && redub[v] > SCIPvarGetLbGlobal(var) )
15035  {
15036  SCIP_Real lb;
15037 
15038  /* if x_v <= redub[v], we can always round x_v up to x_v == redub[v] without violating any constraint
15039  * -> tighten lower bound to x_v >= redub[v]
15040  */
15041  SCIPdebugMsg(scip, "variable <%s> only locked up in linear constraints: dual presolve <%s>[%.15g,%.15g] >= %.15g\n",
15043  redub[v]);
15044  SCIP_CALL( SCIPtightenVarLb(scip, var, redub[v], FALSE, &infeasible, &tightened) );
15045  assert(!infeasible);
15046 
15047  lb = SCIPvarGetLbGlobal(var);
15048  redlb[v] = MAX(redlb[v], lb);
15049  if( tightened )
15050  (*nchgbds)++;
15051  }
15052  }
15053  }
15054 
15055  /* upgrade continuous variables to implied integers */
15056  for( v = nintvars - nbinvars; v < nvars; ++v )
15057  {
15058  SCIP_VAR* var;
15059  SCIP_Bool infeasible;
15060 
15061  var = vars[v];
15062  assert(var != NULL);
15063 
15064  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
15065  assert(SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) >= nlocksdown[v]);
15066  assert(SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) >= nlocksup[v]);
15067  assert(0 <= v - nintvars + nbinvars && v - nintvars + nbinvars < ncontvars);
15068 
15069  /* we can only conclude implied integrality if the variable appears in no other constraint */
15070  if( isimplint[v - nintvars + nbinvars]
15071  && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == nlocksdown[v]
15072  && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == nlocksup[v] )
15073  {
15074  /* since we locally copied the variable array we can change the variable type immediately */
15075  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
15076 
15077  if( infeasible )
15078  {
15079  SCIPdebugMsg(scip, "infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
15080  *cutoff = TRUE;
15081 
15082  break;
15083  }
15084 
15085  SCIPdebugMsg(scip, "dual presolve: converting continuous variable <%s>[%g,%g] to implicit integer\n",
15087  }
15088  }
15089 
15090  /* free temporary memory */
15091  SCIPfreeBufferArray(scip, &conscontvars);
15092  SCIPfreeBufferArray(scip, &isimplint);
15093  SCIPfreeBufferArray(scip, &nlocksup);
15094  SCIPfreeBufferArray(scip, &nlocksdown);
15095  SCIPfreeBufferArray(scip, &redub);
15096  SCIPfreeBufferArray(scip, &redlb);
15097 
15098  SCIPfreeBufferArray(scip, &vars);
15099 
15100  return SCIP_OKAY;
15101 }
15102 
15103 /** helper function to enforce constraints */
15104 static
15106  SCIP* scip, /**< SCIP data structure */
15107  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
15108  SCIP_CONS** conss, /**< constraints to process */
15109  int nconss, /**< number of constraints */
15110  int nusefulconss, /**< number of useful (non-obsolete) constraints to process */
15111  SCIP_SOL* sol, /**< solution to enforce (NULL for the LP solution) */
15112  SCIP_RESULT* result /**< pointer to store the result of the enforcing call */
15113  )
15114 {
15115  SCIP_CONSHDLRDATA* conshdlrdata;
15116  SCIP_Bool checkrelmaxabs;
15117  SCIP_Bool violated;
15118  SCIP_Bool cutoff = FALSE;
15119  int c;
15120 
15121  assert(scip != NULL);
15122  assert(conshdlr != NULL);
15123  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15124  assert(result != NULL);
15125 
15126  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15127  assert(conshdlrdata != NULL);
15128 
15129  checkrelmaxabs = conshdlrdata->checkrelmaxabs;
15130 
15131  SCIPdebugMsg(scip, "Enforcement method of linear constraints for %s solution\n", sol == NULL ? "LP" : "relaxation");
15132 
15133  /* check for violated constraints
15134  * LP is processed at current node -> we can add violated linear constraints to the SCIP_LP
15135  */
15136  *result = SCIP_FEASIBLE;
15137 
15138  /* check all useful linear constraints for feasibility */
15139  for( c = 0; c < nusefulconss; ++c )
15140  {
15141  SCIP_CALL( checkCons(scip, conss[c], sol, FALSE, checkrelmaxabs, &violated) );
15142 
15143  if( violated )
15144  {
15145  /* insert LP row as cut */
15146  SCIP_CALL( addRelaxation(scip, conss[c], &cutoff) );
15147  if ( cutoff )
15148  *result = SCIP_CUTOFF;
15149  else
15150  *result = SCIP_SEPARATED;
15151  }
15152  }
15153 
15154  /* check all obsolete linear constraints for feasibility */
15155  for( c = nusefulconss; c < nconss && *result == SCIP_FEASIBLE; ++c )
15156  {
15157  SCIP_CALL( checkCons(scip, conss[c], sol, FALSE, checkrelmaxabs, &violated) );
15158 
15159  if( violated )
15160  {
15161  /* insert LP row as cut */
15162  SCIP_CALL( addRelaxation(scip, conss[c], &cutoff) );
15163  if ( cutoff )
15164  *result = SCIP_CUTOFF;
15165  else
15166  *result = SCIP_SEPARATED;
15167  }
15168  }
15169 
15170  SCIPdebugMsg(scip, "-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
15171 
15172  return SCIP_OKAY;
15173 }
15174 
15175 /*
15176  * Callback methods of constraint handler
15177  */
15178 
15179 /** copy method for constraint handler plugins (called when SCIP copies plugins) */
15180 static
15181 SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinear)
15182 { /*lint --e{715}*/
15183  assert(scip != NULL);
15184  assert(conshdlr != NULL);
15185  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15186 
15187  /* call inclusion method of constraint handler */
15189 
15190  *valid = TRUE;
15191 
15192  return SCIP_OKAY;
15193 }
15194 
15195 /** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
15196 static
15197 SCIP_DECL_CONSFREE(consFreeLinear)
15198 { /*lint --e{715}*/
15199  SCIP_CONSHDLRDATA* conshdlrdata;
15201  assert(scip != NULL);
15202  assert(conshdlr != NULL);
15203  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15204 
15205  /* free constraint handler data */
15206  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15207  assert(conshdlrdata != NULL);
15208 
15209  conshdlrdataFree(scip, &conshdlrdata);
15210 
15211  SCIPconshdlrSetData(conshdlr, NULL);
15212 
15213  return SCIP_OKAY;
15214 }
15215 
15217 /** initialization method of constraint handler (called after problem was transformed) */
15218 static
15219 SCIP_DECL_CONSINIT(consInitLinear)
15220 {
15221  SCIP_CONSHDLRDATA* conshdlrdata;
15222  int c;
15223 
15224  assert(scip != NULL);
15225 
15226  /* check for event handler */
15227  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15228  assert(conshdlrdata != NULL);
15229  assert(conshdlrdata->eventhdlr != NULL);
15230  assert(nconss == 0 || conss != NULL);
15231 
15232  conshdlrdata->naddconss = 0;
15233 
15234  /* catch events for the constraints */
15235  for( c = 0; c < nconss; ++c )
15236  {
15237  /* catch all events */
15238  SCIP_CALL( consCatchAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
15239  }
15240 
15241  return SCIP_OKAY;
15242 }
15243 
15244 
15245 /** deinitialization method of constraint handler (called before transformed problem is freed) */
15246 static
15247 SCIP_DECL_CONSEXIT(consExitLinear)
15248 {
15249  SCIP_CONSHDLRDATA* conshdlrdata;
15250  int c;
15251 
15252  assert(scip != NULL);
15253 
15254  /* check for event handler */
15255  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15256  assert(conshdlrdata != NULL);
15257  assert(conshdlrdata->eventhdlr != NULL);
15258 
15259  /* drop events for the constraints */
15260  for( c = nconss - 1; c >= 0; --c )
15261  {
15262  SCIP_CONSDATA* consdata;
15263 
15264  consdata = SCIPconsGetData(conss[c]);
15265  assert(consdata != NULL);
15267  if( consdata->eventdata != NULL )
15268  {
15269  /* drop all events */
15270  SCIP_CALL( consDropAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
15271  assert(consdata->eventdata == NULL);
15272  }
15273  }
15274 
15275  return SCIP_OKAY;
15276 }
15277 
15278 /** is constraint ranged row, i.e., -inf < lhs < rhs < inf? */
15279 static
15281  SCIP* scip, /**< SCIP data structure */
15282  SCIP_Real lhs, /**< left hand side */
15283  SCIP_Real rhs /**< right hand side */
15284  )
15285 {
15286  assert(scip != NULL);
15287 
15288  return !(SCIPisEQ(scip, lhs, rhs) || SCIPisInfinity(scip, -lhs) || SCIPisInfinity(scip, rhs) );
15289 }
15290 
15291 /** is constraint ranged row, i.e., -inf < lhs < rhs < inf? */
15292 static
15294  SCIP* scip, /**< SCIP data structure */
15295  SCIP_Real x /**< value */
15296  )
15297 {
15298  assert(scip != NULL);
15300  return (!SCIPisInfinity(scip, x) && !SCIPisNegative(scip, x) && SCIPisIntegral(scip, x));
15301 }
15302 
15303 /** performs linear constraint type classification as used for MIPLIB
15304  *
15305  * iterates through all linear constraints and stores relevant statistics in the linear constraint statistics \p linconsstats.
15306  *
15307  * @note only constraints are iterated that belong to the linear constraint handler. If the problem has been presolved already,
15308  * constraints that were upgraded to more special types such as, e.g., varbound constraints, will not be shown correctly anymore.
15309  * Similarly, if specialized constraints were created through the API, these are currently not present.
15310  */
15312  SCIP* scip, /**< SCIP data structure */
15313  SCIP_LINCONSSTATS* linconsstats /**< linear constraint type classification */
15314  )
15315 {
15316  int c;
15317  SCIP_CONSHDLR* conshdlr;
15318  SCIP_CONS** conss;
15319  int nconss;
15320 
15321  assert(scip != NULL);
15322  assert(linconsstats != NULL);
15323  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
15324  assert(conshdlr != NULL);
15325 
15326  if( SCIPgetStage(scip) == SCIP_STAGE_PROBLEM )
15327  {
15328  conss = SCIPgetConss(scip);
15329  nconss = SCIPgetNConss(scip);
15330  }
15331  else
15332  {
15333  conss = SCIPconshdlrGetConss(conshdlr);
15334  nconss = SCIPconshdlrGetNConss(conshdlr);
15335  }
15336 
15337  /* reset linear constraint type classification */
15338  SCIPlinConsStatsReset(linconsstats);
15339 
15340  /* loop through all constraints */
15341  for( c = 0; c < nconss; c++ )
15342  {
15343  SCIP_CONS* cons;
15344  SCIP_CONSDATA* consdata;
15345  SCIP_Real lhs;
15346  SCIP_Real rhs;
15347  int i;
15348 
15349  /* get constraint */
15350  cons = conss[c];
15351  assert(cons != NULL);
15352 
15353  /* skip constraints that are not handled by the constraint handler */
15354  if( SCIPconsGetHdlr(cons) != conshdlr )
15355  continue;
15356 
15357  /* get constraint data */
15358  consdata = SCIPconsGetData(cons);
15359  assert(consdata != NULL);
15360  rhs = consdata->rhs;
15361  lhs = consdata->lhs;
15362 
15363  /* merge multiples and delete variables with zero coefficient */
15364  SCIP_CALL( mergeMultiples(scip, cons) );
15365  for( i = 0; i < consdata->nvars; i++ )
15366  {
15367  assert(!SCIPisZero(scip, consdata->vals[i]));
15368  }
15369 
15370  /* is constraint of type SCIP_CONSTYPE_EMPTY? */
15371  if( consdata->nvars == 0 )
15372  {
15373  SCIPdebugMsg(scip, "classified as EMPTY: ");
15374  SCIPdebugPrintCons(scip, cons, NULL);
15376 
15377  continue;
15378  }
15379 
15380  /* is constraint of type SCIP_CONSTYPE_FREE? */
15381  if( SCIPisInfinity(scip, rhs) && SCIPisInfinity(scip, -lhs) )
15382  {
15383  SCIPdebugMsg(scip, "classified as FREE: ");
15384  SCIPdebugPrintCons(scip, cons, NULL);
15386 
15387  continue;
15388  }
15389 
15390  /* is constraint of type SCIP_CONSTYPE_SINGLETON? */
15391  if( consdata->nvars == 1 )
15392  {
15393  SCIPdebugMsg(scip, "classified as SINGLETON: ");
15394  SCIPdebugPrintCons(scip, cons, NULL);
15395  SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_SINGLETON, isRangedRow(scip, lhs, rhs) ? 2 : 1);
15396 
15397  continue;
15398  }
15399 
15400  /* is constraint of type SCIP_CONSTYPE_AGGREGATION? */
15401  if( consdata->nvars == 2 && SCIPisEQ(scip, lhs, rhs) )
15402  {
15403  SCIPdebugMsg(scip, "classified as AGGREGATION: ");
15404  SCIPdebugPrintCons(scip, cons, NULL);
15406 
15407  continue;
15408  }
15409 
15410  /* is constraint of type SCIP_CONSTYPE_{VARBOUND,PRECEDENCE}? */
15411  if( consdata->nvars == 2 )
15412  {
15413  SCIP_LINCONSTYPE constype;
15414 
15415  /* precedence constraints have the same coefficient, but with opposite sign for the same variable type */
15416  if( SCIPisEQ(scip, consdata->vals[0], -consdata->vals[1])
15417  && SCIPvarGetType(consdata->vars[0]) == SCIPvarGetType(consdata->vars[1]))
15418  {
15419  constype = SCIP_LINCONSTYPE_PRECEDENCE;
15420  SCIPdebugMsg(scip, "classified as PRECEDENCE: ");
15421  }
15422  else
15423  {
15424  constype = SCIP_LINCONSTYPE_VARBOUND;
15425  SCIPdebugMsg(scip, "classified as VARBOUND: ");
15426  }
15427  SCIPdebugPrintCons(scip, cons, NULL);
15428 
15429  SCIPlinConsStatsIncTypeCount(linconsstats, constype, isRangedRow(scip, lhs, rhs) ? 2 : 1);
15430 
15431  continue;
15432  }
15433 
15434  /* is constraint of type SCIP_CONSTYPE_{SETPARTITION, SETPACKING, SETCOVERING, CARDINALITY, INVKNAPSACK}? */
15435  {
15436  SCIP_Real scale;
15437  SCIP_Real b;
15438  SCIP_Bool unmatched;
15439  int nnegbinvars;
15440 
15441  unmatched = FALSE;
15442  nnegbinvars = 0;
15443 
15444  scale = REALABS(consdata->vals[0]);
15445 
15446  /* scan through variables and detect if all variables are binary and have a coefficient +/-1 */
15447  for( i = 0; i < consdata->nvars && !unmatched; i++ )
15448  {
15449  unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
15450  unmatched = unmatched || SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0);
15451  unmatched = unmatched || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0);
15452  unmatched = unmatched || !SCIPisEQ(scip, REALABS(consdata->vals[i]), scale);
15453 
15454  if( consdata->vals[i] < 0.0 )
15455  nnegbinvars++;
15456  }
15457 
15458  if( !unmatched )
15459  {
15460  if( SCIPisEQ(scip, lhs, rhs) )
15461  {
15462  b = rhs/scale + nnegbinvars;
15463  if( SCIPisEQ(scip, 1.0, b) )
15464  {
15465  SCIPdebugMsg(scip, "classified as SETPARTITION: ");
15466  SCIPdebugPrintCons(scip, cons, NULL);
15468 
15469  continue;
15470  }
15471  else if( SCIPisIntegral(scip, b) && !SCIPisNegative(scip, b) )
15472  {
15473  SCIPdebugMsg(scip, "classified as CARDINALITY: ");
15474  SCIPdebugPrintCons(scip, cons, NULL);
15476 
15477  continue;
15478  }
15479  }
15480 
15481  /* compute right hand side divided by scale */
15482  if( !SCIPisInfinity(scip, rhs) )
15483  b = rhs/scale + nnegbinvars;
15484  else
15485  b = SCIPinfinity(scip);
15486 
15487  if( SCIPisEQ(scip, 1.0, b) )
15488  {
15489  SCIPdebugMsg(scip, "classified as SETPACKING: ");
15490  SCIPdebugPrintCons(scip, cons, NULL);
15492 
15493  /* relax right hand side to prevent further classifications */
15494  rhs = SCIPinfinity(scip);
15495  }
15496  else if( !SCIPisInfinity(scip, b) && SCIPisIntegral(scip, b) && !SCIPisNegative(scip, b) )
15497  {
15498  SCIPdebugMsg(scip, "classified as INVKNAPSACK: ");
15499  SCIPdebugPrintCons(scip, cons, NULL);
15500 
15502 
15503  /* relax right hand side to prevent further classifications */
15504  rhs = SCIPinfinity(scip);
15505  }
15506 
15507  if( !SCIPisInfinity(scip, lhs) )
15508  b = lhs/scale + nnegbinvars;
15509  else
15510  b = SCIPinfinity(scip);
15511 
15512  if( SCIPisEQ(scip, 1.0, b) )
15513  {
15514  SCIPdebugMsg(scip, "classified as SETCOVERING: ");
15515  SCIPdebugPrintCons(scip, cons, NULL);
15517 
15518  /* relax left hand side to prevent further classifications */
15519  lhs = -SCIPinfinity(scip);
15520  }
15521 
15522  /* if both sides are infinite at this point, no further classification is necessary for this constraint */
15523  if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
15524  continue;
15525  }
15526  }
15527 
15528  /* is constraint of type SCIP_CONSTYPE_{EQKNAPSACK, BINPACKING, KNAPSACK}? */
15529  /* @todo If coefficients or rhs are not integral, we currently do not check
15530  * if the constraint could be scaled (finitely), such that they are.
15531  */
15532  {
15533  SCIP_Real b;
15534  SCIP_Bool unmatched;
15535 
15536  b = rhs;
15537  unmatched = FALSE;
15538  for( i = 0; i < consdata->nvars && !unmatched; i++ )
15539  {
15540  unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
15541  unmatched = unmatched || SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0);
15542  unmatched = unmatched || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0);
15543  unmatched = unmatched || !SCIPisIntegral(scip, consdata->vals[i]);
15544 
15545  if( SCIPisNegative(scip, consdata->vals[i]) )
15546  b -= consdata->vals[i];
15547  }
15548  unmatched = unmatched || !isFiniteNonnegativeIntegral(scip, b);
15549 
15550  if( !unmatched )
15551  {
15552  if( SCIPisEQ(scip, lhs, rhs) )
15553  {
15554  SCIPdebugMsg(scip, "classified as EQKNAPSACK: ");
15555  SCIPdebugPrintCons(scip, cons, NULL);
15556 
15558 
15559  continue;
15560  }
15561  else
15562  {
15563  SCIP_Bool matched;
15564 
15565  matched = FALSE;
15566  for( i = 0; i < consdata->nvars && !matched; i++ )
15567  {
15568  matched = matched || SCIPisEQ(scip, b, REALABS(consdata->vals[i]));
15569  }
15570 
15571  SCIPdebugMsg(scip, "classified as %s: ", matched ? "BINPACKING" : "KNAPSACK");
15572  SCIPdebugPrintCons(scip, cons, NULL);
15574  }
15575 
15576  /* check if finite left hand side allows for a second classification, relax already used right hand side */
15577  if( SCIPisInfinity(scip, -lhs) )
15578  continue;
15579  else
15580  rhs = SCIPinfinity(scip);
15581  }
15582  }
15583 
15584  /* is constraint of type SCIP_CONSTYPE_{INTKNAPSACK}? */
15585  {
15586  SCIP_Real b;
15587  SCIP_Bool unmatched;
15588 
15589  unmatched = FALSE;
15590 
15591  b = rhs;
15592  unmatched = unmatched || !isFiniteNonnegativeIntegral(scip, b);
15593 
15594  for( i = 0; i < consdata->nvars && !unmatched; i++ )
15595  {
15596  unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
15597  unmatched = unmatched || SCIPisNegative(scip, SCIPvarGetLbGlobal(consdata->vars[i]));
15598  unmatched = unmatched || !SCIPisIntegral(scip, consdata->vals[i]);
15599  unmatched = unmatched || SCIPisNegative(scip, consdata->vals[i]);
15600  }
15601 
15602  if( !unmatched )
15603  {
15604  SCIPdebugMsg(scip, "classified as INTKNAPSACK: ");
15605  SCIPdebugPrintCons(scip, cons, NULL);
15607 
15608  /* check if finite left hand side allows for a second classification, relax already used right hand side */
15609  if( SCIPisInfinity(scip, -lhs) )
15610  continue;
15611  else
15612  rhs = SCIPinfinity(scip);
15613  }
15614  }
15615 
15616  /* is constraint of type SCIP_CONSTYPE_{MIXEDBINARY}? */
15617  {
15618  SCIP_Bool unmatched;
15619 
15620  unmatched = FALSE;
15621  for( i = 0; i < consdata->nvars && !unmatched; i++ )
15622  {
15623  if( SCIPvarGetType(consdata->vars[i]) != SCIP_VARTYPE_CONTINUOUS
15624  && (SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0)
15625  || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0)) )
15626  unmatched = TRUE;
15627  }
15628 
15629  if( !unmatched )
15630  {
15631  SCIPdebugMsg(scip, "classified as MIXEDBINARY (%d): ", isRangedRow(scip, lhs, rhs) ? 2 : 1);
15632  SCIPdebugPrintCons(scip, cons, NULL);
15633  SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_MIXEDBINARY, isRangedRow(scip, lhs, rhs) ? 2 : 1);
15634 
15635  continue;
15636  }
15637  }
15638 
15639  /* no special structure detected */
15640  SCIPdebugMsg(scip, "classified as GENERAL: ");
15641  SCIPdebugPrintCons(scip, cons, NULL);
15642  SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_GENERAL, isRangedRow(scip, lhs, rhs) ? 2 : 1);
15643  }
15644 
15645  return SCIP_OKAY;
15646 }
15647 
15648 
15649 /** presolving deinitialization method of constraint handler (called after presolving has been finished) */
15650 static
15651 SCIP_DECL_CONSEXITPRE(consExitpreLinear)
15652 { /*lint --e{715}*/
15653  int c;
15654 #ifdef SCIP_STATISTIC
15655  SCIP_CONSHDLRDATA* conshdlrdata;
15656  int ngoodconss;
15657  int nallconss;
15658 #endif
15659 
15660  /* delete all linear constraints that were upgraded to a more specific constraint type;
15661  * make sure, only active variables remain in the remaining constraints
15662  */
15663  assert(scip != NULL);
15664 
15665 #ifdef SCIP_STATISTIC
15666  /* count number of well behaved linear constraints */
15667  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15668  assert(conshdlrdata != NULL);
15669 
15670  ngoodconss = 0;
15671  nallconss = 0;
15672 
15673  for( c = 0; c < nconss; ++c )
15674  {
15675  SCIP_CONSDATA* consdata;
15676 
15677  if( SCIPconsIsDeleted(conss[c]) )
15678  continue;
15679 
15680  consdata = SCIPconsGetData(conss[c]);
15681  assert(consdata != NULL);
15682 
15683  if( consdata->upgraded )
15684  continue;
15685 
15686  nallconss++;
15687 
15688  consdataRecomputeMaxActivityDelta(scip, consdata);
15689 
15690  if( SCIPisLT(scip, consdata->maxactdelta, conshdlrdata->maxeasyactivitydelta) )
15691  ngoodconss++;
15692  }
15693  if( nallconss )
15694  {
15695  SCIPstatisticMessage("below threshold: %d / %d ratio= %g\n", ngoodconss, nallconss, (100.0 * ngoodconss / nallconss));
15696  }
15697 #endif
15698 
15699  for( c = 0; c < nconss; ++c )
15700  {
15701  SCIP_CONSDATA* consdata;
15702 
15703  if( SCIPconsIsDeleted(conss[c]) )
15704  continue;
15705 
15706  consdata = SCIPconsGetData(conss[c]);
15707  assert(consdata != NULL);
15708 
15709  if( consdata->upgraded )
15710  {
15711  /* this is no problem reduction, because the upgraded constraint was added to the problem before, and the
15712  * (redundant) linear constraint was only kept in order to support presolving the the linear constraint handler
15713  */
15714  SCIP_CALL( SCIPdelCons(scip, conss[c]) );
15715  }
15716  else
15717  {
15718  /* since we are not allowed to detect infeasibility in the exitpre stage, we dont give an infeasible pointer */
15719  SCIP_CALL( applyFixings(scip, conss[c], NULL) );
15720  }
15721  }
15722 
15723  return SCIP_OKAY;
15724 }
15725 
15726 /** solving process initialization method of constraint handler */
15727 static
15728 SCIP_DECL_CONSINITSOL(consInitsolLinear)
15729 { /*lint --e{715}*/
15730 
15731  /* add nlrow representation to NLP, if NLP had been constructed */
15732  if( SCIPisNLPConstructed(scip) )
15733  {
15734  int c;
15735  for( c = 0; c < nconss; ++c )
15736  {
15737  SCIP_CALL( addNlrow(scip, conss[c]) );
15738  }
15739  }
15740 
15741  return SCIP_OKAY;
15742 }
15743 
15744 /** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
15745 static
15746 SCIP_DECL_CONSEXITSOL(consExitsolLinear)
15747 { /*lint --e{715}*/
15748  int c;
15749 
15750  assert(scip != NULL);
15751 
15752  /* release the rows and nlrows of all constraints */
15753  for( c = 0; c < nconss; ++c )
15754  {
15755  SCIP_CONSDATA* consdata;
15756 
15757  consdata = SCIPconsGetData(conss[c]);
15758  assert(consdata != NULL);
15759 
15760  if( consdata->row != NULL )
15761  {
15762  SCIP_CALL( SCIPreleaseRow(scip, &consdata->row) );
15763  }
15764 
15765  if( consdata->nlrow != NULL )
15766  {
15767  SCIP_CALL( SCIPreleaseNlRow(scip, &consdata->nlrow) );
15768  }
15769  }
15770 
15771  /* if this is a restart, convert cutpool rows into linear constraints */
15772  if( restart )
15773  {
15774  int ncutsadded;
15775 
15776  ncutsadded = 0;
15777 
15778  /* create out of all active cuts in cutpool linear constraints */
15779  SCIP_CALL( SCIPconvertCutsToConss(scip, NULL, NULL, TRUE, &ncutsadded) );
15780 
15781  if( ncutsadded > 0 )
15782  {
15784  "(restart) converted %d cuts from the global cut pool into linear constraints\n", ncutsadded);
15785  /* an extra blank line should be printed separately since the buffer message handler only handles up to one
15786  * line correctly
15787  */
15789  }
15790  }
15791 
15792  return SCIP_OKAY;
15793 }
15794 
15795 
15796 /** constraint activation notification method of constraint handler */
15797 static
15798 SCIP_DECL_CONSACTIVE(consActiveLinear)
15799 { /*lint --e{715}*/
15800  assert(cons != NULL);
15801 
15802  if( SCIPgetStage(scip) == SCIP_STAGE_SOLVING && SCIPisNLPConstructed(scip) )
15803  {
15804  SCIP_CALL( addNlrow(scip, cons) );
15805  }
15806 
15807  return SCIP_OKAY;
15808 }
15809 
15810 /** constraint deactivation notification method of constraint handler */
15811 static
15812 SCIP_DECL_CONSDEACTIVE(consDeactiveLinear)
15813 { /*lint --e{715}*/
15814  SCIP_CONSDATA* consdata;
15815 
15816  assert(scip != NULL);
15817  assert(conshdlr != NULL);
15818  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15819  assert(cons != NULL );
15820 
15821  /* get constraint data */
15822  consdata = SCIPconsGetData(cons);
15823  assert(consdata != NULL);
15824 
15825  if( SCIPconsIsDeleted(cons) )
15826  {
15827  SCIP_CONSHDLRDATA* conshdlrdata;
15828 
15829  /* check for event handler */
15830  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15831  assert(conshdlrdata != NULL);
15832  assert(conshdlrdata->eventhdlr != NULL);
15833 
15834  /* free event data */
15835  if( consdata->eventdata != NULL )
15836  {
15837  /* drop bound change events of variables */
15838  SCIP_CALL( consDropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
15839  }
15840  assert(consdata->eventdata == NULL);
15841  }
15842 
15843  /* remove row from NLP, if still in solving
15844  * if we are in exitsolve, the whole NLP will be freed anyway
15845  */
15846  if( SCIPgetStage(scip) == SCIP_STAGE_SOLVING && consdata->nlrow != NULL )
15847  {
15848  SCIP_CALL( SCIPdelNlRow(scip, consdata->nlrow) );
15849  }
15850 
15851  return SCIP_OKAY;
15852 }
15853 
15854 
15855 /** frees specific constraint data */
15856 static
15857 SCIP_DECL_CONSDELETE(consDeleteLinear)
15858 { /*lint --e{715}*/
15859  assert(scip != NULL);
15860  assert(conshdlr != NULL);
15861  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15862 
15863  if( (*consdata)->eventdata != NULL )
15864  {
15865  SCIP_CONSHDLRDATA* conshdlrdata;
15866 
15867  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15868  assert(conshdlrdata != NULL);
15869 
15870  /* drop all events */
15871  SCIP_CALL( consDropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
15872  assert((*consdata)->eventdata == NULL);
15873  }
15874 
15875  /* free linear constraint */
15876  SCIP_CALL( consdataFree(scip, consdata) );
15877 
15878  return SCIP_OKAY;
15879 }
15880 
15881 
15882 /** transforms constraint data into data belonging to the transformed problem */
15883 static
15884 SCIP_DECL_CONSTRANS(consTransLinear)
15885 { /*lint --e{715}*/
15886  SCIP_CONSDATA* sourcedata;
15887  SCIP_CONSDATA* targetdata;
15888 
15889  /*debugMsg(scip, "Trans method of linear constraints\n");*/
15890 
15891  assert(scip != NULL);
15892  assert(conshdlr != NULL);
15893  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15894  assert(SCIPgetStage(scip) == SCIP_STAGE_TRANSFORMING);
15895  assert(sourcecons != NULL);
15896  assert(targetcons != NULL);
15897 
15898  sourcedata = SCIPconsGetData(sourcecons);
15899  assert(sourcedata != NULL);
15900  assert(sourcedata->row == NULL); /* in original problem, there cannot be LP rows */
15901 
15902  /* create linear constraint data for target constraint */
15903  SCIP_CALL( consdataCreate(scip, &targetdata, sourcedata->nvars, sourcedata->vars, sourcedata->vals, sourcedata->lhs, sourcedata->rhs) );
15904 
15905 #ifndef NDEBUG
15906  /* if this is a checked or enforced constraints, then there must be no relaxation-only variables */
15907  if( SCIPconsIsEnforced(sourcecons) || SCIPconsIsChecked(sourcecons) )
15908  {
15909  int n;
15910  for(n = targetdata->nvars - 1; n >= 0; --n )
15911  assert(!SCIPvarIsRelaxationOnly(targetdata->vars[n]));
15912  }
15913 #endif
15914 
15915  /* create target constraint */
15916  SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
15917  SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
15918  SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
15919  SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
15920  SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
15921 
15922  return SCIP_OKAY;
15923 }
15924 
15925 
15926 /** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
15927 static
15928 SCIP_DECL_CONSINITLP(consInitlpLinear)
15929 { /*lint --e{715}*/
15930  int c;
15931 
15932  assert(scip != NULL);
15933  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15934 
15935  *infeasible = FALSE;
15936 
15937  for( c = 0; c < nconss && !(*infeasible); ++c )
15938  {
15939  assert(SCIPconsIsInitial(conss[c]));
15940  SCIP_CALL( addRelaxation(scip, conss[c], infeasible) );
15941  }
15942 
15943  return SCIP_OKAY;
15944 }
15945 
15946 
15947 /** separation method of constraint handler for LP solutions */
15948 static
15949 SCIP_DECL_CONSSEPALP(consSepalpLinear)
15950 { /*lint --e{715}*/
15951  SCIP_CONSHDLRDATA* conshdlrdata;
15952  SCIP_Real loclowerbound;
15953  SCIP_Real glblowerbound;
15954  SCIP_Real cutoffbound;
15955  SCIP_Real maxbound;
15956  SCIP_Bool separatecards;
15957  SCIP_Bool cutoff;
15958  int c;
15959  int depth;
15960  int nrounds;
15961  int maxsepacuts;
15962  int ncuts;
15963 
15964  assert(scip != NULL);
15965  assert(conshdlr != NULL);
15966  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15967  assert(result != NULL);
15969  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15970  assert(conshdlrdata != NULL);
15971  depth = SCIPgetDepth(scip);
15972  nrounds = SCIPgetNSepaRounds(scip);
15973 
15974  /*debugMsg(scip, "Sepa method of linear constraints\n");*/
15975 
15976  *result = SCIP_DIDNOTRUN;
15977 
15978  /* only call the separator a given number of times at each node */
15979  if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
15980  || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
15981  return SCIP_OKAY;
15982 
15983  /* get the maximal number of cuts allowed in a separation round */
15984  maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
15985 
15986  /* check if we want to produce knapsack cardinality cuts at this node */
15987  loclowerbound = SCIPgetLocalLowerbound(scip);
15988  glblowerbound = SCIPgetLowerbound(scip);
15989  cutoffbound = SCIPgetCutoffbound(scip);
15990  maxbound = glblowerbound + conshdlrdata->maxcardbounddist * (cutoffbound - glblowerbound);
15991  separatecards = SCIPisLE(scip, loclowerbound, maxbound);
15992  separatecards = separatecards && (SCIPgetNLPBranchCands(scip) > 0);
15993 
15994  *result = SCIP_DIDNOTFIND;
15995  ncuts = 0;
15996  cutoff = FALSE;
15997 
15998  /* check all useful linear constraints for feasibility */
15999  for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
16000  {
16001  /*debugMsg(scip, "separating linear constraint <%s>\n", SCIPconsGetName(conss[c]));*/
16002  SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, NULL, separatecards, conshdlrdata->separateall, &ncuts, &cutoff) );
16003  }
16004 
16005  /* adjust return value */
16006  if( cutoff )
16007  *result = SCIP_CUTOFF;
16008  else if( ncuts > 0 )
16009  *result = SCIP_SEPARATED;
16010 
16011  /* combine linear constraints to get more cuts */
16012  /**@todo further cuts of linear constraints */
16013 
16014  return SCIP_OKAY;
16015 }
16016 
16017 
16018 /** separation method of constraint handler for arbitrary primal solutions */
16019 static
16020 SCIP_DECL_CONSSEPASOL(consSepasolLinear)
16021 { /*lint --e{715}*/
16022  SCIP_CONSHDLRDATA* conshdlrdata;
16023  int c;
16024  int depth;
16025  int nrounds;
16026  int maxsepacuts;
16027  int ncuts;
16028  SCIP_Bool cutoff;
16029 
16030  assert(scip != NULL);
16031  assert(conshdlr != NULL);
16032  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16033  assert(result != NULL);
16034 
16035  conshdlrdata = SCIPconshdlrGetData(conshdlr);
16036  assert(conshdlrdata != NULL);
16037  depth = SCIPgetDepth(scip);
16038  nrounds = SCIPgetNSepaRounds(scip);
16040  /*debugMsg(scip, "Sepa method of linear constraints\n");*/
16041 
16042  *result = SCIP_DIDNOTRUN;
16043 
16044  /* only call the separator a given number of times at each node */
16045  if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
16046  || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
16047  return SCIP_OKAY;
16048 
16049  /* get the maximal number of cuts allowed in a separation round */
16050  maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
16051 
16052  *result = SCIP_DIDNOTFIND;
16053  ncuts = 0;
16054  cutoff = FALSE;
16055 
16056  /* check all useful linear constraints for feasibility */
16057  for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
16058  {
16059  /*debugMsg(scip, "separating linear constraint <%s>\n", SCIPconsGetName(conss[c]));*/
16060  SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, sol, TRUE, conshdlrdata->separateall, &ncuts, &cutoff) );
16061  }
16062 
16063  /* adjust return value */
16064  if( cutoff )
16065  *result = SCIP_CUTOFF;
16066  else if( ncuts > 0 )
16067  *result = SCIP_SEPARATED;
16068 
16069  /* combine linear constraints to get more cuts */
16070  /**@todo further cuts of linear constraints */
16071 
16072  return SCIP_OKAY;
16073 }
16074 
16075 
16076 /** constraint enforcing method of constraint handler for LP solutions */
16077 static
16078 SCIP_DECL_CONSENFOLP(consEnfolpLinear)
16079 { /*lint --e{715}*/
16080  SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, NULL, result) );
16081 
16082  return SCIP_OKAY;
16083 }
16084 
16085 /** constraint enforcing method of constraint handler for relaxation solutions */
16086 static
16087 SCIP_DECL_CONSENFORELAX(consEnforelaxLinear)
16088 { /*lint --e{715}*/
16089  SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, sol, result) );
16090 
16091  return SCIP_OKAY;
16092 }
16093 
16094 /** constraint enforcing method of constraint handler for pseudo solutions */
16095 static
16096 SCIP_DECL_CONSENFOPS(consEnfopsLinear)
16097 { /*lint --e{715}*/
16098  SCIP_CONSHDLRDATA* conshdlrdata;
16099  SCIP_Bool checkrelmaxabs;
16100  SCIP_Bool violated;
16101  int c;
16102 
16103  assert(scip != NULL);
16104  assert(conshdlr != NULL);
16105  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16106  assert(result != NULL);
16107 
16108  conshdlrdata = SCIPconshdlrGetData(conshdlr);
16109  assert(conshdlrdata != NULL);
16110 
16111  checkrelmaxabs = conshdlrdata->checkrelmaxabs;
16112 
16113  SCIPdebugMsg(scip, "Enfops method of linear constraints\n");
16114 
16115  /* if the solution is infeasible anyway due to objective value, skip the enforcement */
16116  if( objinfeasible )
16117  {
16118  SCIPdebugMsg(scip, "-> pseudo solution is objective infeasible, return.\n");
16119 
16120  *result = SCIP_DIDNOTRUN;
16121  return SCIP_OKAY;
16122  }
16123 
16124  /* check all linear constraints for feasibility */
16125  violated = FALSE;
16126  for( c = 0; c < nconss && !violated; ++c )
16127  {
16128  SCIP_CALL( checkCons(scip, conss[c], NULL, TRUE, checkrelmaxabs, &violated) );
16129  }
16130 
16131  if( violated )
16132  *result = SCIP_INFEASIBLE;
16133  else
16134  *result = SCIP_FEASIBLE;
16135 
16136  SCIPdebugMsg(scip, "-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
16137 
16138  return SCIP_OKAY;
16139 }
16140 
16141 
16142 /** feasibility check method of constraint handler for integral solutions */
16143 static
16144 SCIP_DECL_CONSCHECK(consCheckLinear)
16145 { /*lint --e{715}*/
16146  SCIP_CONSHDLRDATA* conshdlrdata;
16147  SCIP_Bool checkrelmaxabs;
16148  int c;
16149 
16150  assert(scip != NULL);
16151  assert(conshdlr != NULL);
16152  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16153  assert(result != NULL);
16154 
16155  *result = SCIP_FEASIBLE;
16156 
16157  conshdlrdata = SCIPconshdlrGetData(conshdlr);
16158  assert(conshdlrdata != NULL);
16159 
16160  checkrelmaxabs = conshdlrdata->checkrelmaxabs;
16161 
16162  /*debugMsg(scip, "Check method of linear constraints\n");*/
16164  /* check all linear constraints for feasibility */
16165  for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
16166  {
16167  SCIP_Bool violated = FALSE;
16168  SCIP_CALL( checkCons(scip, conss[c], sol, checklprows, checkrelmaxabs, &violated) );
16169 
16170  if( violated )
16171  {
16172  *result = SCIP_INFEASIBLE;
16173 
16174  if( printreason )
16175  {
16176  SCIP_CONSDATA* consdata;
16177  SCIP_Real activity;
16178 
16179  consdata = SCIPconsGetData(conss[c]);
16180  assert( consdata != NULL);
16181 
16182  activity = consdataGetActivity(scip, consdata, sol);
16183 
16184  SCIP_CALL( consPrintConsSol(scip, conss[c], sol, NULL ) );
16185  SCIPinfoMessage(scip, NULL, ";\n");
16186 
16187  if( activity == SCIP_INVALID ) /*lint !e777*/
16188  SCIPinfoMessage(scip, NULL, "activity invalid due to positive and negative infinity contributions\n");
16189  else if( SCIPisFeasLT(scip, activity, consdata->lhs) )
16190  SCIPinfoMessage(scip, NULL, "violation: left hand side is violated by %.15g\n", consdata->lhs - activity);
16191  else if( SCIPisFeasGT(scip, activity, consdata->rhs) )
16192  SCIPinfoMessage(scip, NULL, "violation: right hand side is violated by %.15g\n", activity - consdata->rhs);
16193  }
16194  }
16195  }
16196 
16197  return SCIP_OKAY;
16198 }
16199 
16200 
16201 /** domain propagation method of constraint handler */
16202 static
16203 SCIP_DECL_CONSPROP(consPropLinear)
16204 { /*lint --e{715}*/
16205  SCIP_CONSHDLRDATA* conshdlrdata;
16206  SCIP_Bool rangedrowpropagation = FALSE;
16207  SCIP_Bool tightenbounds;
16208  SCIP_Bool cutoff;
16209 
16210  int nchgbds;
16211  int i;
16212 
16213  assert(scip != NULL);
16214  assert(conshdlr != NULL);
16215  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16216  assert(result != NULL);
16217 
16218  conshdlrdata = SCIPconshdlrGetData(conshdlr);
16219  assert(conshdlrdata != NULL);
16220 
16221  /*debugMsg(scip, "Prop method of linear constraints\n");*/
16223  /* check, if we want to tighten variable's bounds (in probing, we always want to tighten the bounds) */
16224  if( SCIPinProbing(scip) )
16225  tightenbounds = TRUE;
16226  else
16227  {
16228  int depth;
16229  int propfreq;
16230  int tightenboundsfreq;
16231  int rangedrowfreq;
16232 
16233  depth = SCIPgetDepth(scip);
16234  propfreq = SCIPconshdlrGetPropFreq(conshdlr);
16235  tightenboundsfreq = propfreq * conshdlrdata->tightenboundsfreq;
16236  tightenbounds = (conshdlrdata->tightenboundsfreq >= 0)
16237  && ((tightenboundsfreq == 0 && depth == 0) || (tightenboundsfreq >= 1 && (depth % tightenboundsfreq == 0)));
16238 
16239  /* check if we want to do ranged row propagation */
16240  rangedrowpropagation = conshdlrdata->rangedrowpropagation;
16241  rangedrowpropagation = rangedrowpropagation && !SCIPinRepropagation(scip);
16242  rangedrowpropagation = rangedrowpropagation && (depth <= conshdlrdata->rangedrowmaxdepth);
16243  rangedrowfreq = propfreq * conshdlrdata->rangedrowfreq;
16244  rangedrowpropagation = rangedrowpropagation && (conshdlrdata->rangedrowfreq >= 0)
16245  && ((rangedrowfreq == 0 && depth == 0) || (rangedrowfreq >= 1 && (depth % rangedrowfreq == 0)));
16246  }
16247 
16248  cutoff = FALSE;
16249  nchgbds = 0;
16250 
16251  /* process constraints marked for propagation */
16252  for( i = 0; i < nmarkedconss && !cutoff; i++ )
16253  {
16254  SCIP_CALL( SCIPunmarkConsPropagate(scip, conss[i]) );
16255  SCIP_CALL( propagateCons(scip, conss[i], tightenbounds, rangedrowpropagation,
16256  conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars, &cutoff, &nchgbds) );
16257  }
16258 
16259  /* adjust result code */
16260  if( cutoff )
16261  *result = SCIP_CUTOFF;
16262  else if( nchgbds > 0 )
16263  *result = SCIP_REDUCEDDOM;
16264  else
16265  *result = SCIP_DIDNOTFIND;
16266 
16267  return SCIP_OKAY;
16268 }
16269 
16270 
16271 #define MAXCONSPRESOLROUNDS 10
16272 /** presolving method of constraint handler */
16273 static
16274 SCIP_DECL_CONSPRESOL(consPresolLinear)
16275 { /*lint --e{715}*/
16276  SCIP_CONSHDLRDATA* conshdlrdata;
16277  SCIP_CONS* cons;
16278  SCIP_CONSDATA* consdata;
16279  SCIP_Real minactivity;
16280  SCIP_Real maxactivity;
16281  SCIP_Bool minactisrelax;
16282  SCIP_Bool maxactisrelax;
16283  SCIP_Bool isminsettoinfinity;
16284  SCIP_Bool ismaxsettoinfinity;
16285  SCIP_Bool cutoff;
16286  int oldnfixedvars;
16287  int oldnaggrvars;
16288  int oldnchgbds;
16289  int oldndelconss;
16290  int oldnupgdconss;
16291  int oldnchgcoefs;
16292  int oldnchgsides;
16293  int firstchange;
16294  int firstupgradetry;
16295  int c;
16296 
16297  assert(scip != NULL);
16298  assert(conshdlr != NULL);
16299  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16300  assert(result != NULL);
16301 
16302  /*debugMsg(scip, "Presol method of linear constraints\n");*/
16303 
16304  /* remember old preprocessing counters */
16305  cutoff = FALSE;
16306  oldnfixedvars = *nfixedvars;
16307  oldnaggrvars = *naggrvars;
16308  oldnchgbds = *nchgbds;
16309  oldndelconss = *ndelconss;
16310  oldnupgdconss = *nupgdconss;
16311  oldnchgcoefs = *nchgcoefs;
16312  oldnchgsides = *nchgsides;
16313 
16314  /* get constraint handler data */
16315  conshdlrdata = SCIPconshdlrGetData(conshdlr);
16316  assert(conshdlrdata != NULL);
16317 
16318  /* process single constraints */
16319  firstchange = INT_MAX;
16320  firstupgradetry = INT_MAX;
16321  for( c = 0; c < nconss && !cutoff && !SCIPisStopped(scip); ++c )
16322  {
16323  int npresolrounds;
16324  SCIP_Bool infeasible;
16325 
16326  infeasible = FALSE;
16327 
16328  cons = conss[c];
16329  assert(SCIPconsIsActive(cons));
16330  consdata = SCIPconsGetData(cons);
16331  assert(consdata != NULL);
16332 
16333  /* ensure that rhs >= lhs is satisfied without numerical tolerance */
16334  if( SCIPisEQ(scip, consdata->rhs, consdata->lhs) )
16335  {
16336  consdata->lhs = consdata->rhs;
16337  assert(consdata->row == NULL);
16338  }
16339 
16340  if( consdata->eventdata == NULL )
16341  {
16342  /* catch bound change events of variables */
16343  SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
16344  assert(consdata->eventdata != NULL);
16345  }
16346 
16347  /* constraint should not be already presolved in the initial round */
16348  assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || SCIPconsIsMarkedPropagate(cons));
16349  assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || consdata->boundstightened == 0);
16350  assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || !consdata->presolved);
16351  assert(!SCIPconsIsMarkedPropagate(cons) || !consdata->presolved);
16352 
16353  /* incorporate fixings and aggregations in constraint */
16354  SCIP_CALL( applyFixings(scip, cons, &infeasible) );
16355 
16356  if( infeasible )
16357  {
16358  SCIPdebugMsg(scip, " -> infeasible fixing\n");
16359  cutoff = TRUE;
16360  break;
16361  }
16362 
16363  assert(consdata->removedfixings);
16364 
16365  /* we can only presolve linear constraints, that are not modifiable */
16366  if( SCIPconsIsModifiable(cons) )
16367  continue;
16368 
16369  /* remember the first changed constraint to begin the next aggregation round with */
16370  if( firstchange == INT_MAX && consdata->changed )
16371  firstchange = c;
16372 
16373  /* remember the first constraint that was not yet tried to be upgraded, to begin the next upgrading round with */
16374  if( firstupgradetry == INT_MAX && !consdata->upgradetried )
16375  firstupgradetry = c;
16376 
16377  /* check, if constraint is already preprocessed */
16378  if( consdata->presolved )
16379  continue;
16380 
16381  assert(SCIPconsIsActive(cons));
16382 
16383  SCIPdebugMsg(scip, "presolving linear constraint <%s>\n", SCIPconsGetName(cons));
16384  SCIPdebugPrintCons(scip, cons, NULL);
16385 
16386  /* apply presolving as long as possible on the single constraint (however, abort after a certain number of rounds
16387  * to avoid nearly infinite cycling due to very small bound changes)
16388  */
16389  npresolrounds = 0;
16390  while( !consdata->presolved && npresolrounds < MAXCONSPRESOLROUNDS && !SCIPisStopped(scip) )
16391  {
16392  assert(!cutoff);
16393  npresolrounds++;
16394 
16395  /* mark constraint being presolved and propagated */
16396  consdata->presolved = TRUE;
16397  SCIP_CALL( SCIPunmarkConsPropagate(scip, cons) );
16398 
16399  /* normalize constraint */
16400  SCIP_CALL( normalizeCons(scip, cons, &infeasible) );
16401 
16402  if( infeasible )
16403  {
16404  SCIPdebugMsg(scip, " -> infeasible normalization\n");
16405  cutoff = TRUE;
16406  break;
16407  }
16408 
16409  /* tighten left and right hand side due to integrality */
16410  SCIP_CALL( tightenSides(scip, cons, nchgsides, &infeasible) );
16411 
16412  if( infeasible )
16413  {
16414  SCIPdebugMsg(scip, " -> infeasibility detected during tightening sides\n");
16415  cutoff = TRUE;
16416  break;
16417  }
16418 
16419  /* check bounds */
16420  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
16421  {
16422  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
16423  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16424  cutoff = TRUE;
16425  break;
16426  }
16427 
16428  /* tighten variable's bounds */
16429  SCIP_CALL( tightenBounds(scip, cons, conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars, &cutoff, nchgbds) );
16430  if( cutoff )
16431  break;
16432 
16433  /* check for fixed variables */
16434  SCIP_CALL( fixVariables(scip, cons, &cutoff, nfixedvars) );
16435  if( cutoff )
16436  break;
16437 
16438  /* check constraint for infeasibility and redundancy */
16439  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
16440  &isminsettoinfinity, &ismaxsettoinfinity);
16441  if( SCIPisFeasGT(scip, minactivity, consdata->rhs) || SCIPisFeasLT(scip, maxactivity, consdata->lhs) )
16442  {
16443  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
16444  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
16445  cutoff = TRUE;
16446  break;
16447  }
16448  else if( SCIPisFeasGE(scip, minactivity, consdata->lhs) && SCIPisFeasLE(scip, maxactivity, consdata->rhs) )
16449  {
16450  SCIPdebugMsg(scip, "linear constraint <%s> is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
16451  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
16452  SCIP_CALL( SCIPdelCons(scip, cons) );
16453  assert(!SCIPconsIsActive(cons));
16454 
16455  if( !consdata->upgraded )
16456  (*ndelconss)++;
16457  break;
16458  }
16459  else if( !SCIPisInfinity(scip, -consdata->lhs) && SCIPisFeasGE(scip, minactivity, consdata->lhs) )
16460  {
16461  SCIPdebugMsg(scip, "linear constraint <%s> left hand side is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
16462  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
16463  SCIP_CALL( chgLhs(scip, cons, -SCIPinfinity(scip)) );
16464  if( !consdata->upgraded )
16465  (*nchgsides)++;
16466  }
16467  else if( !SCIPisInfinity(scip, consdata->rhs) && SCIPisFeasLE(scip, maxactivity, consdata->rhs) )
16468  {
16469  SCIPdebugMsg(scip, "linear constraint <%s> right hand side is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
16470  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
16471  SCIP_CALL( chgRhs(scip, cons, SCIPinfinity(scip)) );
16472  if( !consdata->upgraded )
16473  (*nchgsides)++;
16474  }
16475  assert(consdata->nvars >= 1); /* otherwise, it should be redundant or infeasible */
16476 
16477  /* handle empty constraint */
16478  if( consdata->nvars == 0 )
16479  {
16480  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
16481  {
16482  SCIPdebugMsg(scip, "empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
16483  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16484  cutoff = TRUE;
16485  }
16486  else
16487  {
16488  SCIPdebugMsg(scip, "empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
16489  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16490  SCIP_CALL( SCIPdelCons(scip, cons) );
16491  assert(!SCIPconsIsActive(cons));
16492 
16493  if( !consdata->upgraded )
16494  (*ndelconss)++;
16495  }
16496  break;
16497  }
16498 
16499  /* reduce big-M coefficients, that make the constraint redundant if the variable is on a bound */
16500  SCIP_CALL( consdataTightenCoefs(scip, cons, nchgcoefs, nchgsides) );
16501 
16502  /* try to simplify inequalities */
16503  if( conshdlrdata->simplifyinequalities )
16504  {
16505  SCIP_CALL( simplifyInequalities(scip, cons, nchgcoefs, nchgsides, &cutoff) );
16506 
16507  if( cutoff )
16508  break;
16509  }
16510 
16511  /* aggregation variable in equations */
16512  if( conshdlrdata->aggregatevariables )
16513  {
16514  SCIP_CALL( aggregateVariables(scip, cons, &cutoff, nfixedvars, naggrvars) );
16515  if( cutoff )
16516  break;
16517  }
16518  }
16519 
16520  if( !cutoff && !SCIPisStopped(scip) )
16521  {
16522  /* perform ranged row propagation */
16523  if( conshdlrdata->rangedrowpropagation )
16524  {
16525  int lastnfixedvars;
16526 
16527  lastnfixedvars = *nfixedvars;
16528 
16529  SCIP_CALL( rangedRowPropagation(scip, cons, &cutoff, nfixedvars, nchgbds, naddconss) );
16530  if( !cutoff )
16531  {
16532  if( lastnfixedvars < *nfixedvars )
16533  {
16534  SCIP_CALL( applyFixings(scip, cons, &cutoff) );
16535  }
16536  }
16537  }
16538 
16539  /* extract cliques from constraint */
16540  if( conshdlrdata->extractcliques && !cutoff && SCIPconsIsActive(cons) )
16541  {
16542  SCIP_CALL( extractCliques(scip, cons, conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars,
16543  nfixedvars, nchgbds, &cutoff) );
16544 
16545  /* check if the constraint got redundant or infeasible */
16546  if( !cutoff && SCIPconsIsActive(cons) && consdata->nvars == 0 )
16547  {
16548  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
16549  {
16550  SCIPdebugMsg(scip, "empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
16551  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16552  cutoff = TRUE;
16553  }
16554  else
16555  {
16556  SCIPdebugMsg(scip, "empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
16557  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16558  SCIP_CALL( SCIPdelCons(scip, cons) );
16559  assert(!SCIPconsIsActive(cons));
16560 
16561  if( !consdata->upgraded )
16562  (*ndelconss)++;
16563  }
16564  }
16565  }
16566 
16567  /* convert special equalities */
16568  if( !cutoff && SCIPconsIsActive(cons) )
16569  {
16570  SCIP_CALL( convertEquality(scip, cons, conshdlrdata, &cutoff, nfixedvars, naggrvars, ndelconss) );
16571  }
16572 
16573  /* apply dual presolving for variables that appear in only one constraint */
16574  if( !cutoff && SCIPconsIsActive(cons) && conshdlrdata->dualpresolving && SCIPallowStrongDualReds(scip) )
16575  {
16576  SCIP_CALL( dualPresolve(scip, conshdlrdata, cons, &cutoff, nfixedvars, naggrvars, ndelconss) );
16577  }
16578 
16579  /* check if an inequality is parallel to the objective function */
16580  if( !cutoff && SCIPconsIsActive(cons) )
16581  {
16582  SCIP_CALL( checkParallelObjective(scip, cons, conshdlrdata) );
16583  }
16584 
16585  /* remember the first changed constraint to begin the next aggregation round with */
16586  if( firstchange == INT_MAX && consdata->changed )
16587  firstchange = c;
16588 
16589  /* remember the first constraint that was not yet tried to be upgraded, to begin the next upgrading round with */
16590  if( firstupgradetry == INT_MAX && !consdata->upgradetried )
16591  firstupgradetry = c;
16592  }
16593 
16594  /* singleton column stuffing */
16595  if( !cutoff && SCIPconsIsActive(cons) && SCIPconsIsChecked(cons) &&
16596  (conshdlrdata->singletonstuffing || conshdlrdata->singlevarstuffing) && SCIPallowStrongDualReds(scip) )
16597  {
16598  SCIP_CALL( presolStuffing(scip, cons, conshdlrdata->singletonstuffing,
16599  conshdlrdata->singlevarstuffing, &cutoff, nfixedvars, nchgbds) );
16600 
16601  /* handle empty constraint */
16602  if( consdata->nvars == 0 )
16603  {
16604  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
16605  {
16606  SCIPdebugMsg(scip, "empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
16607  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16608  cutoff = TRUE;
16609  }
16610  else
16611  {
16612  SCIPdebugMsg(scip, "empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
16613  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16614  SCIP_CALL( SCIPdelCons(scip, cons) );
16615  assert(!SCIPconsIsActive(cons));
16616 
16617  if( !consdata->upgraded )
16618  (*ndelconss)++;
16619  }
16620  break;
16621  }
16622  }
16623  }
16624 
16625  /* process pairs of constraints: check them for redundancy and try to aggregate them;
16626  * only apply this expensive procedure in exhaustive presolving timing
16627  */
16628  if( !cutoff && (presoltiming & SCIP_PRESOLTIMING_EXHAUSTIVE) != 0 && (conshdlrdata->presolusehashing || conshdlrdata->presolpairwise) && !SCIPisStopped(scip) )
16629  {
16630  assert(firstchange >= 0);
16631 
16632  if( firstchange < nconss && conshdlrdata->presolusehashing )
16633  {
16634  /* detect redundant constraints; fast version with hash table instead of pairwise comparison */
16635  SCIP_CALL( detectRedundantConstraints(scip, SCIPblkmem(scip), conss, nconss, &firstchange, &cutoff,
16636  ndelconss, nchgsides) );
16637  }
16638 
16639  if( firstchange < nconss && conshdlrdata->presolpairwise )
16640  {
16641  SCIP_CONS** usefulconss;
16642  int nusefulconss;
16643  int firstchangenew;
16644  SCIP_Longint npaircomparisons;
16645 
16646  npaircomparisons = 0;
16647  oldndelconss = *ndelconss;
16648  oldnchgsides = *nchgsides;
16649  oldnchgcoefs = *nchgcoefs;
16650 
16651  /* allocate temporary memory */
16652  SCIP_CALL( SCIPallocBufferArray(scip, &usefulconss, nconss) );
16653 
16654  nusefulconss = 0;
16655  firstchangenew = -1;
16656  for( c = 0; c < nconss; ++c )
16657  {
16658  /* update firstchange */
16659  if( c == firstchange )
16660  firstchangenew = nusefulconss;
16661 
16662  /* ignore inactive and modifiable constraints */
16663  if( !SCIPconsIsActive(conss[c]) || SCIPconsIsModifiable(conss[c]) )
16664  continue;
16665 
16666  usefulconss[nusefulconss] = conss[c];
16667  ++nusefulconss;
16668  }
16669  firstchange = firstchangenew;
16670  assert(firstchangenew >= 0 && firstchangenew <= nusefulconss);
16671 
16672  for( c = firstchange; c < nusefulconss && !cutoff && !SCIPisStopped(scip); ++c )
16673  {
16674  /* constraint has become inactive or modifiable during pairwise presolving */
16675  if( usefulconss[c] == NULL )
16676  continue;
16677 
16678  npaircomparisons += (SCIPconsGetData(conss[c])->changed) ? c : (c - firstchange); /*lint !e776*/
16679 
16680  assert(SCIPconsIsActive(usefulconss[c]) && !SCIPconsIsModifiable(usefulconss[c]));
16681  SCIP_CALL( preprocessConstraintPairs(scip, usefulconss, firstchange, c, conshdlrdata->maxaggrnormscale,
16682  &cutoff, ndelconss, nchgsides, nchgcoefs) );
16683 
16684  if( npaircomparisons > conshdlrdata->nmincomparisons )
16685  {
16686  assert(npaircomparisons > 0);
16687  if( ((*ndelconss - oldndelconss) + (*nchgsides - oldnchgsides)/2.0 + (*nchgcoefs - oldnchgcoefs)/10.0) / ((SCIP_Real) npaircomparisons) < conshdlrdata->mingainpernmincomp )
16688  break;
16689  oldndelconss = *ndelconss;
16690  oldnchgsides = *nchgsides;
16691  oldnchgcoefs = *nchgcoefs;
16692  npaircomparisons = 0;
16693  }
16694  }
16695  /* free temporary memory */
16696  SCIPfreeBufferArray(scip, &usefulconss);
16697  }
16698  }
16699 
16700  /* before upgrading, check whether we can apply some additional dual presolving, because a variable only appears
16701  * in linear constraints and we therefore have full information about it
16702  */
16703  if( !cutoff && firstupgradetry < nconss
16704  && *nfixedvars == oldnfixedvars && *naggrvars == oldnaggrvars && *nchgbds == oldnchgbds && *ndelconss == oldndelconss
16705  && *nupgdconss == oldnupgdconss && *nchgcoefs == oldnchgcoefs && *nchgsides == oldnchgsides
16706  )
16707  {
16708  if( conshdlrdata->dualpresolving && SCIPallowStrongDualReds(scip) && !SCIPisStopped(scip) )
16709  {
16710  SCIP_CALL( fullDualPresolve(scip, conss, nconss, &cutoff, nchgbds) );
16711  }
16712  }
16713 
16714  /* try to upgrade constraints into a more specific constraint type;
16715  * only upgrade constraints, if no reductions were found in this round (otherwise, the linear constraint handler
16716  * may find additional reductions before giving control away to other (less intelligent?) constraint handlers)
16717  */
16718  if( !cutoff && (presoltiming & SCIP_PRESOLTIMING_EXHAUSTIVE) != 0 && SCIPisPresolveFinished(scip) )
16719  {
16720  for( c = firstupgradetry; c < nconss && !SCIPisStopped(scip); ++c )
16721  {
16722  cons = conss[c];
16723 
16724  /* don't upgrade modifiable constraints */
16725  if( SCIPconsIsModifiable(cons) )
16726  continue;
16727 
16728  consdata = SCIPconsGetData(cons);
16729  assert(consdata != NULL);
16730 
16731  /* only upgrade completely presolved constraints, that changed since the last upgrading call */
16732  if( consdata->upgradetried )
16733  continue;
16734  /* @todo force that upgrade will be performed later? */
16735  if( !consdata->presolved )
16736  continue;
16737 
16738  consdata->upgradetried = TRUE;
16739  if( SCIPconsIsActive(cons) )
16740  {
16741  SCIP_CONS* upgdcons;
16742 
16743  SCIP_CALL( SCIPupgradeConsLinear(scip, cons, &upgdcons) );
16744  if( upgdcons != NULL )
16745  {
16746  /* add the upgraded constraint to the problem */
16747  SCIP_CALL( SCIPaddCons(scip, upgdcons) );
16748  SCIP_CALL( SCIPreleaseCons(scip, &upgdcons) );
16749  (*nupgdconss)++;
16750 
16751  /* mark the linear constraint being upgraded and to be removed after presolving;
16752  * don't delete it directly, because it may help to preprocess other linear constraints
16753  */
16754  assert(!consdata->upgraded);
16755  consdata->upgraded = TRUE;
16756 
16757  /* delete upgraded inequalities immediately;
16758  * delete upgraded equalities, if we don't need it anymore for aggregation and redundancy checking
16759  */
16760  if( SCIPisLT(scip, consdata->lhs, consdata->rhs)
16761  || !conshdlrdata->presolpairwise
16762  || (conshdlrdata->maxaggrnormscale == 0.0) )
16763  {
16764  SCIP_CALL( SCIPdelCons(scip, cons) );
16765  }
16766  }
16767  }
16768  }
16769  }
16770 
16771  /* return the correct result code */
16772  if( cutoff )
16773  *result = SCIP_CUTOFF;
16774  else if( *nfixedvars > oldnfixedvars || *naggrvars > oldnaggrvars || *nchgbds > oldnchgbds || *ndelconss > oldndelconss
16775  || *nupgdconss > oldnupgdconss || *nchgcoefs > oldnchgcoefs || *nchgsides > oldnchgsides )
16776  *result = SCIP_SUCCESS;
16777  else
16778  *result = SCIP_DIDNOTFIND;
16779 
16780  return SCIP_OKAY;
16781 }
16782 
16783 
16784 /** propagation conflict resolving method of constraint handler */
16785 static
16786 SCIP_DECL_CONSRESPROP(consRespropLinear)
16787 { /*lint --e{715}*/
16788  assert(scip != NULL);
16789  assert(cons != NULL);
16790  assert(result != NULL);
16791 
16792  SCIP_CALL( resolvePropagation(scip, cons, infervar, intToInferInfo(inferinfo), boundtype, bdchgidx, result) );
16793 
16794  return SCIP_OKAY;
16795 }
16796 
16797 
16798 /** variable rounding lock method of constraint handler */
16799 static
16800 SCIP_DECL_CONSLOCK(consLockLinear)
16801 { /*lint --e{715}*/
16802  SCIP_CONSDATA* consdata;
16803  SCIP_Bool haslhs;
16804  SCIP_Bool hasrhs;
16805  int i;
16806 
16807  assert(scip != NULL);
16808  assert(cons != NULL);
16809  consdata = SCIPconsGetData(cons);
16810  assert(consdata != NULL);
16811 
16812  haslhs = !SCIPisInfinity(scip, -consdata->lhs);
16813  hasrhs = !SCIPisInfinity(scip, consdata->rhs);
16814 
16815  /* update rounding locks of every single variable */
16816  for( i = 0; i < consdata->nvars; ++i )
16817  {
16818  if( SCIPisPositive(scip, consdata->vals[i]) )
16819  {
16820  if( haslhs )
16821  {
16822  SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlockspos, nlocksneg) );
16823  }
16824  if( hasrhs )
16825  {
16826  SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlocksneg, nlockspos) );
16827  }
16828  }
16829  else
16830  {
16831  if( haslhs )
16832  {
16833  SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlocksneg, nlockspos) );
16834  }
16835  if( hasrhs )
16836  {
16837  SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlockspos, nlocksneg) );
16838  }
16839  }
16840  }
16841 
16842  return SCIP_OKAY;
16843 }
16844 
16845 
16846 /** variable deletion method of constraint handler */
16847 static
16848 SCIP_DECL_CONSDELVARS(consDelvarsLinear)
16849 {
16850  assert(scip != NULL);
16851  assert(conshdlr != NULL);
16852  assert(conss != NULL || nconss == 0);
16853 
16854  if( nconss > 0 )
16855  {
16856  SCIP_CALL( performVarDeletions(scip, conshdlr, conss, nconss) );
16857  }
16858 
16859  return SCIP_OKAY;
16860 }
16861 
16862 /** constraint display method of constraint handler */
16863 static
16864 SCIP_DECL_CONSPRINT(consPrintLinear)
16865 { /*lint --e{715}*/
16866  assert(scip != NULL);
16867  assert(conshdlr != NULL);
16868  assert(cons != NULL);
16869 
16870  SCIP_CALL( consdataPrint(scip, SCIPconsGetData(cons), file) );
16871 
16872  return SCIP_OKAY;
16873 }
16874 
16875 /** constraint copying method of constraint handler */
16876 static
16877 SCIP_DECL_CONSCOPY(consCopyLinear)
16878 { /*lint --e{715}*/
16879  SCIP_VAR** sourcevars;
16880  SCIP_Real* sourcecoefs;
16881  const char* consname;
16882  int nvars;
16884  assert(scip != NULL);
16885  assert(sourcescip != NULL);
16886  assert(sourcecons != NULL);
16887 
16888  /* get variables and coefficients of the source constraint */
16889  sourcevars = SCIPgetVarsLinear(sourcescip, sourcecons);
16890  sourcecoefs = SCIPgetValsLinear(sourcescip, sourcecons);
16891  nvars = SCIPgetNVarsLinear(sourcescip, sourcecons);
16892 
16893  if( name != NULL )
16894  consname = name;
16895  else
16896  consname = SCIPconsGetName(sourcecons);
16897 
16898  SCIP_CALL( SCIPcopyConsLinear(scip, cons, sourcescip, consname, nvars, sourcevars, sourcecoefs,
16899  SCIPgetLhsLinear(sourcescip, sourcecons), SCIPgetRhsLinear(sourcescip, sourcecons), varmap, consmap,
16900  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, global, valid) );
16901  assert(cons != NULL || *valid == FALSE);
16902 
16903  /* @todo should also the checkabsolute flag of the constraint be copied? */
16904 
16905  return SCIP_OKAY;
16906 }
16907 
16908 /** find operators '<=', '==', '>=', [free] in input string and return those places
16909  *
16910  * There should only be one operator, except for ranged rows for which exactly two operators '<=' must be present.
16911  */
16912 static
16913 void findOperators(
16914  const char* str, /**< null terminated input string */
16915  char** firstoperator, /**< pointer to store the string starting at the first operator */
16916  char** secondoperator, /**< pointer to store the string starting at the second operator */
16917  SCIP_Bool* success /**< pointer to store if the line contains a valid operator order */
16918  )
16919 {
16920  char* curr;
16921 
16922  assert(str != NULL);
16923  assert(firstoperator != NULL);
16924  assert(secondoperator != NULL);
16925 
16926  *firstoperator = NULL;
16927  *secondoperator = NULL;
16928 
16929  curr = (char*)str;
16930  *success = TRUE;
16931 
16932  /* loop over the input string to find all operators */
16933  while( *curr && *success )
16934  {
16935  SCIP_Bool found = FALSE;
16936  int increment = 1;
16937 
16938  /* try if we found a possible operator */
16939  switch( *curr )
16940  {
16941  case '<':
16942  case '=':
16943  case '>':
16944 
16945  /* check if the two characters curr[0,1] form an operator together */
16946  if( curr[1] == '=' )
16947  {
16948  found = TRUE;
16949 
16950  /* update increment to continue after this operator */
16951  increment = 2;
16952  }
16953  break;
16954  case '[':
16955  if( strncmp(curr, "[free]", 6) == 0 )
16956  {
16957  found = TRUE;
16958 
16959  /* update increment to continue after this operator */
16960  increment = 6;
16961  }
16962  break;
16963  default:
16964  break;
16965  }
16966 
16967  /* assign the found operator to the first or second pointer and check for violations of the linear constraint grammar */
16968  if( found )
16969  {
16970  if( *firstoperator == NULL )
16971  {
16972  *firstoperator = curr;
16973  }
16974  else
16975  {
16976  if( *secondoperator != NULL )
16977  {
16978  SCIPerrorMessage("Found more than two operators in line %s\n", str);
16979  *success = FALSE;
16980  }
16981  else if( strncmp(*firstoperator, "<=", 2) != 0 )
16982  {
16983  SCIPerrorMessage("Two operators in line that is not a ranged row: %s", str);
16984  *success = FALSE;
16985  }
16986  else if( strncmp(curr, "<=", 2) != 0 )
16987  {
16988  SCIPerrorMessage("Bad second operator, expected ranged row specification: %s", str);
16989  *success = FALSE;
16990  }
16991 
16992  *secondoperator = curr;
16993  }
16994  }
16995 
16996  curr += increment;
16997  }
16998 
16999  /* check if we did find at least one operator */
17000  if( *success )
17001  {
17002  if( *firstoperator == NULL )
17003  {
17004  SCIPerrorMessage("Could not find any operator in line %s\n", str);
17005  *success = FALSE;
17006  }
17007  }
17008 }
17009 
17010 /** constraint parsing method of constraint handler */
17011 static
17012 SCIP_DECL_CONSPARSE(consParseLinear)
17013 { /*lint --e{715}*/
17014  SCIP_VAR** vars;
17015  SCIP_Real* coefs;
17016  int nvars;
17017  int coefssize;
17018  int requsize;
17019  SCIP_Real lhs;
17020  SCIP_Real rhs;
17021  char* endptr;
17022  char* firstop;
17023  char* secondop;
17024  SCIP_Bool operatorsuccess;
17025  char* lhsstrptr;
17026  char* rhsstrptr;
17027  char* varstrptr;
17028 
17029  assert(scip != NULL);
17030  assert(success != NULL);
17031  assert(str != NULL);
17032  assert(name != NULL);
17033  assert(cons != NULL);
17034 
17035  /* set left and right hand side to their default values */
17036  lhs = -SCIPinfinity(scip);
17037  rhs = SCIPinfinity(scip);
17038 
17039  (*success) = FALSE;
17040 
17041  /* return of string empty */
17042  if( !*str )
17043  return SCIP_OKAY;
17044 
17045  /* ignore whitespace */
17046  while( isspace((unsigned char)*str) )
17047  ++str;
17048 
17049  /* find operators in the line first, all other remaining parsing depends on occurence of the operators '<=', '>=', '==',
17050  * and the special word [free]
17051  */
17052  findOperators(str, &firstop, &secondop, &operatorsuccess);
17053 
17054  /* if the grammar is not valid for parsing a linear constraint, return */
17055  if( ! operatorsuccess )
17056  return SCIP_OKAY;
17057 
17058  varstrptr = (char *)str;
17059  lhsstrptr = rhsstrptr = NULL;
17060  assert(firstop != NULL);
17061 
17062  /* assign the strings for parsing the left hand side, right hand side, and the linear variable sum */
17063  switch( *firstop )
17064  {
17065  case '<':
17066  assert(firstop[1] == '=');
17067  /* we have ranged row lhs <= a_1 x_1 + ... + a_n x_n <= rhs */
17068  if( secondop != NULL )
17069  {
17070  assert(secondop[0] == '<' && secondop[1] == '=');
17071  lhsstrptr = (char *)str;
17072  varstrptr = firstop + 2;
17073  rhsstrptr = secondop + 2;
17074  }
17075  else
17076  {
17077  /* we have an inequality with infinite left hand side a_1 x_1 + ... + a_n x_n <= rhs */
17078  lhsstrptr = NULL;
17079  varstrptr = (char *)str;
17080  rhsstrptr = firstop + 2;
17081  }
17082  break;
17083  case '>':
17084  assert(firstop[1] == '=');
17085  assert(secondop == NULL);
17086  /* we have a_1 x_1 + ... + a_n x_n >= lhs */
17087  lhsstrptr = firstop + 2;
17088  break;
17089  case '=':
17090  assert(firstop[1] == '=');
17091  assert(secondop == NULL);
17092  /* we have a_1 x_1 + ... + a_n x_n == lhs (rhs) */
17093  rhsstrptr = firstop + 2;
17094  lhsstrptr = firstop + 2;
17095  break;
17096  case '[':
17097  assert(strncmp(firstop, "[free]", 6) == 0);
17098  assert(secondop == NULL);
17099  /* nothing to assign in case of a free a_1 x_1 + ... + a_n x_n [free] */
17100  break;
17101  default:
17102  /* it should not be possible that a different character appears in that position */
17103  SCIPerrorMessage("Parsing has wrong operator character '%c', should be one of <=>[", *firstop);
17104  return SCIP_READERROR;
17105  }
17106 
17107  /* parse left hand side, if necessary */
17108  if( lhsstrptr != NULL )
17109  {
17110  if( ! SCIPparseReal(scip, lhsstrptr, &lhs, &endptr) )
17111  {
17112  SCIPerrorMessage("error parsing left hand side number from <%s>\n", lhsstrptr);
17113  return SCIP_OKAY;
17114  }
17115 
17116  /* in case of an equation, assign the left also to the right hand side */
17117  if( rhsstrptr == lhsstrptr )
17118  rhs = lhs;
17119  }
17120 
17121  /* parse right hand side, if different from left hand side */
17122  if( rhsstrptr != NULL && rhsstrptr != lhsstrptr )
17123  {
17124  if( ! SCIPparseReal(scip, rhsstrptr, &rhs, &endptr) )
17125  {
17126  SCIPerrorMessage("error parsing right hand side number from <%s>\n", lhsstrptr);
17127  return SCIP_OKAY;
17128  }
17129  }
17130 
17131  /* initialize buffers for storing the variables and coefficients */
17132  coefssize = 100;
17133  SCIP_CALL( SCIPallocBufferArray(scip, &vars, coefssize) );
17134  SCIP_CALL( SCIPallocBufferArray(scip, &coefs, coefssize) );
17135 
17136  assert(varstrptr != NULL);
17137 
17138  /* parse linear sum to get variables and coefficients */
17139  SCIP_CALL( SCIPparseVarsLinearsum(scip, varstrptr, vars, coefs, &nvars, coefssize, &requsize, &endptr, success) );
17140 
17141  if( *success && requsize > coefssize )
17142  {
17143  /* realloc buffers and try again */
17144  coefssize = requsize;
17145  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, coefssize) );
17146  SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, coefssize) );
17147 
17148  SCIP_CALL( SCIPparseVarsLinearsum(scip, varstrptr, vars, coefs, &nvars, coefssize, &requsize, &endptr, success) );
17149  assert(!*success || requsize <= coefssize); /* if successful, then should have had enough space now */
17150  }
17151 
17152  if( !*success )
17153  {
17154  SCIPerrorMessage("no luck in parsing linear sum '%s'\n", varstrptr);
17155  }
17156  else
17157  {
17158  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
17159  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
17160  }
17161 
17162  SCIPfreeBufferArray(scip, &coefs);
17163  SCIPfreeBufferArray(scip, &vars);
17164 
17165  return SCIP_OKAY;
17166 }
17167 
17168 
17169 /** constraint method of constraint handler which returns the variables (if possible) */
17170 static
17171 SCIP_DECL_CONSGETVARS(consGetVarsLinear)
17172 { /*lint --e{715}*/
17173  SCIP_CONSDATA* consdata;
17174 
17175  consdata = SCIPconsGetData(cons);
17176  assert(consdata != NULL);
17177 
17178  if( varssize < consdata->nvars )
17179  (*success) = FALSE;
17180  else
17181  {
17182  assert(vars != NULL);
17183 
17184  BMScopyMemoryArray(vars, consdata->vars, consdata->nvars);
17185  (*success) = TRUE;
17186  }
17187 
17188  return SCIP_OKAY;
17189 }
17191 /**! [Callback for the number of variables]*/
17192 /** constraint method of constraint handler which returns the number of variables (if possible) */
17193 static
17194 SCIP_DECL_CONSGETNVARS(consGetNVarsLinear)
17195 { /*lint --e{715}*/
17196  SCIP_CONSDATA* consdata;
17197 
17198  consdata = SCIPconsGetData(cons);
17199  assert(consdata != NULL);
17200 
17201  (*nvars) = consdata->nvars;
17202  (*success) = TRUE;
17203 
17204  return SCIP_OKAY;
17205 }
17206 /**! [Callback for the number of variables]*/
17207 
17208 /*
17209  * Callback methods of event handler
17210  */
17211 
17212 /** execution method of event handler */
17213 static
17214 SCIP_DECL_EVENTEXEC(eventExecLinear)
17215 { /*lint --e{715}*/
17216  SCIP_CONS* cons;
17217  SCIP_CONSDATA* consdata;
17218  SCIP_VAR* var;
17219  SCIP_EVENTTYPE eventtype;
17220 
17221  assert(scip != NULL);
17222  assert(eventhdlr != NULL);
17223  assert(eventdata != NULL);
17224  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
17225  assert(event != NULL);
17226 
17227  cons = eventdata->cons;
17228  assert(cons != NULL);
17229  consdata = SCIPconsGetData(cons);
17230  assert(consdata != NULL);
17231 
17232  /* we can skip events droped for deleted constraints */
17233  if( SCIPconsIsDeleted(cons) )
17234  return SCIP_OKAY;
17235 
17236  eventtype = SCIPeventGetType(event);
17237  var = SCIPeventGetVar(event);
17238 
17239  if( (eventtype & SCIP_EVENTTYPE_BOUNDCHANGED) != 0 )
17240  {
17241  SCIP_Real oldbound;
17242  SCIP_Real newbound;
17243  SCIP_Real val;
17244  int varpos;
17245 
17246  varpos = eventdata->varpos;
17247  assert(0 <= varpos && varpos < consdata->nvars);
17248  oldbound = SCIPeventGetOldbound(event);
17249  newbound = SCIPeventGetNewbound(event);
17250  assert(var != NULL);
17251  assert(consdata->vars[varpos] == var);
17252  val = consdata->vals[varpos];
17253 
17254  /* we only need to update the activities if the constraint is active,
17255  * otherwise we mark them to be invalid
17256  */
17257  if( SCIPconsIsActive(cons) )
17258  {
17259  /* update the activity values */
17260  if( (eventtype & SCIP_EVENTTYPE_LBCHANGED) != 0 )
17261  consdataUpdateActivitiesLb(scip, consdata, var, oldbound, newbound, val, TRUE);
17262  else
17263  {
17264  assert((eventtype & SCIP_EVENTTYPE_UBCHANGED) != 0);
17265  consdataUpdateActivitiesUb(scip, consdata, var, oldbound, newbound, val, TRUE);
17266  }
17267  }
17268  else
17269  consdataInvalidateActivities(consdata);
17270 
17271  consdata->presolved = FALSE;
17272  consdata->rangedrowpropagated = 0;
17273 
17274  /* bound change can turn the constraint infeasible or redundant only if it was a tightening */
17275  if( (eventtype & SCIP_EVENTTYPE_BOUNDTIGHTENED) != 0 )
17276  {
17277  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
17278 
17279  /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
17280  if( consdata->maxactdeltavar == var )
17281  {
17282  consdata->maxactdelta = SCIP_INVALID;
17283  consdata->maxactdeltavar = NULL;
17284  }
17285 
17286  /* check whether bound tightening might now be successful */
17287  if( consdata->boundstightened > 0)
17288  {
17289  switch( eventtype )
17290  {
17292  if( (val > 0.0 ? !SCIPisInfinity(scip, consdata->rhs) : !SCIPisInfinity(scip, -consdata->lhs)) )
17293  consdata->boundstightened = 0;
17294  break;
17296  if( (val > 0.0 ? !SCIPisInfinity(scip, -consdata->lhs) : !SCIPisInfinity(scip, consdata->rhs)) )
17297  consdata->boundstightened = 0;
17298  break;
17299  default:
17300  SCIPerrorMessage("invalid event type %" SCIP_EVENTTYPE_FORMAT "\n", eventtype);
17301  return SCIP_INVALIDDATA;
17302  }
17303  }
17304  }
17305  /* update maximal activity delta if a bound was relaxed */
17306  else if( !SCIPisInfinity(scip, consdata->maxactdelta) )
17307  {
17308  SCIP_Real lb;
17309  SCIP_Real ub;
17310  SCIP_Real domain;
17311  SCIP_Real delta;
17312 
17313  assert((eventtype & SCIP_EVENTTYPE_BOUNDRELAXED) != 0);
17314 
17315  lb = SCIPvarGetLbLocal(var);
17316  ub = SCIPvarGetUbLocal(var);
17317 
17318  domain = ub - lb;
17319  delta = REALABS(val) * domain;
17320 
17321  if( delta > consdata->maxactdelta )
17322  {
17323  consdata->maxactdelta = delta;
17324  consdata->maxactdeltavar = var;
17325  }
17326  }
17327  }
17328  else if( (eventtype & SCIP_EVENTTYPE_VARFIXED) != 0 )
17329  {
17330  /* we want to remove the fixed variable */
17331  consdata->presolved = FALSE;
17332  consdata->removedfixings = FALSE;
17333  consdata->rangedrowpropagated = 0;
17334 
17335  /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
17336  if( consdata->maxactdeltavar == var )
17337  {
17338  consdata->maxactdelta = SCIP_INVALID;
17339  consdata->maxactdeltavar = NULL;
17340  }
17341  }
17342  else if( (eventtype & SCIP_EVENTTYPE_VARUNLOCKED) != 0 )
17343  {
17344  /* there is only one lock left: we may multi-aggregate the variable as slack of an equation */
17345  assert(SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) <= 1);
17346  assert(SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) <= 1);
17347  consdata->presolved = FALSE;
17348  }
17349  else if( (eventtype & SCIP_EVENTTYPE_GBDCHANGED) != 0 )
17350  {
17351  SCIP_Real oldbound;
17352  SCIP_Real newbound;
17353  SCIP_Real val;
17354  int varpos;
17355 
17356  varpos = eventdata->varpos;
17357  assert(0 <= varpos && varpos < consdata->nvars);
17358  oldbound = SCIPeventGetOldbound(event);
17359  newbound = SCIPeventGetNewbound(event);
17360  assert(var != NULL);
17361  assert(consdata->vars[varpos] == var);
17362  val = consdata->vals[varpos];
17363 
17364  consdata->rangedrowpropagated = 0;
17365 
17366  /* update the activity values */
17367  if( (eventtype & SCIP_EVENTTYPE_GLBCHANGED) != 0 )
17368  consdataUpdateActivitiesGlbLb(scip, consdata, oldbound, newbound, val, TRUE);
17369  else
17370  {
17371  assert((eventtype & SCIP_EVENTTYPE_GUBCHANGED) != 0);
17372  consdataUpdateActivitiesGlbUb(scip, consdata, oldbound, newbound, val, TRUE);
17373  }
17374 
17375  /* if the variable is binary but not fixed it had to become binary due to this global change */
17376  if( SCIPvarIsBinary(var) && SCIPisGT(scip, SCIPvarGetUbGlobal(var), SCIPvarGetLbGlobal(var)) )
17377  {
17378  if( SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE )
17379  consdata->indexsorted = FALSE;
17380  else
17381  consdata->coefsorted = FALSE;
17382  }
17383  }
17384  else if( (eventtype & SCIP_EVENTTYPE_TYPECHANGED) != 0 )
17385  {
17386  assert(SCIPgetStage(scip) < SCIP_STAGE_PRESOLVED);
17387 
17388  /* for presolving it only matters if a variable type changed from continuous to some kind of integer */
17389  consdata->presolved = (consdata->presolved && SCIPeventGetOldtype(event) < SCIP_VARTYPE_CONTINUOUS);
17390 
17391  /* the ordering is preserved if the type changes from something different to binary to binary but SCIPvarIsBinary() is true */
17392  consdata->indexsorted = (consdata->indexsorted && SCIPeventGetNewtype(event) == SCIP_VARTYPE_BINARY && SCIPvarIsBinary(var));
17393  }
17394  else
17395  {
17396  assert((eventtype & SCIP_EVENTTYPE_VARDELETED) != 0);
17397  consdata->varsdeleted = TRUE;
17398  }
17399 
17400  return SCIP_OKAY;
17401 }
17402 
17403 
17404 /*
17405  * Callback methods of conflict handler
17406  */
17407 
17408 /** conflict processing method of conflict handler (called when conflict was found) */
17409 static
17410 SCIP_DECL_CONFLICTEXEC(conflictExecLinear)
17411 { /*lint --e{715}*/
17412  SCIP_VAR** vars;
17413  SCIP_Real* vals;
17414  SCIP_Real lhs;
17415  int i;
17416 
17417  assert(scip != NULL);
17418  assert(conflicthdlr != NULL);
17419  assert(strcmp(SCIPconflicthdlrGetName(conflicthdlr), CONFLICTHDLR_NAME) == 0);
17420  assert(bdchginfos != NULL || nbdchginfos == 0);
17421  assert(result != NULL);
17422 
17423  /* don't process already resolved conflicts */
17424  if( resolved )
17425  {
17426  *result = SCIP_DIDNOTRUN;
17427  return SCIP_OKAY;
17428  }
17430  *result = SCIP_DIDNOTFIND;
17431 
17432  /* create array of variables and coefficients: sum_{i \in P} x_i - sum_{i \in N} x_i >= 1 - |N| */
17433  SCIP_CALL( SCIPallocBufferArray(scip, &vars, nbdchginfos) );
17434  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nbdchginfos) );
17435  lhs = 1.0;
17436  for( i = 0; i < nbdchginfos; ++i )
17437  {
17438  assert(bdchginfos != NULL);
17439 
17440  vars[i] = SCIPbdchginfoGetVar(bdchginfos[i]);
17441 
17442  /* we can only treat binary variables */
17443  /**@todo extend linear conflict constraints to some non-binary cases */
17444  if( !SCIPvarIsBinary(vars[i]) )
17445  break;
17446 
17447  /* check whether the variable is fixed to zero (P) or one (N) in the conflict set */
17448  if( SCIPbdchginfoGetNewbound(bdchginfos[i]) < 0.5 )
17449  vals[i] = 1.0;
17450  else
17451  {
17452  vals[i] = -1.0;
17453  lhs -= 1.0;
17454  }
17455  }
17456 
17457  if( i == nbdchginfos )
17458  {
17459  SCIP_CONS* cons;
17460  SCIP_CONS* upgdcons;
17461  char consname[SCIP_MAXSTRLEN];
17462 
17463  /* create a constraint out of the conflict set */
17464  (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "cf%" SCIP_LONGINT_FORMAT, SCIPgetNConflictConssApplied(scip));
17465  SCIP_CALL( SCIPcreateConsLinear(scip, &cons, consname, nbdchginfos, vars, vals, lhs, SCIPinfinity(scip),
17466  FALSE, separate, FALSE, FALSE, TRUE, local, FALSE, dynamic, removable, FALSE) );
17467 
17468  /* try to automatically convert a linear constraint into a more specific and more specialized constraint */
17469  SCIP_CALL( SCIPupgradeConsLinear(scip, cons, &upgdcons) );
17470  if( upgdcons != NULL )
17471  {
17472  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
17473  cons = upgdcons;
17474  }
17475 
17476  /* add conflict to SCIP */
17477  SCIP_CALL( SCIPaddConflict(scip, node, cons, validnode, conftype, cutoffinvolved) );
17478 
17479  *result = SCIP_CONSADDED;
17480  }
17481 
17482  /* free temporary memory */
17483  SCIPfreeBufferArray(scip, &vals);
17484  SCIPfreeBufferArray(scip, &vars);
17485 
17486  return SCIP_OKAY;
17487 }
17488 
17489 
17490 /*
17491  * Nonlinear constraint upgrading
17492  */
17493 
17494 /** tries to upgrade a nonlinear constraint into a linear constraint */
17495 static
17496 SCIP_DECL_NONLINCONSUPGD(upgradeConsNonlinear)
17497 {
17498  SCIP_CONSDATA* consdata;
17499  SCIP_EXPR* expr;
17500  SCIP_Real lhs;
17501  SCIP_Real rhs;
17502  int i;
17503 
17504  assert(nupgdconss != NULL);
17505  assert(upgdconss != NULL);
17506  assert(upgdconsssize > 0);
17507 
17508  expr = SCIPgetExprNonlinear(cons);
17509  assert(expr != NULL);
17510 
17511  /* not a linear constraint if the expression is not a sum
17512  * (unless the expression is a variable or a constant or a constant*variable, but these are simplified away in cons_nonlinear)
17513  */
17514  if( !SCIPisExprSum(scip, expr) )
17515  return SCIP_OKAY;
17516 
17517  /* if at least one child is not a variable, then not a linear constraint */
17518  for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
17519  if( !SCIPisExprVar(scip, SCIPexprGetChildren(expr)[i]) )
17520  return SCIP_OKAY;
17521 
17522  /* consider constant part of the sum expression */
17523  lhs = SCIPisInfinity(scip, -SCIPgetLhsNonlinear(cons)) ? -SCIPinfinity(scip) : (SCIPgetLhsNonlinear(cons) - SCIPgetConstantExprSum(expr));
17524  rhs = SCIPisInfinity(scip, SCIPgetRhsNonlinear(cons)) ? SCIPinfinity(scip) : (SCIPgetRhsNonlinear(cons) - SCIPgetConstantExprSum(expr));
17525 
17526  SCIP_CALL( SCIPcreateConsLinear(scip, &upgdconss[0], SCIPconsGetName(cons),
17527  0, NULL, NULL, lhs, rhs,
17531  SCIPconsIsStickingAtNode(cons)) );
17532  assert(upgdconss[0] != NULL);
17533 
17534  consdata = SCIPconsGetData(upgdconss[0]);
17535 
17536  /* add linear terms */
17537  SCIP_CALL( consdataEnsureVarsSize(scip, consdata, SCIPexprGetNChildren(expr)) );
17538  for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
17539  {
17540  SCIP_CALL( addCoef(scip, upgdconss[0], SCIPgetVarExprVar(SCIPexprGetChildren(expr)[i]), SCIPgetCoefsExprSum(expr)[i]) );
17541  }
17542 
17543  /* check violation of this linear constraint with absolute tolerances, to be consistent with the original nonlinear constraint */
17544  consdata->checkabsolute = TRUE;
17545 
17546  *nupgdconss = 1;
17547 
17548  SCIPdebugMsg(scip, "created linear constraint:\n");
17549  SCIPdebugPrintCons(scip, upgdconss[0], NULL);
17550 
17551  return SCIP_OKAY;
17552 } /*lint !e715*/
17553 
17554 /*
17555  * constraint specific interface methods
17556  */
17557 
17558 /** creates the handler for linear constraints and includes it in SCIP */
17560  SCIP* scip /**< SCIP data structure */
17561  )
17562 {
17563  SCIP_CONSHDLRDATA* conshdlrdata;
17564  SCIP_CONSHDLR* conshdlr;
17565  SCIP_EVENTHDLR* eventhdlr;
17566  SCIP_CONFLICTHDLR* conflicthdlr;
17567 
17568  assert(scip != NULL);
17569 
17570  /* create event handler for bound change events */
17572  eventExecLinear, NULL) );
17573 
17574  /* create conflict handler for linear constraints */
17576  conflictExecLinear, NULL) );
17577 
17578  /* create constraint handler data */
17579  SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
17580 
17581  /* include constraint handler */
17584  consEnfolpLinear, consEnfopsLinear, consCheckLinear, consLockLinear,
17585  conshdlrdata) );
17586 
17587  assert(conshdlr != NULL);
17588 
17589  /* set non-fundamental callbacks via specific setter functions */
17590  SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyLinear, consCopyLinear) );
17591  SCIP_CALL( SCIPsetConshdlrActive(scip, conshdlr, consActiveLinear) );
17592  SCIP_CALL( SCIPsetConshdlrDeactive(scip, conshdlr, consDeactiveLinear) );
17593  SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteLinear) );
17594  SCIP_CALL( SCIPsetConshdlrDelvars(scip, conshdlr, consDelvarsLinear) );
17595  SCIP_CALL( SCIPsetConshdlrExit(scip, conshdlr, consExitLinear) );
17596  SCIP_CALL( SCIPsetConshdlrExitpre(scip, conshdlr, consExitpreLinear) );
17597  SCIP_CALL( SCIPsetConshdlrInitsol(scip, conshdlr, consInitsolLinear) );
17598  SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolLinear) );
17599  SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeLinear) );
17600  SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsLinear) );
17601  SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsLinear) );
17602  SCIP_CALL( SCIPsetConshdlrInit(scip, conshdlr, consInitLinear) );
17603  SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpLinear) );
17604  SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseLinear) );
17605  SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolLinear, CONSHDLR_MAXPREROUNDS, CONSHDLR_PRESOLTIMING) );
17606  SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintLinear) );
17607  SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropLinear, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP,
17609  SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropLinear) );
17610  SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpLinear, consSepasolLinear, CONSHDLR_SEPAFREQ,
17612  SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransLinear) );
17613  SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxLinear) );
17614 
17615  if( SCIPfindConshdlr(scip, "nonlinear") != NULL )
17616  {
17617  /* include the linear constraint upgrade in the nonlinear constraint handler */
17619  }
17620 
17621  /* add linear constraint handler parameters */
17622  SCIP_CALL( SCIPaddIntParam(scip,
17623  "constraints/" CONSHDLR_NAME "/tightenboundsfreq",
17624  "multiplier on propagation frequency, how often the bounds are tightened (-1: never, 0: only at root)",
17625  &conshdlrdata->tightenboundsfreq, TRUE, DEFAULT_TIGHTENBOUNDSFREQ, -1, SCIP_MAXTREEDEPTH, NULL, NULL) );
17626  SCIP_CALL( SCIPaddIntParam(scip,
17627  "constraints/" CONSHDLR_NAME "/maxrounds",
17628  "maximal number of separation rounds per node (-1: unlimited)",
17629  &conshdlrdata->maxrounds, FALSE, DEFAULT_MAXROUNDS, -1, INT_MAX, NULL, NULL) );
17630  SCIP_CALL( SCIPaddIntParam(scip,
17631  "constraints/" CONSHDLR_NAME "/maxroundsroot",
17632  "maximal number of separation rounds per node in the root node (-1: unlimited)",
17633  &conshdlrdata->maxroundsroot, FALSE, DEFAULT_MAXROUNDSROOT, -1, INT_MAX, NULL, NULL) );
17634  SCIP_CALL( SCIPaddIntParam(scip,
17635  "constraints/" CONSHDLR_NAME "/maxsepacuts",
17636  "maximal number of cuts separated per separation round",
17637  &conshdlrdata->maxsepacuts, FALSE, DEFAULT_MAXSEPACUTS, 0, INT_MAX, NULL, NULL) );
17638  SCIP_CALL( SCIPaddIntParam(scip,
17639  "constraints/" CONSHDLR_NAME "/maxsepacutsroot",
17640  "maximal number of cuts separated per separation round in the root node",
17641  &conshdlrdata->maxsepacutsroot, FALSE, DEFAULT_MAXSEPACUTSROOT, 0, INT_MAX, NULL, NULL) );
17643  "constraints/" CONSHDLR_NAME "/presolpairwise",
17644  "should pairwise constraint comparison be performed in presolving?",
17645  &conshdlrdata->presolpairwise, TRUE, DEFAULT_PRESOLPAIRWISE, NULL, NULL) );
17647  "constraints/" CONSHDLR_NAME "/presolusehashing",
17648  "should hash table be used for detecting redundant constraints in advance",
17649  &conshdlrdata->presolusehashing, TRUE, DEFAULT_PRESOLUSEHASHING, NULL, NULL) );
17650  SCIP_CALL( SCIPaddIntParam(scip,
17651  "constraints/" CONSHDLR_NAME "/nmincomparisons",
17652  "number for minimal pairwise presolve comparisons",
17653  &conshdlrdata->nmincomparisons, TRUE, DEFAULT_NMINCOMPARISONS, 1, INT_MAX, NULL, NULL) );
17655  "constraints/" CONSHDLR_NAME "/mingainpernmincomparisons",
17656  "minimal gain per minimal pairwise presolve comparisons to repeat pairwise comparison round",
17657  &conshdlrdata->mingainpernmincomp, TRUE, DEFAULT_MINGAINPERNMINCOMP, 0.0, 1.0, NULL, NULL) );
17659  "constraints/" CONSHDLR_NAME "/maxaggrnormscale",
17660  "maximal allowed relative gain in maximum norm for constraint aggregation (0.0: disable constraint aggregation)",
17661  &conshdlrdata->maxaggrnormscale, TRUE, DEFAULT_MAXAGGRNORMSCALE, 0.0, SCIP_REAL_MAX, NULL, NULL) );
17663  "constraints/" CONSHDLR_NAME "/maxeasyactivitydelta",
17664  "maximum activity delta to run easy propagation on linear constraint (faster, but numerically less stable)",
17665  &conshdlrdata->maxeasyactivitydelta, TRUE, DEFAULT_MAXEASYACTIVITYDELTA, 0.0, SCIP_REAL_MAX, NULL, NULL) );
17667  "constraints/" CONSHDLR_NAME "/maxcardbounddist",
17668  "maximal relative distance from current node's dual bound to primal bound compared to best node's dual bound for separating knapsack cardinality cuts",
17669  &conshdlrdata->maxcardbounddist, TRUE, DEFAULT_MAXCARDBOUNDDIST, 0.0, 1.0, NULL, NULL) );
17671  "constraints/" CONSHDLR_NAME "/separateall",
17672  "should all constraints be subject to cardinality cut generation instead of only the ones with non-zero dual value?",
17673  &conshdlrdata->separateall, FALSE, DEFAULT_SEPARATEALL, NULL, NULL) );
17675  "constraints/" CONSHDLR_NAME "/aggregatevariables",
17676  "should presolving search for aggregations in equations",
17677  &conshdlrdata->aggregatevariables, TRUE, DEFAULT_AGGREGATEVARIABLES, NULL, NULL) );
17679  "constraints/" CONSHDLR_NAME "/simplifyinequalities",
17680  "should presolving try to simplify inequalities",
17681  &conshdlrdata->simplifyinequalities, TRUE, DEFAULT_SIMPLIFYINEQUALITIES, NULL, NULL) );
17683  "constraints/" CONSHDLR_NAME "/dualpresolving",
17684  "should dual presolving steps be performed?",
17685  &conshdlrdata->dualpresolving, TRUE, DEFAULT_DUALPRESOLVING, NULL, NULL) );
17687  "constraints/" CONSHDLR_NAME "/singletonstuffing",
17688  "should stuffing of singleton continuous variables be performed?",
17689  &conshdlrdata->singletonstuffing, TRUE, DEFAULT_SINGLETONSTUFFING, NULL, NULL) );
17691  "constraints/" CONSHDLR_NAME "/singlevarstuffing",
17692  "should single variable stuffing be performed, which tries to fulfill constraints using the cheapest variable?",
17693  &conshdlrdata->singlevarstuffing, TRUE, DEFAULT_SINGLEVARSTUFFING, NULL, NULL) );
17695  "constraints/" CONSHDLR_NAME "/sortvars", "apply binaries sorting in decr. order of coeff abs value?",
17696  &conshdlrdata->sortvars, TRUE, DEFAULT_SORTVARS, NULL, NULL) );
17698  "constraints/" CONSHDLR_NAME "/checkrelmaxabs",
17699  "should the violation for a constraint with side 0.0 be checked relative to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)?",
17700  &conshdlrdata->checkrelmaxabs, TRUE, DEFAULT_CHECKRELMAXABS, NULL, NULL) );
17702  "constraints/" CONSHDLR_NAME "/detectcutoffbound",
17703  "should presolving try to detect constraints parallel to the objective function defining an upper bound and prevent these constraints from entering the LP?",
17704  &conshdlrdata->detectcutoffbound, TRUE, DEFAULT_DETECTCUTOFFBOUND, NULL, NULL) );
17706  "constraints/" CONSHDLR_NAME "/detectlowerbound",
17707  "should presolving try to detect constraints parallel to the objective function defining a lower bound and prevent these constraints from entering the LP?",
17708  &conshdlrdata->detectlowerbound, TRUE, DEFAULT_DETECTLOWERBOUND, NULL, NULL) );
17710  "constraints/" CONSHDLR_NAME "/detectpartialobjective",
17711  "should presolving try to detect subsets of constraints parallel to the objective function?",
17712  &conshdlrdata->detectpartialobjective, TRUE, DEFAULT_DETECTPARTIALOBJECTIVE, NULL, NULL) );
17714  "constraints/" CONSHDLR_NAME "/rangedrowpropagation",
17715  "should presolving and propagation try to improve bounds, detect infeasibility, and extract sub-constraints from ranged rows and equations?",
17716  &conshdlrdata->rangedrowpropagation, TRUE, DEFAULT_RANGEDROWPROPAGATION, NULL, NULL) );
17718  "constraints/" CONSHDLR_NAME "/rangedrowartcons",
17719  "should presolving and propagation extract sub-constraints from ranged rows and equations?",
17720  &conshdlrdata->rangedrowartcons, TRUE, DEFAULT_RANGEDROWARTCONS, NULL, NULL) );
17721  SCIP_CALL( SCIPaddIntParam(scip,
17722  "constraints/" CONSHDLR_NAME "/rangedrowmaxdepth",
17723  "maximum depth to apply ranged row propagation",
17724  &conshdlrdata->rangedrowmaxdepth, TRUE, DEFAULT_RANGEDROWMAXDEPTH, 0, INT_MAX, NULL, NULL) );
17725  SCIP_CALL( SCIPaddIntParam(scip,
17726  "constraints/" CONSHDLR_NAME "/rangedrowfreq",
17727  "frequency for applying ranged row propagation",
17728  &conshdlrdata->rangedrowfreq, TRUE, DEFAULT_RANGEDROWFREQ, 1, SCIP_MAXTREEDEPTH, NULL, NULL) );
17730  "constraints/" CONSHDLR_NAME "/multaggrremove",
17731  "should multi-aggregations only be performed if the constraint can be removed afterwards?",
17732  &conshdlrdata->multaggrremove, TRUE, DEFAULT_MULTAGGRREMOVE, NULL, NULL) );
17734  "constraints/" CONSHDLR_NAME "/maxmultaggrquot",
17735  "maximum coefficient dynamism (ie. maxabsval / minabsval) for primal multiaggregation",
17736  &conshdlrdata->maxmultaggrquot, TRUE, DEFAULT_MAXMULTAGGRQUOT, 1.0, SCIP_REAL_MAX, NULL, NULL) );
17738  "constraints/" CONSHDLR_NAME "/maxdualmultaggrquot",
17739  "maximum coefficient dynamism (ie. maxabsval / minabsval) for dual multiaggregation",
17740  &conshdlrdata->maxdualmultaggrquot, TRUE, DEFAULT_MAXDUALMULTAGGRQUOT, 1.0, SCIP_REAL_MAX, NULL, NULL) );
17742  "constraints/" CONSHDLR_NAME "/extractcliques",
17743  "should Cliques be extracted?",
17744  &conshdlrdata->extractcliques, TRUE, DEFAULT_EXTRACTCLIQUES, NULL, NULL) );
17745 
17746  return SCIP_OKAY;
17747 }
17748 
17749 /** includes a linear constraint update method into the linear constraint handler */
17751  SCIP* scip, /**< SCIP data structure */
17752  SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
17753  int priority, /**< priority of upgrading method */
17754  const char* conshdlrname /**< name of the constraint handler */
17755  )
17756 {
17757  SCIP_CONSHDLR* conshdlr;
17758  SCIP_CONSHDLRDATA* conshdlrdata;
17759  SCIP_LINCONSUPGRADE* linconsupgrade;
17760  char paramname[SCIP_MAXSTRLEN];
17761  char paramdesc[SCIP_MAXSTRLEN];
17762 
17763  assert(scip != NULL);
17764  assert(linconsupgd != NULL);
17765  assert(conshdlrname != NULL );
17766 
17767  /* find the linear constraint handler */
17768  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
17769  if( conshdlr == NULL )
17770  {
17771  SCIPerrorMessage("linear constraint handler not found\n");
17772  return SCIP_PLUGINNOTFOUND;
17773  }
17774 
17775  conshdlrdata = SCIPconshdlrGetData(conshdlr);
17776  assert(conshdlrdata != NULL);
17777 
17778  /* check if linear constraint update method already exists in constraint handler data */
17779  if( !conshdlrdataHasUpgrade(scip, conshdlrdata, linconsupgd, conshdlrname) )
17780  {
17781  /* create a linear constraint upgrade data object */
17782  SCIP_CALL( linconsupgradeCreate(scip, &linconsupgrade, linconsupgd, priority) );
17783 
17784  /* insert linear constraint update method into constraint handler data */
17785  SCIP_CALL( conshdlrdataIncludeUpgrade(scip, conshdlrdata, linconsupgrade) );
17786 
17787  /* adds parameter to turn on and off the upgrading step */
17788  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "constraints/linear/upgrade/%s", conshdlrname);
17789  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "enable linear upgrading for constraint handler <%s>", conshdlrname);
17791  paramname, paramdesc,
17792  &linconsupgrade->active, FALSE, TRUE, NULL, NULL) );
17793  }
17794 
17795  return SCIP_OKAY;
17796 }
17797 
17798 /** creates and captures a linear constraint
17799  *
17800  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
17801  */
17803  SCIP* scip, /**< SCIP data structure */
17804  SCIP_CONS** cons, /**< pointer to hold the created constraint */
17805  const char* name, /**< name of constraint */
17806  int nvars, /**< number of nonzeros in the constraint */
17807  SCIP_VAR** vars, /**< array with variables of constraint entries */
17808  SCIP_Real* vals, /**< array with coefficients of constraint entries */
17809  SCIP_Real lhs, /**< left hand side of constraint */
17810  SCIP_Real rhs, /**< right hand side of constraint */
17811  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
17812  * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
17813  SCIP_Bool separate, /**< should the constraint be separated during LP processing?
17814  * Usually set to TRUE. */
17815  SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
17816  * TRUE for model constraints, FALSE for additional, redundant constraints. */
17817  SCIP_Bool check, /**< should the constraint be checked for feasibility?
17818  * TRUE for model constraints, FALSE for additional, redundant constraints. */
17819  SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
17820  * Usually set to TRUE. */
17821  SCIP_Bool local, /**< is constraint only valid locally?
17822  * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
17823  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
17824  * Usually set to FALSE. In column generation applications, set to TRUE if pricing
17825  * adds coefficients to this constraint. */
17826  SCIP_Bool dynamic, /**< is constraint subject to aging?
17827  * Usually set to FALSE. Set to TRUE for own cuts which
17828  * are separated as constraints. */
17829  SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
17830  * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
17831  SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
17832  * if it may be moved to a more global node?
17833  * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
17834  )
17835 {
17836  SCIP_CONSHDLR* conshdlr;
17837  SCIP_CONSDATA* consdata;
17838 
17839  assert(scip != NULL);
17840  assert(cons != NULL);
17841 
17842  /* find the linear constraint handler */
17843  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
17844  if( conshdlr == NULL )
17845  {
17846  SCIPerrorMessage("linear constraint handler not found\n");
17847  return SCIP_PLUGINNOTFOUND;
17848  }
17849 
17850  /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
17851  * constraint after presolving we have to ensure that it holds active variables
17852  */
17853  if( SCIPgetStage(scip) >= SCIP_STAGE_EXITPRESOLVE && nvars > 0 )
17854  {
17855  SCIP_VAR** consvars;
17856  SCIP_Real* consvals;
17857  SCIP_Real constant = 0.0;
17858  int nconsvars;
17859  int requiredsize;
17860 
17861  nconsvars = nvars;
17862  SCIP_CALL( SCIPduplicateBufferArray(scip, &consvars, vars, nconsvars) );
17863  SCIP_CALL( SCIPduplicateBufferArray(scip, &consvals, vals, nconsvars) );
17864 
17865  /* get active variables for new constraint */
17866  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, nconsvars, &constant, &requiredsize, TRUE) );
17867 
17868  /* if space was not enough we need to resize the buffers */
17869  if( requiredsize > nconsvars )
17870  {
17871  SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
17872  SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
17873 
17874  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize, TRUE) );
17875  assert(requiredsize <= nconsvars);
17876  }
17877 
17878  /* adjust sides and check that we do not subtract infinity values */
17879  if( SCIPisInfinity(scip, REALABS(constant)) )
17880  {
17881  if( constant < 0.0 )
17882  {
17883  if( SCIPisInfinity(scip, lhs) )
17884  {
17885  SCIPfreeBufferArray(scip, &consvals);
17886  SCIPfreeBufferArray(scip, &consvars);
17887 
17888  SCIPerrorMessage("try to generate inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite left hand side of the constraint\n", name);
17889 
17890  SCIPABORT();
17891  return SCIP_INVALIDDATA; /*lint !e527*/
17892  }
17893  if( SCIPisInfinity(scip, rhs) )
17894  {
17895  SCIPfreeBufferArray(scip, &consvals);
17896  SCIPfreeBufferArray(scip, &consvars);
17897 
17898  SCIPerrorMessage("try to generate inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite right hand side of the constraint\n", name);
17899 
17900  SCIPABORT();
17901  return SCIP_INVALIDDATA; /*lint !e527*/
17902  }
17903 
17904  lhs = -SCIPinfinity(scip);
17905  rhs = -SCIPinfinity(scip);
17906  }
17907  else
17908  {
17909  if( SCIPisInfinity(scip, -lhs) )
17910  {
17911  SCIPfreeBufferArray(scip, &consvals);
17912  SCIPfreeBufferArray(scip, &consvars);
17913 
17914  SCIPerrorMessage("try to generate inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite left hand side of the constraint\n", name);
17915 
17916  SCIPABORT();
17917  return SCIP_INVALIDDATA; /*lint !e527*/
17918  }
17919  if( SCIPisInfinity(scip, -rhs) )
17920  {
17921  SCIPfreeBufferArray(scip, &consvals);
17922  SCIPfreeBufferArray(scip, &consvars);
17923 
17924  SCIPerrorMessage("try to generate inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite right hand side of the constraint\n", name);
17925 
17926  SCIPABORT();
17927  return SCIP_INVALIDDATA; /*lint !e527*/
17928  }
17929 
17930  lhs = SCIPinfinity(scip);
17931  rhs = SCIPinfinity(scip);
17932  }
17933  }
17934  else
17935  {
17936  if( !SCIPisInfinity(scip, REALABS(lhs)) )
17937  lhs -= constant;
17938  if( !SCIPisInfinity(scip, REALABS(rhs)) )
17939  rhs -= constant;
17940 
17941  if( SCIPisInfinity(scip, -lhs) )
17942  lhs = -SCIPinfinity(scip);
17943  else if( SCIPisInfinity(scip, lhs) )
17944  lhs = SCIPinfinity(scip);
17945 
17946  if( SCIPisInfinity(scip, rhs) )
17947  rhs = SCIPinfinity(scip);
17948  else if( SCIPisInfinity(scip, -rhs) )
17949  rhs = -SCIPinfinity(scip);
17950  }
17951 
17952  /* create constraint data */
17953  SCIP_CALL( consdataCreate(scip, &consdata, nconsvars, consvars, consvals, lhs, rhs) );
17954  assert(consdata != NULL);
17955 
17956  SCIPfreeBufferArray(scip, &consvals);
17957  SCIPfreeBufferArray(scip, &consvars);
17958  }
17959  else
17960  {
17961  /* create constraint data */
17962  SCIP_CALL( consdataCreate(scip, &consdata, nvars, vars, vals, lhs, rhs) );
17963  assert(consdata != NULL);
17964  }
17965 
17966 #ifndef NDEBUG
17967  /* if this is a checked or enforced constraints, then there must be no relaxation-only variables */
17968  if( check || enforce )
17969  {
17970  int n;
17971  for(n = consdata->nvars - 1; n >= 0; --n )
17972  assert(!SCIPvarIsRelaxationOnly(consdata->vars[n]));
17973  }
17974 #endif
17975 
17976  /* create constraint */
17977  SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
17978  local, modifiable, dynamic, removable, stickingatnode) );
17979 
17980  return SCIP_OKAY;
17981 }
17982 
17983 /** creates and captures a linear constraint
17984  * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
17985  * method SCIPcreateConsLinear(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
17986  *
17987  * @see SCIPcreateConsLinear() for information about the basic constraint flag configuration
17988  *
17989  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
17990  */
17992  SCIP* scip, /**< SCIP data structure */
17993  SCIP_CONS** cons, /**< pointer to hold the created constraint */
17994  const char* name, /**< name of constraint */
17995  int nvars, /**< number of nonzeros in the constraint */
17996  SCIP_VAR** vars, /**< array with variables of constraint entries */
17997  SCIP_Real* vals, /**< array with coefficients of constraint entries */
17998  SCIP_Real lhs, /**< left hand side of constraint */
17999  SCIP_Real rhs /**< right hand side of constraint */
18000  )
18001 {
18002  assert(scip != NULL);
18003 
18004  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, vals, lhs, rhs,
18005  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
18006 
18007  return SCIP_OKAY;
18008 }
18009 
18010 /** creates by copying and captures a linear constraint */
18012  SCIP* scip, /**< target SCIP data structure */
18013  SCIP_CONS** cons, /**< pointer to store the created target constraint */
18014  SCIP* sourcescip, /**< source SCIP data structure */
18015  const char* name, /**< name of constraint */
18016  int nvars, /**< number of variables in source variable array */
18017  SCIP_VAR** sourcevars, /**< source variables of the linear constraints */
18018  SCIP_Real* sourcecoefs, /**< coefficient array of the linear constraint, or NULL if all coefficients are one */
18019  SCIP_Real lhs, /**< left hand side of the linear constraint */
18020  SCIP_Real rhs, /**< right hand side of the linear constraint */
18021  SCIP_HASHMAP* varmap, /**< a SCIP_HASHMAP mapping variables of the source SCIP to corresponding
18022  * variables of the target SCIP */
18023  SCIP_HASHMAP* consmap, /**< a hashmap to store the mapping of source constraints to the corresponding
18024  * target constraints */
18025  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP? */
18026  SCIP_Bool separate, /**< should the constraint be separated during LP processing? */
18027  SCIP_Bool enforce, /**< should the constraint be enforced during node processing? */
18028  SCIP_Bool check, /**< should the constraint be checked for feasibility? */
18029  SCIP_Bool propagate, /**< should the constraint be propagated during node processing? */
18030  SCIP_Bool local, /**< is constraint only valid locally? */
18031  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)? */
18032  SCIP_Bool dynamic, /**< is constraint subject to aging? */
18033  SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup? */
18034  SCIP_Bool stickingatnode, /**< should the constraint always be kept at the node where it was added, even
18035  * if it may be moved to a more global node? */
18036  SCIP_Bool global, /**< create a global or a local copy? */
18037  SCIP_Bool* valid /**< pointer to store if the copying was valid */
18038  )
18039 {
18040  SCIP_VAR** vars;
18041  SCIP_Real* coefs;
18042 
18043  SCIP_Real constant;
18044  int requiredsize;
18045  int v;
18046  SCIP_Bool success;
18047 
18048  if( SCIPisGT(scip, lhs, rhs) )
18049  {
18050  *valid = FALSE;
18051  return SCIP_OKAY;
18052  }
18053 
18054  (*valid) = TRUE;
18055 
18056  if( nvars == 0 )
18057  {
18058  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, 0, NULL, NULL, lhs, rhs,
18059  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
18060  return SCIP_OKAY;
18061  }
18062 
18063  /* duplicate variable array */
18064  SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, sourcevars, nvars) );
18065 
18066  /* duplicate coefficient array */
18067  if( sourcecoefs != NULL )
18068  {
18069  SCIP_CALL( SCIPduplicateBufferArray(scip, &coefs, sourcecoefs, nvars) );
18070  }
18071  else
18072  {
18073  SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
18074  for( v = 0; v < nvars; ++v )
18075  coefs[v] = 1.0;
18076  }
18077 
18078  constant = 0.0;
18079 
18080  /* transform source variable to active variables of the source SCIP since only these can be mapped to variables of
18081  * the target SCIP
18082  */
18083  if( !SCIPvarIsOriginal(vars[0]) )
18084  {
18085  SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, nvars, &constant, &requiredsize, TRUE) );
18086 
18087  if( requiredsize > nvars )
18088  {
18089  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requiredsize) );
18090  SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, requiredsize) );
18091 
18092  SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, requiredsize, &constant, &requiredsize, TRUE) );
18093  assert(requiredsize <= nvars);
18094  }
18095  }
18096  else
18097  {
18098  for( v = 0; v < nvars; ++v )
18099  {
18100  assert(SCIPvarIsOriginal(vars[v]));
18101  SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &coefs[v], &constant) );
18102  assert(vars[v] != NULL);
18103  }
18104  }
18105 
18106  success = TRUE;
18107  /* map variables of the source constraint to variables of the target SCIP */
18108  for( v = 0; v < nvars && success; ++v )
18109  {
18110  SCIP_VAR* var;
18111  var = vars[v];
18112 
18113  /* if this is a checked or enforced constraints, then there must be no relaxation-only variables */
18114  assert(!SCIPvarIsRelaxationOnly(var) || (!check && !enforce));
18115 
18116  SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, var, &vars[v], varmap, consmap, global, &success) );
18117  assert(!(success) || vars[v] != NULL);
18118  }
18119 
18120  /* only create the target constraint, if all variables could be copied */
18121  if( success )
18122  {
18123  if( !SCIPisInfinity(scip, -lhs) )
18124  lhs -= constant;
18125 
18126  if( !SCIPisInfinity(scip, rhs) )
18127  rhs -= constant;
18128 
18129  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
18130  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
18131  }
18132  else
18133  *valid = FALSE;
18134 
18135  /* free buffer array */
18136  SCIPfreeBufferArray(scip, &coefs);
18137  SCIPfreeBufferArray(scip, &vars);
18138 
18139  return SCIP_OKAY;
18140 }
18141 
18142 /** adds coefficient to linear constraint (if it is not zero) */
18144  SCIP* scip, /**< SCIP data structure */
18145  SCIP_CONS* cons, /**< constraint data */
18146  SCIP_VAR* var, /**< variable of constraint entry */
18147  SCIP_Real val /**< coefficient of constraint entry */
18148  )
18149 {
18150  assert(scip != NULL);
18151  assert(cons != NULL);
18152  assert(var != NULL);
18153 
18154  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18155  {
18156  SCIPerrorMessage("constraint is not linear\n");
18157  return SCIP_INVALIDDATA;
18158  }
18159 
18160  /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
18161  * constraint after presolving we have to ensure that it holds active variables
18162  */
18163  if( SCIPgetStage(scip) >= SCIP_STAGE_EXITPRESOLVE )
18164  {
18165  SCIP_CONSDATA* consdata;
18166  SCIP_VAR** consvars;
18167  SCIP_Real* consvals;
18168  SCIP_Real constant = 0.0;
18169  SCIP_Real rhs;
18170  SCIP_Real lhs;
18171  int nconsvars;
18172  int requiredsize;
18173  int v;
18174 
18175  nconsvars = 1;
18176  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nconsvars) );
18177  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
18178  consvars[0] = var;
18179  consvals[0] = val;
18180 
18181  /* get active variables for new constraint */
18182  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, nconsvars, &constant, &requiredsize, TRUE) );
18183 
18184  /* if space was not enough we need to resize the buffers */
18185  if( requiredsize > nconsvars )
18186  {
18187  SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
18188  SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
18189 
18190  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize, TRUE) );
18191  assert(requiredsize <= nconsvars);
18192  }
18193 
18194  consdata = SCIPconsGetData(cons);
18195  assert(consdata != NULL);
18196 
18197  lhs = consdata->lhs;
18198  rhs = consdata->rhs;
18199 
18200  /* adjust sides and check that we do not subtract infinity values */
18201  /* constant is infinite */
18202  if( SCIPisInfinity(scip, REALABS(constant)) )
18203  {
18204  if( constant < 0.0 )
18205  {
18206  if( SCIPisInfinity(scip, lhs) )
18207  {
18208  SCIPfreeBufferArray(scip, &consvals);
18209  SCIPfreeBufferArray(scip, &consvars);
18210 
18211  SCIPerrorMessage("adding variable <%s> leads to inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite left hand side of the constraint\n", SCIPvarGetName(var), SCIPconsGetName(cons));
18212 
18213  SCIPABORT();
18214  return SCIP_INVALIDDATA; /*lint !e527*/
18215  }
18216  if( SCIPisInfinity(scip, rhs) )
18217  {
18218  SCIPfreeBufferArray(scip, &consvals);
18219  SCIPfreeBufferArray(scip, &consvars);
18220 
18221  SCIPerrorMessage("adding variable <%s> leads to inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite right hand side of the constraint\n", SCIPvarGetName(var), SCIPconsGetName(cons));
18222 
18223  SCIPABORT();
18224  return SCIP_INVALIDDATA; /*lint !e527*/
18225  }
18226 
18227  lhs = -SCIPinfinity(scip);
18228  rhs = -SCIPinfinity(scip);
18229  }
18230  else
18231  {
18232  if( SCIPisInfinity(scip, -lhs) )
18233  {
18234  SCIPfreeBufferArray(scip, &consvals);
18235  SCIPfreeBufferArray(scip, &consvars);
18236 
18237  SCIPerrorMessage("adding variable <%s> leads to inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite left hand side of the constraint\n", SCIPvarGetName(var), SCIPconsGetName(cons));
18238 
18239  SCIPABORT();
18240  return SCIP_INVALIDDATA; /*lint !e527*/
18241  }
18242  if( SCIPisInfinity(scip, -rhs) )
18243  {
18244  SCIPfreeBufferArray(scip, &consvals);
18245  SCIPfreeBufferArray(scip, &consvars);
18246 
18247  SCIPerrorMessage("adding variable <%s> leads to inconsistent constraint <%s>, active variables leads to a infinite constant constradict the infinite right hand side of the constraint\n", SCIPvarGetName(var), SCIPconsGetName(cons));
18248 
18249  SCIPABORT();
18250  return SCIP_INVALIDDATA; /*lint !e527*/
18251  }
18252 
18253  lhs = SCIPinfinity(scip);
18254  rhs = SCIPinfinity(scip);
18255  }
18256  }
18257  /* constant is not infinite */
18258  else
18259  {
18260  if( !SCIPisInfinity(scip, REALABS(lhs)) )
18261  lhs -= constant;
18262  if( !SCIPisInfinity(scip, REALABS(rhs)) )
18263  rhs -= constant;
18264 
18265  if( SCIPisInfinity(scip, -lhs) )
18266  lhs = -SCIPinfinity(scip);
18267  else if( SCIPisInfinity(scip, lhs) )
18268  lhs = SCIPinfinity(scip);
18269 
18270  if( SCIPisInfinity(scip, rhs) )
18271  rhs = SCIPinfinity(scip);
18272  else if( SCIPisInfinity(scip, -rhs) )
18273  rhs = -SCIPinfinity(scip);
18274  }
18275 
18276  /* add all active variables to constraint */
18277  for( v = nconsvars - 1; v >= 0; --v )
18278  {
18279  SCIP_CALL( addCoef(scip, cons, consvars[v], consvals[v]) );
18280  }
18281 
18282  /* update left and right hand sides */
18283  SCIP_CALL( chgLhs(scip, cons, lhs));
18284  SCIP_CALL( chgRhs(scip, cons, rhs));
18285 
18286  SCIPfreeBufferArray(scip, &consvals);
18287  SCIPfreeBufferArray(scip, &consvars);
18288  }
18289  else
18290  {
18291  SCIP_CALL( addCoef(scip, cons, var, val) );
18292  }
18293 
18294  return SCIP_OKAY;
18295 }
18296 
18297 /** changes coefficient of variable in linear constraint; deletes the variable if coefficient is zero; adds variable if
18298  * not yet contained in the constraint
18299  *
18300  * @note This method may only be called during problem creation stage for an original constraint and variable.
18301  *
18302  * @note This method requires linear time to search for occurences of the variable in the constraint data.
18303  */
18305  SCIP* scip, /**< SCIP data structure */
18306  SCIP_CONS* cons, /**< constraint data */
18307  SCIP_VAR* var, /**< variable of constraint entry */
18308  SCIP_Real val /**< new coefficient of constraint entry */
18309  )
18310 {
18311  SCIP_CONSDATA* consdata;
18312  SCIP_VAR** vars;
18313  SCIP_Bool found;
18314  int i;
18315 
18316  assert(scip != NULL);
18317  assert(cons != NULL);
18318  assert(var != NULL);
18319 
18320  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18321  {
18322  SCIPerrorMessage("constraint is not linear\n");
18324  }
18325 
18326  if( SCIPgetStage(scip) > SCIP_STAGE_PROBLEM || !SCIPconsIsOriginal(cons) || !SCIPvarIsOriginal(var) )
18327  {
18328  SCIPerrorMessage("method may only be called during problem creation stage for original constraints and variables\n");
18329  return SCIP_INVALIDDATA;
18330  }
18331 
18332  consdata = SCIPconsGetData(cons);
18333  assert(consdata != NULL);
18334 
18335  vars = consdata->vars;
18336  found = FALSE;
18337  i = 0;
18338  while( i < consdata->nvars )
18339  {
18340  if( vars[i] == var )
18341  {
18342  if( found || SCIPisZero(scip, val) )
18343  {
18344  SCIP_CALL( delCoefPos(scip, cons, i) );
18345 
18346  /* decrease i by one since otherwise we would skip the coefficient which has been switched to position i */
18347  i--;
18348  }
18349  else
18350  {
18351  SCIP_CALL( chgCoefPos(scip, cons, i, val) );
18352  }
18353  found = TRUE;
18354  }
18355  i++;
18356  }
18357 
18358  if( !found && !SCIPisZero(scip, val) )
18359  {
18360  SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val) );
18361  }
18362 
18363  return SCIP_OKAY;
18364 }
18365 
18366 /** deletes variable from linear constraint
18367  *
18368  * @note This method may only be called during problem creation stage for an original constraint and variable.
18369  *
18370  * @note This method requires linear time to search for occurences of the variable in the constraint data.
18371  */
18373  SCIP* scip, /**< SCIP data structure */
18374  SCIP_CONS* cons, /**< constraint data */
18375  SCIP_VAR* var /**< variable of constraint entry */
18376  )
18377 {
18378  assert(scip != NULL);
18379  assert(cons != NULL);
18380  assert(var != NULL);
18381 
18382  SCIP_CALL( SCIPchgCoefLinear(scip, cons, var, 0.0) );
18383 
18384  return SCIP_OKAY;
18385 }
18386 
18387 /** gets left hand side of linear constraint */
18389  SCIP* scip, /**< SCIP data structure */
18390  SCIP_CONS* cons /**< constraint data */
18391  )
18392 {
18393  SCIP_CONSDATA* consdata;
18394 
18395  assert(scip != NULL);
18396  assert(cons != NULL);
18397 
18398  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18399  {
18400  SCIPerrorMessage("constraint is not linear\n");
18401  SCIPABORT();
18402  return SCIP_INVALID; /*lint !e527*/
18403  }
18404 
18405  consdata = SCIPconsGetData(cons);
18406  assert(consdata != NULL);
18408  return consdata->lhs;
18409 }
18410 
18411 /** gets right hand side of linear constraint */
18413  SCIP* scip, /**< SCIP data structure */
18414  SCIP_CONS* cons /**< constraint data */
18415  )
18416 {
18417  SCIP_CONSDATA* consdata;
18418 
18419  assert(scip != NULL);
18420  assert(cons != NULL);
18421 
18422  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18423  {
18424  SCIPerrorMessage("constraint is not linear\n");
18425  SCIPABORT();
18426  return SCIP_INVALID; /*lint !e527*/
18427  }
18428 
18429  consdata = SCIPconsGetData(cons);
18430  assert(consdata != NULL);
18432  return consdata->rhs;
18433 }
18434 
18435 /** changes left hand side of linear constraint */
18437  SCIP* scip, /**< SCIP data structure */
18438  SCIP_CONS* cons, /**< constraint data */
18439  SCIP_Real lhs /**< new left hand side */
18440  )
18441 {
18442  assert(scip != NULL);
18443  assert(cons != NULL);
18444 
18445  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18446  {
18447  SCIPerrorMessage("constraint is not linear\n");
18448  return SCIP_INVALIDDATA;
18449  }
18450 
18451  SCIP_CALL( chgLhs(scip, cons, lhs) );
18452 
18453  return SCIP_OKAY;
18454 }
18456 /** changes right hand side of linear constraint */
18458  SCIP* scip, /**< SCIP data structure */
18459  SCIP_CONS* cons, /**< constraint data */
18460  SCIP_Real rhs /**< new right hand side */
18461  )
18462 {
18463  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18464  {
18465  SCIPerrorMessage("constraint is not linear\n");
18466  return SCIP_INVALIDDATA;
18467  }
18468 
18469  SCIP_CALL( chgRhs(scip, cons, rhs) );
18470 
18471  return SCIP_OKAY;
18472 }
18473 
18474 /** gets the number of variables in the linear constraint */
18475 int SCIPgetNVarsLinear(
18476  SCIP* scip, /**< SCIP data structure */
18477  SCIP_CONS* cons /**< constraint data */
18478  )
18479 {
18480  SCIP_CONSDATA* consdata;
18481 
18482  assert(scip != NULL);
18483  assert(cons != NULL);
18484 
18485  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18486  {
18487  SCIPerrorMessage("constraint is not linear\n");
18488  SCIPABORT();
18489  return -1; /*lint !e527*/
18490  }
18491 
18492  consdata = SCIPconsGetData(cons);
18493  assert(consdata != NULL);
18495  return consdata->nvars;
18496 }
18497 
18498 /** gets the array of variables in the linear constraint; the user must not modify this array! */
18500  SCIP* scip, /**< SCIP data structure */
18501  SCIP_CONS* cons /**< constraint data */
18502  )
18503 {
18504  SCIP_CONSDATA* consdata;
18505 
18506  assert(scip != NULL);
18507  assert(cons != NULL);
18508 
18509  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18510  {
18511  SCIPerrorMessage("constraint is not linear\n");
18512  SCIPABORT();
18513  return NULL; /*lint !e527*/
18514  }
18515 
18516  consdata = SCIPconsGetData(cons);
18517  assert(consdata != NULL);
18519  return consdata->vars;
18520 }
18521 
18522 /** gets the array of coefficient values in the linear constraint; the user must not modify this array! */
18524  SCIP* scip, /**< SCIP data structure */
18525  SCIP_CONS* cons /**< constraint data */
18526  )
18527 {
18528  SCIP_CONSDATA* consdata;
18529 
18530  assert(scip != NULL);
18531  assert(cons != NULL);
18532 
18533  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18534  {
18535  SCIPerrorMessage("constraint is not linear\n");
18536  SCIPABORT();
18537  return NULL; /*lint !e527*/
18538  }
18539 
18540  consdata = SCIPconsGetData(cons);
18541  assert(consdata != NULL);
18543  return consdata->vals;
18544 }
18545 
18546 /** gets the activity of the linear constraint in the given solution
18547  *
18548  * @note if the solution contains values at infinity, this method will return SCIP_INVALID in case the activity
18549  * comprises positive and negative infinity contributions
18550  */
18552  SCIP* scip, /**< SCIP data structure */
18553  SCIP_CONS* cons, /**< constraint data */
18554  SCIP_SOL* sol /**< solution, or NULL to use current node's solution */
18555  )
18556 {
18557  SCIP_CONSDATA* consdata;
18558 
18559  assert(scip != NULL);
18560  assert(cons != NULL);
18561 
18562  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18563  {
18564  SCIPerrorMessage("constraint is not linear\n");
18565  SCIPABORT();
18566  return SCIP_INVALID; /*lint !e527*/
18567  }
18568 
18569  consdata = SCIPconsGetData(cons);
18570  assert(consdata != NULL);
18571 
18572  if( consdata->row != NULL )
18573  return SCIPgetRowSolActivity(scip, consdata->row, sol);
18574  else
18575  return consdataGetActivity(scip, consdata, sol);
18576 }
18577 
18578 /** gets the feasibility of the linear constraint in the given solution */
18580  SCIP* scip, /**< SCIP data structure */
18581  SCIP_CONS* cons, /**< constraint data */
18582  SCIP_SOL* sol /**< solution, or NULL to use current node's solution */
18583  )
18584 {
18585  SCIP_CONSDATA* consdata;
18586 
18587  assert(scip != NULL);
18588  assert(cons != NULL);
18589 
18590  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18591  {
18592  SCIPerrorMessage("constraint is not linear\n");
18593  SCIPABORT();
18594  return SCIP_INVALID; /*lint !e527*/
18595  }
18596 
18597  consdata = SCIPconsGetData(cons);
18598  assert(consdata != NULL);
18599 
18600  if( consdata->row != NULL )
18601  return SCIPgetRowSolFeasibility(scip, consdata->row, sol);
18602  else
18603  return consdataGetFeasibility(scip, consdata, sol);
18604 }
18605 
18606 /** gets the dual solution of the linear constraint in the current LP */
18608  SCIP* scip, /**< SCIP data structure */
18609  SCIP_CONS* cons /**< constraint data */
18610  )
18611 {
18612  SCIP_CONSDATA* consdata;
18613 
18614  assert(scip != NULL);
18615  assert(cons != NULL);
18616  assert(!SCIPconsIsOriginal(cons)); /* original constraints would always return 0 */
18617 
18618  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18619  {
18620  SCIPerrorMessage("constraint is not linear\n");
18621  SCIPABORT();
18622  return SCIP_INVALID; /*lint !e527*/
18623  }
18624 
18625  consdata = SCIPconsGetData(cons);
18626  assert(consdata != NULL);
18627 
18628  if( consdata->row != NULL )
18629  return SCIProwGetDualsol(consdata->row);
18630  else
18631  return 0.0;
18632 }
18633 
18634 /** gets the dual Farkas value of the linear constraint in the current infeasible LP */
18636  SCIP* scip, /**< SCIP data structure */
18637  SCIP_CONS* cons /**< constraint data */
18638  )
18639 {
18640  SCIP_CONSDATA* consdata;
18641 
18642  assert(scip != NULL);
18643  assert(cons != NULL);
18644  assert(!SCIPconsIsOriginal(cons)); /* original constraints would always return 0 */
18645 
18646  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18647  {
18648  SCIPerrorMessage("constraint is not linear\n");
18649  SCIPABORT();
18650  return SCIP_INVALID; /*lint !e527*/
18651  }
18652 
18653  consdata = SCIPconsGetData(cons);
18654  assert(consdata != NULL);
18655 
18656  if( consdata->row != NULL )
18657  return SCIProwGetDualfarkas(consdata->row);
18658  else
18659  return 0.0;
18660 }
18661 
18662 /** returns the linear relaxation of the given linear constraint; may return NULL if no LP row was yet created;
18663  * the user must not modify the row!
18664  */
18666  SCIP* scip, /**< SCIP data structure */
18667  SCIP_CONS* cons /**< constraint data */
18668  )
18669 {
18670  SCIP_CONSDATA* consdata;
18671 
18672  assert(scip != NULL);
18673  assert(cons != NULL);
18674 
18675  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18676  {
18677  SCIPerrorMessage("constraint is not linear\n");
18678  SCIPABORT();
18679  return NULL; /*lint !e527*/
18680  }
18681 
18682  consdata = SCIPconsGetData(cons);
18683  assert(consdata != NULL);
18685  return consdata->row;
18686 }
18687 
18688 /** tries to automatically convert a linear constraint into a more specific and more specialized constraint */
18690  SCIP* scip, /**< SCIP data structure */
18691  SCIP_CONS* cons, /**< source constraint to try to convert */
18692  SCIP_CONS** upgdcons /**< pointer to store upgraded constraint, or NULL if not successful */
18693  )
18694 {
18695  SCIP_CONSHDLR* conshdlr;
18696  SCIP_CONSHDLRDATA* conshdlrdata;
18697  SCIP_CONSDATA* consdata;
18698  SCIP_VAR* var;
18699  SCIP_Real val;
18700  SCIP_Real lb;
18701  SCIP_Real ub;
18702  SCIP_Real poscoeffsum;
18703  SCIP_Real negcoeffsum;
18704  SCIP_Bool infeasible;
18705  SCIP_Bool integral;
18706  int nchgsides = 0;
18707  int nposbin;
18708  int nnegbin;
18709  int nposint;
18710  int nnegint;
18711  int nposimpl;
18712  int nnegimpl;
18713  int nposimplbin;
18714  int nnegimplbin;
18715  int nposcont;
18716  int nnegcont;
18717  int ncoeffspone;
18718  int ncoeffsnone;
18719  int ncoeffspint;
18720  int ncoeffsnint;
18721  int ncoeffspfrac;
18722  int ncoeffsnfrac;
18723  int i;
18724 
18725  assert(scip != NULL);
18726  assert(cons != NULL);
18727  assert(upgdcons != NULL);
18728 
18729  *upgdcons = NULL;
18730 
18731  /* we cannot upgrade a modifiable linear constraint, since we don't know what additional coefficients to expect */
18732  if( SCIPconsIsModifiable(cons) )
18733  return SCIP_OKAY;
18734 
18735  /* check for upgradability */
18736  if( SCIPconsGetNUpgradeLocks(cons) > 0 )
18737  return SCIP_OKAY;
18738 
18739  /* get the constraint handler and check, if it's really a linear constraint */
18740  conshdlr = SCIPconsGetHdlr(cons);
18741  if( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) != 0 )
18742  {
18743  SCIPerrorMessage("constraint is not linear\n");
18744  return SCIP_INVALIDDATA;
18745  }
18746 
18747  /* get constraint handler data and constraint data */
18748  conshdlrdata = SCIPconshdlrGetData(conshdlr);
18749  assert(conshdlrdata != NULL);
18750  consdata = SCIPconsGetData(cons);
18751  assert(consdata != NULL);
18752 
18753  /* check, if the constraint was already upgraded and will be deleted anyway after preprocessing */
18754  if( consdata->upgraded )
18755  return SCIP_OKAY;
18756 
18757  /* check, if the constraint is already stored as LP row */
18758  if( consdata->row != NULL )
18759  {
18760  if( SCIProwIsInLP(consdata->row) )
18761  {
18762  SCIPerrorMessage("cannot upgrade linear constraint that is already stored as row in the LP\n");
18763  return SCIP_INVALIDDATA;
18764  }
18765  else
18766  {
18767  SCIP_CALL( SCIPreleaseRow(scip, &consdata->row) );
18768  }
18769  }
18770 
18771  /* normalize constraint */
18772  SCIP_CALL( normalizeCons(scip, cons, &infeasible) );
18773 
18774  /* normalizeCons() can only detect infeasibility when scaling with the gcd. in that case, the scaling was
18775  * skipped and we hope that the infeasibility gets detected later again.
18776  *
18777  * TODO: do we want to try to upgrade the constraint anyway?
18778  *
18779  * TODO: this needs to be fixed on master by changing the API and passing a pointer to whether the constraint is
18780  * proven to be infeasible.
18781  */
18782  if( infeasible ) /*lint !e774*/
18783  return SCIP_OKAY;
18784 
18785  /* tighten sides */
18786  SCIP_CALL( tightenSides(scip, cons, &nchgsides, &infeasible) );
18787 
18788  if( infeasible ) /*lint !e774*/
18789  return SCIP_OKAY;
18790 
18791  /*
18792  * calculate some statistics on linear constraint
18793  */
18794 
18795  nposbin = 0;
18796  nnegbin = 0;
18797  nposint = 0;
18798  nnegint = 0;
18799  nposimpl = 0;
18800  nnegimpl = 0;
18801  nposimplbin = 0;
18802  nnegimplbin = 0;
18803  nposcont = 0;
18804  nnegcont = 0;
18805  ncoeffspone = 0;
18806  ncoeffsnone = 0;
18807  ncoeffspint = 0;
18808  ncoeffsnint = 0;
18809  ncoeffspfrac = 0;
18810  ncoeffsnfrac = 0;
18811  integral = TRUE;
18812  poscoeffsum = 0.0;
18813  negcoeffsum = 0.0;
18814 
18815  for( i = 0; i < consdata->nvars; ++i )
18816  {
18817  var = consdata->vars[i];
18818  val = consdata->vals[i];
18819  lb = SCIPvarGetLbLocal(var);
18820  ub = SCIPvarGetUbLocal(var);
18821  assert(!SCIPisZero(scip, val));
18822 
18823  switch( SCIPvarGetType(var) )
18824  {
18825  case SCIP_VARTYPE_BINARY:
18826  if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
18827  integral = integral && SCIPisIntegral(scip, val);
18828  if( val >= 0.0 )
18829  nposbin++;
18830  else
18831  nnegbin++;
18832  break;
18833  case SCIP_VARTYPE_INTEGER:
18834  if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
18835  integral = integral && SCIPisIntegral(scip, val);
18836  if( val >= 0.0 )
18837  nposint++;
18838  else
18839  nnegint++;
18840  break;
18841  case SCIP_VARTYPE_IMPLINT:
18842  if( SCIPvarIsBinary(var) )
18843  {
18844  if( val >= 0.0 )
18845  nposimplbin++;
18846  else
18847  nnegimplbin++;
18848  }
18849  if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
18850  integral = integral && SCIPisIntegral(scip, val);
18851  if( val >= 0.0 )
18852  nposimpl++;
18853  else
18854  nnegimpl++;
18855  break;
18857  integral = integral && SCIPisEQ(scip, lb, ub) && SCIPisIntegral(scip, val * lb);
18858  if( val >= 0.0 )
18859  nposcont++;
18860  else
18861  nnegcont++;
18862  break;
18863  default:
18864  SCIPerrorMessage("unknown variable type\n");
18865  return SCIP_INVALIDDATA;
18866  }
18867  if( SCIPisEQ(scip, val, 1.0) )
18868  ncoeffspone++;
18869  else if( SCIPisEQ(scip, val, -1.0) )
18870  ncoeffsnone++;
18871  else if( SCIPisIntegral(scip, val) )
18872  {
18873  if( SCIPisPositive(scip, val) )
18874  ncoeffspint++;
18875  else
18876  ncoeffsnint++;
18877  }
18878  else
18879  {
18880  if( SCIPisPositive(scip, val) )
18881  ncoeffspfrac++;
18882  else
18883  ncoeffsnfrac++;
18884  }
18885  if( SCIPisPositive(scip, val) )
18886  poscoeffsum += val;
18887  else
18888  negcoeffsum += val;
18889  }
18890 
18891  /*
18892  * call the upgrading methods
18893  */
18894 
18895  SCIPdebugMsg(scip, "upgrading linear constraint <%s> (%d upgrade methods):\n",
18896  SCIPconsGetName(cons), conshdlrdata->nlinconsupgrades);
18897  SCIPdebugMsg(scip, " +bin=%d -bin=%d +int=%d -int=%d +impl=%d -impl=%d +cont=%d -cont=%d +1=%d -1=%d +I=%d -I=%d +F=%d -F=%d possum=%.15g negsum=%.15g integral=%u\n",
18898  nposbin, nnegbin, nposint, nnegint, nposimpl, nnegimpl, nposcont, nnegcont,
18899  ncoeffspone, ncoeffsnone, ncoeffspint, ncoeffsnint, ncoeffspfrac, ncoeffsnfrac,
18900  poscoeffsum, negcoeffsum, integral);
18901 
18902  /* try all upgrading methods in priority order in case the upgrading step is enable */
18903  for( i = 0; i < conshdlrdata->nlinconsupgrades && *upgdcons == NULL; ++i )
18904  {
18905  if( conshdlrdata->linconsupgrades[i]->active )
18906  {
18907  SCIP_CALL( conshdlrdata->linconsupgrades[i]->linconsupgd(scip, cons, consdata->nvars,
18908  consdata->vars, consdata->vals, consdata->lhs, consdata->rhs,
18909  nposbin, nnegbin, nposint, nnegint, nposimpl, nnegimpl, nposimplbin, nnegimplbin, nposcont, nnegcont,
18910  ncoeffspone, ncoeffsnone, ncoeffspint, ncoeffsnint, ncoeffspfrac, ncoeffsnfrac,
18911  poscoeffsum, negcoeffsum, integral,
18912  upgdcons) );
18913  }
18914  }
18915 
18916 #ifdef SCIP_DEBUG
18917  if( *upgdcons != NULL )
18918  {
18919  SCIPdebugPrintCons(scip, cons, NULL);
18920  SCIPdebugMsg(scip, " -> upgraded to constraint type <%s>\n", SCIPconshdlrGetName(SCIPconsGetHdlr(*upgdcons)));
18921  SCIPdebugPrintCons(scip, *upgdcons, NULL);
18922  }
18923 #endif
18924 
18925  return SCIP_OKAY; /*lint !e438*/
18926 }
18927 
18928 /** cleans up (multi-)aggregations and fixings from linear constraints */
18930  SCIP* scip, /**< SCIP data structure */
18931  SCIP_Bool onlychecked, /**< should only checked constraints be cleaned up? */
18932  SCIP_Bool* infeasible /**< pointer to return whether the problem was detected to be infeasible */
18933  )
18934 {
18935  SCIP_CONSHDLR* conshdlr;
18936  SCIP_CONS** conss;
18937  int nconss;
18938  int i;
18939 
18940  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
18941  if( conshdlr == NULL )
18942  return SCIP_OKAY;
18943 
18944  assert(infeasible != NULL);
18945  *infeasible = FALSE;
18946 
18947  nconss = onlychecked ? SCIPconshdlrGetNCheckConss(conshdlr) : SCIPconshdlrGetNActiveConss(conshdlr);
18948  conss = onlychecked ? SCIPconshdlrGetCheckConss(conshdlr) : SCIPconshdlrGetConss(conshdlr);
18949 
18950  for( i = 0; i < nconss; ++i )
18951  {
18952  SCIP_CALL( applyFixings(scip, conss[i], infeasible) );
18953 
18954  if( *infeasible )
18955  break;
18956  }
18957 
18958  return SCIP_OKAY;
18959 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
#define EVENTHDLR_DESC
Definition: cons_linear.c:109
#define CONSHDLR_DELAYSEPA
Definition: cons_linear.c:101
void SCIPsortRealInt(SCIP_Real *realarray, int *intarray, int len)
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:101
#define SCIP_DECL_LINCONSUPGD(x)
Definition: cons_linear.h:111
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
Definition: cons.c:4205
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
struct InferInfo INFERINFO
SCIP_RETCODE SCIPincConsAge(SCIP *scip, SCIP_CONS *cons)
Definition: scip_cons.c:1721
SCIP_RETCODE SCIPcreateEmptyRowCons(SCIP *scip, SCIP_ROW **row, SCIP_CONS *cons, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
Definition: scip_lp.c:1413
SCIP_Real SCIPgetActivityLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip_mem.h:90
SCIP_RETCODE SCIPflattenVarAggregationGraph(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1690
enum SCIP_LinConstype SCIP_LINCONSTYPE
Definition: type_cons.h:81
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
Definition: scip_cons.c:563
SCIP_Bool SCIPinRepropagation(SCIP *scip)
Definition: scip_tree.c:137
static SCIP_RETCODE tightenVarBounds(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool force)
Definition: cons_linear.c:6824
static void consdataCalcMinAbsval(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1458
static SCIP_DECL_CONSDEACTIVE(consDeactiveLinear)
SCIP_Real SCIPfeastol(SCIP *scip)
SCIP_RETCODE SCIPincludeConshdlrLinear(SCIP *scip)
static SCIP_RETCODE consdataCreate(SCIP *scip, SCIP_CONSDATA **consdata, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs)
Definition: cons_linear.c:867
static int inferInfoGetPos(INFERINFO inferinfo)
Definition: cons_linear.c:418
static SCIP_RETCODE consCatchEvent(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
Definition: cons_linear.c:731
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:84
static SCIP_RETCODE chgCoefPos(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Real newval)
Definition: cons_linear.c:4029
SCIP_Bool SCIPisNLPConstructed(SCIP *scip)
Definition: scip_nlp.c:101
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5200
static SCIP_Real consdataGetFeasibility(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol)
Definition: cons_linear.c:3171
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2125
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
public methods for SCIP parameter handling
int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition: var.c:3289
#define DEFAULT_MAXAGGRNORMSCALE
Definition: cons_linear.c:132
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:356
#define DEFAULT_PRESOLPAIRWISE
Definition: cons_linear.c:120
#define SCIP_EVENTTYPE_VARFIXED
Definition: type_event.h:63
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:8344
SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
Definition: var.c:17702
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
Definition: scip_cons.c:586
SCIP_RETCODE SCIPincludeConsUpgradeNonlinear(SCIP *scip, SCIP_DECL_NONLINCONSUPGD((*nlconsupgd)), int priority, SCIP_Bool active, const char *conshdlrname)
SCIP_RETCODE SCIPcreateConsBasicLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs)
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define CONSHDLR_NAME
Definition: cons_linear.c:90
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:1989
#define CONSHDLR_MAXPREROUNDS
Definition: cons_linear.c:100
static void calculateMinvalAndMaxval(SCIP *scip, SCIP_Real side, SCIP_Real val, SCIP_Real minresactivity, SCIP_Real maxresactivity, SCIP_Real *minval, SCIP_Real *maxval)
#define BINWEIGHT
static void consdataUpdateSignatures(SCIP_CONSDATA *consdata, int pos)
Definition: cons_linear.c:3192
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2487
static void consdataUpdateActivities(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_Real val, SCIP_BOUNDTYPE boundtype, SCIP_Bool global, SCIP_Bool checkreliability)
Definition: cons_linear.c:1625
public methods for memory management
#define DEFAULT_RANGEDROWFREQ
Definition: cons_linear.c:167
static void consdataRecomputeMaxActivityDelta(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1563
#define MAXSCALEDCOEF
Definition: cons_linear.c:177
SCIP_RETCODE SCIPcatchVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: scip_event.c:345
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:877
static SCIP_Bool checkEqualObjective(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real *scale, SCIP_Real *offset)
#define DEFAULT_CHECKRELMAXABS
Definition: cons_linear.c:129
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
int SCIPexprGetNChildren(SCIP_EXPR *expr)
Definition: expr.c:3798
static SCIP_RETCODE fixVariables(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars)
Definition: cons_linear.c:7895
SCIP_VAR * SCIPbdchginfoGetVar(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18512
SCIP_Bool SCIPisUbBetter(SCIP *scip, SCIP_Real newub, SCIP_Real oldlb, SCIP_Real oldub)
#define DEFAULT_MAXROUNDS
Definition: cons_linear.c:116
#define DEFAULT_SORTVARS
Definition: cons_linear.c:126
static SCIP_RETCODE convertUnaryEquality(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *ndelconss)
Definition: cons_linear.c:9555
static SCIP_RETCODE tightenVarLb(SCIP *scip, SCIP_CONS *cons, int pos, PROPRULE proprule, SCIP_Real newlb, SCIP_Real oldlb, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool force)
Definition: cons_linear.c:5436
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17910
SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETVARS((*consgetvars)))
Definition: scip_cons.c:816
SCIP_RETCODE SCIPcopyConsLinear(SCIP *scip, SCIP_CONS **cons, SCIP *sourcescip, const char *name, int nvars, SCIP_VAR **sourcevars, SCIP_Real *sourcecoefs, SCIP_Real lhs, SCIP_Real rhs, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode, SCIP_Bool global, SCIP_Bool *valid)
SCIP_RETCODE SCIPupdateCutoffbound(SCIP *scip, SCIP_Real cutoffbound)
#define SCIP_MAXSTRLEN
Definition: def.h:293
int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition: var.c:3347
SCIP_RETCODE SCIPcleanupConssLinear(SCIP *scip, SCIP_Bool onlychecked, SCIP_Bool *infeasible)
SCIP_Bool SCIPvarIsInitial(SCIP_VAR *var)
Definition: var.c:17452
SCIP_Bool SCIPparseReal(SCIP *scip, const char *str, SCIP_Real *value, char **endptr)
public methods for conflict handler plugins and conflict analysis
SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
Definition: scip_cons.c:308
SCIP_RETCODE SCIPresetConsAge(SCIP *scip, SCIP_CONS *cons)
Definition: scip_cons.c:1749
static SCIP_RETCODE consDropAllEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linear.c:836
void SCIPlinConsStatsIncTypeCount(SCIP_LINCONSSTATS *linconsstats, SCIP_LINCONSTYPE linconstype, int increment)
Definition: cons.c:7979
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2842
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:130
SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
Definition: var.c:17690
static long bound
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
Definition: scip_lp.c:1686
SCIP_RETCODE SCIPsetConsPropagated(SCIP *scip, SCIP_CONS *cons, SCIP_Bool propagate)
Definition: scip_cons.c:1308
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisSumRelEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static void consdataUpdateActivitiesGlbUb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real oldub, SCIP_Real newub, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:2083
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17966
SCIP_Bool SCIPisUpdateUnreliable(SCIP *scip, SCIP_Real newvalue, SCIP_Real oldvalue)
SCIP_Real SCIPgetConstantExprSum(SCIP_EXPR *expr)
Definition: expr_sum.c:1172
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPsetConshdlrDeactive(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDEACTIVE((*consdeactive)))
Definition: scip_cons.c:678
SCIP_VARTYPE SCIPeventGetNewtype(SCIP_EVENT *event)
Definition: event.c:1274
SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: scip_event.c:95
static SCIP_Real consdataGetMaxAbsval(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:2312
static SCIP_RETCODE linconsupgradeCreate(SCIP *scip, SCIP_LINCONSUPGRADE **linconsupgrade, SCIP_DECL_LINCONSUPGD((*linconsupgd)), int priority)
Definition: cons_linear.c:521
SCIP_Real SCIPgetRhsNonlinear(SCIP_CONS *cons)
static SCIP_DECL_CONSINITSOL(consInitsolLinear)
void SCIPsortDownRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
#define DEFAULT_MAXSEPACUTS
Definition: cons_linear.c:118
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:1436
SCIP_RETCODE SCIPupdateConsFlags(SCIP *scip, SCIP_CONS *cons0, SCIP_CONS *cons1)
Definition: scip_cons.c:1461
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1245
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17431
static void consdataRecomputeMinactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1326
SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE normalizeCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible)
Definition: cons_linear.c:4260
#define SCIP_EVENTTYPE_TYPECHANGED
Definition: type_event.h:77
#define DEFAULT_DETECTPARTIALOBJECTIVE
Definition: cons_linear.c:161
SCIP_RETCODE SCIPconvertCutsToConss(SCIP *scip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, int *ncutsadded)
Definition: scip_copy.c:2054
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define NLOCKTYPES
Definition: type_var.h:81
static void consdataGetGlbActivityBounds(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Bool goodrelax, SCIP_Real *glbminactivity, SCIP_Real *glbmaxactivity, SCIP_Bool *minisrelax, SCIP_Bool *maxisrelax, SCIP_Bool *isminsettoinfinity, SCIP_Bool *ismaxsettoinfinity)
Definition: cons_linear.c:2889
static void permSortConsdata(SCIP_CONSDATA *consdata, int *perm, int nvars)
Definition: cons_linear.c:3346
SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4547
#define DEFAULT_AGGREGATEVARIABLES
Definition: cons_linear.c:144
#define FALSE
Definition: def.h:87
SCIP_Real SCIPadjustedVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real ub)
Definition: scip_var.c:4642
static SCIP_DECL_HASHGETKEY(hashGetKeyLinearcons)
static SCIP_DECL_CONSEXITSOL(consExitsolLinear)
static void consdataInvalidateActivities(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1227
int SCIPconsGetPos(SCIP_CONS *cons)
Definition: cons.c:8095
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:315
SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
Definition: misc.c:11063
SCIP_RETCODE SCIPincludeConshdlrBasic(SCIP *scip, SCIP_CONSHDLR **conshdlrptr, const char *name, const char *desc, int enfopriority, int chckpriority, int eagerfreq, SCIP_Bool needscons, SCIP_DECL_CONSENFOLP((*consenfolp)), SCIP_DECL_CONSENFOPS((*consenfops)), SCIP_DECL_CONSCHECK((*conscheck)), SCIP_DECL_CONSLOCK((*conslock)), SCIP_CONSHDLRDATA *conshdlrdata)
Definition: scip_cons.c:166
static SCIP_DECL_CONSCOPY(consCopyLinear)
SCIP_Real SCIPinfinity(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10755
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
static void consdataGetGlbActivityResiduals(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real val, SCIP_Bool goodrelax, SCIP_Real *minresactivity, SCIP_Real *maxresactivity, SCIP_Bool *minisrelax, SCIP_Bool *maxisrelax, SCIP_Bool *isminsettoinfinity, SCIP_Bool *ismaxsettoinfinity)
Definition: cons_linear.c:2951
static SCIP_Bool conshdlrdataHasUpgrade(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_DECL_LINCONSUPGD((*linconsupgd)), const char *conshdlrname)
Definition: cons_linear.c:602
#define TRUE
Definition: def.h:86
#define SCIPdebug(x)
Definition: pub_message.h:84
#define DEFAULT_MAXCARDBOUNDDIST
Definition: cons_linear.c:138
SCIP_RETCODE SCIPunmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
Definition: scip_cons.c:1979
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
SCIP_Real SCIPgetLocalLowerbound(SCIP *scip)
Definition: scip_prob.c:3584
SCIP_Real SCIPvarGetNegationConstant(SCIP_VAR *var)
Definition: var.c:17747
#define DEFAULT_NMINCOMPARISONS
Definition: cons_linear.c:122
#define SCIPstatisticMessage
Definition: pub_message.h:114
SCIP_ROW * SCIPgetRowLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPaddConflictUb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
static SCIP_DECL_CONSINITLP(consInitlpLinear)
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition: cons.c:8364
#define SCIP_PRESOLTIMING_EXHAUSTIVE
Definition: type_timing.h:45
static SCIP_RETCODE separateCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_SOL *sol, SCIP_Bool separatecards, SCIP_Bool separateall, int *ncuts, SCIP_Bool *cutoff)
Definition: cons_linear.c:7657
static SCIP_Bool consdataIsResidualIntegral(SCIP *scip, SCIP_CONSDATA *consdata, int pos, SCIP_Real val)
enum SCIP_Varstatus SCIP_VARSTATUS
Definition: type_var.h:48
static SCIP_RETCODE preprocessConstraintPairs(SCIP *scip, SCIP_CONS **conss, int firstchange, int chkind, SCIP_Real maxaggrnormscale, SCIP_Bool *cutoff, int *ndelconss, int *nchgsides, int *nchgcoefs)
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17600
#define SCIP_EVENTTYPE_GLBCHANGED
Definition: type_event.h:66
static SCIP_DECL_CONSENFOPS(consEnfopsLinear)
void SCIPlinConsStatsReset(SCIP_LINCONSSTATS *linconsstats)
Definition: cons.c:7947
SCIP_Real SCIPvarGetAggrScalar(SCIP_VAR *var)
Definition: var.c:17654
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:8394
public methods for problem variables
static GRAPHNODE ** active
SCIP_RETCODE SCIPinitConflictAnalysis(SCIP *scip, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5317
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:99
#define SCIPdebugMessage
Definition: pub_message.h:87
#define DEFAULT_MINGAINPERNMINCOMP
Definition: cons_linear.c:123
SCIP_RETCODE SCIPsetConshdlrSepa(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSSEPALP((*conssepalp)), SCIP_DECL_CONSSEPASOL((*conssepasol)), int sepafreq, int sepapriority, SCIP_Bool delaysepa)
Definition: scip_cons.c:220
SCIP_Real SCIPselectSimpleValue(SCIP_Real lb, SCIP_Real ub, SCIP_Longint maxdnom)
Definition: misc.c:9719
int SCIPconsGetNLocksNeg(SCIP_CONS *cons)
Definition: cons.c:8444
SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
Definition: scip_message.c:79
static SCIP_DECL_CONSEXITPRE(consExitpreLinear)
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:123
SCIP_CONS ** SCIPgetConss(SCIP *scip)
Definition: scip_prob.c:3087
enum Proprule PROPRULE
Definition: cons_linear.c:368
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static SCIP_DECL_CONSRESPROP(consRespropLinear)
static SCIP_RETCODE detectRedundantConstraints(SCIP *scip, BMS_BLKMEM *blkmem, SCIP_CONS **conss, int nconss, int *firstchange, SCIP_Bool *cutoff, int *ndelconss, int *nchgsides)
static SCIP_RETCODE aggregateConstraints(SCIP *scip, SCIP_CONS *cons0, SCIP_CONS *cons1, int *commonidx0, int *commonidx1, int *diffidx0minus1, int *diffidx1minus0, int nvarscommon, int commonidxweight, int diffidx0minus1weight, int diffidx1minus0weight, SCIP_Real maxaggrnormscale, int *nchgcoefs, SCIP_Bool *aggregated, SCIP_Bool *infeasible)
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:127
static INFERINFO getInferInfo(PROPRULE proprule, int pos)
Definition: cons_linear.c:427
static SCIP_RETCODE rangedRowPropagation(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *nchgbds, int *naddconss)
Definition: cons_linear.c:5839
SCIP_Real SCIPadjustedVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real lb)
Definition: scip_var.c:4610
SCIP_Bool SCIPvarIsRemovable(SCIP_VAR *var)
Definition: var.c:17462
#define SCIPdebugPrintCons(x, y, z)
Definition: pub_message.h:93
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip_general.c:566
SCIP_RETCODE SCIPdelCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
int SCIPgetNLPBranchCands(SCIP *scip)
Definition: scip_branch.c:419
static SCIP_RETCODE consDropEvent(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
Definition: cons_linear.c:770
public methods for SCIP variables
SCIP_RETCODE SCIPsetConshdlrDelvars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELVARS((*consdelvars)))
Definition: scip_cons.c:747
#define checkMaxActivityDelta(scip, consdata)
Definition: cons_linear.c:1558
SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:17736
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:8354
#define SCIP_EVENTTYPE_BOUNDCHANGED
Definition: type_event.h:116
static SCIP_DECL_SORTINDCOMP(consdataCompVar)
Definition: cons_linear.c:3237
SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
Definition: scip_cons.c:609
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
Definition: lp.c:17245
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:111
#define SCIPdebugMsgPrint
Definition: scip_message.h:70
#define SCIPdebugMsg
Definition: scip_message.h:69
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:74
static SCIP_Real consdataGetMinAbsval(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:2328
SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip_var.c:1477
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
Definition: scip_cons.c:793
#define DEFAULT_SEPARATEALL
Definition: cons_linear.c:141
SCIP_VAR ** x
Definition: circlepacking.c:54
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition: cons.c:8146
static SCIP_RETCODE tightenSides(SCIP *scip, SCIP_CONS *cons, int *nchgsides, SCIP_Bool *infeasible)
Definition: cons_linear.c:8999
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:199
#define DEFAULT_MAXSEPACUTSROOT
Definition: cons_linear.c:119
int SCIPgetNContVars(SCIP *scip)
Definition: scip_prob.c:2171
static SCIP_RETCODE addConflictFixedVars(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *infervar, SCIP_BDCHGIDX *bdchgidx, int inferpos)
Definition: cons_linear.c:5106
SCIP_RETCODE SCIPcreateCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_CONSHDLR *conshdlr, SCIP_CONSDATA *consdata, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: scip_cons.c:934
SCIP_Real SCIPepsilon(SCIP *scip)
SCIP_RETCODE SCIPparseVarsLinearsum(SCIP *scip, const char *str, SCIP_VAR **vars, SCIP_Real *vals, int *nvars, int varssize, int *requiredsize, char **endptr, SCIP_Bool *success)
Definition: scip_var.c:700
#define CONSHDLR_PRESOLTIMING
Definition: cons_linear.c:105
SCIP_RETCODE SCIPaddConflictLb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
#define CONSHDLR_PROP_TIMING
Definition: cons_linear.c:106
public methods for numerical tolerances
static SCIP_RETCODE rangedRowSimplify(SCIP *scip, SCIP_CONS *cons, int *nchgcoefs, int *nchgsides)
SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
Definition: misc.c:2236
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPconsIsOriginal(SCIP_CONS *cons)
Definition: cons.c:8384
public functions to work with algebraic expressions
#define SCIP_EVENTTYPE_LBCHANGED
Definition: type_event.h:112
public methods for querying solving statistics
static SCIP_DECL_CONSFREE(consFreeLinear)
#define CONSHDLR_SEPAFREQ
Definition: cons_linear.c:95
SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
Definition: var.c:17726
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:17456
#define MAXCONSPRESOLROUNDS
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition: scip_var.c:4256
SCIP_Bool SCIPisConflictAnalysisApplicable(SCIP *scip)
public methods for the branch-and-bound tree
static SCIP_DECL_EVENTEXEC(eventExecLinear)
SCIP_Bool SCIPrealToRational(SCIP_Real val, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Longint *nominator, SCIP_Longint *denominator)
Definition: misc.c:9295
SCIP_Bool SCIPisLbBetter(SCIP *scip, SCIP_Real newlb, SCIP_Real oldlb, SCIP_Real oldub)
static void linconsupgradeFree(SCIP *scip, SCIP_LINCONSUPGRADE **linconsupgrade)
Definition: cons_linear.c:542
SCIP_RETCODE SCIPsetConsSeparated(SCIP *scip, SCIP_CONS *cons, SCIP_Bool separate)
Definition: scip_cons.c:1233
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8173
static SCIP_RETCODE analyzeConflict(SCIP *scip, SCIP_CONS *cons, SCIP_Bool reasonisrhs)
Definition: cons_linear.c:5315
static SCIP_RETCODE checkCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool checklprows, SCIP_Bool checkrelmaxabs, SCIP_Bool *violated)
Definition: cons_linear.c:7274
SCIP_RETCODE SCIPaddClique(SCIP *scip, SCIP_VAR **vars, SCIP_Bool *values, int nvars, SCIP_Bool isequation, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip_var.c:6918
SCIP_EXPR ** SCIPexprGetChildren(SCIP_EXPR *expr)
Definition: expr.c:3808
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17920
SCIP_RETCODE SCIPsetConshdlrInitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITSOL((*consinitsol)))
Definition: scip_cons.c:429
SCIP_VAR * w
Definition: circlepacking.c:58
static SCIP_RETCODE checkParallelObjective(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata)
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:96
#define CONFLICTHDLR_NAME
Definition: cons_linear.c:111
SCIP_RETCODE SCIPmultiaggregateVar(SCIP *scip, SCIP_VAR *var, int naggvars, SCIP_VAR **aggvars, SCIP_Real *scalars, SCIP_Real constant, SCIP_Bool *infeasible, SCIP_Bool *aggregated)
Definition: scip_var.c:8532
public methods for managing constraints
Constraint handler for knapsack constraints of the form , x binary and .
#define DEFAULT_DETECTCUTOFFBOUND
Definition: cons_linear.c:151
static SCIP_RETCODE updateCutoffbound(SCIP *scip, SCIP_CONS *cons, SCIP_Real primalbound)
SCIP_Real SCIPeventGetNewbound(SCIP_EVENT *event)
Definition: event.c:1233
SCIP_Bool SCIPisPresolveFinished(SCIP *scip)
Definition: scip_general.c:603
SCIP_Bool SCIPnlrowIsInNLP(SCIP_NLROW *nlrow)
Definition: nlp.c:1863
SCIP_Bool SCIPconsIsLocked(SCIP_CONS *cons)
Definition: cons.c:8424
static SCIP_DECL_CONSDELETE(consDeleteLinear)
#define CONFLICTHDLR_PRIORITY
Definition: cons_linear.c:113
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
Definition: scip_cons.c:332
static SCIP_RETCODE simplifyInequalities(SCIP *scip, SCIP_CONS *cons, int *nchgcoefs, int *nchgsides, SCIP_Bool *infeasible)
SCIP_Real * SCIPgetCoefsExprSum(SCIP_EXPR *expr)
Definition: expr_sum.c:1157
static SCIP_RETCODE tightenVarUb(SCIP *scip, SCIP_CONS *cons, int pos, PROPRULE proprule, SCIP_Real newub, SCIP_Real oldub, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool force)
Definition: cons_linear.c:5367
static void getMaxActivity(SCIP *scip, SCIP_CONSDATA *consdata, int posinf, int neginf, int poshuge, int neghuge, SCIP_Real delta, SCIP_Bool global, SCIP_Bool goodrelax, SCIP_Real *maxactivity, SCIP_Bool *isrelax, SCIP_Bool *issettoinfinity)
Definition: cons_linear.c:2509
enum SCIP_LockType SCIP_LOCKTYPE
Definition: type_var.h:87
SCIP_Bool SCIPisSumRelLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define SCIPerrorMessage
Definition: pub_message.h:55
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4175
SCIP_VARTYPE SCIPeventGetOldtype(SCIP_EVENT *event)
Definition: event.c:1257
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2769
#define CONSHDLR_PROPFREQ
Definition: cons_linear.c:96
SCIP_Real SCIPgetDualsolLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPaddConsLocal(SCIP *scip, SCIP_CONS *cons, SCIP_NODE *validnode)
Definition: scip_prob.c:3392
static SCIP_DECL_CONSENFOLP(consEnfolpLinear)
SCIP_RETCODE SCIPaddNlRow(SCIP *scip, SCIP_NLROW *nlrow)
Definition: scip_nlp.c:354
SCIP_Bool SCIPdoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8595
SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:3473
public methods for event handler plugins and event handlers
SCIP_RETCODE SCIPinferVarFixCons(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5429
SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
Definition: expr_var.c:407
SCIP_RETCODE SCIPupgradeConsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **upgdcons)
static SCIP_DECL_CONSSEPALP(consSepalpLinear)
SCIP_RETCODE SCIPreleaseNlRow(SCIP *scip, SCIP_NLROW **nlrow)
Definition: scip_nlp.c:1016
SCIP_RETCODE SCIPgetProbvarSum(SCIP *scip, SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: scip_var.c:1791
static void consdataCalcMaxAbsval(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1434
SCIP_RETCODE SCIPaddVarImplication(SCIP *scip, SCIP_VAR *var, SCIP_Bool varfixing, SCIP_VAR *implvar, SCIP_BOUNDTYPE impltype, SCIP_Real implbound, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip_var.c:6777
static INLINE uint32_t SCIPrealHashCode(double x)
Definition: pub_misc.h:535
#define DEFAULT_MULTAGGRREMOVE
Definition: cons_linear.c:169
static SCIP_RETCODE chgRhs(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
Definition: cons_linear.c:3615
static SCIP_RETCODE conshdlrdataEnsureLinconsupgradesSize(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, int num)
Definition: cons_linear.c:461
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:48
static void consdataUpdateDelCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:2156
static SCIP_RETCODE consdataSort(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:3422
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4434
static void consdataUpdateAddCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:2106
static int inferInfoGetProprule(INFERINFO inferinfo)
Definition: cons_linear.c:409
static SCIP_RETCODE consdataTightenCoefs(SCIP *scip, SCIP_CONS *cons, int *nchgcoefs, int *nchgsides)
Definition: cons_linear.c:9121
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8085
SCIP_Real SCIPvarGetAggrConstant(SCIP_VAR *var)
Definition: var.c:17666
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:8304
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:164
static SCIP_RETCODE aggregateVariables(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *naggrvars)
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17251
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
Definition: scip_cons.c:357
SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4195
SCIP_EXPR * SCIPgetExprNonlinear(SCIP_CONS *cons)
static SCIP_RETCODE addConflictReasonVars(SCIP *scip, SCIP_VAR **vars, int nvars, SCIP_VAR *var, SCIP_Real bound)
Definition: cons_linear.c:5171
#define NULL
Definition: lpi_spx1.cpp:155
SCIP_RETCODE SCIPmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
Definition: scip_cons.c:1951
static SCIP_RETCODE delCoefPos(SCIP *scip, SCIP_CONS *cons, int pos)
Definition: cons_linear.c:3908
static SCIP_RETCODE resolvePropagation(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *infervar, INFERINFO inferinfo, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_RESULT *result)
Definition: cons_linear.c:5222
static int getInferInt(PROPRULE proprule, int pos)
Definition: cons_linear.c:446
#define SCIPhashSeven(a, b, c, d, e, f, g)
Definition: pub_misc.h:526
#define REALABS(x)
Definition: def.h:201
SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
Definition: scip_param.c:260
static SCIP_RETCODE checkPartialObjective(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata)
static SCIP_RETCODE conshdlrdataIncludeUpgrade(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_LINCONSUPGRADE *linconsupgrade)
Definition: cons_linear.c:632
#define CONSHDLR_DELAYPROP
Definition: cons_linear.c:102
public methods for problem copies
int SCIPconsGetNLocksPos(SCIP_CONS *cons)
Definition: cons.c:8434
int SCIPconshdlrGetPropFreq(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:5094
SCIP_Bool SCIPisExprSum(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1443
#define SCIP_CALL(x)
Definition: def.h:384
SCIP_Real SCIPgetLowerbound(SCIP *scip)
#define SCIP_EVENTTYPE_LBTIGHTENED
Definition: type_event.h:68
static void consdataGetActivityBounds(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Bool goodrelax, SCIP_Real *minactivity, SCIP_Real *maxactivity, SCIP_Bool *minisrelax, SCIP_Bool *maxisrelax, SCIP_Bool *isminsettoinfinity, SCIP_Bool *ismaxsettoinfinity)
Definition: cons_linear.c:2608
enum Proprule PROPRULE
Definition: cons_and.c:169
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define CONSHDLR_CHECKPRIORITY
Definition: cons_linear.c:94
static SCIP_RETCODE tightenVarBoundsEasy(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool force)
Definition: cons_linear.c:5505
#define SCIPhashSignature64(a)
Definition: pub_misc.h:508
SCIP_RETCODE SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize, SCIP_Bool mergemultiples)
Definition: scip_var.c:1735
SCIP_Real SCIPvarGetMultaggrConstant(SCIP_VAR *var)
Definition: var.c:17714
SCIP_Bool SCIPvarIsRelaxationOnly(SCIP_VAR *var)
Definition: var.c:17538
SCIP_RETCODE SCIPhashtableRemove(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2617
void SCIPupdateSolLPConsViolation(SCIP *scip, SCIP_SOL *sol, SCIP_Real absviol, SCIP_Real relviol)
Definition: scip_sol.c:276
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static void getMinActivity(SCIP *scip, SCIP_CONSDATA *consdata, int posinf, int neginf, int poshuge, int neghuge, SCIP_Real delta, SCIP_Bool global, SCIP_Bool goodrelax, SCIP_Real *minactivity, SCIP_Bool *isrelax, SCIP_Bool *issettoinfinity)
Definition: cons_linear.c:2408
SCIP_RETCODE SCIPanalyzeConflictCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip_message.c:216
static SCIP_Bool isFiniteNonnegativeIntegral(SCIP *scip, SCIP_Real x)
Definition: graph_load.c:93
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8324
static SCIP_RETCODE scaleCons(SCIP *scip, SCIP_CONS *cons, SCIP_Real scalar)
Definition: cons_linear.c:4108
SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
Definition: scip_cut.c:241
static SCIP_DECL_CONSINIT(consInitLinear)
SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
Definition: scip_cons.c:632
#define SCIPdebugGetSolVal(scip, var, val)
Definition: debug.h:281
struct SCIP_ConsData SCIP_CONSDATA
Definition: type_cons.h:56
static SCIP_DECL_CONSTRANS(consTransLinear)
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
Definition: lp.c:17344
#define SCIP_EVENTTYPE_BOUNDTIGHTENED
Definition: type_event.h:114
static SCIP_DECL_HASHKEYVAL(hashKeyValLinearcons)
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition: scip_lp.c:74
#define SCIP_EVENTTYPE_UBCHANGED
Definition: type_event.h:113
int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4590
public methods for constraint handler plugins and constraints
static SCIP_RETCODE propagateCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool tightenbounds, SCIP_Bool rangedrowpropagation, SCIP_Real maxeasyactivitydelta, SCIP_Bool sortvars, SCIP_Bool *cutoff, int *nchgbds)
Definition: cons_linear.c:7747
SCIP_Real SCIPgetDualfarkasLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisHugeValue(SCIP *scip, SCIP_Real val)
static void consdataUpdateChgCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real oldval, SCIP_Real newval, SCIP_Bool checkreliability)
Definition: cons_linear.c:2213
#define DEFAULT_DETECTLOWERBOUND
Definition: cons_linear.c:156
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:4510
static SCIP_RETCODE consdataPrint(SCIP *scip, SCIP_CONSDATA *consdata, FILE *file)
Definition: cons_linear.c:1116
SCIP_Bool SCIPvarIsOriginal(SCIP_VAR *var)
Definition: var.c:17380
void SCIPhashtablePrintStatistics(SCIP_HASHTABLE *hashtable, SCIP_MESSAGEHDLR *messagehdlr)
Definition: misc.c:2744
static SCIP_RETCODE retrieveParallelConstraints(SCIP_HASHTABLE *hashtable, SCIP_CONS **querycons, SCIP_CONS **parallelconss, int *nparallelconss)
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:115
public data structures and miscellaneous methods
static SCIP_RETCODE chgLhs(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
Definition: cons_linear.c:3489
SCIP_Bool SCIPisSumGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
Definition: event.c:1044
#define SCIP_Bool
Definition: def.h:84
SCIP_RETCODE SCIPchgRowRhs(SCIP *scip, SCIP_ROW *row, SCIP_Real rhs)
Definition: scip_lp.c:1598
#define CONSHDLR_NEEDSCONS
Definition: cons_linear.c:103
#define CONSHDLR_EAGERFREQ
Definition: cons_linear.c:97
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:1021
static SCIP_RETCODE performVarDeletions(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss)
Definition: cons_linear.c:4201
static const char * paramname[]
Definition: lpi_msk.c:5021
static void consdataRecomputeGlbMaxactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1407
static SCIP_Real consdataGetActivity(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol)
Definition: cons_linear.c:3103
int SCIPgetDepth(SCIP *scip)
Definition: scip_tree.c:661
#define MAXTIGHTENROUNDS
Definition: cons_linear.c:7092
constraint handler for nonlinear constraints specified by algebraic expressions
static void conshdlrdataFree(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata)
Definition: cons_linear.c:580
#define DEFAULT_SINGLEVARSTUFFING
Definition: cons_linear.c:148
static SCIP_DECL_CONSPROP(consPropLinear)
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip_cons.c:2473
#define DEFAULT_DUALPRESOLVING
Definition: cons_linear.c:146
#define MAX(x, y)
Definition: tclique_def.h:83
static SCIP_RETCODE mergeMultiples(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:4593
static SCIP_RETCODE addRelaxation(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff)
Definition: cons_linear.c:7558
static SCIP_DECL_CONSDELVARS(consDelvarsLinear)
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8105
int SCIPvarCompare(SCIP_VAR *var1, SCIP_VAR *var2)
Definition: var.c:11941
methods for debugging
public methods for LP management
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition: cons.c:8214
SCIP_RETCODE SCIPhashtableSafeInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2519
static SCIP_RETCODE presolStuffing(SCIP *scip, SCIP_CONS *cons, SCIP_Bool singletonstuffing, SCIP_Bool singlevarstuffing, SCIP_Bool *cutoff, int *nfixedvars, int *nchgbds)
SCIP_RETCODE SCIPchgRowLhs(SCIP *scip, SCIP_ROW *row, SCIP_Real lhs)
Definition: scip_lp.c:1574
public methods for cuts and aggregation rows
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8284
static void consdataUpdateActivitiesGlbLb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real oldlb, SCIP_Real newlb, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:2060
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:8254
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17758
static SCIP_Real consdataComputePseudoActivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1273
SCIP_RETCODE SCIPdropVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: scip_event.c:391
SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18502
static void consdataCalcActivities(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:2346
#define NONLINCONSUPGD_PRIORITY
Definition: cons_linear.c:193
SCIP_VAR * SCIPvarGetAggrVar(SCIP_VAR *var)
Definition: var.c:17642
SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: scip_var.c:105
static int getVarWeight(SCIP_VAR *var)
SCIP_RETCODE SCIPcreateNlRow(SCIP *scip, SCIP_NLROW **nlrow, const char *name, SCIP_Real constant, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, SCIP_EXPR *expr, SCIP_Real lhs, SCIP_Real rhs, SCIP_EXPRCURV curvature)
Definition: scip_nlp.c:912
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip_var.c:8273
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:127
int SCIPgetNRuns(SCIP *scip)
SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
Definition: lp.c:17258
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4348
#define MAXDNOM
Definition: cons_linear.c:176
SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
Definition: scip_cons.c:770
#define SCIP_EVENTTYPE_UBTIGHTENED
Definition: type_event.h:70
Constraint handler for linear constraints in their most general form, .
int SCIPgetNObjVars(SCIP *scip)
Definition: scip_prob.c:2219
SCIP_Longint SCIPgetNConflictConssApplied(SCIP *scip)
void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
Definition: misc.c:2548
SCIP_RETCODE SCIPchgRhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
Definition: var.c:17678
SCIP_Bool SCIPisSumRelGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPgetRowSolActivity(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
Definition: scip_lp.c:2129
#define DEFAULT_MAXROUNDSROOT
Definition: cons_linear.c:117
#define SCIP_EVENTTYPE_GBDCHANGED
Definition: type_event.h:111
static void findOperators(const char *str, char **firstoperator, char **secondoperator, SCIP_Bool *success)
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12773
SCIP_Real SCIPgetFeasibilityLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
SCIP_RETCODE SCIPinferVarLbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5498
SCIP_RETCODE SCIPclassifyConstraintTypesLinear(SCIP *scip, SCIP_LINCONSSTATS *linconsstats)
#define DEFAULT_TIGHTENBOUNDSFREQ
Definition: cons_linear.c:115
#define SCIP_MAXTREEDEPTH
Definition: def.h:320
int SCIPgetNBinVars(SCIP *scip)
Definition: scip_prob.c:2036
int SCIPconshdlrGetNActiveConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4624
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip_probing.c:88
public methods for the LP relaxation, rows and columns
#define DEFAULT_SIMPLIFYINEQUALITIES
Definition: cons_linear.c:145
static SCIP_RETCODE createRow(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:7534
#define MINVALRECOMP
Definition: cons_linear.c:190
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:2286
SCIP_RETCODE SCIPincludeLinconsUpgrade(SCIP *scip, SCIP_DECL_LINCONSUPGD((*linconsupgd)), int priority, const char *conshdlrname)
#define CONSHDLR_SEPAPRIORITY
Definition: cons_linear.c:92
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:1991
int SCIPconsGetNUpgradeLocks(SCIP_CONS *cons)
Definition: cons.c:8536
#define SCIP_REAL_MAX
Definition: def.h:178
SCIP_RETCODE SCIPdelNlRow(SCIP *scip, SCIP_NLROW *nlrow)
Definition: scip_nlp.c:382
static void consdataGetReliableResidualActivity(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *cancelvar, SCIP_Real *resactivity, SCIP_Bool isminresact, SCIP_Bool useglobalbounds)
Definition: cons_linear.c:2657
static void consdataRecomputeMaxactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1353
SCIP_RETCODE SCIPwriteVarsLinearsum(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Bool type)
Definition: scip_var.c:334
SCIP_RETCODE SCIPupdateLocalLowerbound(SCIP *scip, SCIP_Real newbound)
Definition: scip_prob.c:3695
static SCIP_Bool canTightenBounds(SCIP_CONS *cons)
Definition: cons_linear.c:5339
static SCIP_DECL_CONSENFORELAX(consEnforelaxLinear)
#define MAXSCALEDCOEFINTEGER
Definition: cons_linear.c:178
static SCIP_DECL_CONSACTIVE(consActiveLinear)
methods for sorting joint arrays of various types
static SCIP_DECL_CONSCHECK(consCheckLinear)
SCIP_Bool SCIPconsIsLockedType(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition: cons.c:8478
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPsetConshdlrExitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITPRE((*consexitpre)))
Definition: scip_cons.c:501
#define EPSGT(x, y, eps)
Definition: def.h:205
static SCIP_RETCODE conshdlrdataCreate(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linear.c:556
public methods for branching rule plugins and branching
SCIP_VAR ** b
Definition: circlepacking.c:56
static void consdataCalcSignatures(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:3217
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition: scip_lp.c:1553
static SCIP_DECL_CONSPARSE(consParseLinear)
public methods for managing events
static SCIP_RETCODE analyzeConflictRangedRow(SCIP *scip, SCIP_CONS *cons, SCIP_VAR **vars, int nvars, SCIP_VAR *var, SCIP_Real bound)
Definition: cons_linear.c:5781
static SCIP_RETCODE lockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
Definition: cons_linear.c:664
general public methods
static SCIP_DECL_CONSGETVARS(consGetVarsLinear)
void SCIPsort(int *perm, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
Definition: misc.c:5440
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static void consdataGetActivityResiduals(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real val, SCIP_Bool goodrelax, SCIP_Real *minresactivity, SCIP_Real *maxresactivity, SCIP_Bool *minisrelax, SCIP_Bool *maxisrelax, SCIP_Bool *isminsettoinfinity, SCIP_Bool *ismaxsettoinfinity)
Definition: cons_linear.c:2738
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE fullDualPresolve(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool *cutoff, int *nchgbds)
public methods for solutions
static const SCIP_Real scalars[]
Definition: lp.c:5736
SCIP_RETCODE SCIPgetVarCopy(SCIP *sourcescip, SCIP *targetscip, SCIP_VAR *sourcevar, SCIP_VAR **targetvar, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, SCIP_Bool *success)
Definition: scip_copy.c:702
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1667
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition: cons.c:8115
SCIP_RETCODE SCIPinferVarUbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5612
SCIP_RETCODE SCIPsetConshdlrInit(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINIT((*consinit)))
Definition: scip_cons.c:381
#define CONTWEIGHT
SCIP_CONS ** SCIPconshdlrGetCheckConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4567
SCIP_Real SCIPgetHugeValue(SCIP *scip)
static SCIP_DECL_CONSLOCK(consLockLinear)
SCIP_RETCODE SCIPsetConsEnforced(SCIP *scip, SCIP_CONS *cons, SCIP_Bool enforce)
Definition: scip_cons.c:1258
static void consdataCheckNonbinvar(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1487
static SCIP_RETCODE consCatchAllEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linear.c:804
SCIP_RETCODE SCIPsetConshdlrExit(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXIT((*consexit)))
Definition: scip_cons.c:405
static SCIP_DECL_CONSSEPASOL(consSepasolLinear)
#define SCIP_EVENTTYPE_FORMAT
Definition: type_event.h:143
public methods for conflict analysis handlers
int SCIPgetNConss(SCIP *scip)
Definition: scip_prob.c:3041
static SCIP_RETCODE extractCliques(SCIP *scip, SCIP_CONS *cons, SCIP_Real maxeasyactivitydelta, SCIP_Bool sortvars, int *nfixedvars, int *nchgbds, SCIP_Bool *cutoff)
Definition: cons_linear.c:8030
SCIP_Bool SCIPisConsCompressionEnabled(SCIP *scip)
Definition: scip_copy.c:651
public methods for the probing mode
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1110
static SCIP_DECL_CONSPRINT(consPrintLinear)
static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinear)
SCIP_RETCODE SCIPincludeConflicthdlrBasic(SCIP *scip, SCIP_CONFLICTHDLR **conflicthdlrptr, const char *name, const char *desc, int priority, SCIP_DECL_CONFLICTEXEC((*conflictexec)), SCIP_CONFLICTHDLRDATA *conflicthdlrdata)
Definition: scip_conflict.c:99
const char * SCIPconflicthdlrGetName(SCIP_CONFLICTHDLR *conflicthdlr)
Definition: conflict.c:763
SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
Definition: scip_cons.c:525
public methods for message output
SCIP_Real SCIPeventGetOldbound(SCIP_EVENT *event)
Definition: event.c:1209
SCIP_VAR * a
Definition: circlepacking.c:57
SCIP_Bool SCIPisFeasPositive(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisExprVar(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1421
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition: message.c:609
static SCIP_RETCODE convertBinaryEquality(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *naggrvars, int *ndelconss)
Definition: cons_linear.c:9611
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:1946
static SCIP_DECL_HASHKEYEQ(hashKeyEqLinearcons)
#define CONFLICTHDLR_DESC
Definition: cons_linear.c:112
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17370
SCIP_RETCODE SCIPaggregateVars(SCIP *scip, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *redundant, SCIP_Bool *aggregated)
Definition: scip_var.c:8398
#define DEFAULT_MAXDUALMULTAGGRQUOT
Definition: cons_linear.c:173
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1211
#define SCIP_Real
Definition: def.h:177
static SCIP_RETCODE tightenBounds(SCIP *scip, SCIP_CONS *cons, SCIP_Real maxeasyactivitydelta, SCIP_Bool sortvars, SCIP_Bool *cutoff, int *nchgbds)
Definition: cons_linear.c:7096
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8334
SCIP_RETCODE SCIPaddVarsToRow(SCIP *scip, SCIP_ROW *row, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip_lp.c:1712
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip_general.c:694
#define SCIP_EVENTTYPE_VARUNLOCKED
Definition: type_event.h:64
static void getNewSidesAfterAggregation(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *slackvar, SCIP_Real slackcoef, SCIP_Real *newlhs, SCIP_Real *newrhs)
Definition: cons_linear.c:9669
#define DEFAULT_SINGLETONSTUFFING
Definition: cons_linear.c:147
SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETNVARS((*consgetnvars)))
Definition: scip_cons.c:839
#define EVENTHDLR_NAME
Definition: cons_linear.c:108
SCIP_Bool SCIPisScalingIntegral(SCIP *scip, SCIP_Real val, SCIP_Real scalar)
#define CONSHDLR_ENFOPRIORITY
Definition: cons_linear.c:93
static SCIP_RETCODE convertEquality(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_Bool *cutoff, int *nfixedvars, int *naggrvars, int *ndelconss)
static SCIP_RETCODE applyFixings(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible)
Definition: cons_linear.c:4664
int SCIPconshdlrGetNCheckConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4610
public methods for message handling
static SCIP_RETCODE consPrintConsSol(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, FILE *file)
Definition: cons_linear.c:1155
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:8274
SCIP_Bool SCIPdoNotAggr(SCIP *scip)
Definition: scip_var.c:8562
static unsigned int getParallelConsKey(SCIP_CONS *cons)
#define SCIP_INVALID
Definition: def.h:197
#define DEFAULT_RANGEDROWPROPAGATION
Definition: cons_linear.c:164
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8264
Proprule
Definition: cons_and.c:161
SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
Definition: scip_lp.c:2197
static SCIP_RETCODE addCoef(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
Definition: cons_linear.c:3743
static SCIP_DECL_CONFLICTEXEC(conflictExecLinear)
#define CONSHDLR_DESC
Definition: cons_linear.c:91
SCIP_Real SCIPcutoffbounddelta(SCIP *scip)
#define SCIP_Longint
Definition: def.h:162
SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
Definition: var.c:18022
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:17590
SCIP_Real SCIPgetRowSolFeasibility(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
Definition: scip_lp.c:2152
static SCIP_RETCODE consdataEnsureVarsSize(SCIP *scip, SCIP_CONSDATA *consdata, int num)
Definition: cons_linear.c:486
#define SCIPdebugAddSolVal(scip, var, val)
Definition: debug.h:280
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17416
static SCIP_DECL_NONLINCONSUPGD(upgradeConsNonlinear)
#define MAX_CLIQUE_NONZEROS_PER_CONS
Definition: cons_linear.c:7963
static void consdataRecomputeGlbMinactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1380
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:60
static SCIP_RETCODE convertLongEquality(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_CONS *cons, SCIP_Bool *cutoff, int *naggrvars, int *ndelconss)
Definition: cons_linear.c:9723
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition: type_cons.h:55
SCIP_RETCODE SCIPchgLhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17976
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip_mem.h:102
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:17393
static int inferInfoToInt(INFERINFO inferinfo)
Definition: cons_linear.c:400
SCIP_Bool SCIPconsIsMarkedPropagate(SCIP_CONS *cons)
Definition: cons.c:8294
static SCIP_Bool isRangedRow(SCIP *scip, SCIP_Real lhs, SCIP_Real rhs)
#define MAXVALRECOMP
Definition: cons_linear.c:189
static SCIP_RETCODE unlockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
Definition: cons_linear.c:697
static SCIP_DECL_CONSPRESOL(consPresolLinear)
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:123
SCIP_RETCODE SCIPsetConshdlrActive(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSACTIVE((*consactive)))
Definition: scip_cons.c:655
#define DEFAULT_MAXEASYACTIVITYDELTA
Definition: cons_linear.c:135
SCIPallocBlockMemory(scip, subsol))
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:430
#define DEFAULT_EXTRACTCLIQUES
Definition: cons_linear.c:174
#define SCIP_EVENTTYPE_GUBCHANGED
Definition: type_event.h:67
SCIP_RETCODE SCIPaddConflict(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons, SCIP_NODE *validnode, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
Definition: scip_prob.c:3227
static SCIP_RETCODE enforceConstraint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss, int nusefulconss, SCIP_SOL *sol, SCIP_RESULT *result)
#define SCIP_CALL_ABORT(x)
Definition: def.h:363
static SCIP_DECL_CONSGETNVARS(consGetNVarsLinear)
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
static SCIP_DECL_CONSEXIT(consExitLinear)
#define DEFAULT_RANGEDROWMAXDEPTH
Definition: cons_linear.c:166
SCIP_RETCODE SCIPsetConshdlrExitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITSOL((*consexitsol)))
Definition: scip_cons.c:453
#define SCIPABORT()
Definition: def.h:356
SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
Definition: scip_var.c:221
public methods for global and local (sub)problems
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17442
SCIP_Real SCIPgetLhsNonlinear(SCIP_CONS *cons)
SCIP_Longint SCIPcalcGreComDiv(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:9022
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1352
SCIP_Bool SCIPvarIsDeleted(SCIP_VAR *var)
Definition: var.c:17472
static INFERINFO intToInferInfo(int i)
Definition: cons_linear.c:387
SCIP_RETCODE SCIPaddObjoffset(SCIP *scip, SCIP_Real addval)
Definition: scip_prob.c:1267
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
#define MAXACTVAL
Definition: cons_linear.c:183
#define INTWEIGHT
SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
Definition: scip_var.c:8626
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:130
static SCIP_RETCODE dualPresolve(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *naggrvars, int *ndelconss)
static SCIP_RETCODE addConflictBounds(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *infervar, SCIP_BDCHGIDX *bdchgidx, int inferpos, SCIP_Bool reasonisrhs)
Definition: cons_linear.c:4924
SCIP_Longint SCIPcalcSmaComMul(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:9274
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE addNlrow(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:7621
#define SCIP_EVENTTYPE_VARDELETED
Definition: type_event.h:62
static void consdataUpdateActivitiesLb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:2010
SCIP_RETCODE SCIPseparateRelaxedKnapsack(SCIP *scip, SCIP_CONS *cons, SCIP_SEPA *sepa, int nknapvars, SCIP_VAR **knapvars, SCIP_Real *knapvals, SCIP_Real valscale, SCIP_Real rhs, SCIP_SOL *sol, SCIP_Bool *cutoff, int *ncuts)
#define DEFAULT_MAXMULTAGGRQUOT
Definition: cons_linear.c:172
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:48
int SCIPgetNSepaRounds(SCIP *scip)
#define DEFAULT_PRESOLUSEHASHING
Definition: cons_linear.c:121
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17580
SCIP_RETCODE SCIPchgCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17406
static void consdataUpdateActivitiesUb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:2035
static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata)
Definition: cons_linear.c:1075
uint64_t SCIP_EVENTTYPE
Definition: type_event.h:142
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:119
SCIP_RETCODE SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
Definition: scip_cons.c:266
SCIP_RETCODE SCIPsetConsInitial(SCIP *scip, SCIP_CONS *cons, SCIP_Bool initial)
Definition: scip_cons.c:1208
#define SCIP_EVENTTYPE_BOUNDRELAXED
Definition: type_event.h:115
memory allocation routines
#define DEFAULT_RANGEDROWARTCONS
Definition: cons_linear.c:165