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-2021 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_knapsack.h"
52 #include "scip/cons_linear.h"
53 #include "scip/cons_nonlinear.h"
54 #include "scip/cons_quadratic.h"
55 #include "scip/debug.h"
56 #include "scip/pub_conflict.h"
57 #include "scip/pub_cons.h"
58 #include "scip/pub_event.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  */
167 #define MAXVALRECOMP 1e+06 /**< maximal abolsute value we trust without recomputing the activity */
168 #define MINVALRECOMP 1e-05 /**< minimal abolsute value we trust without recomputing the activity */
170 
171 #define QUADCONSUPGD_PRIORITY 1000000 /**< priority of the constraint handler for upgrading of quadratic constraints */
172 #define NONLINCONSUPGD_PRIORITY 1000000 /**< priority of the constraint handler for upgrading of nonlinear constraints */
174 /* @todo add multi-aggregation of variables that are in exactly two equations (, if not numerically an issue),
175  * maybe in fullDualPresolve(), see convertLongEquality()
176  */
179 /** constraint data for linear constraints */
180 struct SCIP_ConsData
181 {
182  SCIP_Real lhs; /**< left hand side of row (for ranged rows) */
183  SCIP_Real rhs; /**< right hand side of row */
184  SCIP_Real maxabsval; /**< maximum absolute value of all coefficients */
185  SCIP_Real minabsval; /**< minimal absolute value of all coefficients */
186  SCIP_Real minactivity; /**< minimal value w.r.t. the variable's local bounds for the constraint's
187  * activity, ignoring the coefficients contributing with infinite value */
188  SCIP_Real maxactivity; /**< maximal 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 lastminactivity; /**< last minimal activity which was computed by complete summation
191  * over all contributing values */
192  SCIP_Real lastmaxactivity; /**< last maximal activity which was computed by complete summation
193  * over all contributing values */
194  SCIP_Real glbminactivity; /**< minimal value w.r.t. the variable's global bounds for the constraint's
195  * activity, ignoring the coefficients contributing with infinite value */
196  SCIP_Real glbmaxactivity; /**< maximal 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 lastglbminactivity; /**< last global minimal activity which was computed by complete summation
199  * over all contributing values */
200  SCIP_Real lastglbmaxactivity; /**< last global maximal activity which was computed by complete summation
201  * over all contributing values */
202  SCIP_Real maxactdelta; /**< maximal activity contribution of a single variable, or SCIP_INVALID if invalid */
203  SCIP_VAR* maxactdeltavar; /**< variable with maximal activity contribution, or NULL if invalid */
204  uint64_t possignature; /**< bit signature of coefficients that may take a positive value */
205  uint64_t negsignature; /**< bit signature of coefficients that may take a negative value */
206  SCIP_ROW* row; /**< LP row, if constraint is already stored in LP row format */
207  SCIP_VAR** vars; /**< variables of constraint entries */
208  SCIP_Real* vals; /**< coefficients of constraint entries */
209  SCIP_EVENTDATA** eventdata; /**< event data for bound change events of the variables */
210  int minactivityneginf; /**< number of coefficients contributing with neg. infinite value to minactivity */
211  int minactivityposinf; /**< number of coefficients contributing with pos. infinite value to minactivity */
212  int maxactivityneginf; /**< number of coefficients contributing with neg. infinite value to maxactivity */
213  int maxactivityposinf; /**< number of coefficients contributing with pos. infinite value to maxactivity */
214  int minactivityneghuge; /**< number of coefficients contributing with huge neg. value to minactivity */
215  int minactivityposhuge; /**< number of coefficients contributing with huge pos. value to minactivity */
216  int maxactivityneghuge; /**< number of coefficients contributing with huge neg. value to maxactivity */
217  int maxactivityposhuge; /**< number of coefficients contributing with huge pos. value to maxactivity */
218  int glbminactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbminactivity */
219  int glbminactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbminactivity */
220  int glbmaxactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbmaxactivity */
221  int glbmaxactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbmaxactivity */
222  int glbminactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbminactivity */
223  int glbminactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbminactivity */
224  int glbmaxactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbmaxactivity */
225  int glbmaxactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbmaxactivity */
226  int varssize; /**< size of the vars- and vals-arrays */
227  int nvars; /**< number of nonzeros in constraint */
228  int nbinvars; /**< the number of binary variables in the constraint, only valid after
229  * sorting in stage >= SCIP_STAGE_INITSOLVE
230  */
231  unsigned int boundstightened:2; /**< is constraint already propagated with bound tightening? */
232  unsigned int rangedrowpropagated:2; /**< did we perform ranged row propagation on this constraint?
233  * (0: no, 1: yes, 2: with potentially adding artificial constraint */
234  unsigned int validmaxabsval:1; /**< is the maximum absolute value valid? */
235  unsigned int validminabsval:1; /**< is the minimum absolute value valid? */
236  unsigned int validactivities:1; /**< are the activity bounds (local and global) valid? */
237  unsigned int validminact:1; /**< is the local minactivity valid? */
238  unsigned int validmaxact:1; /**< is the local maxactivity valid? */
239  unsigned int validglbminact:1; /**< is the global minactivity valid? */
240  unsigned int validglbmaxact:1; /**< is the global maxactivity valid? */
241  unsigned int presolved:1; /**< is constraint already presolved? */
242  unsigned int removedfixings:1; /**< are all fixed variables removed from the constraint? */
243  unsigned int validsignature:1; /**< is the bit signature valid? */
244  unsigned int changed:1; /**< was constraint changed since last aggregation round in preprocessing? */
245  unsigned int normalized:1; /**< is the constraint in normalized form? */
246  unsigned int upgradetried:1; /**< was the constraint already tried to be upgraded? */
247  unsigned int upgraded:1; /**< is the constraint upgraded and will it be removed after preprocessing? */
248  unsigned int indexsorted:1; /**< are the constraint's variables sorted by type and index? */
249  unsigned int merged:1; /**< are the constraint's equal variables already merged? */
250  unsigned int cliquesadded:1; /**< were the cliques of the constraint already extracted? */
251  unsigned int implsadded:1; /**< were the implications of the constraint already extracted? */
252  unsigned int coefsorted:1; /**< are variables sorted by type and their absolute activity delta? */
253  unsigned int varsdeleted:1; /**< were variables deleted after last cleanup? */
254  unsigned int hascontvar:1; /**< does the constraint contain at least one continuous variable? */
255  unsigned int hasnonbinvar:1; /**< does the constraint contain at least one non-binary variable? */
256  unsigned int hasnonbinvalid:1; /**< is the information stored in hasnonbinvar and hascontvar valid? */
257  unsigned int checkabsolute:1; /**< should the constraint be checked w.r.t. an absolute feasibilty tolerance? */
258 };
259 
260 /** event data for bound change event */
261 struct SCIP_EventData
262 {
263  SCIP_CONS* cons; /**< linear constraint to process the bound change for */
264  int varpos; /**< position of variable in vars array */
265  int filterpos; /**< position of event in variable's event filter */
266 };
267 
268 /** constraint handler data */
269 struct SCIP_ConshdlrData
270 {
271  SCIP_EVENTHDLR* eventhdlr; /**< event handler for bound change events */
272  SCIP_LINCONSUPGRADE** linconsupgrades; /**< linear constraint upgrade methods for specializing linear constraints */
273  SCIP_Real maxaggrnormscale; /**< maximal allowed relative gain in maximum norm for constraint aggregation
274  * (0.0: disable constraint aggregation) */
275  SCIP_Real maxcardbounddist; /**< maximal relative distance from current node's dual bound to primal bound compared
276  * to best node's dual bound for separating knapsack cardinality cuts */
277  SCIP_Real mingainpernmincomp; /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise comparison round */
278  SCIP_Real maxeasyactivitydelta;/**< maximum activity delta to run easy propagation on linear constraint
279  * (faster, but numerically less stable) */
280  int linconsupgradessize;/**< size of linconsupgrade array */
281  int nlinconsupgrades; /**< number of linear constraint upgrade methods */
282  int tightenboundsfreq; /**< multiplier on propagation frequency, how often the bounds are tightened */
283  int maxrounds; /**< maximal number of separation rounds per node (-1: unlimited) */
284  int maxroundsroot; /**< maximal number of separation rounds in the root node (-1: unlimited) */
285  int maxsepacuts; /**< maximal number of cuts separated per separation round */
286  int maxsepacutsroot; /**< maximal number of cuts separated per separation round in root node */
287  int nmincomparisons; /**< number for minimal pairwise presolving comparisons */
288  int naddconss; /**< number of added constraints */
289  SCIP_Bool presolpairwise; /**< should pairwise constraint comparison be performed in presolving? */
290  SCIP_Bool presolusehashing; /**< should hash table be used for detecting redundant constraints in advance */
291  SCIP_Bool separateall; /**< should all constraints be subject to cardinality cut generation instead of only
292  * the ones with non-zero dual value? */
293  SCIP_Bool aggregatevariables; /**< should presolving search for redundant variables in equations */
294  SCIP_Bool simplifyinequalities;/**< should presolving try to cancel down or delete coefficients in inequalities */
295  SCIP_Bool dualpresolving; /**< should dual presolving steps be performed? */
296  SCIP_Bool singletonstuffing; /**< should stuffing of singleton continuous variables be performed? */
297  SCIP_Bool singlevarstuffing; /**< should single variable stuffing be performed, which tries to fulfill
298  * constraints using the cheapest variable? */
299  SCIP_Bool sortvars; /**< should binary variables be sorted for faster propagation? */
300  SCIP_Bool checkrelmaxabs; /**< should the violation for a constraint with side 0.0 be checked relative
301  * to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
302  SCIP_Bool detectcutoffbound; /**< should presolving try to detect constraints parallel to the objective
303  * function defining an upper bound and prevent these constraints from
304  * entering the LP */
305  SCIP_Bool detectlowerbound; /**< should presolving try to detect constraints parallel to the objective
306  * function defining a lower bound and prevent these constraints from
307  * entering the LP */
308  SCIP_Bool detectpartialobjective;/**< should presolving try to detect subsets of constraints parallel to
309  * the objective function */
310  SCIP_Bool rangedrowpropagation;/**< should presolving and propagation try to improve bounds, detect
311  * infeasibility, and extract sub-constraints from ranged rows and
312  * equations */
313  SCIP_Bool rangedrowartcons; /**< should presolving and propagation extract sub-constraints from ranged rows and equations?*/
314  int rangedrowmaxdepth; /**< maximum depth to apply ranged row propagation */
315  int rangedrowfreq; /**< frequency for applying ranged row propagation */
316  SCIP_Bool multaggrremove; /**< should multi-aggregations only be performed if the constraint can be
317  * removed afterwards? */
318  SCIP_Real maxmultaggrquot; /**< maximum coefficient dynamism (ie. maxabsval / minabsval) for primal multiaggregation */
319  SCIP_Real maxdualmultaggrquot;/**< maximum coefficient dynamism (ie. maxabsval / minabsval) for dual multiaggregation */
320  SCIP_Bool extractcliques; /**< should cliques be extracted? */
321 };
322 
323 /** linear constraint update method */
324 struct SCIP_LinConsUpgrade
325 {
326  SCIP_DECL_LINCONSUPGD((*linconsupgd)); /**< method to call for upgrading linear constraint */
327  int priority; /**< priority of upgrading method */
328  SCIP_Bool active; /**< is upgrading enabled */
329 };
330 
331 
332 /*
333  * Propagation rules
334  */
335 
336 enum Proprule
337 {
338  PROPRULE_1_RHS = 1, /**< activity residuals of all other variables tighten bounds of single
339  * variable due to the right hand side of the inequality */
340  PROPRULE_1_LHS = 2, /**< activity residuals of all other variables tighten bounds of single
341  * variable due to the left hand side of the inequality */
342  PROPRULE_1_RANGEDROW = 3, /**< fixed variables and gcd of all left variables tighten bounds of a
343  * single variable in this reanged row */
344  PROPRULE_INVALID = 0 /**< propagation was applied without a specific propagation rule */
345 };
346 typedef enum Proprule PROPRULE;
347 
348 /** inference information */
349 struct InferInfo
350 {
351  union
352  {
353  struct
354  {
355  unsigned int proprule:8; /**< propagation rule that was applied */
356  unsigned int pos:24; /**< variable position, the propagation rule was applied at */
357  } asbits;
358  int asint; /**< inference information as a single int value */
359  } val;
360 };
361 typedef struct InferInfo INFERINFO;
362 
363 /** converts an integer into an inference information */
364 static
366  int i /**< integer to convert */
367  )
368 {
369  INFERINFO inferinfo;
370 
371  inferinfo.val.asint = i;
372 
373  return inferinfo;
374 }
375 
376 /** converts an inference information into an int */
377 static
379  INFERINFO inferinfo /**< inference information to convert */
380  )
381 {
382  return inferinfo.val.asint;
383 }
384 
385 /** returns the propagation rule stored in the inference information */
386 static
388  INFERINFO inferinfo /**< inference information to convert */
389  )
390 {
391  return (int) inferinfo.val.asbits.proprule;
392 }
393 
394 /** returns the position stored in the inference information */
395 static
396 int inferInfoGetPos(
397  INFERINFO inferinfo /**< inference information to convert */
398  )
399 {
400  return (int) inferinfo.val.asbits.pos;
401 }
402 
403 /** constructs an inference information out of a propagation rule and a position number */
404 static
406  PROPRULE proprule, /**< propagation rule that deduced the value */
407  int pos /**< variable position, the propagation rule was applied at */
408  )
409 {
410  INFERINFO inferinfo;
411 
412  assert(pos >= 0);
413  /* in the inferinfo struct only 24 bits for 'pos' are reserved */
414  assert(pos < (1<<24));
415 
416  inferinfo.val.asbits.proprule = (unsigned int) proprule; /*lint !e641*/
417  inferinfo.val.asbits.pos = (unsigned int) pos; /*lint !e732*/
418 
419  return inferinfo;
420 }
421 
422 /** constructs an inference information out of a propagation rule and a position number, returns info as int */
423 static
424 int getInferInt(
425  PROPRULE proprule, /**< propagation rule that deduced the value */
426  int pos /**< variable position, the propagation rule was applied at */
427  )
428 {
429  return inferInfoToInt(getInferInfo(proprule, pos));
430 }
431 
432 
433 /*
434  * memory growing methods for dynamically allocated arrays
435  */
436 
437 /** ensures, that linconsupgrades array can store at least num entries */
438 static
440  SCIP* scip, /**< SCIP data structure */
441  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
442  int num /**< minimum number of entries to store */
443  )
444 {
445  assert(scip != NULL);
446  assert(conshdlrdata != NULL);
447  assert(conshdlrdata->nlinconsupgrades <= conshdlrdata->linconsupgradessize);
448 
449  if( num > conshdlrdata->linconsupgradessize )
450  {
451  int newsize;
452 
453  newsize = SCIPcalcMemGrowSize(scip, num);
454  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &conshdlrdata->linconsupgrades, conshdlrdata->linconsupgradessize, newsize) );
455  conshdlrdata->linconsupgradessize = newsize;
456  }
457  assert(num <= conshdlrdata->linconsupgradessize);
458 
459  return SCIP_OKAY;
460 }
461 
462 /** ensures, that vars and vals arrays can store at least num entries */
463 static
465  SCIP* scip, /**< SCIP data structure */
466  SCIP_CONSDATA* consdata, /**< linear constraint data */
467  int num /**< minimum number of entries to store */
468  )
469 {
470  assert(scip != NULL);
471  assert(consdata != NULL);
472  assert(consdata->nvars <= consdata->varssize);
473 
474  if( num > consdata->varssize )
475  {
476  int newsize;
477 
478  newsize = SCIPcalcMemGrowSize(scip, num);
479  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vars, consdata->varssize, newsize) );
480  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vals, consdata->varssize, newsize) );
481  if( consdata->eventdata != NULL )
482  {
483  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize, newsize) );
484  }
485  consdata->varssize = newsize;
486  }
487  assert(num <= consdata->varssize);
488 
489  return SCIP_OKAY;
490 }
491 
492 
493 /*
494  * local methods for managing linear constraint update methods
495  */
496 
497 /** creates a linear constraint upgrade data object */
498 static
500  SCIP* scip, /**< SCIP data structure */
501  SCIP_LINCONSUPGRADE** linconsupgrade, /**< pointer to store the linear constraint upgrade */
502  SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
503  int priority /**< priority of upgrading method */
504  )
505 {
506  assert(scip != NULL);
507  assert(linconsupgrade != NULL);
508  assert(linconsupgd != NULL);
509 
510  SCIP_CALL( SCIPallocBlockMemory(scip, linconsupgrade) );
511  (*linconsupgrade)->linconsupgd = linconsupgd;
512  (*linconsupgrade)->priority = priority;
513  (*linconsupgrade)->active = TRUE;
514 
515  return SCIP_OKAY;
516 }
517 
518 /** frees a linear constraint upgrade data object */
519 static
520 void linconsupgradeFree(
521  SCIP* scip, /**< SCIP data structure */
522  SCIP_LINCONSUPGRADE** linconsupgrade /**< pointer to the linear constraint upgrade */
523  )
524 {
525  assert(scip != NULL);
526  assert(linconsupgrade != NULL);
527  assert(*linconsupgrade != NULL);
528 
529  SCIPfreeBlockMemory(scip, linconsupgrade);
530 }
531 
532 /** creates constraint handler data for linear constraint handler */
533 static
535  SCIP* scip, /**< SCIP data structure */
536  SCIP_CONSHDLRDATA** conshdlrdata, /**< pointer to store the constraint handler data */
537  SCIP_EVENTHDLR* eventhdlr /**< event handler */
538  )
539 {
540  assert(scip != NULL);
541  assert(conshdlrdata != NULL);
542  assert(eventhdlr != NULL);
543 
544  SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
545  (*conshdlrdata)->linconsupgrades = NULL;
546  (*conshdlrdata)->linconsupgradessize = 0;
547  (*conshdlrdata)->nlinconsupgrades = 0;
548  (*conshdlrdata)->naddconss = 0;
549 
550  /* set event handler for updating linear constraint activity bounds */
551  (*conshdlrdata)->eventhdlr = eventhdlr;
552 
553  return SCIP_OKAY;
554 }
555 
556 /** frees constraint handler data for linear constraint handler */
557 static
558 void conshdlrdataFree(
559  SCIP* scip, /**< SCIP data structure */
560  SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to the constraint handler data */
561  )
562 {
563  int i;
564 
565  assert(scip != NULL);
566  assert(conshdlrdata != NULL);
567  assert(*conshdlrdata != NULL);
568 
569  for( i = 0; i < (*conshdlrdata)->nlinconsupgrades; ++i )
570  {
571  linconsupgradeFree(scip, &(*conshdlrdata)->linconsupgrades[i]);
572  }
573  SCIPfreeBlockMemoryArrayNull(scip, &(*conshdlrdata)->linconsupgrades, (*conshdlrdata)->linconsupgradessize);
574 
575  SCIPfreeBlockMemory(scip, conshdlrdata);
576 }
577 
578 /** creates a linear constraint upgrade data object */
579 static
581  SCIP* scip, /**< SCIP data structure */
582  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
583  SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
584  const char* conshdlrname /**< name of the constraint handler */
585  )
586 {
587  int i;
588 
589  assert(scip != NULL);
590  assert(conshdlrdata != NULL);
591  assert(linconsupgd != NULL);
592  assert(conshdlrname != NULL);
593 
594  for( i = conshdlrdata->nlinconsupgrades - 1; i >= 0; --i )
595  {
596  if( conshdlrdata->linconsupgrades[i]->linconsupgd == linconsupgd )
597  {
598 #ifdef SCIP_DEBUG
599  SCIPwarningMessage(scip, "Try to add already known upgrade message for constraint handler %s.\n", conshdlrname);
600 #endif
601  return TRUE;
602  }
603  }
604 
605  return FALSE;
606 }
607 
608 /** adds a linear constraint update method to the constraint handler's data */
609 static
611  SCIP* scip, /**< SCIP data structure */
612  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
613  SCIP_LINCONSUPGRADE* linconsupgrade /**< linear constraint upgrade method */
614  )
615 {
616  int i;
617 
618  assert(scip != NULL);
619  assert(conshdlrdata != NULL);
620  assert(linconsupgrade != NULL);
621 
622  SCIP_CALL( conshdlrdataEnsureLinconsupgradesSize(scip, conshdlrdata, conshdlrdata->nlinconsupgrades+1) );
623 
624  for( i = conshdlrdata->nlinconsupgrades;
625  i > 0 && conshdlrdata->linconsupgrades[i-1]->priority < linconsupgrade->priority; --i )
626  {
627  conshdlrdata->linconsupgrades[i] = conshdlrdata->linconsupgrades[i-1];
628  }
629  assert(0 <= i && i <= conshdlrdata->nlinconsupgrades);
630  conshdlrdata->linconsupgrades[i] = linconsupgrade;
631  conshdlrdata->nlinconsupgrades++;
632 
633  return SCIP_OKAY;
634 }
635 
636 /*
637  * local methods
638  */
639 
640 /** installs rounding locks for the given variable associated to the given coefficient in the linear constraint */
641 static
643  SCIP* scip, /**< SCIP data structure */
644  SCIP_CONS* cons, /**< linear constraint */
645  SCIP_VAR* var, /**< variable of constraint entry */
646  SCIP_Real val /**< coefficient of constraint entry */
647  )
648 {
649  SCIP_CONSDATA* consdata;
650 
651  assert(scip != NULL);
652  assert(cons != NULL);
653  assert(var != NULL);
654 
655  consdata = SCIPconsGetData(cons);
656  assert(consdata != NULL);
657  assert(!SCIPisZero(scip, val));
658 
659  if( SCIPisPositive(scip, val) )
660  {
661  SCIP_CALL( SCIPlockVarCons(scip, var, cons,
662  !SCIPisInfinity(scip, -consdata->lhs), !SCIPisInfinity(scip, consdata->rhs)) );
663  }
664  else
665  {
666  SCIP_CALL( SCIPlockVarCons(scip, var, cons,
667  !SCIPisInfinity(scip, consdata->rhs), !SCIPisInfinity(scip, -consdata->lhs)) );
668  }
669 
670  return SCIP_OKAY;
671 }
672 
673 /** removes rounding locks for the given variable associated to the given coefficient in the linear constraint */
674 static
676  SCIP* scip, /**< SCIP data structure */
677  SCIP_CONS* cons, /**< linear constraint */
678  SCIP_VAR* var, /**< variable of constraint entry */
679  SCIP_Real val /**< coefficient of constraint entry */
680  )
681 {
682  SCIP_CONSDATA* consdata;
683 
684  assert(scip != NULL);
685  assert(cons != NULL);
686  assert(var != NULL);
687 
688  consdata = SCIPconsGetData(cons);
689  assert(consdata != NULL);
690  assert(!SCIPisZero(scip, val));
691 
692  if( SCIPisPositive(scip, val) )
693  {
694  SCIP_CALL( SCIPunlockVarCons(scip, var, cons, !SCIPisInfinity(scip, -consdata->lhs),
695  !SCIPisInfinity(scip, consdata->rhs)) );
696  }
697  else
698  {
699  SCIP_CALL( SCIPunlockVarCons(scip, var, cons, !SCIPisInfinity(scip, consdata->rhs),
700  !SCIPisInfinity(scip, -consdata->lhs)) );
701  }
702 
703  return SCIP_OKAY;
704 }
705 
706 /** creates event data for variable at given position, and catches events */
707 /**! [SnippetDebugAssertions] */
708 static
710  SCIP* scip, /**< SCIP data structure */
711  SCIP_CONS* cons, /**< linear constraint */
712  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
713  int pos /**< array position of variable to catch bound change events for */
714  )
715 {
716  SCIP_CONSDATA* consdata;
717  assert(scip != NULL);
718  assert(cons != NULL);
719  assert(eventhdlr != NULL);
720 
721  consdata = SCIPconsGetData(cons);
722  assert(consdata != NULL);
723 
724  assert(0 <= pos && pos < consdata->nvars);
725  assert(consdata->vars != NULL);
726  assert(consdata->vars[pos] != NULL);
727  assert(SCIPvarIsTransformed(consdata->vars[pos]));
728  assert(consdata->eventdata != NULL);
729  assert(consdata->eventdata[pos] == NULL);
730 
731  SCIP_CALL( SCIPallocBlockMemory(scip, &(consdata->eventdata[pos])) ); /*lint !e866*/
732  consdata->eventdata[pos]->cons = cons;
733  consdata->eventdata[pos]->varpos = pos;
734 
735  SCIP_CALL( SCIPcatchVarEvent(scip, consdata->vars[pos],
738  eventhdlr, consdata->eventdata[pos], &consdata->eventdata[pos]->filterpos) );
739 
740  consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(consdata->vars[pos]);
741 
742  return SCIP_OKAY;
743 }
744 /**! [SnippetDebugAssertions] */
745 
746 /** deletes event data for variable at given position, and drops events */
747 static
749  SCIP* scip, /**< SCIP data structure */
750  SCIP_CONS* cons, /**< linear constraint */
751  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
752  int pos /**< array position of variable to catch bound change events for */
753  )
754 {
755  SCIP_CONSDATA* consdata;
756  assert(scip != NULL);
757  assert(cons != NULL);
758  assert(eventhdlr != NULL);
759 
760  consdata = SCIPconsGetData(cons);
761  assert(consdata != NULL);
762 
763  assert(0 <= pos && pos < consdata->nvars);
764  assert(consdata->vars[pos] != NULL);
765  assert(consdata->eventdata != NULL);
766  assert(consdata->eventdata[pos] != NULL);
767  assert(consdata->eventdata[pos]->cons == cons);
768  assert(consdata->eventdata[pos]->varpos == pos);
769 
770  SCIP_CALL( SCIPdropVarEvent(scip, consdata->vars[pos],
773  eventhdlr, consdata->eventdata[pos], consdata->eventdata[pos]->filterpos) );
774 
775  SCIPfreeBlockMemory(scip, &consdata->eventdata[pos]); /*lint !e866*/
776 
777  return SCIP_OKAY;
778 }
779 
780 /** catches bound change events for all variables in transformed linear constraint */
781 static
783  SCIP* scip, /**< SCIP data structure */
784  SCIP_CONS* cons, /**< linear constraint */
785  SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
786  )
787 {
788  SCIP_CONSDATA* consdata;
789  int i;
790 
791  assert(scip != NULL);
792  assert(cons != NULL);
793 
794  consdata = SCIPconsGetData(cons);
795  assert(consdata != NULL);
796  assert(consdata->eventdata == NULL);
797 
798  /* allocate eventdata array */
799  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize) );
800  assert(consdata->eventdata != NULL);
801  BMSclearMemoryArray(consdata->eventdata, consdata->nvars);
802 
803  /* catch event for every single variable */
804  for( i = 0; i < consdata->nvars; ++i )
805  {
806  SCIP_CALL( consCatchEvent(scip, cons, eventhdlr, i) );
807  }
808 
809  return SCIP_OKAY;
810 }
811 
812 /** drops bound change events for all variables in transformed linear constraint */
813 static
815  SCIP* scip, /**< SCIP data structure */
816  SCIP_CONS* cons, /**< linear constraint */
817  SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
818  )
819 {
820  SCIP_CONSDATA* consdata;
821  int i;
822 
823  assert(scip != NULL);
824  assert(cons != NULL);
825 
826  consdata = SCIPconsGetData(cons);
827  assert(consdata != NULL);
828  assert(consdata->eventdata != NULL);
829 
830  /* drop event of every single variable */
831  for( i = consdata->nvars - 1; i >= 0; --i )
832  {
833  SCIP_CALL( consDropEvent(scip, cons, eventhdlr, i) );
834  }
835 
836  /* free eventdata array */
837  SCIPfreeBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize);
838  assert(consdata->eventdata == NULL);
839 
840  return SCIP_OKAY;
841 }
842 
843 /** creates a linear constraint data */
844 static
846  SCIP* scip, /**< SCIP data structure */
847  SCIP_CONSDATA** consdata, /**< pointer to linear constraint data */
848  int nvars, /**< number of nonzeros in the constraint */
849  SCIP_VAR** vars, /**< array with variables of constraint entries */
850  SCIP_Real* vals, /**< array with coefficients of constraint entries */
851  SCIP_Real lhs, /**< left hand side of row */
852  SCIP_Real rhs /**< right hand side of row */
853  )
854 {
855  int v;
856  SCIP_Real constant;
857 
858  assert(scip != NULL);
859  assert(consdata != NULL);
860  assert(nvars == 0 || vars != NULL);
861  assert(nvars == 0 || vals != NULL);
863  if( SCIPisInfinity(scip, rhs) )
864  rhs = SCIPinfinity(scip);
865  else if( SCIPisInfinity(scip, -rhs) )
866  rhs = -SCIPinfinity(scip);
867 
868  if( SCIPisInfinity(scip, -lhs) )
869  lhs = -SCIPinfinity(scip);
870  else if( SCIPisInfinity(scip, lhs) )
871  lhs = SCIPinfinity(scip);
872 
873  if( SCIPisGT(scip, lhs, rhs) )
874  {
875  SCIPwarningMessage(scip, "left hand side of linear constraint greater than right hand side\n");
876  SCIPwarningMessage(scip, " -> lhs=%g, rhs=%g\n", lhs, rhs);
877  }
878 
879  SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
880 
881  (*consdata)->varssize = 0;
882  (*consdata)->nvars = nvars;
883  (*consdata)->hascontvar = FALSE;
884  (*consdata)->hasnonbinvar = FALSE;
885  (*consdata)->hasnonbinvalid = TRUE;
886  (*consdata)->vars = NULL;
887  (*consdata)->vals = NULL;
888 
889  constant = 0.0;
890  if( nvars > 0 )
891  {
892  int k;
893 
894  SCIP_VAR** varsbuffer;
895  SCIP_Real* valsbuffer;
896 
897  /* copy variables into temporary buffer */
898  SCIP_CALL( SCIPallocBufferArray(scip, &varsbuffer, nvars) );
899  SCIP_CALL( SCIPallocBufferArray(scip, &valsbuffer, nvars) );
900  k = 0;
901 
902  /* loop over variables and sort out fixed ones */
903  for( v = 0; v < nvars; ++v )
904  {
905  SCIP_VAR* var;
906  SCIP_Real val;
907 
908  var = vars[v];
909  val = vals[v];
910 
911  assert(var != NULL);
912  if( !SCIPisZero(scip, val) )
913  {
914  /* treat fixed variable as a constant if problem compression is enabled */
916  {
917  constant += SCIPvarGetLbGlobal(var) * val;
918  }
919  else
920  {
921  varsbuffer[k] = var;
922  valsbuffer[k] = val;
923  k++;
924 
925  /* update hascontvar and hasnonbinvar flags */
926  if( !(*consdata)->hascontvar )
927  {
928  SCIP_VARTYPE vartype = SCIPvarGetType(var);
929 
930  if( vartype != SCIP_VARTYPE_BINARY )
931  {
932  (*consdata)->hasnonbinvar = TRUE;
933 
934  if( vartype == SCIP_VARTYPE_CONTINUOUS )
935  (*consdata)->hascontvar = TRUE;
936  }
937  }
938  }
939  }
940  }
941  (*consdata)->nvars = k;
942 
943  if( k > 0 )
944  {
945  /* copy the possibly reduced buffer arrays into block */
946  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, varsbuffer, k) );
947  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vals, valsbuffer, k) );
948  (*consdata)->varssize = k;
949  }
950  /* free temporary buffer */
951  SCIPfreeBufferArray(scip, &valsbuffer);
952  SCIPfreeBufferArray(scip, &varsbuffer);
953  }
954 
955  (*consdata)->eventdata = NULL;
956 
957  /* due to compressed copying, we may have fixed variables contributing to the left and right hand side */
958  if( !SCIPisZero(scip, constant) )
959  {
960  if( !SCIPisInfinity(scip, REALABS(lhs)) )
961  lhs -= constant;
962 
963  if( !SCIPisInfinity(scip, REALABS(rhs)) )
964  rhs -= constant;
965  }
966 
967  (*consdata)->row = NULL;
968  (*consdata)->lhs = lhs;
969  (*consdata)->rhs = rhs;
970  (*consdata)->maxabsval = SCIP_INVALID;
971  (*consdata)->minabsval = SCIP_INVALID;
972  (*consdata)->minactivity = SCIP_INVALID;
973  (*consdata)->maxactivity = SCIP_INVALID;
974  (*consdata)->lastminactivity = SCIP_INVALID;
975  (*consdata)->lastmaxactivity = SCIP_INVALID;
976  (*consdata)->maxactdelta = SCIP_INVALID;
977  (*consdata)->maxactdeltavar = NULL;
978  (*consdata)->minactivityneginf = -1;
979  (*consdata)->minactivityposinf = -1;
980  (*consdata)->maxactivityneginf = -1;
981  (*consdata)->maxactivityposinf = -1;
982  (*consdata)->minactivityneghuge = -1;
983  (*consdata)->minactivityposhuge = -1;
984  (*consdata)->maxactivityneghuge = -1;
985  (*consdata)->maxactivityposhuge = -1;
986  (*consdata)->glbminactivity = SCIP_INVALID;
987  (*consdata)->glbmaxactivity = SCIP_INVALID;
988  (*consdata)->lastglbminactivity = SCIP_INVALID;
989  (*consdata)->lastglbmaxactivity = SCIP_INVALID;
990  (*consdata)->glbminactivityneginf = -1;
991  (*consdata)->glbminactivityposinf = -1;
992  (*consdata)->glbmaxactivityneginf = -1;
993  (*consdata)->glbmaxactivityposinf = -1;
994  (*consdata)->glbminactivityneghuge = -1;
995  (*consdata)->glbminactivityposhuge = -1;
996  (*consdata)->glbmaxactivityneghuge = -1;
997  (*consdata)->glbmaxactivityposhuge = -1;
998  (*consdata)->possignature = 0;
999  (*consdata)->negsignature = 0;
1000  (*consdata)->validmaxabsval = FALSE;
1001  (*consdata)->validminabsval = FALSE;
1002  (*consdata)->validactivities = FALSE;
1003  (*consdata)->validminact = FALSE;
1004  (*consdata)->validmaxact = FALSE;
1005  (*consdata)->validglbminact = FALSE;
1006  (*consdata)->validglbmaxact = FALSE;
1007  (*consdata)->boundstightened = 0;
1008  (*consdata)->presolved = FALSE;
1009  (*consdata)->removedfixings = FALSE;
1010  (*consdata)->validsignature = FALSE;
1011  (*consdata)->changed = TRUE;
1012  (*consdata)->normalized = FALSE;
1013  (*consdata)->upgradetried = FALSE;
1014  (*consdata)->upgraded = FALSE;
1015  (*consdata)->indexsorted = (nvars <= 1);
1016  (*consdata)->merged = (nvars <= 1);
1017  (*consdata)->cliquesadded = FALSE;
1018  (*consdata)->implsadded = FALSE;
1019  (*consdata)->coefsorted = FALSE;
1020  (*consdata)->nbinvars = -1;
1021  (*consdata)->varsdeleted = FALSE;
1022  (*consdata)->rangedrowpropagated = 0;
1023  (*consdata)->checkabsolute = FALSE;
1024 
1025  if( SCIPisTransformed(scip) )
1026  {
1027  /* get transformed variables */
1028  SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
1029  }
1030 
1031  /* capture variables */
1032  for( v = 0; v < (*consdata)->nvars; v++ )
1033  {
1034  assert((*consdata)->vars[v] != NULL);
1035  assert(!SCIPisZero(scip, (*consdata)->vals[v]));
1036  SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->vars[v]) );
1037  }
1038 
1039  return SCIP_OKAY;
1040 }
1041 
1042 /** frees a linear constraint data */
1043 static
1045  SCIP* scip, /**< SCIP data structure */
1046  SCIP_CONSDATA** consdata /**< pointer to linear constraint data */
1047  )
1048 {
1049  int v;
1050 
1051  assert(scip != NULL);
1052  assert(consdata != NULL);
1053  assert(*consdata != NULL);
1054  assert((*consdata)->varssize >= 0);
1055 
1056  /* release the row */
1057  if( (*consdata)->row != NULL )
1058  {
1059  SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->row) );
1060  }
1062  /* release variables */
1063  for( v = 0; v < (*consdata)->nvars; v++ )
1064  {
1065  assert((*consdata)->vars[v] != NULL);
1066  assert(!SCIPisZero(scip, (*consdata)->vals[v]));
1067  SCIP_CALL( SCIPreleaseVar(scip, &((*consdata)->vars[v])) );
1068  }
1069 
1070  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vars, (*consdata)->varssize);
1071  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vals, (*consdata)->varssize);
1072  SCIPfreeBlockMemory(scip, consdata);
1073 
1074  return SCIP_OKAY;
1075 }
1076 
1077 /** prints linear constraint in CIP format to file stream */
1078 static
1080  SCIP* scip, /**< SCIP data structure */
1081  SCIP_CONSDATA* consdata, /**< linear constraint data */
1082  FILE* file /**< output file (or NULL for standard output) */
1083  )
1084 {
1085  assert(scip != NULL);
1086  assert(consdata != NULL);
1087 
1088  /* print left hand side for ranged rows */
1089  if( !SCIPisInfinity(scip, -consdata->lhs)
1090  && !SCIPisInfinity(scip, consdata->rhs)
1091  && !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1092  SCIPinfoMessage(scip, file, "%.15g <= ", consdata->lhs);
1093 
1094  /* print coefficients and variables */
1095  if( consdata->nvars == 0 )
1096  SCIPinfoMessage(scip, file, "0");
1097  else
1098  {
1099  /* post linear sum of the linear constraint */
1100  SCIP_CALL( SCIPwriteVarsLinearsum(scip, file, consdata->vars, consdata->vals, consdata->nvars, TRUE) );
1101  }
1102 
1103  /* print right hand side */
1104  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1105  SCIPinfoMessage(scip, file, " == %.15g", consdata->rhs);
1106  else if( !SCIPisInfinity(scip, consdata->rhs) )
1107  SCIPinfoMessage(scip, file, " <= %.15g", consdata->rhs);
1108  else if( !SCIPisInfinity(scip, -consdata->lhs) )
1109  SCIPinfoMessage(scip, file, " >= %.15g", consdata->lhs);
1110  else
1111  SCIPinfoMessage(scip, file, " [free]");
1112 
1113  return SCIP_OKAY;
1114 }
1115 
1116 /** prints linear constraint and contained solution values of variables to file stream */
1117 static
1119  SCIP* scip, /**< SCIP data structure */
1120  SCIP_CONS* cons, /**< linear constraint */
1121  SCIP_SOL* sol, /**< solution to print */
1122  FILE* file /**< output file (or NULL for standard output) */
1123  )
1124 {
1125  SCIP_CONSDATA* consdata;
1126 
1127  assert(scip != NULL);
1128  assert(cons != NULL);
1129 
1130  consdata = SCIPconsGetData(cons);
1131  assert(consdata != NULL);
1132 
1134 
1135  /* print left hand side for ranged rows */
1136  if( !SCIPisInfinity(scip, -consdata->lhs)
1137  && !SCIPisInfinity(scip, consdata->rhs)
1138  && !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1139  SCIPinfoMessage(scip, file, "%.15g <= ", consdata->lhs);
1140 
1141  /* print coefficients and variables */
1142  if( consdata->nvars == 0 )
1143  SCIPinfoMessage(scip, file, "0");
1144  else
1145  {
1146  int v;
1147 
1148  /* post linear sum of the linear constraint */
1149  for( v = 0; v < consdata->nvars; ++v )
1150  {
1151  if( consdata->vals != NULL )
1152  {
1153  if( consdata->vals[v] == 1.0 )
1154  {
1155  if( v > 0 )
1156  SCIPinfoMessage(scip, file, " +");
1157  }
1158  else if( consdata->vals[v] == -1.0 )
1159  SCIPinfoMessage(scip, file, " -");
1160  else
1161  SCIPinfoMessage(scip, file, " %+.9g", consdata->vals[v]);
1162  }
1163  else if( consdata->nvars > 0 )
1164  SCIPinfoMessage(scip, file, " +");
1165 
1166  /* print variable name */
1167  SCIP_CALL( SCIPwriteVarName(scip, file, consdata->vars[v], TRUE) );
1168 
1169  SCIPinfoMessage(scip, file, " (%+.9g)", SCIPgetSolVal(scip, sol, consdata->vars[v]));
1170  }
1171  }
1172 
1173  /* print right hand side */
1174  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1175  SCIPinfoMessage(scip, file, " == %.15g", consdata->rhs);
1176  else if( !SCIPisInfinity(scip, consdata->rhs) )
1177  SCIPinfoMessage(scip, file, " <= %.15g", consdata->rhs);
1178  else if( !SCIPisInfinity(scip, -consdata->lhs) )
1179  SCIPinfoMessage(scip, file, " >= %.15g", consdata->lhs);
1180  else
1181  SCIPinfoMessage(scip, file, " [free]");
1182 
1183  SCIPinfoMessage(scip, file, ";\n");
1184 
1185  return SCIP_OKAY;
1186 }
1187 
1188 /** invalidates activity bounds, such that they are recalculated in next get */
1189 static
1191  SCIP_CONSDATA* consdata /**< linear constraint */
1192  )
1193 {
1194  assert(consdata != NULL);
1195 
1196  consdata->validactivities = FALSE;
1197  consdata->validminact = FALSE;
1198  consdata->validmaxact = FALSE;
1199  consdata->validglbminact = FALSE;
1200  consdata->validglbmaxact = FALSE;
1201  consdata->validmaxabsval = FALSE;
1202  consdata->validminabsval = FALSE;
1203  consdata->hasnonbinvalid = FALSE;
1204  consdata->minactivity = SCIP_INVALID;
1205  consdata->maxactivity = SCIP_INVALID;
1206  consdata->lastminactivity = SCIP_INVALID;
1207  consdata->lastmaxactivity = SCIP_INVALID;
1208  consdata->maxabsval = SCIP_INVALID;
1209  consdata->minabsval = SCIP_INVALID;
1210  consdata->maxactdelta = SCIP_INVALID;
1211  consdata->maxactdeltavar = NULL;
1212  consdata->minactivityneginf = -1;
1213  consdata->minactivityposinf = -1;
1214  consdata->maxactivityneginf = -1;
1215  consdata->maxactivityposinf = -1;
1216  consdata->minactivityneghuge = -1;
1217  consdata->minactivityposhuge = -1;
1218  consdata->maxactivityneghuge = -1;
1219  consdata->maxactivityposhuge = -1;
1220  consdata->glbminactivity = SCIP_INVALID;
1221  consdata->glbmaxactivity = SCIP_INVALID;
1222  consdata->lastglbminactivity = SCIP_INVALID;
1223  consdata->lastglbmaxactivity = SCIP_INVALID;
1224  consdata->glbminactivityneginf = -1;
1225  consdata->glbminactivityposinf = -1;
1226  consdata->glbmaxactivityneginf = -1;
1227  consdata->glbmaxactivityposinf = -1;
1228  consdata->glbminactivityneghuge = -1;
1229  consdata->glbminactivityposhuge = -1;
1230  consdata->glbmaxactivityneghuge = -1;
1231  consdata->glbmaxactivityposhuge = -1;
1232 }
1233 
1234 /** compute the pseudo activity of a constraint */
1235 static
1237  SCIP* scip, /**< SCIP data structure */
1238  SCIP_CONSDATA* consdata /**< linear constraint data */
1239  )
1240 {
1241  int i;
1242  int pseudoactivityposinf;
1243  int pseudoactivityneginf;
1244  SCIP_Real pseudoactivity;
1245  SCIP_Real bound;
1246  SCIP_Real val;
1247 
1248  pseudoactivity = 0;
1249  pseudoactivityposinf = 0;
1250  pseudoactivityneginf = 0;
1251 
1252  for( i = consdata->nvars - 1; i >= 0; --i )
1253  {
1254  val = consdata->vals[i];
1255  bound = (SCIPvarGetBestBoundType(consdata->vars[i]) == SCIP_BOUNDTYPE_LOWER) ? SCIPvarGetLbLocal(consdata->vars[i]) : SCIPvarGetUbLocal(consdata->vars[i]);
1256  if( SCIPisInfinity(scip, bound) )
1257  {
1258  if( val > 0.0 )
1259  pseudoactivityposinf++;
1260  else
1261  pseudoactivityneginf++;
1262  }
1263  else
1264  {
1265  if( SCIPisInfinity(scip, -bound) )
1266  {
1267  if( val > 0.0 )
1268  pseudoactivityneginf++;
1269  else
1270  pseudoactivityposinf++;
1271  }
1272  else
1273  pseudoactivity += val * bound;
1274  }
1275  }
1276 
1277  if( pseudoactivityneginf > 0 && pseudoactivityposinf > 0 )
1278  return SCIP_INVALID;
1279  else if( pseudoactivityneginf > 0 )
1280  return -SCIPinfinity(scip);
1281  else if( pseudoactivityposinf > 0 )
1282  return SCIPinfinity(scip);
1283 
1284  return pseudoactivity;
1285 }
1286 
1287 /** recompute the minactivity of a constraint */
1288 static
1290  SCIP* scip, /**< SCIP data structure */
1291  SCIP_CONSDATA* consdata /**< linear constraint data */
1292  )
1293 {
1294  int i;
1295  SCIP_Real bound;
1296 
1297  consdata->minactivity = 0;
1298 
1299  for( i = consdata->nvars - 1; i >= 0; --i )
1300  {
1301  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetLbLocal(consdata->vars[i]) : SCIPvarGetUbLocal(consdata->vars[i]);
1302  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1303  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1304  consdata->minactivity += consdata->vals[i] * bound;
1305  }
1307  /* the activity was just computed from scratch and is valid now */
1308  consdata->validminact = TRUE;
1309 
1310  /* the activity was just computed from scratch, mark it to be reliable */
1311  consdata->lastminactivity = consdata->minactivity;
1312 }
1313 
1314 /** recompute the maxactivity of a constraint */
1315 static
1317  SCIP* scip, /**< SCIP data structure */
1318  SCIP_CONSDATA* consdata /**< linear constraint data */
1319  )
1320 {
1321  int i;
1322  SCIP_Real bound;
1323 
1324  consdata->maxactivity = 0;
1325 
1326  for( i = consdata->nvars - 1; i >= 0; --i )
1327  {
1328  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetUbLocal(consdata->vars[i]) : SCIPvarGetLbLocal(consdata->vars[i]);
1329  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1330  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1331  consdata->maxactivity += consdata->vals[i] * bound;
1332  }
1334  /* the activity was just computed from scratch and is valid now */
1335  consdata->validmaxact = TRUE;
1336 
1337  /* the activity was just computed from scratch, mark it to be reliable */
1338  consdata->lastmaxactivity = consdata->maxactivity;
1339 }
1340 
1341 /** recompute the global minactivity of a constraint */
1342 static
1344  SCIP* scip, /**< SCIP data structure */
1345  SCIP_CONSDATA* consdata /**< linear constraint data */
1346  )
1347 {
1348  int i;
1349  SCIP_Real bound;
1350 
1351  consdata->glbminactivity = 0;
1352 
1353  for( i = consdata->nvars - 1; i >= 0; --i )
1354  {
1355  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetLbGlobal(consdata->vars[i]) : SCIPvarGetUbGlobal(consdata->vars[i]);
1356  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1357  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1358  consdata->glbminactivity += consdata->vals[i] * bound;
1359  }
1361  /* the activity was just computed from scratch and is valid now */
1362  consdata->validglbminact = TRUE;
1363 
1364  /* the activity was just computed from scratch, mark it to be reliable */
1365  consdata->lastglbminactivity = consdata->glbminactivity;
1366 }
1367 
1368 /** recompute the global maxactivity of a constraint */
1369 static
1371  SCIP* scip, /**< SCIP data structure */
1372  SCIP_CONSDATA* consdata /**< linear constraint data */
1373  )
1374 {
1375  int i;
1376  SCIP_Real bound;
1377 
1378  consdata->glbmaxactivity = 0;
1379 
1380  for( i = consdata->nvars - 1; i >= 0; --i )
1381  {
1382  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetUbGlobal(consdata->vars[i]) : SCIPvarGetLbGlobal(consdata->vars[i]);
1383  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1384  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1385  consdata->glbmaxactivity += consdata->vals[i] * bound;
1386  }
1388  /* the activity was just computed from scratch and is valid now */
1389  consdata->validglbmaxact = TRUE;
1390 
1391  /* the activity was just computed from scratch, mark it to be reliable */
1392  consdata->lastglbmaxactivity = consdata->glbmaxactivity;
1393 }
1394 
1395 /** calculates maximum absolute value of coefficients */
1396 static
1398  SCIP_CONSDATA* consdata /**< linear constraint data */
1399  )
1400 {
1401  SCIP_Real absval;
1402  int i;
1403 
1404  assert(consdata != NULL);
1405  assert(!consdata->validmaxabsval);
1406  assert(consdata->maxabsval >= SCIP_INVALID);
1407 
1408  consdata->validmaxabsval = TRUE;
1409  consdata->maxabsval = 0.0;
1410  for( i = 0; i < consdata->nvars; ++i )
1411  {
1412  absval = consdata->vals[i];
1413  absval = REALABS(absval);
1414  if( absval > consdata->maxabsval )
1415  consdata->maxabsval = absval;
1416  }
1417 }
1418 
1419 /** calculates minimum absolute value of coefficients */
1420 static
1422  SCIP_CONSDATA* consdata /**< linear constraint data */
1423  )
1424 {
1425  SCIP_Real absval;
1426  int i;
1427 
1428  assert(consdata != NULL);
1429  assert(!consdata->validminabsval);
1430  assert(consdata->minabsval >= SCIP_INVALID);
1431 
1432  consdata->validminabsval = TRUE;
1433 
1434  if( consdata->nvars > 0 )
1435  consdata->minabsval = REALABS(consdata->vals[0]);
1436  else
1437  consdata->minabsval = 0.0;
1439  for( i = 1; i < consdata->nvars; ++i )
1440  {
1441  absval = consdata->vals[i];
1442  absval = REALABS(absval);
1443  if( absval < consdata->minabsval )
1444  consdata->minabsval = absval;
1445  }
1446 }
1447 
1448 /** checks the type of all variables of the constraint and sets hasnonbinvar and hascontvar flags accordingly */
1449 static
1451  SCIP_CONSDATA* consdata /**< linear constraint data */
1452  )
1453 {
1454  int v;
1455 
1456  assert(!consdata->hasnonbinvalid);
1457  consdata->hasnonbinvar = FALSE;
1458  consdata->hascontvar = FALSE;
1459 
1460  for( v = consdata->nvars - 1; v >= 0; --v )
1461  {
1462  SCIP_VARTYPE vartype = SCIPvarGetType(consdata->vars[v]);
1463 
1464  if( vartype != SCIP_VARTYPE_BINARY )
1465  {
1466  consdata->hasnonbinvar = TRUE;
1468  if( vartype == SCIP_VARTYPE_CONTINUOUS )
1469  {
1470  consdata->hascontvar = TRUE;
1471  break;
1472  }
1473  }
1474  }
1475  assert(consdata->hascontvar || v < 0);
1476 
1477  consdata->hasnonbinvalid = TRUE;
1478 }
1479 
1480 
1481 #ifdef CHECKMAXACTDELTA
1482 /** checks that the stored maximal activity delta (if not invalid) is correct */
1483 static
1485  SCIP* scip, /**< SCIP data structure */
1486  SCIP_CONSDATA* consdata /**< linear constraint data */
1487  )
1488 {
1489  if( consdata->maxactdelta != SCIP_INVALID )
1490  {
1491  SCIP_Real maxactdelta = 0.0;
1492  SCIP_Real domain;
1493  SCIP_Real delta;
1494  SCIP_Real lb;
1495  SCIP_Real ub;
1496  int v;
1497 
1498  for( v = consdata->nvars - 1; v >= 0; --v )
1499  {
1500  lb = SCIPvarGetLbLocal(consdata->vars[v]);
1501  ub = SCIPvarGetUbLocal(consdata->vars[v]);
1502 
1503  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
1504  {
1505  maxactdelta = SCIPinfinity(scip);
1506  break;
1507  }
1508 
1509  domain = ub - lb;
1510  delta = REALABS(consdata->vals[v]) * domain;
1511 
1512  if( delta > maxactdelta )
1513  {
1514  maxactdelta = delta;
1515  }
1516  }
1517  assert(SCIPisFeasEQ(scip, maxactdelta, consdata->maxactdelta));
1518  }
1519 }
1520 #else
1521 #define checkMaxActivityDelta(scip, consdata) /**/
1522 #endif
1523 
1524 /** recompute maximal activity contribution for a single variable */
1525 static
1527  SCIP* scip, /**< SCIP data structure */
1528  SCIP_CONSDATA* consdata /**< linear constraint data */
1529  )
1530 {
1531  SCIP_Real delta;
1532  int v;
1533 
1534  consdata->maxactdelta = 0.0;
1535 
1536  if( !consdata->hasnonbinvalid )
1537  consdataCheckNonbinvar(consdata);
1539  /* easy case, the problem consists only of binary variables */
1540  if( !consdata->hasnonbinvar )
1541  {
1542  for( v = consdata->nvars - 1; v >= 0; --v )
1543  {
1544  if( SCIPvarGetLbLocal(consdata->vars[v]) < 0.5 && SCIPvarGetUbLocal(consdata->vars[v]) > 0.5 )
1545  {
1546  delta = REALABS(consdata->vals[v]);
1547 
1548  if( delta > consdata->maxactdelta )
1549  {
1550  consdata->maxactdelta = delta;
1551  consdata->maxactdeltavar = consdata->vars[v];
1552  }
1553  }
1554  }
1555  return;
1556  }
1557 
1558  for( v = consdata->nvars - 1; v >= 0; --v )
1559  {
1560  SCIP_Real domain;
1561  SCIP_Real lb;
1562  SCIP_Real ub;
1563 
1564  lb = SCIPvarGetLbLocal(consdata->vars[v]);
1565  ub = SCIPvarGetUbLocal(consdata->vars[v]);
1566 
1567  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
1568  {
1569  consdata->maxactdelta = SCIPinfinity(scip);
1570  consdata->maxactdeltavar = consdata->vars[v];
1571  break;
1572  }
1573 
1574  domain = ub - lb;
1575  delta = REALABS(consdata->vals[v]) * domain;
1576 
1577  if( delta > consdata->maxactdelta )
1578  {
1579  consdata->maxactdelta = delta;
1580  consdata->maxactdeltavar = consdata->vars[v];
1581  }
1582  }
1583 }
1584 
1585 
1586 /** updates activities for a change in a bound */
1587 static
1589  SCIP* scip, /**< SCIP data structure */
1590  SCIP_CONSDATA* consdata, /**< linear constraint data */
1591  SCIP_VAR* var, /**< variable that has been changed; can be NULL for global bound changes */
1592  SCIP_Real oldbound, /**< old bound of variable */
1593  SCIP_Real newbound, /**< new bound of variable */
1594  SCIP_Real val, /**< coefficient of constraint entry */
1595  SCIP_BOUNDTYPE boundtype, /**< type of the bound change */
1596  SCIP_Bool global, /**< is it a global or a local bound change? */
1597  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1598  )
1599 {
1600  SCIP_Real* activity;
1601  SCIP_Real* lastactivity;
1602  int* activityposinf;
1603  int* activityneginf;
1604  int* activityposhuge;
1605  int* activityneghuge;
1606  SCIP_Real oldcontribution;
1607  SCIP_Real newcontribution;
1608  SCIP_Real delta;
1609  SCIP_Bool validact;
1610  SCIP_Bool finitenewbound;
1611  SCIP_Bool hugevalnewcont;
1612 
1613  assert(scip != NULL);
1614  assert(consdata != NULL);
1615  assert(global || (var != NULL));
1616  assert(consdata->validactivities);
1617  assert(consdata->minactivity < SCIP_INVALID);
1618  assert(consdata->maxactivity < SCIP_INVALID);
1619  assert(consdata->lastminactivity < SCIP_INVALID);
1620  assert(consdata->lastmaxactivity < SCIP_INVALID);
1621  assert(consdata->minactivityneginf >= 0);
1622  assert(consdata->minactivityposinf >= 0);
1623  assert(consdata->maxactivityneginf >= 0);
1624  assert(consdata->maxactivityposinf >= 0);
1625  assert(consdata->minactivityneghuge >= 0);
1626  assert(consdata->minactivityposhuge >= 0);
1627  assert(consdata->maxactivityneghuge >= 0);
1628  assert(consdata->maxactivityposhuge >= 0);
1629  assert(consdata->glbminactivity < SCIP_INVALID);
1630  assert(consdata->glbmaxactivity < SCIP_INVALID);
1631  assert(consdata->lastglbminactivity < SCIP_INVALID);
1632  assert(consdata->lastglbmaxactivity < SCIP_INVALID);
1633  assert(consdata->glbminactivityneginf >= 0);
1634  assert(consdata->glbminactivityposinf >= 0);
1635  assert(consdata->glbmaxactivityneginf >= 0);
1636  assert(consdata->glbmaxactivityposinf >= 0);
1637  assert(consdata->glbminactivityneghuge >= 0);
1638  assert(consdata->glbminactivityposhuge >= 0);
1639  assert(consdata->glbmaxactivityneghuge >= 0);
1640  assert(consdata->glbmaxactivityposhuge >= 0);
1641 
1642  delta = 0.0;
1643 
1644  /* we are updating global activities */
1645  if( global )
1646  {
1647  /* depending on the boundtype and the coefficient, we choose the activity to be updated:
1648  * lower bound + pos. coef: update minactivity
1649  * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
1650  * upper bound + pos. coef: update maxactivity
1651  * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
1652  */
1653  if( boundtype == SCIP_BOUNDTYPE_LOWER )
1654  {
1655  if( val > 0.0 )
1656  {
1657  activity = &(consdata->glbminactivity);
1658  lastactivity = &(consdata->lastglbminactivity);
1659  activityposinf = &(consdata->glbminactivityposinf);
1660  activityneginf = &(consdata->glbminactivityneginf);
1661  activityposhuge = &(consdata->glbminactivityposhuge);
1662  activityneghuge = &(consdata->glbminactivityneghuge);
1663  validact = consdata->validglbminact;
1664  }
1665  else
1666  {
1667  activity = &(consdata->glbmaxactivity);
1668  lastactivity = &(consdata->lastglbmaxactivity);
1669  activityposinf = &(consdata->glbmaxactivityneginf);
1670  activityneginf = &(consdata->glbmaxactivityposinf);
1671  activityposhuge = &(consdata->glbmaxactivityposhuge);
1672  activityneghuge = &(consdata->glbmaxactivityneghuge);
1673  validact = consdata->validglbmaxact;
1674  }
1675  }
1676  else
1677  {
1678  if( val > 0.0 )
1679  {
1680  activity = &(consdata->glbmaxactivity);
1681  lastactivity = &(consdata->lastglbmaxactivity);
1682  activityposinf = &(consdata->glbmaxactivityposinf);
1683  activityneginf = &(consdata->glbmaxactivityneginf);
1684  activityposhuge = &(consdata->glbmaxactivityposhuge);
1685  activityneghuge = &(consdata->glbmaxactivityneghuge);
1686  validact = consdata->validglbmaxact;
1687  }
1688  else
1689  {
1690  activity = &(consdata->glbminactivity);
1691  lastactivity = &(consdata->lastglbminactivity);
1692  activityposinf = &(consdata->glbminactivityneginf);
1693  activityneginf = &(consdata->glbminactivityposinf);
1694  activityposhuge = &(consdata->glbminactivityposhuge);
1695  activityneghuge = &(consdata->glbminactivityneghuge);
1696  validact = consdata->validglbminact;
1697  }
1698  }
1699  }
1700  /* we are updating local activities */
1701  else
1702  {
1703  /* depending on the boundtype and the coefficient, we choose the activity to be updated:
1704  * lower bound + pos. coef: update minactivity
1705  * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
1706  * upper bound + pos. coef: update maxactivity
1707  * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
1708  */
1709  if( boundtype == SCIP_BOUNDTYPE_LOWER )
1710  {
1711  if( val > 0.0 )
1712  {
1713  activity = &(consdata->minactivity);
1714  lastactivity = &(consdata->lastminactivity);
1715  activityposinf = &(consdata->minactivityposinf);
1716  activityneginf = &(consdata->minactivityneginf);
1717  activityposhuge = &(consdata->minactivityposhuge);
1718  activityneghuge = &(consdata->minactivityneghuge);
1719  validact = consdata->validminact;
1720  }
1721  else
1722  {
1723  activity = &(consdata->maxactivity);
1724  lastactivity = &(consdata->lastmaxactivity);
1725  activityposinf = &(consdata->maxactivityneginf);
1726  activityneginf = &(consdata->maxactivityposinf);
1727  activityposhuge = &(consdata->maxactivityposhuge);
1728  activityneghuge = &(consdata->maxactivityneghuge);
1729  validact = consdata->validmaxact;
1730  }
1731  }
1732  else
1733  {
1734  if( val > 0.0 )
1735  {
1736  activity = &(consdata->maxactivity);
1737  lastactivity = &(consdata->lastmaxactivity);
1738  activityposinf = &(consdata->maxactivityposinf);
1739  activityneginf = &(consdata->maxactivityneginf);
1740  activityposhuge = &(consdata->maxactivityposhuge);
1741  activityneghuge = &(consdata->maxactivityneghuge);
1742  validact = consdata->validmaxact;
1743  }
1744  else
1745  {
1746  activity = &(consdata->minactivity);
1747  lastactivity = &(consdata->lastminactivity);
1748  activityposinf = &(consdata->minactivityneginf);
1749  activityneginf = &(consdata->minactivityposinf);
1750  activityposhuge = &(consdata->minactivityposhuge);
1751  activityneghuge = &(consdata->minactivityneghuge);
1752  validact = consdata->validminact;
1753  }
1754  }
1755  }
1756 
1757  oldcontribution = val * oldbound;
1758  newcontribution = val * newbound;
1759  hugevalnewcont = SCIPisHugeValue(scip, REALABS(newcontribution));
1760  finitenewbound = !SCIPisInfinity(scip, REALABS(newbound));
1761 
1762  if( SCIPisInfinity(scip, REALABS(oldbound)) )
1763  {
1764  /* old bound was +infinity */
1765  if( oldbound > 0.0 )
1766  {
1767  assert((*activityposinf) >= 1);
1768 
1769  /* we only have to do something if the new bound is not again +infinity */
1770  if( finitenewbound || newbound < 0.0 )
1771  {
1772  /* decrease the counter for positive infinite contributions */
1773  (*activityposinf)--;
1774 
1775  /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1776  if( !finitenewbound && newbound < 0.0 )
1777  (*activityneginf)++;
1778  else if( hugevalnewcont )
1779  {
1780  /* if the contribution of this variable is too large, increase the counter for huge values */
1781  if( newcontribution > 0.0 )
1782  (*activityposhuge)++;
1783  else
1784  (*activityneghuge)++;
1785  }
1786  /* "normal case": just add the contribution to the activity */
1787  else
1788  delta = newcontribution;
1789  }
1790  }
1791  /* old bound was -infinity */
1792  else
1793  {
1794  assert(oldbound < 0.0);
1795  assert((*activityneginf) >= 1);
1796 
1797  /* we only have to do something ig the new bound is not again -infinity */
1798  if( finitenewbound || newbound > 0.0 )
1799  {
1800  /* decrease the counter for negative infinite contributions */
1801  (*activityneginf)--;
1802 
1803  /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1804  if( !finitenewbound && newbound > 0.0 )
1805  (*activityposinf)++;
1806  else if( hugevalnewcont )
1807  {
1808  /* if the contribution of this variable is too large, increase the counter for huge values */
1809  if( newcontribution > 0.0 )
1810  (*activityposhuge)++;
1811  else
1812  (*activityneghuge)++;
1813  }
1814  /* "normal case": just add the contribution to the activity */
1815  else
1816  delta = newcontribution;
1817  }
1818  }
1819  }
1820  else if( SCIPisHugeValue(scip, REALABS(oldcontribution)) )
1821  {
1822  /* old contribution was too large and positive */
1823  if( oldcontribution > 0.0 )
1824  {
1825  assert((*activityposhuge) >= 1);
1826 
1827  /* decrease the counter for huge positive contributions; it might be increased again later,
1828  * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
1829  */
1830  (*activityposhuge)--;
1831 
1832  if( !finitenewbound )
1833  {
1834  /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1835  if( newbound > 0.0 )
1836  (*activityposinf)++;
1837  /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1838  else
1839  (*activityneginf)++;
1840  }
1841  else if( hugevalnewcont )
1842  {
1843  /* if the contribution of this variable is too large and positive, increase the corresponding counter */
1844  if( newcontribution > 0.0 )
1845  (*activityposhuge)++;
1846  /* if the contribution of this variable is too large and negative, increase the corresponding counter */
1847  else
1848  (*activityneghuge)++;
1849  }
1850  /* "normal case": just add the contribution to the activity */
1851  else
1852  delta = newcontribution;
1853  }
1854  /* old contribution was too large and negative */
1855  else
1856  {
1857  assert(oldcontribution < 0.0);
1858  assert((*activityneghuge) >= 1);
1859 
1860  /* decrease the counter for huge negative contributions; it might be increased again later,
1861  * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
1862  */
1863  (*activityneghuge)--;
1864 
1865  if( !finitenewbound )
1866  {
1867  /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1868  if( newbound > 0.0 )
1869  (*activityposinf)++;
1870  /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1871  else
1872  (*activityneginf)++;
1873  }
1874  else if( hugevalnewcont )
1875  {
1876  /* if the contribution of this variable is too large and positive, increase the corresponding counter */
1877  if( newcontribution > 0.0 )
1878  (*activityposhuge)++;
1879  /* if the contribution of this variable is too large and negative, increase the corresponding counter */
1880  else
1881  (*activityneghuge)++;
1882  }
1883  /* "normal case": just add the contribution to the activity */
1884  else
1885  delta = newcontribution;
1886  }
1887  }
1888  /* old bound was finite and not too large */
1889  else
1890  {
1891  if( !finitenewbound )
1892  {
1893  /* if the new bound is +infinity, the old contribution has to be subtracted
1894  * and the counter for positive infinite contributions has to be increased
1895  */
1896  if( newbound > 0.0 )
1897  {
1898  (*activityposinf)++;
1899  delta = -oldcontribution;
1900  }
1901  /* if the new bound is -infinity, the old contribution has to be subtracted
1902  * and the counter for negative infinite contributions has to be increased
1903  */
1904  else
1905  {
1906  assert(newbound < 0.0 );
1907 
1908  (*activityneginf)++;
1909  delta = -oldcontribution;
1910  }
1911  }
1912  /* if the contribution of this variable is too large, increase the counter for huge values */
1913  else if( hugevalnewcont )
1914  {
1915  if( newcontribution > 0.0 )
1916  {
1917  (*activityposhuge)++;
1918  delta = -oldcontribution;
1919  }
1920  else
1921  {
1922  (*activityneghuge)++;
1923  delta = -oldcontribution;
1924  }
1925  }
1926  /* "normal case": just update the activity */
1927  else
1928  delta = newcontribution - oldcontribution;
1929  }
1930 
1931  /* update the activity, if the current value is valid and there was a change in the finite part */
1932  if( validact && (delta != 0.0) )
1933  {
1934  /* if the absolute value of the activity is increased, this is regarded as reliable,
1935  * otherwise, we check whether we can still trust the updated value
1936  */
1937  (*activity) = (*activity) + delta;
1938  assert(!SCIPisInfinity(scip, -(*activity)) && !SCIPisInfinity(scip, *activity));
1939 
1940  if( REALABS((*lastactivity)) < REALABS(*activity) )
1941  {
1942  (*lastactivity) = (*activity);
1943  }
1944  else
1945  {
1946  if( checkreliability && SCIPisUpdateUnreliable(scip, (*activity), (*lastactivity)) )
1947  {
1948  SCIPdebugMsg(scip, "%s activity of linear constraint unreliable after update: %16.9g\n",
1949  (global ? "global " : ""), (*activity));
1950 
1951  /* mark the activity that was just changed and is not reliable anymore to be invalid */
1952  if( global )
1953  {
1954  if( (boundtype == SCIP_BOUNDTYPE_LOWER) == (val > 0.0) )
1955  consdata->validglbminact = FALSE;
1956  else
1957  consdata->validglbmaxact = FALSE;
1958  }
1959  else
1960  {
1961  if( (boundtype == SCIP_BOUNDTYPE_LOWER) == (val > 0.0) )
1962  consdata->validminact = FALSE;
1963  else
1964  consdata->validmaxact = FALSE;
1965  }
1966  }
1967  }
1968  }
1969 }
1970 
1971 /** updates minimum and maximum activity for a change in lower bound */
1972 static
1974  SCIP* scip, /**< SCIP data structure */
1975  SCIP_CONSDATA* consdata, /**< linear constraint data */
1976  SCIP_VAR* var, /**< variable that has been changed */
1977  SCIP_Real oldlb, /**< old lower bound of variable */
1978  SCIP_Real newlb, /**< new lower bound of variable */
1979  SCIP_Real val, /**< coefficient of constraint entry */
1980  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1981  )
1982 {
1983  assert(scip != NULL);
1984  assert(consdata != NULL);
1985  assert(var != NULL);
1986 
1987  if( consdata->validactivities )
1988  {
1989  consdataUpdateActivities(scip, consdata, var, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, FALSE, checkreliability);
1991  assert(!SCIPisInfinity(scip, -consdata->minactivity) && !SCIPisInfinity(scip, consdata->minactivity));
1992  assert(!SCIPisInfinity(scip, -consdata->maxactivity) && !SCIPisInfinity(scip, consdata->maxactivity));
1993  }
1994 }
1995 
1996 /** updates minimum and maximum activity for a change in upper bound */
1997 static
1999  SCIP* scip, /**< SCIP data structure */
2000  SCIP_CONSDATA* consdata, /**< linear constraint data */
2001  SCIP_VAR* var, /**< variable that has been changed */
2002  SCIP_Real oldub, /**< old upper bound of variable */
2003  SCIP_Real newub, /**< new upper bound of variable */
2004  SCIP_Real val, /**< coefficient of constraint entry */
2005  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2006  )
2007 {
2008  assert(scip != NULL);
2009  assert(consdata != NULL);
2010  assert(var != NULL);
2011 
2012  if( consdata->validactivities )
2013  {
2014  consdataUpdateActivities(scip, consdata, var, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, FALSE, checkreliability);
2016  assert(!SCIPisInfinity(scip, -consdata->minactivity) && !SCIPisInfinity(scip, consdata->minactivity));
2017  assert(!SCIPisInfinity(scip, -consdata->maxactivity) && !SCIPisInfinity(scip, consdata->maxactivity));
2018  }
2019 }
2020 
2021 /** updates minimum and maximum global activity for a change in the global lower bound */
2022 static
2024  SCIP* scip, /**< SCIP data structure */
2025  SCIP_CONSDATA* consdata, /**< linear constraint data */
2026  SCIP_Real oldlb, /**< old lower bound of variable */
2027  SCIP_Real newlb, /**< new lower bound of variable */
2028  SCIP_Real val, /**< coefficient of constraint entry */
2029  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2030  )
2031 {
2032  assert(scip != NULL);
2033  assert(consdata != NULL);
2034 
2035  if( consdata->validactivities )
2036  {
2037  consdataUpdateActivities(scip, consdata, NULL, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, TRUE, checkreliability);
2038 
2039  assert(!SCIPisInfinity(scip, -consdata->glbminactivity) && !SCIPisInfinity(scip, consdata->glbminactivity));
2040  assert(!SCIPisInfinity(scip, -consdata->glbmaxactivity) && !SCIPisInfinity(scip, consdata->glbmaxactivity));
2041  }
2042 }
2043 
2044 /** updates minimum and maximum global activity for a change in global upper bound */
2045 static
2047  SCIP* scip, /**< SCIP data structure */
2048  SCIP_CONSDATA* consdata, /**< linear constraint data */
2049  SCIP_Real oldub, /**< old upper bound of variable */
2050  SCIP_Real newub, /**< new upper bound of variable */
2051  SCIP_Real val, /**< coefficient of constraint entry */
2052  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2053  )
2054 {
2055  assert(scip != NULL);
2056  assert(consdata != NULL);
2057 
2058  if( consdata->validactivities )
2059  {
2060  consdataUpdateActivities(scip, consdata, NULL, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, TRUE, checkreliability);
2061 
2062  assert(!SCIPisInfinity(scip, -consdata->glbminactivity) && !SCIPisInfinity(scip, consdata->glbminactivity));
2063  assert(!SCIPisInfinity(scip, -consdata->glbmaxactivity) && !SCIPisInfinity(scip, consdata->glbmaxactivity));
2064  }
2065 }
2066 
2067 /** updates minimum and maximum activity and maximum absolute value for coefficient addition */
2068 static
2070  SCIP* scip, /**< SCIP data structure */
2071  SCIP_CONSDATA* consdata, /**< linear constraint data */
2072  SCIP_VAR* var, /**< variable of constraint entry */
2073  SCIP_Real val, /**< coefficient of constraint entry */
2074  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2075  )
2076 {
2077  assert(scip != NULL);
2078  assert(consdata != NULL);
2079  assert(var != NULL);
2080 
2081  /* update maximum absolute value */
2082  if( consdata->validmaxabsval )
2083  {
2084  SCIP_Real absval;
2085 
2086  assert(consdata->maxabsval < SCIP_INVALID);
2087 
2088  absval = REALABS(val);
2089  consdata->maxabsval = MAX(consdata->maxabsval, absval);
2090  }
2091 
2092  if( consdata->validminabsval )
2093  {
2094  SCIP_Real absval;
2095 
2096  assert(consdata->minabsval < SCIP_INVALID);
2097 
2098  absval = REALABS(val);
2099  consdata->minabsval = MIN(consdata->minabsval, absval);
2100  }
2101 
2102  /* update minimal and maximal activity */
2103  if( consdata->validactivities )
2104  {
2105  assert(consdata->minactivity < SCIP_INVALID);
2106  assert(consdata->maxactivity < SCIP_INVALID);
2107  assert(consdata->glbminactivity < SCIP_INVALID);
2108  assert(consdata->glbmaxactivity < SCIP_INVALID);
2109 
2110  consdataUpdateActivitiesLb(scip, consdata, var, 0.0, SCIPvarGetLbLocal(var), val, checkreliability);
2111  consdataUpdateActivitiesUb(scip, consdata, var, 0.0, SCIPvarGetUbLocal(var), val, checkreliability);
2112  consdataUpdateActivitiesGlbLb(scip, consdata, 0.0, SCIPvarGetLbGlobal(var), val, checkreliability);
2113  consdataUpdateActivitiesGlbUb(scip, consdata, 0.0, SCIPvarGetUbGlobal(var), val, checkreliability);
2114  }
2115 }
2116 
2117 /** updates minimum and maximum activity for coefficient deletion, invalidates maximum absolute value if necessary */
2118 static
2120  SCIP* scip, /**< SCIP data structure */
2121  SCIP_CONSDATA* consdata, /**< linear constraint data */
2122  SCIP_VAR* var, /**< variable of constraint entry */
2123  SCIP_Real val, /**< coefficient of constraint entry */
2124  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2125  )
2126 {
2127  assert(scip != NULL);
2128  assert(consdata != NULL);
2129  assert(var != NULL);
2130 
2131  /* invalidate maximum absolute value, if this coefficient was the maximum */
2132  if( consdata->validmaxabsval )
2133  {
2134  SCIP_Real absval;
2135 
2136  absval = REALABS(val);
2137 
2138  if( SCIPisEQ(scip, absval, consdata->maxabsval) )
2139  {
2140  consdata->validmaxabsval = FALSE;
2141  consdata->maxabsval = SCIP_INVALID;
2142  }
2143  }
2144 
2145  /* invalidate minimum absolute value, if this coefficient was the minimum */
2146  if( consdata->validminabsval )
2147  {
2148  SCIP_Real absval;
2149 
2150  absval = REALABS(val);
2151 
2152  if( SCIPisEQ(scip, absval, consdata->minabsval) )
2153  {
2154  consdata->validminabsval = FALSE;
2155  consdata->minabsval = SCIP_INVALID;
2156  }
2157  }
2158 
2159  /* update minimal and maximal activity */
2160  if( consdata->validactivities )
2161  {
2162  assert(consdata->minactivity < SCIP_INVALID);
2163  assert(consdata->maxactivity < SCIP_INVALID);
2164  assert(consdata->glbminactivity < SCIP_INVALID);
2165  assert(consdata->glbmaxactivity < SCIP_INVALID);
2166 
2167  consdataUpdateActivitiesLb(scip, consdata, var, SCIPvarGetLbLocal(var), 0.0, val, checkreliability);
2168  consdataUpdateActivitiesUb(scip, consdata, var, SCIPvarGetUbLocal(var), 0.0, val, checkreliability);
2169  consdataUpdateActivitiesGlbLb(scip, consdata, SCIPvarGetLbGlobal(var), 0.0, val, checkreliability);
2170  consdataUpdateActivitiesGlbUb(scip, consdata, SCIPvarGetUbGlobal(var), 0.0, val, checkreliability);
2171  }
2172 }
2173 
2174 /** updates minimum and maximum activity for coefficient change, invalidates maximum absolute value if necessary */
2175 static
2177  SCIP* scip, /**< SCIP data structure */
2178  SCIP_CONSDATA* consdata, /**< linear constraint data */
2179  SCIP_VAR* var, /**< variable of constraint entry */
2180  SCIP_Real oldval, /**< old coefficient of constraint entry */
2181  SCIP_Real newval, /**< new coefficient of constraint entry */
2182  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2183  )
2184 {
2185  assert(scip != NULL);
2186  assert(consdata != NULL);
2187  assert(var != NULL);
2188 
2189  /* old zero coefficients should be handled by consdataUpdateAddCoef() */
2190  assert(!SCIPisZero(scip, oldval));
2191 
2192  /* new zero coefficients should be handled by consdataUpdateDelCoef() */
2193  assert(!SCIPisZero(scip, newval));
2194 
2195  /* update maximum absolute value */
2196  if( consdata->validmaxabsval )
2197  {
2198  SCIP_Real absval;
2199 
2200  absval = REALABS(newval);
2201 
2202  if( SCIPisGE(scip, absval, consdata->maxabsval) )
2203  {
2204  consdata->maxabsval = absval;
2205  }
2206  else
2207  {
2208  absval = REALABS(oldval);
2209 
2210  /* invalidate maximum absolute value */
2211  if( SCIPisEQ(scip, absval, consdata->maxabsval) )
2212  {
2213  consdata->validmaxabsval = FALSE;
2214  consdata->maxabsval = SCIP_INVALID;
2215  }
2216  }
2217  }
2218 
2219  /* update minimum absolute value */
2220  if( consdata->validminabsval )
2221  {
2222  SCIP_Real absval;
2223 
2224  absval = REALABS(newval);
2225 
2226  if( SCIPisLE(scip, absval, consdata->minabsval) )
2227  {
2228  consdata->minabsval = absval;
2229  }
2230  else
2231  {
2232  absval = REALABS(oldval);
2233 
2234  /* invalidate minimum absolute value */
2235  if( SCIPisEQ(scip, absval, consdata->minabsval) )
2236  {
2237  consdata->validminabsval = FALSE;
2238  consdata->minabsval = SCIP_INVALID;
2239  }
2240  }
2241  }
2242 
2243  /* update maximum activity delta */
2244  if( !SCIPisInfinity(scip, consdata->maxactdelta ) )
2245  {
2246  SCIP_Real domain;
2247  SCIP_Real delta;
2248 
2249  assert(!SCIPisInfinity(scip, SCIPvarGetLbLocal(var)));
2250  assert(!SCIPisInfinity(scip, SCIPvarGetUbLocal(var)));
2251 
2252  domain = SCIPvarGetUbLocal(var) - SCIPvarGetLbLocal(var);
2253  delta = REALABS(newval) * domain;
2254 
2255  if( delta > consdata->maxactdelta )
2256  {
2257  consdata->maxactdelta = delta;
2258  consdata->maxactdeltavar = var;
2259  }
2260  else
2261  {
2262  /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
2263  if( consdata->maxactdeltavar == var )
2264  consdata->maxactdelta = SCIP_INVALID;
2265  }
2266  }
2267 
2268  /* @todo do something more clever here, e.g. if oldval * newval >= 0, do the update directly */
2269  consdataUpdateDelCoef(scip, consdata, var, oldval, checkreliability);
2270  consdataUpdateAddCoef(scip, consdata, var, newval, checkreliability);
2271 }
2272 
2273 /** returns the maximum absolute value of all coefficients in the constraint */
2274 static
2276  SCIP_CONSDATA* consdata /**< linear constraint data */
2277  )
2278 {
2279  assert(consdata != NULL);
2280 
2281  if( !consdata->validmaxabsval )
2282  consdataCalcMaxAbsval(consdata);
2283  assert(consdata->validmaxabsval);
2284  assert(consdata->maxabsval < SCIP_INVALID);
2285 
2286  return consdata->maxabsval;
2287 }
2288 
2289 /** returns the minimum absolute value of all coefficients in the constraint */
2290 static
2292  SCIP_CONSDATA* consdata /**< linear constraint data */
2293  )
2294 {
2295  assert(consdata != NULL);
2296 
2297  if( !consdata->validminabsval )
2298  consdataCalcMinAbsval(consdata);
2299  assert(consdata->validminabsval);
2300  assert(consdata->minabsval < SCIP_INVALID);
2301 
2302  return consdata->minabsval;
2303 }
2304 
2305 /** calculates minimum and maximum local and global activity for constraint from scratch;
2306  * additionally recalculates maximum absolute value of coefficients
2307  */
2308 static
2310  SCIP* scip, /**< SCIP data structure */
2311  SCIP_CONSDATA* consdata /**< linear constraint data */
2312  )
2313 {
2314  int i;
2315 
2316  assert(scip != NULL);
2317  assert(consdata != NULL);
2318  assert(!consdata->validactivities);
2319  assert(consdata->minactivity >= SCIP_INVALID || consdata->validminact);
2320  assert(consdata->maxactivity >= SCIP_INVALID || consdata->validmaxact);
2321  assert(consdata->glbminactivity >= SCIP_INVALID || consdata->validglbminact);
2322  assert(consdata->glbmaxactivity >= SCIP_INVALID || consdata->validglbmaxact);
2323 
2324  consdata->validmaxabsval = TRUE;
2325  consdata->validminabsval = TRUE;
2326  consdata->validactivities = TRUE;
2327  consdata->validminact = TRUE;
2328  consdata->validmaxact = TRUE;
2329  consdata->validglbminact = TRUE;
2330  consdata->validglbmaxact = TRUE;
2331  consdata->maxabsval = 0.0;
2332  consdata->minabsval = (consdata->nvars == 0 ? 0.0 : REALABS(consdata->vals[0]));
2333  consdata->minactivity = 0.0;
2334  consdata->maxactivity = 0.0;
2335  consdata->lastminactivity = 0.0;
2336  consdata->lastmaxactivity = 0.0;
2337  consdata->minactivityneginf = 0;
2338  consdata->minactivityposinf = 0;
2339  consdata->maxactivityneginf = 0;
2340  consdata->maxactivityposinf = 0;
2341  consdata->minactivityneghuge = 0;
2342  consdata->minactivityposhuge = 0;
2343  consdata->maxactivityneghuge = 0;
2344  consdata->maxactivityposhuge = 0;
2345  consdata->glbminactivity = 0.0;
2346  consdata->glbmaxactivity = 0.0;
2347  consdata->lastglbminactivity = 0.0;
2348  consdata->lastglbmaxactivity = 0.0;
2349  consdata->glbminactivityneginf = 0;
2350  consdata->glbminactivityposinf = 0;
2351  consdata->glbmaxactivityneginf = 0;
2352  consdata->glbmaxactivityposinf = 0;
2353  consdata->glbminactivityneghuge = 0;
2354  consdata->glbminactivityposhuge = 0;
2355  consdata->glbmaxactivityneghuge = 0;
2356  consdata->glbmaxactivityposhuge = 0;
2357 
2358  for( i = 0; i < consdata->nvars; ++i )
2359  consdataUpdateAddCoef(scip, consdata, consdata->vars[i], consdata->vals[i], FALSE);
2360 
2361  consdata->lastminactivity = consdata->minactivity;
2362  consdata->lastmaxactivity = consdata->maxactivity;
2363  consdata->lastglbminactivity = consdata->glbminactivity;
2364  consdata->lastglbmaxactivity = consdata->glbmaxactivity;
2365 }
2366 
2367 /** gets minimal activity for constraint and given values of counters for infinite and huge contributions
2368  * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
2369  */
2370 static
2371 void getMinActivity(
2372  SCIP* scip, /**< SCIP data structure */
2373  SCIP_CONSDATA* consdata, /**< linear constraint */
2374  int posinf, /**< number of coefficients contributing pos. infinite value */
2375  int neginf, /**< number of coefficients contributing neg. infinite value */
2376  int poshuge, /**< number of coefficients contributing huge pos. value */
2377  int neghuge, /**< number of coefficients contributing huge neg. value */
2378  SCIP_Real delta, /**< value to subtract from stored minactivity
2379  * (contribution of the variable set to zero when getting residual activity) */
2380  SCIP_Bool global, /**< should the global or local minimal activity be returned? */
2381  SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
2382  SCIP_Real* minactivity, /**< pointer to store the minimal activity */
2383  SCIP_Bool* isrelax, /**< pointer to store whether the activity is a relaxation,
2384  * i.e. is <= the exact minactivity (in case of huge contributing values) */
2385  SCIP_Bool* issettoinfinity /**< pointer to store whether minactivity was set to infinity or calculated */
2386  )
2387 {
2388  assert(scip != NULL);
2389  assert(consdata != NULL);
2390  assert(posinf >= 0);
2391  assert(neginf >= 0);
2392  assert(poshuge >= 0);
2393  assert(neghuge >= 0);
2394  assert(minactivity != NULL);
2395  assert(isrelax != NULL);
2396  assert(issettoinfinity != NULL);
2397 
2398  /* if we have pos. infinite contributions, the minactivity is +infty */
2399  if( posinf > 0 )
2400  {
2401  *minactivity = SCIPinfinity(scip);
2402  *issettoinfinity = TRUE;
2403  *isrelax = FALSE;
2404  }
2405  /* if we have neg. (and no pos.) infinite contributions, the minactivity is -infty */
2406  else if( neginf > 0 )
2407  {
2408  *minactivity = -SCIPinfinity(scip);
2409  *issettoinfinity = TRUE;
2410  *isrelax = FALSE;
2411  }
2412  /* if we have neg. huge contributions, we only know that -infty is a relaxation of the minactivity */
2413  else if( neghuge > 0 )
2414  {
2415  *minactivity = -SCIPinfinity(scip);
2416  *issettoinfinity = TRUE;
2417  *isrelax = TRUE;
2418  }
2419  /* we do not need a good relaxation and we have positive huge contributions, so we just return -infty as activity */
2420  else if( !goodrelax && poshuge > 0 )
2421  {
2422  *minactivity = -SCIPinfinity(scip);
2423  *issettoinfinity = TRUE;
2424  *isrelax = TRUE;
2425  }
2426  else
2427  {
2428  SCIP_Real tmpactivity;
2429 
2430  /* recompute minactivity if it is not valid */
2431  if( global )
2432  {
2433  if( !consdata->validglbminact )
2434  consdataRecomputeGlbMinactivity(scip, consdata);
2435  assert(consdata->validglbminact);
2436 
2437  tmpactivity = consdata->glbminactivity;
2438  }
2439  else
2440  {
2441  if( !consdata->validminact )
2442  consdataRecomputeMinactivity(scip, consdata);
2443  assert(consdata->validminact);
2444 
2445  tmpactivity = consdata->minactivity;
2446  }
2447 
2448  /* we have no infinite and no neg. huge contributions, but pos. huge contributions;
2449  * a feasible relaxation of the minactivity is the number of positive huge contributions
2450  * times the minimum value counting as "huge" plus finite (and non-huge) part of minactivity - delta
2451  */
2452  if( poshuge > 0 )
2453  {
2454  *minactivity = 1.0 * poshuge * SCIPgetHugeValue(scip) + (tmpactivity - delta);
2455  *issettoinfinity = FALSE;
2456  *isrelax = TRUE;
2457  }
2458  /* all counters are zero, so the minactivity is just stored and we subtract the delta */
2459  else
2460  {
2461  *minactivity = tmpactivity - delta;
2462  *issettoinfinity = FALSE;
2463  *isrelax = FALSE;
2464  }
2465  }
2466 }
2467 
2468 /** gets maximal activity for constraint and given values of counters for infinite and huge contributions
2469  * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
2470  */
2471 static
2472 void getMaxActivity(
2473  SCIP* scip, /**< SCIP data structure */
2474  SCIP_CONSDATA* consdata, /**< linear constraint */
2475  int posinf, /**< number of coefficients contributing pos. infinite value */
2476  int neginf, /**< number of coefficients contributing neg. infinite value */
2477  int poshuge, /**< number of coefficients contributing huge pos. value */
2478  int neghuge, /**< number of coefficients contributing huge neg. value */
2479  SCIP_Real delta, /**< value to subtract from stored maxactivity
2480  * (contribution of the variable set to zero when getting residual activity) */
2481  SCIP_Bool global, /**< should the global or local maximal activity be returned? */
2482  SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
2483  SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
2484  SCIP_Bool* isrelax, /**< pointer to store whether the activity is a relaxation,
2485  * i.e. is >= the exact maxactivity (in case of huge contributing values) */
2486  SCIP_Bool* issettoinfinity /**< pointer to store whether maxactivity was set to infinity or calculated */
2487  )
2488 {
2489  assert(scip != NULL);
2490  assert(consdata != NULL);
2491  assert(posinf >= 0);
2492  assert(neginf >= 0);
2493  assert(poshuge >= 0);
2494  assert(neghuge >= 0);
2495  assert(maxactivity != NULL);
2496  assert(isrelax != NULL);
2497  assert(issettoinfinity != NULL);
2498 
2499  /* if we have neg. infinite contributions, the maxactivity is -infty */
2500  if( neginf > 0 )
2501  {
2502  *maxactivity = -SCIPinfinity(scip);
2503  *issettoinfinity = TRUE;
2504  *isrelax = FALSE;
2505  }
2506  /* if we have pos. (and no neg.) infinite contributions, the maxactivity is +infty */
2507  else if( posinf > 0 )
2508  {
2509  *maxactivity = SCIPinfinity(scip);
2510  *issettoinfinity = TRUE;
2511  *isrelax = FALSE;
2512  }
2513  /* if we have pos. huge contributions, we only know that +infty is a relaxation of the maxactivity */
2514  else if( poshuge > 0 )
2515  {
2516  *maxactivity = SCIPinfinity(scip);
2517  *issettoinfinity = TRUE;
2518  *isrelax = TRUE;
2519  }
2520  /* we do not need a good relaxation and we have positve huge contributions, so we just return +infty as activity */
2521  else if( !goodrelax && neghuge > 0 )
2522  {
2523  *maxactivity = SCIPinfinity(scip);
2524  *issettoinfinity = TRUE;
2525  *isrelax = TRUE;
2526  }
2527  else
2528  {
2529  SCIP_Real tmpactivity;
2530 
2531  /* recompute maxactivity if it is not valid */
2532  if( global )
2533  {
2534  if( !consdata->validglbmaxact )
2535  consdataRecomputeGlbMaxactivity(scip, consdata);
2536  assert(consdata->validglbmaxact);
2537 
2538  tmpactivity = consdata->glbmaxactivity;
2539  }
2540  else
2541  {
2542  if( !consdata->validmaxact )
2543  consdataRecomputeMaxactivity(scip, consdata);
2544  assert(consdata->validmaxact);
2545 
2546  tmpactivity = consdata->maxactivity;
2547  }
2548 
2549  /* we have no infinite, and no pos. huge contributions, but neg. huge contributions;
2550  * a feasible relaxation of the maxactivity is minus the number of negative huge contributions
2551  * times the minimum value counting as "huge" plus the finite (and non-huge) part of maxactivity minus delta
2552  */
2553  if( neghuge > 0 )
2554  {
2555  *maxactivity = -1.0 * neghuge * SCIPgetHugeValue(scip) + tmpactivity - delta;
2556  *issettoinfinity = FALSE;
2557  *isrelax = TRUE;
2558  }
2559  /* all counters are zero, so the maxactivity is just stored and we subtract the delta */
2560  else
2561  {
2562  *maxactivity = tmpactivity - delta;
2563  *issettoinfinity = FALSE;
2564  *isrelax = FALSE;
2565  }
2566  }
2567 }
2568 
2569 /** gets activity bounds for constraint */
2570 static
2572  SCIP* scip, /**< SCIP data structure */
2573  SCIP_CONSDATA* consdata, /**< linear constraint */
2574  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2575  * relaxed activities ignored, anyway? */
2576  SCIP_Real* minactivity, /**< pointer to store the minimal activity */
2577  SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
2578  SCIP_Bool* minisrelax, /**< pointer to store whether the returned minactivity is just a relaxation,
2579  * i.e. <= the exact minactivity (in case of huge contributions),
2580  * or equal to the exact minimal activity */
2581  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned maxactivity is just a relaxation,
2582  * i.e. >= the exact maxactivity (in case of huge contributions),
2583  * or equal to the exact maximal activity */
2584  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minactivity was set to infinity or calculated */
2585  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxactivity was set to infinity or calculated */
2586 
2587  )
2589  assert(scip != NULL);
2590  assert(consdata != NULL);
2591  assert(minactivity != NULL);
2592  assert(maxactivity != NULL);
2593  assert(isminsettoinfinity != NULL);
2594  assert(ismaxsettoinfinity != NULL);
2595 
2596  if( !consdata->validactivities )
2597  {
2598  consdataCalcActivities(scip, consdata);
2599  assert(consdata->validminact);
2600  assert(consdata->validmaxact);
2601  }
2602  assert(consdata->minactivity < SCIP_INVALID);
2603  assert(consdata->maxactivity < SCIP_INVALID);
2604  assert(consdata->minactivityneginf >= 0);
2605  assert(consdata->minactivityposinf >= 0);
2606  assert(consdata->maxactivityneginf >= 0);
2607  assert(consdata->maxactivityposinf >= 0);
2608 
2609  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2610  consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2611  minactivity, minisrelax, isminsettoinfinity);
2612 
2613  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2614  consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2615  maxactivity, maxisrelax, ismaxsettoinfinity);
2616 }
2617 
2618 /** calculates activity bounds for constraint after setting variable to zero */
2619 static
2621  SCIP* scip, /**< SCIP data structure */
2622  SCIP_CONSDATA* consdata, /**< linear constraint */
2623  SCIP_VAR* cancelvar, /**< variable to calculate activity residual for */
2624  SCIP_Real* resactivity, /**< pointer to store the residual activity */
2625  SCIP_Bool isminresact, /**< should minimal or maximal residual activity be calculated? */
2626  SCIP_Bool useglobalbounds /**< should global or local bounds be used? */
2627  )
2628 {
2629  SCIP_VAR* var;
2630  SCIP_Real val;
2631  SCIP_Real lb;
2632  SCIP_Real ub;
2633  int v;
2634 
2635  assert(scip != NULL);
2636  assert(consdata != NULL);
2637  assert(cancelvar != NULL);
2638  assert(resactivity != NULL);
2639 
2640  *resactivity = 0.0;
2641 
2642  for( v = 0; v < consdata->nvars; ++v )
2643  {
2644  var = consdata->vars[v];
2645  assert(var != NULL);
2646  if( var == cancelvar )
2647  continue;
2648 
2649  val = consdata->vals[v];
2650 
2651  if( useglobalbounds )
2652  {
2653  lb = SCIPvarGetLbGlobal(var);
2654  ub = SCIPvarGetUbGlobal(var);
2655  }
2656  else
2657  {
2658  lb = SCIPvarGetLbLocal(var);
2659  ub = SCIPvarGetUbLocal(var);
2660  }
2661 
2662  assert(!SCIPisZero(scip, val));
2663  assert(SCIPisLE(scip, lb, ub));
2664 
2665  if( val > 0.0 )
2666  {
2667  if( isminresact )
2668  {
2669  assert(!SCIPisInfinity(scip, -lb));
2670  assert(!SCIPisHugeValue(scip, REALABS(val*lb)));
2671  *resactivity += val*lb;
2672  }
2673  else
2674  {
2675  assert(!SCIPisInfinity(scip, ub));
2676  assert(!SCIPisHugeValue(scip, REALABS(val*ub)));
2677  *resactivity += val*ub;
2678  }
2679  }
2680  else
2681  {
2682  if( isminresact)
2683  {
2684  assert(!SCIPisInfinity(scip, ub));
2685  assert(!SCIPisHugeValue(scip, REALABS(val*ub)));
2686  *resactivity += val*ub;
2687  }
2688  else
2689  {
2690  assert(!SCIPisInfinity(scip, -lb));
2691  assert(!SCIPisHugeValue(scip, REALABS(val*lb)));
2692  *resactivity += val*lb;
2693  }
2694  }
2695  }
2696  assert(!SCIPisInfinity(scip, *resactivity) && !SCIPisInfinity(scip, -(*resactivity)));
2697 }
2698 
2699 /** gets activity bounds for constraint after setting variable to zero */
2700 static
2702  SCIP* scip, /**< SCIP data structure */
2703  SCIP_CONSDATA* consdata, /**< linear constraint */
2704  SCIP_VAR* var, /**< variable to calculate activity residual for */
2705  SCIP_Real val, /**< coefficient value of variable in linear constraint */
2706  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2707  * relaxed acticities ignored, anyway? */
2708  SCIP_Real* minresactivity, /**< pointer to store the minimal residual activity */
2709  SCIP_Real* maxresactivity, /**< pointer to store the maximal residual activity */
2710  SCIP_Bool* minisrelax, /**< pointer to store whether the returned residual minactivity is just a
2711  * relaxation, i.e. <= the exact residual minactivity (in case of huge
2712  * contributions), or equal to the exact residual minactivity */
2713  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned residual maxactivity is just a
2714  * relaxation, i.e. <= the exact residual maxactivity (in case of huge
2715  * contributions), or equal to the exact residual minactivity */
2716  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2717  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
2718  )
2719 {
2720  SCIP_Real minactbound;
2721  SCIP_Real maxactbound;
2722  SCIP_Real absval;
2723 
2724  assert(scip != NULL);
2725  assert(consdata != NULL);
2726  assert(var != NULL);
2727  assert(minresactivity != NULL);
2728  assert(maxresactivity != NULL);
2729  assert(minisrelax != NULL);
2730  assert(maxisrelax != NULL);
2731  assert(isminsettoinfinity != NULL);
2732  assert(ismaxsettoinfinity != NULL);
2733 
2734  /* get activity bounds of linear constraint */
2735  if( !consdata->validactivities )
2736  {
2737  consdataCalcActivities(scip, consdata);
2738  assert(consdata->validminact);
2739  assert(consdata->validmaxact);
2740  }
2741  assert(consdata->minactivity < SCIP_INVALID);
2742  assert(consdata->maxactivity < SCIP_INVALID);
2743  assert(consdata->minactivityneginf >= 0);
2744  assert(consdata->minactivityposinf >= 0);
2745  assert(consdata->maxactivityneginf >= 0);
2746  assert(consdata->maxactivityposinf >= 0);
2747  assert(consdata->minactivityneghuge >= 0);
2748  assert(consdata->minactivityposhuge >= 0);
2749  assert(consdata->maxactivityneghuge >= 0);
2750  assert(consdata->maxactivityposhuge >= 0);
2751 
2752  if( val > 0.0 )
2753  {
2754  minactbound = SCIPvarGetLbLocal(var);
2755  maxactbound = SCIPvarGetUbLocal(var);
2756  absval = val;
2757  }
2758  else
2759  {
2760  minactbound = -SCIPvarGetUbLocal(var);
2761  maxactbound = -SCIPvarGetLbLocal(var);
2762  absval = -val;
2763  }
2764 
2765  /* get/compute minactivity by calling getMinActivity() with updated counters for infinite and huge values
2766  * and contribution of variable set to zero that has to be subtracted from finite part of activity
2767  */
2768  if( SCIPisInfinity(scip, minactbound) )
2769  {
2770  assert(consdata->minactivityposinf >= 1);
2771 
2772  getMinActivity(scip, consdata, consdata->minactivityposinf - 1, consdata->minactivityneginf,
2773  consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2774  minresactivity, minisrelax, isminsettoinfinity);
2775  }
2776  else if( SCIPisInfinity(scip, -minactbound) )
2777  {
2778  assert(consdata->minactivityneginf >= 1);
2779 
2780  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf - 1,
2781  consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2782  minresactivity, minisrelax, isminsettoinfinity);
2783  }
2784  else if( SCIPisHugeValue(scip, minactbound * absval) )
2785  {
2786  assert(consdata->minactivityposhuge >= 1);
2787 
2788  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2789  consdata->minactivityposhuge - 1, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2790  minresactivity, minisrelax, isminsettoinfinity);
2791  }
2792  else if( SCIPisHugeValue(scip, -minactbound * absval) )
2793  {
2794  assert(consdata->minactivityneghuge >= 1);
2795 
2796  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2797  consdata->minactivityposhuge, consdata->minactivityneghuge - 1, 0.0, FALSE, goodrelax,
2798  minresactivity, minisrelax, isminsettoinfinity);
2799  }
2800  else
2801  {
2802  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2803  consdata->minactivityposhuge, consdata->minactivityneghuge, absval * minactbound, FALSE, goodrelax,
2804  minresactivity, minisrelax, isminsettoinfinity);
2805  }
2806 
2807  /* get/compute maxactivity by calling getMaxActivity() with updated counters for infinite and huge values
2808  * and contribution of variable set to zero that has to be subtracted from finite part of activity
2809  */
2810  if( SCIPisInfinity(scip, -maxactbound) )
2811  {
2812  assert(consdata->maxactivityneginf >= 1);
2813 
2814  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf - 1,
2815  consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2816  maxresactivity, maxisrelax, ismaxsettoinfinity);
2817  }
2818  else if( SCIPisInfinity(scip, maxactbound) )
2819  {
2820  assert(consdata->maxactivityposinf >= 1);
2821 
2822  getMaxActivity(scip, consdata, consdata->maxactivityposinf - 1, consdata->maxactivityneginf,
2823  consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2824  maxresactivity, maxisrelax, ismaxsettoinfinity);
2825  }
2826  else if( SCIPisHugeValue(scip, absval * maxactbound) )
2827  {
2828  assert(consdata->maxactivityposhuge >= 1);
2829 
2830  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2831  consdata->maxactivityposhuge - 1, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2832  maxresactivity, maxisrelax, ismaxsettoinfinity);
2833  }
2834  else if( SCIPisHugeValue(scip, -absval * maxactbound) )
2835  {
2836  assert(consdata->maxactivityneghuge >= 1);
2837 
2838  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2839  consdata->maxactivityposhuge, consdata->maxactivityneghuge - 1, 0.0, FALSE, goodrelax,
2840  maxresactivity, maxisrelax, ismaxsettoinfinity);
2841  }
2842  else
2843  {
2844  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2845  consdata->maxactivityposhuge, consdata->maxactivityneghuge, absval * maxactbound, FALSE, goodrelax,
2846  maxresactivity, maxisrelax, ismaxsettoinfinity);
2847  }
2848 }
2849 
2850 /** gets global activity bounds for constraint */
2851 static
2853  SCIP* scip, /**< SCIP data structure */
2854  SCIP_CONSDATA* consdata, /**< linear constraint */
2855  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2856  * relaxed acticities ignored, anyway? */
2857  SCIP_Real* glbminactivity, /**< pointer to store the minimal activity, or NULL, if not needed */
2858  SCIP_Real* glbmaxactivity, /**< pointer to store the maximal activity, or NULL, if not needed */
2859  SCIP_Bool* minisrelax, /**< pointer to store whether the returned minactivity is just a relaxation,
2860  * i.e. <= the exact minactivity (in case of huge contributions),
2861  * or equal to the exact minimal activity */
2862  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned maxactivity is just a relaxation,
2863  * i.e. >= the exact maxactivity (in case of huge contributions),
2864  * or equal to the exact maximal activity */
2865  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2866  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
2867  )
2868 {
2869  assert(scip != NULL);
2870  assert(consdata != NULL);
2871  assert((glbminactivity != NULL && minisrelax != NULL && isminsettoinfinity != NULL)
2872  || (glbmaxactivity != NULL && maxisrelax != NULL && ismaxsettoinfinity != NULL));
2873 
2874  if( !consdata->validactivities )
2875  {
2876  consdataCalcActivities(scip, consdata);
2877  assert(consdata->validglbminact);
2878  assert(consdata->validglbmaxact);
2879  }
2880  assert(consdata->glbminactivity < SCIP_INVALID);
2881  assert(consdata->glbmaxactivity < SCIP_INVALID);
2882  assert(consdata->glbminactivityneginf >= 0);
2883  assert(consdata->glbminactivityposinf >= 0);
2884  assert(consdata->glbmaxactivityneginf >= 0);
2885  assert(consdata->glbmaxactivityposinf >= 0);
2886  assert(consdata->glbminactivityneghuge >= 0);
2887  assert(consdata->glbminactivityposhuge >= 0);
2888  assert(consdata->glbmaxactivityneghuge >= 0);
2889  assert(consdata->glbmaxactivityposhuge >= 0);
2890 
2891  if( glbminactivity != NULL )
2892  {
2893  assert(isminsettoinfinity != NULL);
2894  assert(minisrelax != NULL);
2895 
2896  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
2897  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
2898  glbminactivity, minisrelax, isminsettoinfinity);
2899  }
2900 
2901  if( glbmaxactivity != NULL )
2902  {
2903  assert(ismaxsettoinfinity != NULL);
2904  assert(maxisrelax != NULL);
2905 
2906  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
2907  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
2908  glbmaxactivity, maxisrelax, ismaxsettoinfinity);
2909  }
2910 }
2911 
2912 /** gets global activity bounds for constraint after setting variable to zero */
2913 static
2915  SCIP* scip, /**< SCIP data structure */
2916  SCIP_CONSDATA* consdata, /**< linear constraint */
2917  SCIP_VAR* var, /**< variable to calculate activity residual for */
2918  SCIP_Real val, /**< coefficient value of variable in linear constraint */
2919  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2920  * relaxed acticities ignored, anyway? */
2921  SCIP_Real* minresactivity, /**< pointer to store the minimal residual activity, or NULL, if not needed */
2922  SCIP_Real* maxresactivity, /**< pointer to store the maximal residual activity, or NULL, if not needed */
2923  SCIP_Bool* minisrelax, /**< pointer to store whether the returned residual minactivity is just a
2924  * relaxation, i.e. <= the exact residual minactivity (in case of huge
2925  * contributions), or equal to the exact residual minactivity */
2926  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned residual maxactivity is just a
2927  * relaxation, i.e. <= the exact residual maxactivity (in case of huge
2928  * contributions), or equal to the exact residual minactivity */
2929  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2930  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
2931  )
2932 {
2933  SCIP_Real minactbound;
2934  SCIP_Real maxactbound;
2935  SCIP_Real absval;
2936 
2937  assert(scip != NULL);
2938  assert(consdata != NULL);
2939  assert(var != NULL);
2940  assert((minresactivity != NULL && minisrelax != NULL && isminsettoinfinity != NULL )
2941  || (maxresactivity != NULL && maxisrelax != NULL && ismaxsettoinfinity != NULL));
2942 
2943  /* get activity bounds of linear constraint */
2944  if( !consdata->validactivities )
2945  consdataCalcActivities(scip, consdata);
2946 
2947  assert(consdata->glbminactivity < SCIP_INVALID);
2948  assert(consdata->glbmaxactivity < SCIP_INVALID);
2949  assert(consdata->glbminactivityneginf >= 0);
2950  assert(consdata->glbminactivityposinf >= 0);
2951  assert(consdata->glbmaxactivityneginf >= 0);
2952  assert(consdata->glbmaxactivityposinf >= 0);
2953 
2954  if( val > 0.0 )
2955  {
2956  minactbound = SCIPvarGetLbGlobal(var);
2957  maxactbound = SCIPvarGetUbGlobal(var);
2958  absval = val;
2959  }
2960  else
2961  {
2962  minactbound = -SCIPvarGetUbGlobal(var);
2963  maxactbound = -SCIPvarGetLbGlobal(var);
2964  absval = -val;
2965  }
2966 
2967  if( minresactivity != NULL )
2968  {
2969  assert(isminsettoinfinity != NULL);
2970  assert(minisrelax != NULL);
2971 
2972  /* get/compute minactivity by calling getMinActivity() with updated counters for infinite and huge values
2973  * and contribution of variable set to zero that has to be subtracted from finite part of activity
2974  */
2975  if( SCIPisInfinity(scip, minactbound) )
2976  {
2977  assert(consdata->glbminactivityposinf >= 1);
2978 
2979  getMinActivity(scip, consdata, consdata->glbminactivityposinf - 1, consdata->glbminactivityneginf,
2980  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
2981  minresactivity, minisrelax, isminsettoinfinity);
2982  }
2983  else if( SCIPisInfinity(scip, -minactbound) )
2984  {
2985  assert(consdata->glbminactivityneginf >= 1);
2986 
2987  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf - 1,
2988  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
2989  minresactivity, minisrelax, isminsettoinfinity);
2990  }
2991  else if( SCIPisHugeValue(scip, minactbound * absval) )
2992  {
2993  assert(consdata->glbminactivityposhuge >= 1);
2994 
2995  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
2996  consdata->glbminactivityposhuge - 1, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
2997  minresactivity, minisrelax, isminsettoinfinity);
2998  }
2999  else if( SCIPisHugeValue(scip, -minactbound * absval) )
3000  {
3001  assert(consdata->glbminactivityneghuge >= 1);
3002 
3003  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
3004  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge - 1, 0.0, TRUE, goodrelax,
3005  minresactivity, minisrelax, isminsettoinfinity);
3006  }
3007  else
3008  {
3009  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
3010  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, absval * minactbound, TRUE,
3011  goodrelax, minresactivity, minisrelax, isminsettoinfinity);
3012  }
3013  }
3014 
3015  if( maxresactivity != NULL )
3016  {
3017  assert(ismaxsettoinfinity != NULL);
3018  assert(maxisrelax != NULL);
3019 
3020  /* get/compute maxactivity by calling getMaxActivity() with updated counters for infinite and huge values
3021  * and contribution of variable set to zero that has to be subtracted from finite part of activity
3022  */
3023  if( SCIPisInfinity(scip, -maxactbound) )
3024  {
3025  assert(consdata->glbmaxactivityneginf >= 1);
3026 
3027  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf - 1,
3028  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
3029  maxresactivity, maxisrelax, ismaxsettoinfinity);
3030  }
3031  else if( SCIPisInfinity(scip, maxactbound) )
3032  {
3033  assert(consdata->glbmaxactivityposinf >= 1);
3034 
3035  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf - 1, consdata->glbmaxactivityneginf,
3036  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
3037  maxresactivity, maxisrelax, ismaxsettoinfinity);
3038  }
3039  else if( SCIPisHugeValue(scip, absval * maxactbound) )
3040  {
3041  assert(consdata->glbmaxactivityposhuge >= 1);
3042 
3043  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
3044  consdata->glbmaxactivityposhuge - 1, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
3045  maxresactivity, maxisrelax, ismaxsettoinfinity);
3046  }
3047  else if( SCIPisHugeValue(scip, -absval * maxactbound) )
3048  {
3049  assert(consdata->glbmaxactivityneghuge >= 1);
3050 
3051  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
3052  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge - 1, 0.0, TRUE, goodrelax,
3053  maxresactivity, maxisrelax, ismaxsettoinfinity);
3054  }
3055  else
3056  {
3057  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
3058  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, absval * maxactbound, TRUE,
3059  goodrelax, maxresactivity, maxisrelax, ismaxsettoinfinity);
3060  }
3061  }
3062 }
3063 
3064 /** calculates the activity of the linear constraint for given solution */
3065 static
3067  SCIP* scip, /**< SCIP data structure */
3068  SCIP_CONSDATA* consdata, /**< linear constraint data */
3069  SCIP_SOL* sol /**< solution to get activity for, NULL to current solution */
3070  )
3071 {
3072  SCIP_Real activity;
3073 
3074  assert(scip != NULL);
3075  assert(consdata != NULL);
3076 
3077  if( sol == NULL && !SCIPhasCurrentNodeLP(scip) )
3078  activity = consdataComputePseudoActivity(scip, consdata);
3079  else
3080  {
3081  SCIP_Real solval;
3082  int nposinf;
3083  int nneginf;
3084  SCIP_Bool negsign;
3085  int v;
3086 
3087  activity = 0.0;
3088  nposinf = 0;
3089  nneginf = 0;
3090 
3091  for( v = 0; v < consdata->nvars; ++v )
3092  {
3093  solval = SCIPgetSolVal(scip, sol, consdata->vars[v]);
3094 
3095  if( consdata->vals[v] < 0 )
3096  negsign = TRUE;
3097  else
3098  negsign = FALSE;
3099 
3100  if( (SCIPisInfinity(scip, solval) && !negsign) || (SCIPisInfinity(scip, -solval) && negsign) )
3101  ++nposinf;
3102  else if( (SCIPisInfinity(scip, solval) && negsign) || (SCIPisInfinity(scip, -solval) && !negsign) )
3103  ++nneginf;
3104  else
3105  activity += consdata->vals[v] * solval;
3106  }
3107  assert(nneginf >= 0 && nposinf >= 0);
3108 
3109  SCIPdebugMsg(scip, "activity of linear constraint: %.15g, %d positive infinity values, %d negative infinity values \n", activity, nposinf, nneginf);
3110 
3111  /* check for amount of infinity values and correct the activity */
3112  if( nposinf > 0 && nneginf > 0 )
3113  activity = (consdata->rhs + consdata->lhs) / 2;
3114  else if( nposinf > 0 )
3115  activity = SCIPinfinity(scip);
3116  else if( nneginf > 0 )
3117  activity = -SCIPinfinity(scip);
3118 
3119  SCIPdebugMsg(scip, "corrected activity of linear constraint: %.15g\n", activity);
3120  }
3121 
3122  if( activity == SCIP_INVALID ) /*lint !e777*/
3123  return activity;
3124  else if( activity < 0 )
3125  activity = MAX(activity, -SCIPinfinity(scip)); /*lint !e666*/
3126  else
3127  activity = MIN(activity, SCIPinfinity(scip)); /*lint !e666*/
3128 
3129  return activity;
3130 }
3131 
3132 /** calculates the feasibility of the linear constraint for given solution */
3133 static
3135  SCIP* scip, /**< SCIP data structure */
3136  SCIP_CONSDATA* consdata, /**< linear constraint data */
3137  SCIP_SOL* sol /**< solution to get feasibility for, NULL to current solution */
3138  )
3139 {
3140  SCIP_Real activity;
3141 
3142  assert(scip != NULL);
3143  assert(consdata != NULL);
3144 
3145  activity = consdataGetActivity(scip, consdata, sol);
3146 
3147  if( activity == SCIP_INVALID ) /*lint !e777*/
3148  return -SCIPinfinity(scip);
3149 
3150  return MIN(consdata->rhs - activity, activity - consdata->lhs);
3152 
3153 /** updates bit signatures after adding a single coefficient */
3154 static
3156  SCIP_CONSDATA* consdata, /**< linear constraint data */
3157  int pos /**< position of coefficient to update signatures for */
3158  )
3159 {
3160  uint64_t varsignature;
3161  SCIP_Real lb;
3162  SCIP_Real ub;
3163  SCIP_Real val;
3164 
3165  assert(consdata != NULL);
3166  assert(consdata->validsignature);
3167 
3168  varsignature = SCIPhashSignature64(SCIPvarGetIndex(consdata->vars[pos]));
3169  lb = SCIPvarGetLbGlobal(consdata->vars[pos]);
3170  ub = SCIPvarGetUbGlobal(consdata->vars[pos]);
3171  val = consdata->vals[pos];
3172  if( (val > 0.0 && ub > 0.0) || (val < 0.0 && lb < 0.0) )
3173  consdata->possignature |= varsignature;
3174  if( (val > 0.0 && lb < 0.0) || (val < 0.0 && ub > 0.0) )
3175  consdata->negsignature |= varsignature;
3176 }
3177 
3178 /** calculates the bit signatures of the given constraint data */
3179 static
3181  SCIP_CONSDATA* consdata /**< linear constraint data */
3182  )
3183 {
3184  assert(consdata != NULL);
3185 
3186  if( !consdata->validsignature )
3187  {
3188  int i;
3189 
3190  consdata->validsignature = TRUE;
3191  consdata->possignature = 0;
3192  consdata->negsignature = 0;
3193  for( i = 0; i < consdata->nvars; ++i )
3194  consdataUpdateSignatures(consdata, i);
3195  }
3196 }
3198 /** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
3199 static
3200 SCIP_DECL_SORTINDCOMP(consdataCompVar)
3201 { /*lint --e{715}*/
3202  SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
3203  SCIP_VAR* var1;
3204  SCIP_VAR* var2;
3205 
3206  assert(consdata != NULL);
3207  assert(0 <= ind1 && ind1 < consdata->nvars);
3208  assert(0 <= ind2 && ind2 < consdata->nvars);
3209 
3210  var1 = consdata->vars[ind1];
3211  var2 = consdata->vars[ind2];
3212 
3213  /* exactly one variable is binary */
3214  if( SCIPvarIsBinary(var1) != SCIPvarIsBinary(var2) )
3215  {
3216  return (SCIPvarIsBinary(var1) ? -1 : +1);
3217  }
3218  /* both variables are binary */
3219  else if( SCIPvarIsBinary(var1) )
3220  {
3221  return SCIPvarCompare(var1, var2);
3222  }
3223  else
3224  {
3225  SCIP_VARTYPE vartype1 = SCIPvarGetType(var1);
3226  SCIP_VARTYPE vartype2 = SCIPvarGetType(var2);
3227 
3228  if( vartype1 < vartype2 )
3229  return -1;
3230  else if( vartype1 > vartype2 )
3231  return +1;
3232  else
3233  return SCIPvarCompare(var1, var2);
3234  }
3235 }
3236 
3237 /** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
3238 static
3239 SCIP_DECL_SORTINDCOMP(consdataCompVarProp)
3240 { /*lint --e{715}*/
3241  SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
3242  SCIP_VAR* var1;
3243  SCIP_VAR* var2;
3244 
3245  assert(consdata != NULL);
3246  assert(0 <= ind1 && ind1 < consdata->nvars);
3247  assert(0 <= ind2 && ind2 < consdata->nvars);
3248 
3249  var1 = consdata->vars[ind1];
3250  var2 = consdata->vars[ind2];
3251 
3252  /* exactly one variable is binary */
3253  if( SCIPvarIsBinary(var1) != SCIPvarIsBinary(var2) )
3254  {
3255  return (SCIPvarIsBinary(var1) ? -1 : +1);
3256  }
3257  /* both variables are binary */
3258  else if( SCIPvarIsBinary(var1) )
3259  {
3260  SCIP_Real abscoef1 = REALABS(consdata->vals[ind1]);
3261  SCIP_Real abscoef2 = REALABS(consdata->vals[ind2]);
3262 
3263  if( EPSGT(abscoef1, abscoef2, 1e-9) )
3264  return -1;
3265  else if( EPSGT(abscoef2, abscoef1, 1e-9) )
3266  return +1;
3267  else
3268  return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
3269  }
3270  else
3271  {
3272  SCIP_VARTYPE vartype1 = SCIPvarGetType(var1);
3273  SCIP_VARTYPE vartype2 = SCIPvarGetType(var2);
3274 
3275  if( vartype1 < vartype2 )
3276  {
3277  return -1;
3278  }
3279  else if( vartype1 > vartype2 )
3280  {
3281  return +1;
3282  }
3283  else
3284  {
3285  /* both variables are continuous */
3286  if( !SCIPvarIsIntegral(var1) )
3287  {
3288  assert(!SCIPvarIsIntegral(var2));
3289  return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
3290  }
3291  else
3292  {
3293  SCIP_Real abscont1 = REALABS(consdata->vals[ind1] * (SCIPvarGetUbGlobal(var1) - SCIPvarGetLbGlobal(var1)));
3294  SCIP_Real abscont2 = REALABS(consdata->vals[ind2] * (SCIPvarGetUbGlobal(var2) - SCIPvarGetLbGlobal(var2)));
3295 
3296  if( EPSGT(abscont1, abscont2, 1e-9) )
3297  return -1;
3298  else if( EPSGT(abscont2, abscont1, 1e-9) )
3299  return +1;
3300  else
3301  return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
3302  }
3303  }
3304  }
3305 }
3306 
3307 /** permutes the constraint's variables according to a given permutation. */
3308 static
3309 void permSortConsdata(
3310  SCIP_CONSDATA* consdata, /**< the constraint data */
3311  int* perm, /**< the target permutation */
3312  int nvars /**< the number of variables */
3313  )
3314 { /*lint --e{715}*/
3315  SCIP_VAR* varv;
3316  SCIP_EVENTDATA* eventdatav;
3317  SCIP_Real valv;
3318  int v;
3319  int i;
3320  int nexti;
3321 
3322  assert(perm != NULL);
3323  assert(consdata != NULL);
3324 
3325  /* permute the variables in the linear constraint according to the target permutation */
3326  eventdatav = NULL;
3327  for( v = 0; v < nvars; ++v )
3328  {
3329  if( perm[v] != v )
3330  {
3331  varv = consdata->vars[v];
3332  valv = consdata->vals[v];
3333  if( consdata->eventdata != NULL )
3334  eventdatav = consdata->eventdata[v];
3335  i = v;
3336  do
3337  {
3338  assert(0 <= perm[i] && perm[i] < nvars);
3339  assert(perm[i] != i);
3340  consdata->vars[i] = consdata->vars[perm[i]];
3341  consdata->vals[i] = consdata->vals[perm[i]];
3342  if( consdata->eventdata != NULL )
3343  {
3344  consdata->eventdata[i] = consdata->eventdata[perm[i]];
3345  consdata->eventdata[i]->varpos = i;
3346  }
3347  nexti = perm[i];
3348  perm[i] = i;
3349  i = nexti;
3350  }
3351  while( perm[i] != v );
3352  consdata->vars[i] = varv;
3353  consdata->vals[i] = valv;
3354  if( consdata->eventdata != NULL )
3355  {
3356  consdata->eventdata[i] = eventdatav;
3357  consdata->eventdata[i]->varpos = i;
3358  }
3359  perm[i] = i;
3360  }
3361  }
3362 #ifdef SCIP_DEBUG
3363  /* check sorting */
3364  for( v = 0; v < nvars; ++v )
3365  {
3366  assert(perm[v] == v);
3367  assert(consdata->eventdata == NULL || consdata->eventdata[v]->varpos == v);
3368  }
3369 #endif
3370 }
3371 
3372 /** sorts linear constraint's variables depending on the stage of the solving process:
3373  * - during PRESOLVING
3374  * sorts variables by binaries, integers, implicit integers, and continuous variables,
3375  * and the variables of the same type by non-decreasing variable index
3376  *
3377  * - during SOLVING
3378  * sorts variables of the remaining problem by binaries, integers, implicit integers, and continuous variables,
3379  * and binary and integer variables by their global max activity delta (within each group),
3380  * ties within a group are broken by problem index of the variable.
3381  *
3382  * This fastens the propagation time of the constraint handler.
3383  */
3384 static
3386  SCIP* scip, /**< SCIP data structure */
3387  SCIP_CONSDATA* consdata /**< linear constraint data */
3388  )
3389 {
3390  assert(scip != NULL);
3391  assert(consdata != NULL);
3392 
3393  /* check if there are variables for sorting */
3394  if( consdata->nvars <= 1 )
3395  {
3396  consdata->indexsorted = TRUE;
3397  consdata->coefsorted = TRUE;
3398  consdata->nbinvars = (consdata->nvars == 1 ? (int)SCIPvarIsBinary(consdata->vars[0]) : 0);
3399  }
3400  else if( (!consdata->indexsorted && SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE)
3401  || (!consdata->coefsorted && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE) )
3402  {
3403  int* perm;
3404  int v;
3405 
3406  /* get temporary memory to store the sorted permutation */
3407  SCIP_CALL( SCIPallocBufferArray(scip, &perm, consdata->nvars) );
3408 
3409  /* call sorting method */
3410  if( SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE )
3411  SCIPsort(perm, consdataCompVar, (void*)consdata, consdata->nvars);
3412  else
3413  SCIPsort(perm, consdataCompVarProp, (void*)consdata, consdata->nvars);
3414 
3415  permSortConsdata(consdata, perm, consdata->nvars);
3416 
3417  /* free temporary memory */
3418  SCIPfreeBufferArray(scip, &perm);
3419 
3420  if( SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE )
3421  {
3422  consdata->indexsorted = FALSE;
3423  consdata->coefsorted = TRUE;
3424 
3425  /* count binary variables in the sorted vars array */
3426  consdata->nbinvars = 0;
3427  for( v = 0; v < consdata->nvars; ++v )
3428  {
3429  if( SCIPvarIsBinary(consdata->vars[v]) )
3430  ++consdata->nbinvars;
3431  else
3432  break;
3433  }
3434  }
3435  else
3436  {
3437  consdata->indexsorted = TRUE;
3438  consdata->coefsorted = FALSE;
3439  }
3440  }
3441 
3442  return SCIP_OKAY;
3443 }
3444 
3445 
3446 /*
3447  * local linear constraint handler methods
3448  */
3449 
3450 /** sets left hand side of linear constraint */
3451 static
3453  SCIP* scip, /**< SCIP data structure */
3454  SCIP_CONS* cons, /**< linear constraint */
3455  SCIP_Real lhs /**< new left hand side */
3456  )
3457 {
3458  SCIP_CONSDATA* consdata;
3459  SCIP_Bool locked;
3460  int i;
3461 
3462  assert(scip != NULL);
3463  assert(cons != NULL);
3464  assert(!SCIPisInfinity(scip, lhs));
3465 
3466  /* adjust value to not be smaller than -inf */
3467  if ( SCIPisInfinity(scip, -lhs) )
3468  lhs = -SCIPinfinity(scip);
3470  consdata = SCIPconsGetData(cons);
3471  assert(consdata != NULL);
3472  assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
3473  assert(!SCIPisInfinity(scip, consdata->lhs));
3474 
3475  /* check whether the side is not changed */
3476  if( SCIPisEQ(scip, consdata->lhs, lhs) )
3477  return SCIP_OKAY;
3478 
3479  /* ensure that rhs >= lhs is satisfied without numerical tolerance */
3480  if( SCIPisEQ(scip, lhs, consdata->rhs) )
3481  {
3482  consdata->rhs = lhs;
3483  assert(consdata->row == NULL);
3484  }
3485 
3486  locked = FALSE;
3487  for( i = 0; i < NLOCKTYPES && !locked; i++ )
3488  locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
3489 
3490  /* if necessary, update the rounding locks of variables */
3491  if( locked )
3492  {
3493  if( SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, -lhs) )
3494  {
3495  SCIP_VAR** vars;
3496  SCIP_Real* vals;
3497  int v;
3498 
3499  /* the left hand side switched from -infinity to a non-infinite value -> install rounding locks */
3500  vars = consdata->vars;
3501  vals = consdata->vals;
3502 
3503  for( v = 0; v < consdata->nvars; ++v )
3504  {
3505  assert(vars[v] != NULL);
3506  assert(!SCIPisZero(scip, vals[v]));
3507 
3508  if( SCIPisPositive(scip, vals[v]) )
3509  {
3510  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3511  }
3512  else
3513  {
3514  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3515  }
3516  }
3517  }
3518  else if( !SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, -lhs) )
3519  {
3520  SCIP_VAR** vars;
3521  SCIP_Real* vals;
3522  int v;
3523 
3524  /* the left hand side switched from a non-infinite value to -infinity -> remove rounding locks */
3525  vars = consdata->vars;
3526  vals = consdata->vals;
3527 
3528  for( v = 0; v < consdata->nvars; ++v )
3529  {
3530  assert(vars[v] != NULL);
3531  assert(!SCIPisZero(scip, vals[v]));
3532 
3533  if( SCIPisPositive(scip, vals[v]) )
3534  {
3535  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3536  }
3537  else
3538  {
3539  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3540  }
3541  }
3542  }
3543  }
3544 
3545  /* 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 */
3546  if( !SCIPisInfinity(scip, -lhs) && SCIPisGT(scip, lhs, consdata->lhs) )
3547  {
3548  consdata->boundstightened = 0;
3549  consdata->presolved = FALSE;
3550  consdata->cliquesadded = FALSE;
3551  consdata->implsadded = FALSE;
3552 
3553  /* mark the constraint for propagation */
3554  if( SCIPconsIsTransformed(cons) )
3555  {
3556  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3557  }
3558  }
3559 
3560  /* set new left hand side and update constraint data */
3561  consdata->lhs = lhs;
3562  consdata->changed = TRUE;
3563  consdata->normalized = FALSE;
3564  consdata->upgradetried = FALSE;
3565  consdata->rangedrowpropagated = 0;
3566 
3567  /* update the lhs of the LP row */
3568  if( consdata->row != NULL )
3569  {
3570  SCIP_CALL( SCIPchgRowLhs(scip, consdata->row, lhs) );
3571  }
3572 
3573  return SCIP_OKAY;
3574 }
3575 
3576 /** sets right hand side of linear constraint */
3577 static
3579  SCIP* scip, /**< SCIP data structure */
3580  SCIP_CONS* cons, /**< linear constraint */
3581  SCIP_Real rhs /**< new right hand side */
3582  )
3583 {
3584  SCIP_CONSDATA* consdata;
3585  SCIP_Bool locked;
3586  int i;
3587 
3588  assert(scip != NULL);
3589  assert(cons != NULL);
3590  assert(!SCIPisInfinity(scip, -rhs));
3591 
3592  /* adjust value to not be larger than inf */
3593  if ( SCIPisInfinity(scip, rhs) )
3594  rhs = SCIPinfinity(scip);
3596  consdata = SCIPconsGetData(cons);
3597  assert(consdata != NULL);
3598  assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
3599  assert(!SCIPisInfinity(scip, -consdata->rhs));
3600 
3601  /* check whether the side is not changed */
3602  if( SCIPisEQ(scip, consdata->rhs, rhs) )
3603  return SCIP_OKAY;
3604 
3605  /* ensure that rhs >= lhs is satisfied without numerical tolerance */
3606  if( SCIPisEQ(scip, rhs, consdata->lhs) )
3607  {
3608  consdata->lhs = rhs;
3609  assert(consdata->row == NULL);
3610  }
3611 
3612  locked = FALSE;
3613  for( i = 0; i < NLOCKTYPES && !locked; i++ )
3614  locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
3615 
3616  /* if necessary, update the rounding locks of variables */
3617  if( locked )
3618  {
3619  assert(SCIPconsIsTransformed(cons));
3620 
3621  if( SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, rhs) )
3622  {
3623  SCIP_VAR** vars;
3624  SCIP_Real* vals;
3625  int v;
3626 
3627  /* the right hand side switched from infinity to a non-infinite value -> install rounding locks */
3628  vars = consdata->vars;
3629  vals = consdata->vals;
3630 
3631  for( v = 0; v < consdata->nvars; ++v )
3632  {
3633  assert(vars[v] != NULL);
3634  assert(!SCIPisZero(scip, vals[v]));
3635 
3636  if( SCIPisPositive(scip, vals[v]) )
3637  {
3638  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3639  }
3640  else
3641  {
3642  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3643  }
3644  }
3645  }
3646  else if( !SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, rhs) )
3647  {
3648  SCIP_VAR** vars;
3649  SCIP_Real* vals;
3650  int v;
3651 
3652  /* the right hand side switched from a non-infinite value to infinity -> remove rounding locks */
3653  vars = consdata->vars;
3654  vals = consdata->vals;
3655 
3656  for( v = 0; v < consdata->nvars; ++v )
3657  {
3658  assert(vars[v] != NULL);
3659  assert(!SCIPisZero(scip, vals[v]));
3660 
3661  if( SCIPisPositive(scip, vals[v]) )
3662  {
3663  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3664  }
3665  else
3666  {
3667  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3668  }
3669  }
3670  }
3671  }
3672 
3673  /* 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 */
3674  if( !SCIPisInfinity(scip, rhs) && SCIPisLT(scip, rhs, consdata->rhs) )
3675  {
3676  consdata->boundstightened = 0;
3677  consdata->presolved = FALSE;
3678  consdata->cliquesadded = FALSE;
3679  consdata->implsadded = FALSE;
3680 
3681  /* mark the constraint for propagation */
3682  if( SCIPconsIsTransformed(cons) )
3683  {
3684  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3685  }
3686  }
3687 
3688  /* set new right hand side and update constraint data */
3689  consdata->rhs = rhs;
3690  consdata->changed = TRUE;
3691  consdata->normalized = FALSE;
3692  consdata->upgradetried = FALSE;
3693  consdata->rangedrowpropagated = 0;
3694 
3695  /* update the rhs of the LP row */
3696  if( consdata->row != NULL )
3697  {
3698  SCIP_CALL( SCIPchgRowRhs(scip, consdata->row, rhs) );
3699  }
3700 
3701  return SCIP_OKAY;
3702 }
3703 
3704 /** adds coefficient in linear constraint */
3705 static
3707  SCIP* scip, /**< SCIP data structure */
3708  SCIP_CONS* cons, /**< linear constraint */
3709  SCIP_VAR* var, /**< variable of constraint entry */
3710  SCIP_Real val /**< coefficient of constraint entry */
3711  )
3712 {
3713  SCIP_CONSDATA* consdata;
3714  SCIP_Bool transformed;
3715 
3716  assert(scip != NULL);
3717  assert(cons != NULL);
3718  assert(var != NULL);
3719 
3720  /* relaxation-only variables must not be used in checked or enforced constraints */
3721  assert(!SCIPvarIsRelaxationOnly(var) || (!SCIPconsIsChecked(cons) && !SCIPconsIsEnforced(cons)));
3722 
3723  /* ignore coefficient if it is nearly zero */
3724  if( SCIPisZero(scip, val) )
3725  return SCIP_OKAY;
3726 
3727  consdata = SCIPconsGetData(cons);
3728  assert(consdata != NULL);
3729 
3730  /* are we in the transformed problem? */
3731  transformed = SCIPconsIsTransformed(cons);
3732 
3733  /* always use transformed variables in transformed constraints */
3734  if( transformed )
3735  {
3736  SCIP_CALL( SCIPgetTransformedVar(scip, var, &var) );
3737  }
3738  assert(var != NULL);
3739  assert(transformed == SCIPvarIsTransformed(var));
3740 
3741  SCIP_CALL( consdataEnsureVarsSize(scip, consdata, consdata->nvars+1) );
3742  consdata->vars[consdata->nvars] = var;
3743  consdata->vals[consdata->nvars] = val;
3744  consdata->nvars++;
3745 
3746  /* capture variable */
3747  SCIP_CALL( SCIPcaptureVar(scip, var) );
3748 
3749  /* if we are in transformed problem, the variable needs an additional event data */
3750  if( transformed )
3751  {
3752  if( consdata->eventdata != NULL )
3753  {
3754  SCIP_CONSHDLR* conshdlr;
3755  SCIP_CONSHDLRDATA* conshdlrdata;
3756 
3757  /* check for event handler */
3758  conshdlr = SCIPconsGetHdlr(cons);
3759  conshdlrdata = SCIPconshdlrGetData(conshdlr);
3760  assert(conshdlrdata != NULL);
3761  assert(conshdlrdata->eventhdlr != NULL);
3762 
3763  /* initialize eventdata array */
3764  consdata->eventdata[consdata->nvars-1] = NULL;
3765 
3766  /* catch bound change events of variable */
3767  SCIP_CALL( consCatchEvent(scip, cons, conshdlrdata->eventhdlr, consdata->nvars-1) );
3768  }
3769 
3770  /* update minimum and maximum activities */
3771  consdataUpdateAddCoef(scip, consdata, var, val, FALSE);
3772 
3773  /* update maximum activity delta */
3774  if( !SCIPisInfinity(scip, consdata->maxactdelta ) )
3775  {
3776  SCIP_Real lb;
3777  SCIP_Real ub;
3778 
3779  lb = SCIPvarGetLbLocal(var);
3780  ub = SCIPvarGetUbLocal(var);
3781 
3782  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
3783  {
3784  consdata->maxactdelta = SCIPinfinity(scip);
3785  consdata->maxactdeltavar = var;
3786  }
3787  else
3788  {
3789  SCIP_Real domain = ub - lb;
3790  SCIP_Real delta = REALABS(val) * domain;
3791 
3792  if( delta > consdata->maxactdelta )
3793  {
3794  consdata->maxactdelta = delta;
3795  consdata->maxactdeltavar = var;
3796  }
3797  }
3798  }
3799  }
3800 
3801  /* install rounding locks for new variable */
3802  SCIP_CALL( lockRounding(scip, cons, var, val) );
3803 
3804  /* mark the constraint for propagation */
3805  if( transformed )
3806  {
3807  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3808  }
3809 
3810  consdata->boundstightened = 0;
3811  consdata->presolved = FALSE;
3812  consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(var);
3813 
3814  if( consdata->validsignature )
3815  consdataUpdateSignatures(consdata, consdata->nvars-1);
3816 
3817  consdata->changed = TRUE;
3818  consdata->normalized = FALSE;
3819  consdata->upgradetried = FALSE;
3820  consdata->cliquesadded = FALSE;
3821  consdata->implsadded = FALSE;
3822  consdata->rangedrowpropagated = 0;
3823 
3824  if( consdata->nvars == 1 )
3825  {
3826  consdata->indexsorted = TRUE;
3827  consdata->coefsorted = TRUE;
3828  consdata->merged = TRUE;
3829  }
3830  else
3831  {
3832  consdata->merged = FALSE;
3833 
3834  if( SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE )
3835  {
3836  consdata->indexsorted = consdata->indexsorted && (consdataCompVar((void*)consdata, consdata->nvars-2, consdata->nvars-1) <= 0);
3837  consdata->coefsorted = FALSE;
3838  }
3839  else
3840  {
3841  consdata->indexsorted = FALSE;
3842  consdata->coefsorted = consdata->coefsorted && (consdataCompVarProp((void*)consdata, consdata->nvars-2, consdata->nvars-1) <= 0);
3843  }
3844  }
3845 
3846  /* update hascontvar and hasnonbinvar flags */
3847  if( consdata->hasnonbinvalid && !consdata->hascontvar )
3848  {
3849  SCIP_VARTYPE vartype = SCIPvarGetType(var);
3850 
3851  if( vartype != SCIP_VARTYPE_BINARY )
3852  {
3853  consdata->hasnonbinvar = TRUE;
3854 
3855  if( vartype == SCIP_VARTYPE_CONTINUOUS )
3856  consdata->hascontvar = TRUE;
3857  }
3858  }
3859 
3860  /* add the new coefficient to the LP row */
3861  if( consdata->row != NULL )
3862  {
3863  SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, var, val) );
3864  }
3865 
3866  return SCIP_OKAY;
3867 }
3868 
3869 /** deletes coefficient at given position from linear constraint data */
3870 static
3872  SCIP* scip, /**< SCIP data structure */
3873  SCIP_CONS* cons, /**< linear constraint */
3874  int pos /**< position of coefficient to delete */
3875  )
3876 {
3877  SCIP_CONSDATA* consdata;
3878  SCIP_VAR* var;
3879  SCIP_Real val;
3880 
3881  assert(scip != NULL);
3882  assert(cons != NULL);
3883 
3884  consdata = SCIPconsGetData(cons);
3885  assert(consdata != NULL);
3886  assert(0 <= pos && pos < consdata->nvars);
3887 
3888  var = consdata->vars[pos];
3889  val = consdata->vals[pos];
3890  assert(var != NULL);
3891 
3892  /* remove rounding locks for deleted variable */
3893  SCIP_CALL( unlockRounding(scip, cons, var, val) );
3894 
3895  /* if we are in transformed problem, delete the event data of the variable */
3896  if( SCIPconsIsTransformed(cons) )
3897  {
3898  SCIP_CONSHDLR* conshdlr;
3899  SCIP_CONSHDLRDATA* conshdlrdata;
3900 
3901  /* check for event handler */
3902  conshdlr = SCIPconsGetHdlr(cons);
3903  conshdlrdata = SCIPconshdlrGetData(conshdlr);
3904  assert(conshdlrdata != NULL);
3905  assert(conshdlrdata->eventhdlr != NULL);
3906 
3907  /* drop bound change events of variable */
3908  if( consdata->eventdata != NULL )
3909  {
3910  SCIP_CALL( consDropEvent(scip, cons, conshdlrdata->eventhdlr, pos) );
3911  assert(consdata->eventdata[pos] == NULL);
3912  }
3913  }
3914 
3915  /* move the last variable to the free slot */
3916  if( pos != consdata->nvars - 1 )
3917  {
3918  consdata->vars[pos] = consdata->vars[consdata->nvars-1];
3919  consdata->vals[pos] = consdata->vals[consdata->nvars-1];
3920 
3921  if( consdata->eventdata != NULL )
3922  {
3923  consdata->eventdata[pos] = consdata->eventdata[consdata->nvars-1];
3924  assert(consdata->eventdata[pos] != NULL);
3925  consdata->eventdata[pos]->varpos = pos;
3926  }
3927 
3928  consdata->indexsorted = consdata->indexsorted && (pos + 2 >= consdata->nvars);
3929  consdata->coefsorted = consdata->coefsorted && (pos + 2 >= consdata->nvars);
3930  }
3931  consdata->nvars--;
3932 
3933  /* if at most one variable is left, the activities should be recalculated (to correspond exactly to the bounds
3934  * of the remaining variable, or give exactly 0.0)
3935  */
3936  if( consdata->nvars <= 1 )
3937  consdataInvalidateActivities(consdata);
3938  else
3939  {
3940  if( SCIPconsIsTransformed(cons) )
3941  {
3942  /* if we are in transformed problem, update minimum and maximum activities */
3943  consdataUpdateDelCoef(scip, consdata, var, val, TRUE);
3944 
3945  /* if the variable defining the maximal activity delta was removed from the constraint, the maximal activity
3946  * delta needs to be recalculated on the next real propagation
3947  */
3948  if( consdata->maxactdeltavar == var )
3949  {
3950  consdata->maxactdelta = SCIP_INVALID;
3951  consdata->maxactdeltavar = NULL;
3952  }
3953  }
3954  }
3955 
3956  /* mark the constraint for propagation */
3957  if( SCIPconsIsTransformed(cons) )
3958  {
3959  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3960  }
3961 
3962  consdata->boundstightened = 0;
3963  consdata->presolved = FALSE;
3964  consdata->validsignature = FALSE;
3965  consdata->changed = TRUE;
3966  consdata->normalized = FALSE;
3967  consdata->upgradetried = FALSE;
3968  consdata->cliquesadded = FALSE;
3969  consdata->implsadded = FALSE;
3970  consdata->rangedrowpropagated = 0;
3971 
3972  /* check if hasnonbinvar flag might be incorrect now */
3973  if( consdata->hasnonbinvar && SCIPvarGetType(var) != SCIP_VARTYPE_BINARY )
3974  {
3975  consdata->hasnonbinvalid = FALSE;
3976  }
3977 
3978  /* delete coefficient from the LP row */
3979  if( consdata->row != NULL )
3980  {
3981  SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, var, -val) );
3982  }
3983 
3984  /* release variable */
3985  SCIP_CALL( SCIPreleaseVar(scip, &var) );
3986 
3987  return SCIP_OKAY;
3988 }
3989 
3990 /** changes coefficient value at given position of linear constraint data */
3991 static
3993  SCIP* scip, /**< SCIP data structure */
3994  SCIP_CONS* cons, /**< linear constraint */
3995  int pos, /**< position of coefficient to delete */
3996  SCIP_Real newval /**< new value of coefficient */
3997  )
3998 {
3999  SCIP_CONSDATA* consdata;
4000  SCIP_VAR* var;
4001  SCIP_Real val;
4002  SCIP_Bool locked;
4003  int i;
4004 
4005  assert(scip != NULL);
4006  assert(cons != NULL);
4007  assert(!SCIPisZero(scip, newval));
4008 
4009  consdata = SCIPconsGetData(cons);
4010  assert(consdata != NULL);
4011  assert(0 <= pos && pos < consdata->nvars);
4012  assert(!SCIPisZero(scip, newval));
4013 
4014  var = consdata->vars[pos];
4015  val = consdata->vals[pos];
4016  assert(var != NULL);
4017  assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(var));
4018 
4019  locked = FALSE;
4020  for( i = 0; i < NLOCKTYPES && !locked; i++ )
4021  locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
4022 
4023  /* if necessary, update the rounding locks of the variable */
4024  if( locked && newval * val < 0.0 )
4025  {
4026  assert(SCIPconsIsTransformed(cons));
4027 
4028  /* remove rounding locks for variable with old coefficient */
4029  SCIP_CALL( unlockRounding(scip, cons, var, val) );
4030 
4031  /* install rounding locks for variable with new coefficient */
4032  SCIP_CALL( lockRounding(scip, cons, var, newval) );
4033  }
4034 
4035  /* change the value */
4036  consdata->vals[pos] = newval;
4037 
4038  if( consdata->coefsorted )
4039  {
4040  if( pos > 0 )
4041  consdata->coefsorted = (consdataCompVarProp((void*)consdata, pos - 1, pos) <= 0);
4042  if( consdata->coefsorted && pos < consdata->nvars - 1 )
4043  consdata->coefsorted = (consdataCompVarProp((void*)consdata, pos, pos + 1) <= 0);
4044  }
4045 
4046  /* update minimum and maximum activities */
4047  if( SCIPconsIsTransformed(cons) )
4048  consdataUpdateChgCoef(scip, consdata, var, val, newval, TRUE);
4049 
4050  /* mark the constraint for propagation */
4051  if( SCIPconsIsTransformed(cons) )
4052  {
4053  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
4054  }
4055 
4056  consdata->boundstightened = 0;
4057  consdata->presolved = FALSE;
4058  consdata->validsignature = consdata->validsignature && (newval * val > 0.0);
4059  consdata->changed = TRUE;
4060  consdata->normalized = FALSE;
4061  consdata->upgradetried = FALSE;
4062  consdata->cliquesadded = FALSE;
4063  consdata->implsadded = FALSE;
4064  consdata->rangedrowpropagated = 0;
4065 
4066  return SCIP_OKAY;
4067 }
4068 
4069 /** scales a linear constraint with a constant scalar */
4070 static
4072  SCIP* scip, /**< SCIP data structure */
4073  SCIP_CONS* cons, /**< linear constraint to scale */
4074  SCIP_Real scalar /**< value to scale constraint with */
4075  )
4076 {
4077  SCIP_CONSDATA* consdata;
4078  SCIP_Real newval;
4079  SCIP_Real absscalar;
4080  int i;
4081 
4082  assert(scip != NULL);
4083  assert(cons != NULL);
4084 
4085  consdata = SCIPconsGetData(cons);
4086  assert(consdata != NULL);
4087  assert(consdata->row == NULL);
4088  assert(!SCIPisEQ(scip, scalar, 1.0));
4089 
4090  if( (!SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, -consdata->lhs * scalar))
4091  || (!SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, consdata->rhs * scalar)) )
4092  {
4093  SCIPwarningMessage(scip, "skipped scaling for linear constraint <%s> to avoid numerical troubles (scalar: %.15g)\n",
4094  SCIPconsGetName(cons), scalar);
4095 
4096  return SCIP_OKAY;
4097  }
4098 
4099  /* scale the coefficients */
4100  for( i = consdata->nvars - 1; i >= 0; --i )
4101  {
4102  newval = scalar * consdata->vals[i];
4103 
4104  /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasFloor, we add an additional 0.5 before
4105  * flooring down our new value
4106  */
4107  if( SCIPisScalingIntegral(scip, consdata->vals[i], scalar) )
4108  newval = SCIPfeasFloor(scip, newval + 0.5);
4109 
4110  if( SCIPisZero(scip, newval) )
4111  {
4112  SCIPwarningMessage(scip, "coefficient %.15g of variable <%s> in linear constraint <%s> scaled to zero (scalar: %.15g)\n",
4113  consdata->vals[i], SCIPvarGetName(consdata->vars[i]), SCIPconsGetName(cons), scalar);
4114  SCIP_CALL( delCoefPos(scip, cons, i) );
4115  }
4116  else
4117  consdata->vals[i] = newval;
4118  }
4119 
4120  /* scale the sides */
4121  if( scalar < 0.0 )
4122  {
4123  SCIP_Real lhs;
4124 
4125  lhs = consdata->lhs;
4126  consdata->lhs = -consdata->rhs;
4127  consdata->rhs = -lhs;
4128  }
4129  absscalar = REALABS(scalar);
4130  if( !SCIPisInfinity(scip, -consdata->lhs) )
4131  {
4132  newval = absscalar * consdata->lhs;
4133 
4134  /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasFloor, we add an additional 0.5 before
4135  * flooring down our new value
4136  */
4137  if( SCIPisScalingIntegral(scip, consdata->lhs, absscalar) )
4138  consdata->lhs = SCIPfeasFloor(scip, newval + 0.5);
4139  else
4140  consdata->lhs = newval;
4141  }
4142  if( !SCIPisInfinity(scip, consdata->rhs) )
4143  {
4144  newval = absscalar * consdata->rhs;
4145 
4146  /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasCeil, we subtract 0.5 before ceiling up
4147  * our new value
4148  */
4149  if( SCIPisScalingIntegral(scip, consdata->rhs, absscalar) )
4150  consdata->rhs = SCIPfeasCeil(scip, newval - 0.5);
4151  else
4152  consdata->rhs = newval;
4153  }
4154 
4155  consdataInvalidateActivities(consdata);
4156  consdata->cliquesadded = FALSE;
4157  consdata->implsadded = FALSE;
4158 
4159  return SCIP_OKAY;
4160 }
4161 
4162 /** perform deletion of variables in all constraints of the constraint handler */
4163 static
4165  SCIP* scip, /**< SCIP data structure */
4166  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4167  SCIP_CONS** conss, /**< array of constraints */
4168  int nconss /**< number of constraints */
4169  )
4170 {
4171  SCIP_CONSDATA* consdata;
4172  int i;
4173  int v;
4174 
4175  assert(scip != NULL);
4176  assert(conshdlr != NULL);
4177  assert(conss != NULL);
4178  assert(nconss >= 0);
4179  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
4180 
4181  /* iterate over all constraints */
4182  for( i = 0; i < nconss; i++ )
4183  {
4184  consdata = SCIPconsGetData(conss[i]);
4185 
4186  /* constraint is marked, that some of its variables were deleted */
4187  if( consdata->varsdeleted )
4188  {
4189  /* iterate over all variables of the constraint and delete them from the constraint */
4190  for( v = consdata->nvars - 1; v >= 0; --v )
4191  {
4192  if( SCIPvarIsDeleted(consdata->vars[v]) )
4193  {
4194  SCIP_CALL( delCoefPos(scip, conss[i], v) );
4195  }
4196  }
4197  consdata->varsdeleted = FALSE;
4198  }
4199  }
4200 
4201  return SCIP_OKAY;
4202 }
4203 
4204 
4205 /** normalizes a linear constraint with the following rules:
4206  * - if all coefficients have them same absolute value, change them to (-)1.0
4207  * - multiplication with +1 or -1:
4208  * Apply the following rules in the given order, until the sign of the factor is determined. Later rules only apply,
4209  * if the current rule doesn't determine the sign):
4210  * 1. the right hand side must not be negative
4211  * 2. the right hand side must not be infinite
4212  * 3. the absolute value of the right hand side must be greater than that of the left hand side
4213  * 4. the number of positive coefficients must not be smaller than the number of negative coefficients
4214  * 5. multiply with +1
4215  * - rationals to integrals
4216  * Try to identify a rational representation of the fractional coefficients, and multiply all coefficients
4217  * by the smallest common multiple of all denominators to get integral coefficients.
4218  * Forbid large denominators due to numerical stability.
4219  * - division by greatest common divisor
4220  * If all coefficients are integral, divide them by the greatest common divisor.
4221  */
4222 static
4224  SCIP* scip, /**< SCIP data structure */
4225  SCIP_CONS* cons, /**< linear constraint to normalize */
4226  SCIP_Bool* infeasible /**< pointer to store whether infeasibility was detected */
4227  )
4228 {
4229  SCIP_CONSDATA* consdata;
4230  SCIP_Real* vals;
4231  SCIP_Longint scm;
4232  SCIP_Longint nominator;
4233  SCIP_Longint denominator;
4234  SCIP_Longint gcd;
4235  SCIP_Longint maxmult;
4236  SCIP_Real epsilon;
4237  SCIP_Real feastol;
4238  SCIP_Real maxabsval;
4239  SCIP_Real minabsval;
4240  SCIP_Bool success;
4241  SCIP_Bool onlyintegral;
4242  int nvars;
4243  int mult;
4244  int nposcoeffs;
4245  int nnegcoeffs;
4246  int i;
4247  int v;
4248 
4249  assert(scip != NULL);
4250  assert(cons != NULL);
4251  assert(infeasible != NULL);
4252 
4253  *infeasible = FALSE;
4254 
4255  /* we must not change a modifiable constraint in any way */
4256  if( SCIPconsIsModifiable(cons) )
4257  return SCIP_OKAY;
4258 
4259  /* get constraint data */
4260  consdata = SCIPconsGetData(cons);
4261  assert(consdata != NULL);
4262 
4263  /* check, if the constraint is already normalized */
4264  if( consdata->normalized )
4265  return SCIP_OKAY;
4266 
4267  /* get coefficient arrays */
4268  vals = consdata->vals;
4269  nvars = consdata->nvars;
4270  assert(nvars == 0 || vals != NULL);
4271 
4272  if( nvars == 0 )
4273  {
4274  consdata->normalized = TRUE;
4275  return SCIP_OKAY;
4276  }
4277 
4278  assert(vals != NULL);
4279 
4280  /* get maximal and minimal absolute coefficient */
4281  maxabsval = consdataGetMaxAbsval(consdata);
4282  minabsval = consdataGetMinAbsval(consdata);
4283 
4284  /* return if scaling by maxval will eliminate coefficients */
4285  if( SCIPisZero(scip, minabsval/maxabsval) )
4286  return SCIP_OKAY;
4287 
4288  /* check if all coefficients are in absolute value equal, and not 1.0 */
4289  if( !SCIPisEQ(scip, maxabsval, 1.0) )
4290  {
4291  SCIP_Bool abscoefsequ;
4292 
4293  abscoefsequ = TRUE;
4294 
4295  for( v = nvars - 1; v >= 0; --v )
4296  {
4297  if( !SCIPisEQ(scip, REALABS(vals[v]), maxabsval) )
4298  {
4299  abscoefsequ = FALSE;
4300  break;
4301  }
4302  }
4303 
4304  /* all coefficients are in absolute value equal, so change them to (-)1.0 */
4305  if( abscoefsequ )
4306  {
4307  SCIPdebugMsg(scip, "divide linear constraint with %g, because all coefficients are in absolute value the same\n", maxabsval);
4308  SCIPdebugPrintCons(scip, cons, NULL);
4309  SCIP_CALL( scaleCons(scip, cons, 1/maxabsval) );
4310 
4311  if( consdata->validmaxabsval )
4312  {
4313  if( !SCIPisEQ(scip, consdata->maxabsval, 1.0) )
4314  consdata->maxabsval = 1.0;
4315  if( !SCIPisEQ(scip, consdata->minabsval, 1.0) )
4316  consdata->minabsval = 1.0;
4317 
4318  maxabsval = 1.0;
4319  }
4320  else
4321  {
4322  /* get maximal absolute coefficient */
4323  maxabsval = consdataGetMaxAbsval(consdata);
4324  }
4325 
4326  /* get new consdata information, because scaleCons() might have deleted variables */
4327  vals = consdata->vals;
4328  nvars = consdata->nvars;
4329 
4330  assert(nvars == 0 || vals != NULL);
4331  }
4332  }
4333 
4334  /* nvars might have changed */
4335  if( nvars == 0 )
4336  {
4337  consdata->normalized = TRUE;
4338  return SCIP_OKAY;
4339  }
4340 
4341  assert(vals != NULL);
4342 
4343  /* calculate the maximal multiplier for common divisor calculation:
4344  * |p/q - val| < epsilon and q < feastol/epsilon => |p - q*val| < feastol
4345  * which means, a value of feastol/epsilon should be used as maximal multiplier;
4346  * additionally, we don't want to scale the constraint if this would lead to too
4347  * large coefficients
4348  */
4349  epsilon = SCIPepsilon(scip) * 0.9; /* slightly decrease epsilon to be safe in rational conversion below */
4350  feastol = SCIPfeastol(scip);
4351  maxmult = (SCIP_Longint)(feastol/epsilon + feastol);
4352 
4353  if( !consdata->hasnonbinvalid )
4354  consdataCheckNonbinvar(consdata);
4355 
4356  /* if all variables are of integral type we will allow a greater multiplier */
4357  if( !consdata->hascontvar )
4358  maxmult = MIN(maxmult, (SCIP_Longint) (MAXSCALEDCOEFINTEGER / MAX(maxabsval, 1.0))); /*lint !e835*/
4359  else
4360  maxmult = MIN(maxmult, (SCIP_Longint) (MAXSCALEDCOEF / MAX(maxabsval, 1.0))); /*lint !e835*/
4361 
4362  /*
4363  * multiplication with +1 or -1
4364  */
4365  mult = 0;
4366 
4367  /* 1. the right hand side must not be negative */
4368  if( SCIPisPositive(scip, consdata->lhs) )
4369  mult = +1;
4370  else if( SCIPisNegative(scip, consdata->rhs) )
4371  mult = -1;
4372 
4373  if( mult == 0 )
4374  {
4375  /* 2. the right hand side must not be infinite */
4376  if( SCIPisInfinity(scip, -consdata->lhs) )
4377  mult = +1;
4378  else if( SCIPisInfinity(scip, consdata->rhs) )
4379  mult = -1;
4380  }
4381 
4382  if( mult == 0 )
4383  {
4384  /* 3. the absolute value of the right hand side must be greater than that of the left hand side */
4385  if( SCIPisGT(scip, REALABS(consdata->rhs), REALABS(consdata->lhs)) )
4386  mult = +1;
4387  else if( SCIPisLT(scip, REALABS(consdata->rhs), REALABS(consdata->lhs)) )
4388  mult = -1;
4389  }
4390 
4391  if( mult == 0 )
4392  {
4393  /* 4. the number of positive coefficients must not be smaller than the number of negative coefficients */
4394  nposcoeffs = 0;
4395  nnegcoeffs = 0;
4396  for( i = 0; i < nvars; ++i )
4397  {
4398  if( vals[i] > 0.0 )
4399  nposcoeffs++;
4400  else
4401  nnegcoeffs++;
4402  }
4403  if( nposcoeffs > nnegcoeffs )
4404  mult = +1;
4405  else if( nposcoeffs < nnegcoeffs )
4406  mult = -1;
4407  }
4408 
4409  if( mult == 0 )
4410  {
4411  /* 5. multiply with +1 */
4412  mult = +1;
4413  }
4414 
4415  assert(mult == +1 || mult == -1);
4416  if( mult == -1 )
4417  {
4418  /* scale the constraint with -1 */
4419  SCIPdebugMsg(scip, "multiply linear constraint with -1.0\n");
4420  SCIPdebugPrintCons(scip, cons, NULL);
4421  SCIP_CALL( scaleCons(scip, cons, -1.0) );
4422 
4423  /* scalecons() can delete variables, but scaling with -1 should not do that */
4424  assert(nvars == consdata->nvars);
4425  }
4426 
4427  /*
4428  * rationals to integrals
4429  *
4430  * @todo try scaling only on behalf of non-continuous variables
4431  */
4432  success = TRUE;
4433  scm = 1;
4434  for( i = 0; i < nvars && success && scm <= maxmult; ++i )
4435  {
4436  if( !SCIPisIntegral(scip, vals[i]) )
4437  {
4438  /* epsilon has been slightly decreased above - to be on the safe side */
4439  success = SCIPrealToRational(vals[i], -epsilon, epsilon , maxmult, &nominator, &denominator);
4440  if( success )
4441  scm = SCIPcalcSmaComMul(scm, denominator);
4442  }
4443  }
4444  assert(scm >= 1);
4445 
4446  /* it might be that we have really big coefficients, but all are integral, in that case we want to divide them by
4447  * their greatest common divisor
4448  */
4449  onlyintegral = TRUE;
4450  if( scm == 1 )
4451  {
4452  for( i = nvars - 1; i >= 0; --i )
4453  {
4454  if( !SCIPisIntegral(scip, vals[i]) )
4455  {
4456  onlyintegral = FALSE;
4457  break;
4458  }
4459  }
4460  }
4461 
4462  success = success && (scm <= maxmult || (scm == 1 && onlyintegral));
4463  if( success && scm != 1 )
4464  {
4465  /* scale the constraint with the smallest common multiple of all denominators */
4466  SCIPdebugMsg(scip, "scale linear constraint with %" SCIP_LONGINT_FORMAT " to make coefficients integral\n", scm);
4467  SCIPdebugPrintCons(scip, cons, NULL);
4468  SCIP_CALL( scaleCons(scip, cons, (SCIP_Real)scm) );
4469 
4470  if( consdata->validmaxabsval )
4471  {
4472  consdata->maxabsval *= REALABS((SCIP_Real)scm);
4473  if( !SCIPisIntegral(scip, consdata->maxabsval) )
4474  {
4475  consdata->validmaxabsval = FALSE;
4476  consdata->maxabsval = SCIP_INVALID;
4477  consdataCalcMaxAbsval(consdata);
4478  }
4479  }
4480 
4481  if( consdata->validminabsval )
4482  {
4483  consdata->minabsval *= REALABS((SCIP_Real)scm);
4484  if( !SCIPisIntegral(scip, consdata->minabsval) )
4485  {
4486  consdata->validminabsval = FALSE;
4487  consdata->minabsval = SCIP_INVALID;
4488  consdataCalcMinAbsval(consdata);
4489  }
4490  }
4491 
4492  /* get new consdata information, because scalecons() might have deleted variables */
4493  vals = consdata->vals;
4494  nvars = consdata->nvars;
4495  assert(nvars == 0 || vals != NULL);
4496  }
4497 
4498  /*
4499  * division by greatest common divisor
4500  */
4501  if( success && nvars >= 1 )
4502  {
4503  /* all coefficients are integral: divide them by their greatest common divisor */
4504  assert(SCIPisIntegral(scip, vals[0]));
4505 
4506  gcd = (SCIP_Longint)(REALABS(vals[0]) + feastol);
4507  for( i = 1; i < nvars && gcd > 1; ++i )
4508  {
4509  assert(SCIPisIntegral(scip, vals[i]));
4510  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[i]) + feastol));
4511  }
4512 
4513  if( gcd > 1 )
4514  {
4515  /* since the lhs/rhs is not respected for gcd calculation it can happen that we detect infeasibility */
4516  if( !consdata->hascontvar && onlyintegral )
4517  {
4518  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) && !SCIPisFeasIntegral(scip, consdata->rhs / gcd) )
4519  {
4520  *infeasible = TRUE;
4521 
4522  SCIPdebugMsg(scip, "detected infeasibility of constraint after scaling with gcd=%" SCIP_LONGINT_FORMAT ":\n", gcd);
4523  SCIPdebugPrintCons(scip, cons, NULL);
4524 
4525  return SCIP_OKAY;
4526  }
4527  }
4528 
4529  /* divide the constraint by the greatest common divisor of the coefficients */
4530  SCIPdebugMsg(scip, "divide linear constraint by greatest common divisor %" SCIP_LONGINT_FORMAT "\n", gcd);
4531  SCIPdebugPrintCons(scip, cons, NULL);
4532  SCIP_CALL( scaleCons(scip, cons, 1.0/(SCIP_Real)gcd) );
4533 
4534  if( consdata->validmaxabsval )
4535  {
4536  consdata->maxabsval /= REALABS((SCIP_Real)gcd);
4537  }
4538  if( consdata->validminabsval )
4539  {
4540  consdata->minabsval /= REALABS((SCIP_Real)gcd);
4541  }
4542  }
4543  }
4544 
4545  /* mark constraint to be normalized */
4546  consdata->normalized = TRUE;
4547 
4548  SCIPdebugMsg(scip, "normalized constraint:\n");
4549  SCIPdebugPrintCons(scip, cons, NULL);
4550 
4551  return SCIP_OKAY;
4552 }
4553 
4554 /** replaces multiple occurrences of a variable by a single coefficient */
4555 static
4557  SCIP* scip, /**< SCIP data structure */
4558  SCIP_CONS* cons /**< linear constraint */
4559  )
4560 {
4561  SCIP_CONSDATA* consdata;
4562  SCIP_VAR* var;
4563  SCIP_Real valsum;
4564  int v;
4565 
4566  assert(scip != NULL);
4567  assert(cons != NULL);
4568 
4569  consdata = SCIPconsGetData(cons);
4570  assert(consdata != NULL);
4571 
4572  if( consdata->merged )
4573  return SCIP_OKAY;
4574 
4575  /* sort the constraint */
4576  SCIP_CALL( consdataSort(scip, consdata) );
4577 
4578  /* go backwards through the constraint looking for multiple occurrences of the same variable;
4579  * backward direction is necessary, since delCoefPos() modifies the given position and
4580  * the subsequent ones
4581  */
4582  v = consdata->nvars-1;
4583  while( v >= 1 )
4584  {
4585  var = consdata->vars[v];
4586  if( consdata->vars[v-1] == var )
4587  {
4588  valsum = consdata->vals[v];
4589  do
4590  {
4591  SCIP_CALL( delCoefPos(scip, cons, v) );
4592  --v;
4593  valsum += consdata->vals[v];
4594  }
4595  while( v >= 1 && consdata->vars[v-1] == var );
4596 
4597  /* modify the last existing occurrence of the variable */
4598  assert(consdata->vars[v] == var);
4599  if( SCIPisZero(scip, valsum) )
4600  {
4601  SCIP_CALL( delCoefPos(scip, cons, v) );
4602 
4603  /* if the variable defining the maximal activity delta was removed from the constraint, the maximal activity
4604  * delta needs to be recalculated on the next real propagation
4605  */
4606  if( consdata->maxactdeltavar == var )
4607  {
4608  consdata->maxactdelta = SCIP_INVALID;
4609  consdata->maxactdeltavar = NULL;
4610  }
4611  }
4612  else
4613  {
4614  SCIP_CALL( chgCoefPos(scip, cons, v, valsum) );
4615  }
4616  }
4617  --v;
4618  }
4619 
4620  consdata->merged = TRUE;
4621 
4622  return SCIP_OKAY;
4623 }
4624 
4625 /** replaces all fixed and aggregated variables by their non-fixed counterparts */
4626 static
4628  SCIP* scip, /**< SCIP data structure */
4629  SCIP_CONS* cons, /**< linear constraint */
4630  SCIP_Bool* infeasible /**< pointer to store if infeasibility is detected; or NULL if this
4631  * information is not needed; in this case, we apply all fixings
4632  * instead of stopping after the first infeasible one */
4633  )
4634 {
4635  SCIP_CONSDATA* consdata;
4636  SCIP_VAR* var;
4637  SCIP_VAR** aggrvars;
4638  SCIP_Real val;
4639  SCIP_Real* aggrscalars;
4640  SCIP_Real fixedval;
4641  SCIP_Real aggrconst;
4642  int v;
4643  int naggrvars;
4644  int i;
4645 
4646  assert(scip != NULL);
4647  assert(cons != NULL);
4648 
4649  if( infeasible != NULL )
4650  *infeasible = FALSE;
4651 
4652  consdata = SCIPconsGetData(cons);
4653  assert(consdata != NULL);
4654 
4655  if( consdata->eventdata == NULL )
4656  {
4657  SCIP_CONSHDLR* conshdlr;
4658  SCIP_CONSHDLRDATA* conshdlrdata;
4659 
4660  conshdlr = SCIPconsGetHdlr(cons);
4661  assert(conshdlr != NULL);
4662 
4663  conshdlrdata = SCIPconshdlrGetData(conshdlr);
4664  assert(conshdlrdata != NULL);
4665 
4666  /* catch bound change events of variables */
4667  SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
4668  assert(consdata->eventdata != NULL);
4669  }
4670 
4671  if( !consdata->removedfixings )
4672  {
4673  SCIP_Real lhssubtrahend;
4674  SCIP_Real rhssubtrahend;
4675 
4676  /* if an unmodifiable row has been added to the LP, then we cannot apply fixing anymore (cannot change a row)
4677  * this should not happen, as applyFixings is called in addRelaxation() before creating and adding a row
4678  */
4679  assert(consdata->row == NULL || !SCIProwIsInLP(consdata->row) || SCIProwIsModifiable(consdata->row));
4680 
4681  lhssubtrahend = 0.0;
4682  rhssubtrahend = 0.0;
4683 
4684  SCIPdebugMsg(scip, "applying fixings:\n");
4685  SCIPdebugPrintCons(scip, cons, NULL);
4686 
4687  v = 0;
4688  while( v < consdata->nvars )
4689  {
4690  var = consdata->vars[v];
4691  val = consdata->vals[v];
4692  assert(SCIPvarIsTransformed(var));
4693 
4694  switch( SCIPvarGetStatus(var) )
4695  {
4697  SCIPerrorMessage("original variable in transformed linear constraint\n");
4698  return SCIP_INVALIDDATA;
4699 
4700  case SCIP_VARSTATUS_LOOSE:
4701  case SCIP_VARSTATUS_COLUMN:
4702  ++v;
4703  break;
4704 
4705  case SCIP_VARSTATUS_FIXED:
4706  assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)));
4707  fixedval = SCIPvarGetLbGlobal(var);
4708  if( !SCIPisInfinity(scip, -consdata->lhs) )
4709  {
4710  if( SCIPisInfinity(scip, ABS(fixedval)) )
4711  {
4712  if( val * fixedval > 0.0 )
4713  {
4714  SCIP_CALL( chgLhs(scip, cons, -SCIPinfinity(scip)) );
4715  }
4716  else
4717  {
4718  if( infeasible != NULL )
4719  {
4720  /* if lhs gets infinity it means that the problem is infeasible */
4721  *infeasible = TRUE;
4722  return SCIP_OKAY;
4723  }
4724  else
4725  {
4726  SCIP_CALL( chgLhs(scip, cons, SCIPinfinity(scip)) );
4727  }
4728  }
4729  }
4730  else
4731  lhssubtrahend += val * fixedval;
4732  }
4733  if( !SCIPisInfinity(scip, consdata->rhs) )
4734  {
4735  if( SCIPisInfinity(scip, ABS(fixedval)) )
4736  {
4737  if( val * fixedval > 0.0 )
4738  {
4739  if( infeasible != NULL )
4740  {
4741  /* if rhs gets -infinity it means that the problem is infeasible */
4742  *infeasible = TRUE;
4743  return SCIP_OKAY;
4744  }
4745  else
4746  {
4747  SCIP_CALL( chgRhs(scip, cons, -SCIPinfinity(scip)) );
4748  }
4749  }
4750  else
4751  {
4752  SCIP_CALL( chgRhs(scip, cons, SCIPinfinity(scip)) );
4753  }
4754  }
4755  else
4756  rhssubtrahend += val * fixedval;
4757  }
4758  SCIP_CALL( delCoefPos(scip, cons, v) );
4759  break;
4760 
4762  {
4763  SCIP_VAR* activevar = SCIPvarGetAggrVar(var);
4764  SCIP_Real activescalar = val * SCIPvarGetAggrScalar(var);
4765  SCIP_Real activeconstant = val * SCIPvarGetAggrConstant(var);
4766 
4767  assert(activevar != NULL);
4768  SCIP_CALL( SCIPgetProbvarSum(scip, &activevar, &activescalar, &activeconstant) );
4769  assert(activevar != NULL);
4770 
4771  if( !SCIPisZero(scip, activescalar) )
4772  {
4773  SCIP_CALL( addCoef(scip, cons, activevar, activescalar) );
4774  }
4775 
4776  if( !SCIPisZero(scip, activeconstant) )
4777  {
4778  if( !SCIPisInfinity(scip, -consdata->lhs) )
4779  lhssubtrahend += activeconstant;
4780  if( !SCIPisInfinity(scip, consdata->rhs) )
4781  rhssubtrahend += activeconstant;
4782  }
4783 
4784  SCIP_CALL( delCoefPos(scip, cons, v) );
4785  break;
4786  }
4789  naggrvars = SCIPvarGetMultaggrNVars(var);
4790  aggrvars = SCIPvarGetMultaggrVars(var);
4791  aggrscalars = SCIPvarGetMultaggrScalars(var);
4792  for( i = 0; i < naggrvars; ++i )
4793  {
4794  SCIP_CALL( addCoef(scip, cons, aggrvars[i], val * aggrscalars[i]) );
4795  }
4796  aggrconst = SCIPvarGetMultaggrConstant(var);
4797 
4798  if( !SCIPisInfinity(scip, -consdata->lhs) )
4799  lhssubtrahend += val * aggrconst;
4800  if( !SCIPisInfinity(scip, consdata->rhs) )
4801  rhssubtrahend += val * aggrconst;
4802 
4803  SCIP_CALL( delCoefPos(scip, cons, v) );
4804  break;
4805 
4807  SCIP_CALL( addCoef(scip, cons, SCIPvarGetNegationVar(var), -val) );
4808  aggrconst = SCIPvarGetNegationConstant(var);
4809 
4810  if( !SCIPisInfinity(scip, -consdata->lhs) )
4811  lhssubtrahend += val * aggrconst;
4812  if( !SCIPisInfinity(scip, consdata->rhs) )
4813  rhssubtrahend += val * aggrconst;
4814 
4815  SCIP_CALL( delCoefPos(scip, cons, v) );
4816  break;
4817 
4818  default:
4819  SCIPerrorMessage("unknown variable status\n");
4820  SCIPABORT();
4821  return SCIP_INVALIDDATA; /*lint !e527*/
4822  }
4823  }
4824 
4825  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->lhs) )
4826  {
4827  /* for large numbers that are relatively equal, substraction can lead to cancellation,
4828  * causing wrong fixings of other variables --> better use a real zero here;
4829  * for small numbers, polishing the difference might lead to wrong results -->
4830  * better use the exact difference in this case
4831  */
4832  if( SCIPisEQ(scip, lhssubtrahend, consdata->lhs) && SCIPisFeasGE(scip, REALABS(lhssubtrahend), 1.0) )
4833  {
4834  SCIP_CALL( chgLhs(scip, cons, 0.0) );
4835  }
4836  else
4837  {
4838  SCIP_CALL( chgLhs(scip, cons, consdata->lhs - lhssubtrahend) );
4839  }
4840  }
4841  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, -consdata->rhs))
4842  {
4843  /* for large numbers that are relatively equal, substraction can lead to cancellation,
4844  * causing wrong fixings of other variables --> better use a real zero here;
4845  * for small numbers, polishing the difference might lead to wrong results -->
4846  * better use the exact difference in this case
4847  */
4848  if( SCIPisEQ(scip, rhssubtrahend, consdata->rhs ) && SCIPisFeasGE(scip, REALABS(rhssubtrahend), 1.0) )
4849  {
4850  SCIP_CALL( chgRhs(scip, cons, 0.0) );
4851  }
4852  else
4853  {
4854  SCIP_CALL( chgRhs(scip, cons, consdata->rhs - rhssubtrahend) );
4855  }
4856  }
4857  consdata->removedfixings = TRUE;
4858 
4859  SCIPdebugMsg(scip, "after fixings:\n");
4860  SCIPdebugPrintCons(scip, cons, NULL);
4861 
4862  /* if aggregated variables have been replaced, multiple entries of the same variable are possible and we have
4863  * to clean up the constraint
4864  */
4865  SCIP_CALL( mergeMultiples(scip, cons) );
4866 
4867  SCIPdebugMsg(scip, "after merging:\n");
4868  SCIPdebugPrintCons(scip, cons, NULL);
4869  }
4870  assert(consdata->removedfixings);
4871 
4872 #ifndef NDEBUG
4873  /* check, if all fixings are applied */
4874  for( v = 0; v < consdata->nvars; ++v )
4875  assert(SCIPvarIsActive(consdata->vars[v]));
4876 #endif
4877 
4878  return SCIP_OKAY;
4879 }
4880 
4881 /** for each variable in the linear constraint, except the inferred variable, adds one bound to the conflict analysis'
4882  * candidate store (bound depends on sign of coefficient and whether the left or right hand side was the reason for the
4883  * inference variable's bound change); the conflict analysis can be initialized with the linear constraint being the
4884  * conflict detecting constraint by using NULL as inferred variable
4885  */
4886 static
4888  SCIP* scip, /**< SCIP data structure */
4889  SCIP_CONS* cons, /**< constraint that inferred the bound change */
4890  SCIP_VAR* infervar, /**< variable that was deduced, or NULL */
4891  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
4892  int inferpos, /**< position of the inferred variable in the vars array */
4893  SCIP_Bool reasonisrhs /**< is the right hand side responsible for the bound change? */
4894  )
4895 {
4896  SCIP_CONSDATA* consdata;
4897  SCIP_VAR** vars;
4898  SCIP_Real* vals;
4899  int nvars;
4900  int i;
4901 
4902  assert(scip != NULL);
4903  assert(cons != NULL);
4905  consdata = SCIPconsGetData(cons);
4906 
4907  assert(consdata != NULL);
4908 
4909  vars = consdata->vars;
4910  vals = consdata->vals;
4911  nvars = consdata->nvars;
4912 
4913  assert(vars != NULL || nvars == 0);
4914  assert(vals != NULL || nvars == 0);
4915 
4916  assert(-1 <= inferpos && inferpos < nvars);
4917  assert((infervar == NULL) == (inferpos == -1));
4918  assert(inferpos == -1 || vars[inferpos] == infervar); /*lint !e613*/
4919 
4920  /* for each variable, add the bound to the conflict queue, that is responsible for the minimal or maximal
4921  * residual value, depending on whether the left or right hand side is responsible for the bound change:
4922  * - if the right hand side is the reason, the minimal residual activity is responsible
4923  * - if the left hand side is the reason, the maximal residual activity is responsible
4924  */
4925 
4926  /* if the variable is integral we only need to add reason bounds until the propagation could be applied */
4927  if( infervar == NULL || SCIPvarIsIntegral(infervar) )
4928  {
4929  SCIP_Real minresactivity;
4930  SCIP_Real maxresactivity;
4931  SCIP_Bool minisrelax;
4932  SCIP_Bool maxisrelax;
4933  SCIP_Bool isminsettoinfinity;
4934  SCIP_Bool ismaxsettoinfinity;
4935 
4936  minresactivity = -SCIPinfinity(scip);
4937  maxresactivity = SCIPinfinity(scip);
4938 
4939  /* calculate the minimal and maximal global activity of all other variables involved in the constraint */
4940  if( infervar != NULL )
4941  {
4942  assert(vals != NULL); /* for flexelint */
4943  if( reasonisrhs )
4944  consdataGetGlbActivityResiduals(scip, consdata, infervar, vals[inferpos], FALSE, &minresactivity, NULL,
4945  &minisrelax, NULL, &isminsettoinfinity, NULL);
4946  else
4947  consdataGetGlbActivityResiduals(scip, consdata, infervar, vals[inferpos], FALSE, NULL, &maxresactivity,
4948  NULL, &maxisrelax, NULL, &ismaxsettoinfinity);
4949  }
4950  else
4951  {
4952  if( reasonisrhs )
4953  consdataGetGlbActivityBounds(scip, consdata, FALSE, &minresactivity, NULL,
4954  &minisrelax, NULL, &isminsettoinfinity, NULL);
4955  else
4956  consdataGetGlbActivityBounds(scip, consdata, FALSE, NULL, &maxresactivity,
4957  NULL, &maxisrelax, NULL, &ismaxsettoinfinity);
4958  }
4959 
4960  /* we can only do something clever, if the residual activity is finite and not relaxed */
4961  if( (reasonisrhs && !isminsettoinfinity && !minisrelax) || (!reasonisrhs && !ismaxsettoinfinity && !maxisrelax) ) /*lint !e644*/
4962  {
4963  SCIP_Real rescap;
4964  SCIP_Bool resactisinf;
4965 
4966  resactisinf = FALSE;
4967 
4968  /* calculate the residual capacity that would be left, if the variable would be set to one more / one less
4969  * than its inferred bound
4970  */
4971  if( infervar != NULL )
4972  {
4973  assert(vals != NULL); /* for flexelint */
4974 
4975  if( reasonisrhs )
4976  {
4977  if( SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastglbminactivity) )
4978  {
4979  consdataGetReliableResidualActivity(scip, consdata, infervar, &minresactivity, TRUE, TRUE);
4980  if( SCIPisInfinity(scip, -minresactivity) )
4981  resactisinf = TRUE;
4982  }
4983  rescap = consdata->rhs - minresactivity;
4984  }
4985  else
4986  {
4987  if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastglbmaxactivity) )
4988  {
4989  consdataGetReliableResidualActivity(scip, consdata, infervar, &maxresactivity, FALSE, TRUE);
4990  if( SCIPisInfinity(scip, maxresactivity) )
4991  resactisinf = TRUE;
4992  }
4993  rescap = consdata->lhs - maxresactivity;
4994  }
4995 
4996  if( reasonisrhs == (vals[inferpos] > 0.0) )
4997  rescap -= vals[inferpos] * (SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) + 1.0);
4998  else
4999  rescap -= vals[inferpos] * (SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) - 1.0);
5000  }
5001  else
5002  rescap = (reasonisrhs ? consdata->rhs - minresactivity : consdata->lhs - maxresactivity);
5003 
5004  if( !resactisinf )
5005  {
5006  /* now add bounds as reasons until the residual capacity is exceeded */
5007  for( i = 0; i < nvars; ++i )
5008  {
5009  assert( vars != NULL && vals != NULL ); /* for lint */
5010 
5011  /* zero coefficients and the infered variable can be ignored */
5012  if( vars[i] == infervar || SCIPisZero(scip, vals[i]) )
5013  continue;
5014 
5015  /* check if the residual capacity is exceeded */
5016  if( (reasonisrhs && SCIPisFeasNegative(scip, rescap))
5017  || (!reasonisrhs && SCIPisFeasPositive(scip, rescap)) )
5018  break;
5019 
5020  /* update the residual capacity due to the local bound of this variable */
5021  if( reasonisrhs == (vals[i] > 0.0) )
5022  {
5023  /* rhs is reason and coeff is positive, or lhs is reason and coeff is negative -> lower bound */
5024  SCIP_CALL( SCIPaddConflictLb(scip, vars[i], bdchgidx) );
5025  rescap -= vals[i] * (SCIPgetVarLbAtIndex(scip, vars[i], bdchgidx, FALSE) - SCIPvarGetLbGlobal(vars[i]));
5026  }
5027  else
5028  {
5029  /* lhs is reason and coeff is positive, or rhs is reason and coeff is negative -> upper bound */
5030  SCIP_CALL( SCIPaddConflictUb(scip, vars[i], bdchgidx) );
5031  rescap -= vals[i] * (SCIPgetVarUbAtIndex(scip, vars[i], bdchgidx, FALSE) - SCIPvarGetUbGlobal(vars[i]));
5032  }
5033  }
5034  return SCIP_OKAY;
5035  }
5036  }
5037  }
5038 
5039  /* for a bound change on a continuous variable, all locally changed bounds are responsible */
5040  for( i = 0; i < nvars; ++i )
5041  {
5042  assert(vars != NULL); /* for flexelint */
5043  assert(vals != NULL); /* for flexelint */
5044 
5045  /* zero coefficients and the infered variable can be ignored */
5046  if( vars[i] == infervar || SCIPisZero(scip, vals[i]) )
5047  continue;
5048 
5049  if( reasonisrhs == (vals[i] > 0.0) )
5050  {
5051  /* rhs is reason and coeff is positive, or lhs is reason and coeff is negative -> lower bound is responsible */
5052  SCIP_CALL( SCIPaddConflictLb(scip, vars[i], bdchgidx) );
5053  }
5054  else
5055  {
5056  /* lhs is reason and coeff is positive, or rhs is reason and coeff is negative -> upper bound is responsible */
5057  SCIP_CALL( SCIPaddConflictUb(scip, vars[i], bdchgidx) );
5058  }
5059  }
5060 
5061  return SCIP_OKAY;
5062 }
5063 
5064 /** for each variable in the linear ranged row constraint, except the inferred variable, adds the bounds of all fixed
5065  * variables to the conflict analysis' candidate store; the conflict analysis can be initialized
5066  * with the linear constraint being the conflict detecting constraint by using NULL as inferred variable
5067  */
5068 static
5070  SCIP* scip, /**< SCIP data structure */
5071  SCIP_CONS* cons, /**< constraint that inferred the bound change */
5072  SCIP_VAR* infervar, /**< variable that was deduced, or NULL */
5073  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
5074  int inferpos /**< position of the inferred variable in the vars array, or -1 */
5075  )
5076 {
5077  SCIP_CONSDATA* consdata;
5078  SCIP_VAR** vars;
5079  int nvars;
5080  int v;
5081 
5082  assert(scip != NULL);
5083  assert(cons != NULL);
5084 
5085  consdata = SCIPconsGetData(cons);
5086  assert(consdata != NULL);
5087  vars = consdata->vars;
5088  nvars = consdata->nvars;
5089  assert(vars != NULL || nvars == 0);
5090  assert(-1 <= inferpos && inferpos < nvars);
5091  assert((infervar == NULL) == (inferpos == -1));
5092  assert(inferpos == -1 || vars != NULL);
5093  assert(inferpos == -1 || vars[inferpos] == infervar); /*lint !e613*/
5094 
5095  /* collect all fixed variables */
5096  for( v = nvars - 1; v >= 0; --v )
5097  {
5098  assert(vars != NULL); /* for flexelint */
5099 
5100  /* need to add old bounds before propagation of inferrence variable */
5101  if( vars[v] == infervar )
5102  {
5103  assert(vars[v] != NULL);
5104 
5105  if( !SCIPisEQ(scip, SCIPgetVarLbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPvarGetLbGlobal(vars[v])) )
5106  {
5107  /* @todo get boundchange index before this last boundchange and correct the index */
5108  SCIP_CALL( SCIPaddConflictLb(scip, vars[v], bdchgidx) );
5109  }
5110 
5111  if( !SCIPisEQ(scip, SCIPgetVarUbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPvarGetUbGlobal(vars[v])) )
5112  {
5113  /* @todo get boundchange index before this last boundchange and correct the index */
5114  SCIP_CALL( SCIPaddConflictUb(scip, vars[v], bdchgidx) );
5115  }
5116 
5117  continue;
5118  }
5119 
5120  /* check for fixed variables */
5121  if( SCIPisEQ(scip, SCIPgetVarLbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPgetVarUbAtIndex(scip, vars[v], bdchgidx, FALSE)) )
5122  {
5123  /* add all bounds of fixed variables which lead to the boundchange of the given inference variable */
5124  SCIP_CALL( SCIPaddConflictLb(scip, vars[v], bdchgidx) );
5125  SCIP_CALL( SCIPaddConflictUb(scip, vars[v], bdchgidx) );
5126  }
5127  }
5128 
5129  return SCIP_OKAY;
5130 }
5131 
5132 /** add reasoning variables to conflict candidate queue which led to the conflict */
5133 static
5135  SCIP* scip, /**< SCIP data structure */
5136  SCIP_VAR** vars, /**< variables reasoning the infeasibility */
5137  int nvars, /**< number of variables reasoning the infeasibility */
5138  SCIP_VAR* var, /**< variable which was tried to fix/tighten, or NULL */
5139  SCIP_Real bound /**< bound of variable which was tried to apply, or SCIP_INVALID */
5140  )
5141 {
5142  int v;
5143 
5144  assert(scip != NULL);
5145 
5146  /* collect all variables for which the local bounds differ from their global bounds */
5147  for( v = nvars - 1; v >= 0; --v )
5148  {
5149  assert(vars != NULL);
5150 
5151  /* check for local bound changes variables */
5152  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(vars[v]), SCIPvarGetLbGlobal(vars[v])) )
5153  {
5154  /* add conflict bound */
5155  SCIP_CALL( SCIPaddConflictLb(scip, vars[v], 0) );
5156  }
5157 
5158  if( !SCIPisEQ(scip, SCIPvarGetUbLocal(vars[v]), SCIPvarGetUbGlobal(vars[v])) )
5159  {
5160  SCIP_CALL( SCIPaddConflictUb(scip, vars[v], 0) );
5161  }
5162  }
5163 
5164  if( var != NULL )
5165  {
5166  if( bound < SCIPvarGetLbLocal(var) )
5167  {
5168  SCIP_CALL( SCIPaddConflictLb(scip, var, 0) );
5169  }
5170 
5171  if( bound > SCIPvarGetUbLocal(var) )
5172  {
5173  SCIP_CALL( SCIPaddConflictUb(scip, var, 0) );
5174  }
5175  }
5176 
5177  return SCIP_OKAY;
5178 }
5179 
5180 /** resolves a propagation on the given variable by supplying the variables needed for applying the corresponding
5181  * propagation rule (see propagateCons()):
5182  * (1) activity residuals of all other variables tighten bounds of single variable
5183  */
5184 static
5186  SCIP* scip, /**< SCIP data structure */
5187  SCIP_CONS* cons, /**< constraint that inferred the bound change */
5188  SCIP_VAR* infervar, /**< variable that was deduced */
5189  INFERINFO inferinfo, /**< inference information */
5190  SCIP_BOUNDTYPE boundtype, /**< the type of the changed bound (lower or upper bound) */
5191  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
5192  SCIP_RESULT* result /**< pointer to store the result of the propagation conflict resolving call */
5193  )
5194 {
5195  SCIP_CONSDATA* consdata;
5196  SCIP_VAR** vars;
5197 #ifndef NDEBUG
5198  SCIP_Real* vals;
5199 #endif
5200  int nvars;
5201  int inferpos;
5203  assert(scip != NULL);
5204  assert(cons != NULL);
5205  assert(result != NULL);
5206 
5207  consdata = SCIPconsGetData(cons);
5208  assert(consdata != NULL);
5209  vars = consdata->vars;
5210  nvars = consdata->nvars;
5211 #ifndef NDEBUG
5212  vals = consdata->vals;
5213  assert(vars != NULL);
5214  assert(vals != NULL);
5215 #endif
5216 
5217  /* get the position of the inferred variable in the vars array */
5218  inferpos = inferInfoGetPos(inferinfo);
5219  if( inferpos >= nvars || vars[inferpos] != infervar )
5220  {
5221  /* find inference variable in constraint */
5222  /**@todo use a binary search here; the variables can be sorted by variable index */
5223  for( inferpos = 0; inferpos < nvars && vars[inferpos] != infervar; ++inferpos )
5224  {}
5225  }
5226  assert(inferpos < nvars);
5227  assert(vars[inferpos] == infervar);
5228  assert(!SCIPisZero(scip, vals[inferpos]));
5229 
5230  switch( inferInfoGetProprule(inferinfo) )
5231  {
5232  case PROPRULE_1_RHS:
5233  /* the bound of the variable was tightened, because the minimal or maximal residual activity of the linear
5234  * constraint (only taking the other variables into account) didn't leave enough space for a larger
5235  * domain in order to not exceed the right hand side of the inequality
5236  */
5237  assert((vals[inferpos] > 0.0) == (boundtype == SCIP_BOUNDTYPE_UPPER));
5238  SCIP_CALL( addConflictBounds(scip, cons, infervar, bdchgidx, inferpos, TRUE) );
5239  *result = SCIP_SUCCESS;
5240  break;
5241 
5242  case PROPRULE_1_LHS:
5243  /* the bound of the variable was tightened, because the minimal or maximal residual activity of the linear
5244  * constraint (only taking the other variables into account) didn't leave enough space for a larger
5245  * domain in order to not fall below the left hand side of the inequality
5246  */
5247  assert((vals[inferpos] > 0.0) == (boundtype == SCIP_BOUNDTYPE_LOWER));
5248  SCIP_CALL( addConflictBounds(scip, cons, infervar, bdchgidx, inferpos, FALSE) );
5249  *result = SCIP_SUCCESS;
5250  break;
5251 
5252  case PROPRULE_1_RANGEDROW:
5253  /* the bound of the variable was tightened, because some variables were already fixed and the leftover only allow
5254  * the given inference variable to their bounds in this given ranged row
5255  */
5256 
5257  /* check that we really have a ranged row here */
5258  assert(!SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->rhs));
5259  SCIP_CALL( addConflictFixedVars(scip, cons, infervar, bdchgidx, inferpos) );
5260  *result = SCIP_SUCCESS;
5261  break;
5262 
5263  case PROPRULE_INVALID:
5264  default:
5265  SCIPerrorMessage("invalid inference information %d in linear constraint <%s> at position %d for %s bound of variable <%s>\n",
5266  inferInfoGetProprule(inferinfo), SCIPconsGetName(cons), inferInfoGetPos(inferinfo),
5267  boundtype == SCIP_BOUNDTYPE_LOWER ? "lower" : "upper", SCIPvarGetName(infervar));
5268  SCIP_CALL( SCIPprintCons(scip, cons, NULL) );
5269  SCIPinfoMessage(scip, NULL, ";\n");
5270  return SCIP_INVALIDDATA;
5271  }
5272 
5273  return SCIP_OKAY;
5274 }
5275 
5276 /** analyzes conflicting bounds on given constraint, and adds conflict constraint to problem */
5277 static
5279  SCIP* scip, /**< SCIP data structure */
5280  SCIP_CONS* cons, /**< conflict detecting constraint */
5281  SCIP_Bool reasonisrhs /**< is the right hand side responsible for the conflict? */
5282  )
5283 {
5284  /* conflict analysis can only be applied in solving stage and if it is turned on */
5286  return SCIP_OKAY;
5287 
5288  /* initialize conflict analysis */
5290 
5291  /* add the conflicting bound for each variable of infeasible constraint to conflict candidate queue */
5292  SCIP_CALL( addConflictBounds(scip, cons, NULL, NULL, -1, reasonisrhs) );
5293 
5294  /* analyze the conflict */
5296 
5297  return SCIP_OKAY;
5298 }
5299 
5300 /** check if there is any hope of tightening some bounds */
5301 static
5303  SCIP_CONS* cons /**< linear constraint */
5304  )
5305 {
5306  SCIP_CONSDATA* consdata;
5307  int infcountmin;
5308  int infcountmax;
5309 
5310  consdata = SCIPconsGetData(cons);
5311  assert(consdata != NULL);
5312 
5313  infcountmin = consdata->minactivityneginf
5314  + consdata->minactivityposinf
5315  + consdata->minactivityneghuge
5316  + consdata->minactivityposhuge;
5317  infcountmax = consdata->maxactivityneginf
5318  + consdata->maxactivityposinf
5319  + consdata->maxactivityneghuge
5320  + consdata->maxactivityposhuge;
5321 
5322  if( infcountmin > 1 && infcountmax > 1 )
5323  return FALSE;
5324 
5325  return TRUE;
5326 }
5327 
5328 /** tighten upper bound */
5329 static
5331  SCIP* scip, /**< SCIP data structure */
5332  SCIP_CONS* cons, /**< linear constraint */
5333  int pos, /**< variable position */
5334  PROPRULE proprule, /**< propagation rule that deduced the value */
5335  SCIP_Real newub, /**< new upper bound */
5336  SCIP_Real oldub, /**< old upper bound */
5337  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
5338  int* nchgbds, /**< pointer to count the total number of tightened bounds */
5339  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
5340  )
5341 {
5342  SCIP_CONSDATA* consdata;
5343  SCIP_VAR* var;
5344  SCIP_Real lb;
5345  SCIP_Bool infeasible;
5346  SCIP_Bool tightened;
5348  assert(cons != NULL);
5349  assert(!SCIPisInfinity(scip, newub));
5350 
5351  consdata = SCIPconsGetData(cons);
5352  assert(consdata != NULL);
5353  var = consdata->vars[pos];
5354  assert(var != NULL);
5355 
5356  lb = SCIPvarGetLbLocal(var);
5357  newub = SCIPadjustedVarUb(scip, var, newub);
5358 
5359  if( force || SCIPisUbBetter(scip, newub, lb, oldub) )
5360  {
5361  SCIP_VARTYPE vartype;
5362 
5363  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, activity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newub=%.15g\n",
5364  SCIPconsGetName(cons), SCIPvarGetName(var), lb, oldub, consdata->vals[pos], consdata->minactivity, consdata->maxactivity, consdata->lhs, consdata->rhs, newub);
5365 
5366  vartype = SCIPvarGetType(var);
5367 
5368  /* tighten upper bound */
5369  SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(proprule, pos), force, &infeasible, &tightened) );
5370 
5371  if( infeasible )
5372  {
5373  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5374  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5375 
5376  /* analyze conflict */
5377  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
5378 
5379  *cutoff = TRUE;
5380  }
5381  else if( tightened )
5382  {
5383  assert(SCIPisFeasLE(scip, SCIPvarGetUbLocal(var), oldub));
5384  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
5385  SCIPconsGetName(cons), SCIPvarGetName(var), lb, SCIPvarGetUbLocal(var));
5386 
5387  (*nchgbds)++;
5388 
5389  /* if variable type was changed we might be able to upgrade the constraint */
5390  if( vartype != SCIPvarGetType(var) )
5391  consdata->upgradetried = FALSE;
5392  }
5393  }
5394  return SCIP_OKAY;
5395 }
5396 
5397 /** tighten lower bound */
5398 static
5400  SCIP* scip, /**< SCIP data structure */
5401  SCIP_CONS* cons, /**< linear constraint */
5402  int pos, /**< variable position */
5403  PROPRULE proprule, /**< propagation rule that deduced the value */
5404  SCIP_Real newlb, /**< new lower bound */
5405  SCIP_Real oldlb, /**< old lower bound */
5406  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
5407  int* nchgbds, /**< pointer to count the total number of tightened bounds */
5408  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
5409  )
5410 {
5411  SCIP_CONSDATA* consdata;
5412  SCIP_VAR* var;
5413  SCIP_Real ub;
5414  SCIP_Bool infeasible;
5415  SCIP_Bool tightened;
5417  assert(cons != NULL);
5418  assert(!SCIPisInfinity(scip, newlb));
5419 
5420  consdata = SCIPconsGetData(cons);
5421  assert(consdata != NULL);
5422  var = consdata->vars[pos];
5423  assert(var != NULL);
5424 
5425  ub = SCIPvarGetUbLocal(var);
5426  newlb = SCIPadjustedVarLb(scip, var, newlb);
5427 
5428  if( force || SCIPisLbBetter(scip, newlb, oldlb, ub) )
5429  {
5430  SCIP_VARTYPE vartype;
5431 
5432  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, activity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
5433  SCIPconsGetName(cons), SCIPvarGetName(var), oldlb, ub, consdata->vals[pos], consdata->minactivity, consdata->maxactivity, consdata->lhs, consdata->rhs, newlb);
5434 
5435  vartype = SCIPvarGetType(var);
5436 
5437  /* tighten lower bound */
5438  SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(proprule, pos), force, &infeasible, &tightened) );
5439 
5440  if( infeasible )
5441  {
5442  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5443  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5444 
5445  /* analyze conflict */
5446  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
5447 
5448  *cutoff = TRUE;
5449  }
5450  else if( tightened )
5451  {
5452  assert(SCIPisFeasGE(scip, SCIPvarGetLbLocal(var), oldlb));
5453  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
5454  SCIPconsGetName(cons), SCIPvarGetName(var), SCIPvarGetLbLocal(var), ub);
5455 
5456  (*nchgbds)++;
5457 
5458  /* if variable type was changed we might be able to upgrade the constraint */
5459  if( vartype != SCIPvarGetType(var) )
5460  consdata->upgradetried = FALSE;
5461  }
5462  }
5463  return SCIP_OKAY;
5464 }
5465 
5466 /** tightens bounds of a single variable due to activity bounds (easy case) */
5467 static
5469  SCIP* scip, /**< SCIP data structure */
5470  SCIP_CONS* cons, /**< linear constraint */
5471  int pos, /**< position of the variable in the vars array */
5472  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
5473  int* nchgbds, /**< pointer to count the total number of tightened bounds */
5474  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
5475  )
5476 {
5477  SCIP_CONSDATA* consdata;
5478  SCIP_VAR* var;
5479  SCIP_Real val;
5480  SCIP_Real lb;
5481  SCIP_Real ub;
5482  SCIP_Real lhs;
5483  SCIP_Real rhs;
5484 
5485  assert(scip != NULL);
5486  assert(cons != NULL);
5487  assert(cutoff != NULL);
5488  assert(nchgbds != NULL);
5489 
5490  /* we cannot tighten variables' bounds, if the constraint may be not complete */
5491  if( SCIPconsIsModifiable(cons) )
5492  return SCIP_OKAY;
5493 
5494  consdata = SCIPconsGetData(cons);
5495  assert(consdata != NULL);
5496  assert(0 <= pos && pos < consdata->nvars);
5497 
5498  *cutoff = FALSE;
5499 
5500  var = consdata->vars[pos];
5501  assert(var != NULL);
5502 
5503  /* we cannot tighten bounds of multi-aggregated variables */
5505  return SCIP_OKAY;
5506 
5507  val = consdata->vals[pos];
5508  lhs = consdata->lhs;
5509  rhs = consdata->rhs;
5510  assert(!SCIPisZero(scip, val));
5511  assert(!SCIPisInfinity(scip, lhs));
5512  assert(!SCIPisInfinity(scip, -rhs));
5513 
5514  lb = SCIPvarGetLbLocal(var);
5515  ub = SCIPvarGetUbLocal(var);
5516  assert(SCIPisLE(scip, lb, ub));
5517 
5518  /* recompute activities if needed */
5519  if( !consdata->validactivities )
5520  consdataCalcActivities(scip, consdata);
5521  assert(consdata->validactivities);
5522  if( !consdata->validminact )
5523  consdataRecomputeMinactivity(scip, consdata);
5524  assert(consdata->validminact);
5525 
5526  if( val > 0.0 )
5527  {
5528  /* check, if we can tighten the variable's upper bound */
5529  if( !SCIPisInfinity(scip, rhs) )
5530  {
5531  SCIP_Real slack;
5532  SCIP_Real alpha;
5533 
5534  /* min activity should be valid at this point (if this is not true, then some decisions might be wrong!) */
5535  assert(consdata->validminact);
5536 
5537  /* if the minactivity is larger than the right hand side by feasibility epsilon, the constraint is infeasible */
5538  if( SCIPisFeasLT(scip, rhs, consdata->minactivity) )
5539  {
5540  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, minactivity=%.15g > rhs=%.15g\n",
5541  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->minactivity, rhs);
5542 
5543  *cutoff = TRUE;
5544  return SCIP_OKAY;
5545  }
5546 
5547  slack = rhs - consdata->minactivity;
5548 
5549  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5550  * it to zero
5551  */
5552  if( !SCIPisPositive(scip, slack) )
5553  slack = 0.0;
5554 
5555  alpha = val * (ub - lb);
5556  assert(!SCIPisNegative(scip, alpha));
5557 
5558  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5559  {
5560  SCIP_Real newub;
5561 
5562  /* compute new upper bound */
5563  newub = lb + (slack / val);
5564 
5565  SCIP_CALL( tightenVarUb(scip, cons, pos, PROPRULE_1_RHS, newub, ub, cutoff, nchgbds, force) );
5566 
5567  if( *cutoff )
5568  {
5569  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5570  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5571 
5572  return SCIP_OKAY;
5573  }
5574 
5575  /* collect the new upper bound which is needed for the lower bound computation */
5576  ub = SCIPvarGetUbLocal(var);
5577  }
5578  }
5579 
5580  /* check, if we can tighten the variable's lower bound */
5581  if( !SCIPisInfinity(scip, -lhs) )
5582  {
5583  SCIP_Real slack;
5584  SCIP_Real alpha;
5585 
5586  /* make sure the max activity is reliable */
5587  if( !consdata->validmaxact )
5588  {
5589  consdataRecomputeMaxactivity(scip, consdata);
5590  }
5591  assert(consdata->validmaxact);
5592 
5593 
5594  /* if the maxactivity is smaller than the left hand side by feasibility epsilon, the constraint is infeasible */
5595  if( SCIPisFeasLT(scip, consdata->maxactivity, lhs) )
5596  {
5597  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, maxactivity=%.15g < lhs=%.15g\n",
5598  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->maxactivity, lhs);
5599  *cutoff = TRUE;
5600  return SCIP_OKAY;
5601  }
5602 
5603  slack = consdata->maxactivity - lhs;
5604 
5605  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5606  * it to zero
5607  */
5608  if( !SCIPisPositive(scip, slack) )
5609  slack = 0.0;
5610 
5611  alpha = val * (ub - lb);
5612  assert(!SCIPisNegative(scip, alpha));
5613 
5614  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5615  {
5616  SCIP_Real newlb;
5617 
5618  /* compute new lower bound */
5619  newlb = ub - (slack / val);
5620 
5621  SCIP_CALL( tightenVarLb(scip, cons, pos, PROPRULE_1_LHS, newlb, lb, cutoff, nchgbds, force) );
5622 
5623  if( *cutoff )
5624  {
5625  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5626  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5627 
5628  return SCIP_OKAY;
5629  }
5630  }
5631  }
5632  }
5633  else
5634  {
5635  /* check, if we can tighten the variable's lower bound */
5636  if( !SCIPisInfinity(scip, rhs) )
5637  {
5638  SCIP_Real slack;
5639  SCIP_Real alpha;
5640 
5641  /* min activity should be valid at this point (if this is not true, then some decisions might be wrong!) */
5642  assert(consdata->validminact);
5643 
5644  /* if the minactivity is larger than the right hand side by feasibility epsilon, the constraint is infeasible */
5645  if( SCIPisFeasLT(scip, rhs, consdata->minactivity) )
5646  {
5647  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, minactivity=%.15g > rhs=%.15g\n",
5648  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->minactivity, rhs);
5649 
5650  *cutoff = TRUE;
5651  return SCIP_OKAY;
5652  }
5653 
5654  slack = rhs - consdata->minactivity;
5655 
5656  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5657  * it to zero
5658  */
5659  if( !SCIPisPositive(scip, slack) )
5660  slack = 0.0;
5661 
5662  alpha = val * (lb - ub);
5663  assert(!SCIPisNegative(scip, alpha));
5664 
5665  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5666  {
5667  SCIP_Real newlb;
5668 
5669  /* compute new lower bound */
5670  newlb = ub + slack / val;
5671 
5672  SCIP_CALL( tightenVarLb(scip, cons, pos, PROPRULE_1_RHS, newlb, lb, cutoff, nchgbds, force) );
5673 
5674  if( *cutoff )
5675  {
5676  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5677  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5678 
5679  return SCIP_OKAY;
5680  }
5681  /* collect the new lower bound which is needed for the upper bound computation */
5682  lb = SCIPvarGetLbLocal(var);
5683  }
5684  }
5685 
5686  /* check, if we can tighten the variable's upper bound */
5687  if( !SCIPisInfinity(scip, -lhs) )
5688  {
5689  SCIP_Real slack;
5690  SCIP_Real alpha;
5691 
5692  /* make sure the max activity is reliable */
5693  if( !consdata->validmaxact )
5694  {
5695  consdataRecomputeMaxactivity(scip, consdata);
5696  }
5697  assert(consdata->validmaxact);
5698 
5699  /* if the maxactivity is smaller than the left hand side by feasibility epsilon, the constraint is infeasible */
5700  if( SCIPisFeasLT(scip, consdata->maxactivity, lhs) )
5701  {
5702  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, maxactivity=%.15g < lhs=%.15g\n",
5703  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->maxactivity, lhs);
5704 
5705  *cutoff = TRUE;
5706  return SCIP_OKAY;
5707  }
5708 
5709  slack = consdata->maxactivity - lhs;
5710 
5711  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5712  * it to zero
5713  */
5714  if( !SCIPisPositive(scip, slack) )
5715  slack = 0.0;
5716 
5717  alpha = val * (lb - ub);
5718  assert(!SCIPisNegative(scip, alpha));
5719 
5720  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5721  {
5722  SCIP_Real newub;
5723 
5724  /* compute new upper bound */
5725  newub = lb - (slack / val);
5726 
5727  SCIP_CALL( tightenVarUb(scip, cons, pos, PROPRULE_1_LHS, newub, ub, cutoff, nchgbds, force) );
5728 
5729  if( *cutoff )
5730  {
5731  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5732  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5733 
5734  return SCIP_OKAY;
5735  }
5736  }
5737  }
5738  }
5739 
5740  return SCIP_OKAY;
5741 }
5742 
5743 /** analyzes conflicting bounds on given ranged row constraint, and adds conflict constraint to problem */
5744 static
5746  SCIP* scip, /**< SCIP data structure */
5747  SCIP_CONS* cons, /**< conflict detecting constraint */
5748  SCIP_VAR** vars, /**< variables reasoning the infeasibility */
5749  int nvars, /**< number of variables reasoning the infeasibility */
5750  SCIP_VAR* var, /**< variable which was tried to fix/tighten, or NULL */
5751  SCIP_Real bound /**< bound of variable which was tried to apply, or SCIP_INVALID */
5752  )
5753 {
5754 #ifndef NDEBUG
5755  SCIP_CONSDATA* consdata;
5756 
5757  assert(scip != NULL);
5758  assert(cons != NULL);
5759 
5760  consdata = SCIPconsGetData(cons);
5761  assert(consdata != NULL);
5762  assert(!SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->rhs));
5763 #endif
5764 
5765  /* conflict analysis can only be applied in solving stage and if it is turned on */
5767  return SCIP_OKAY;
5768 
5769  /* initialize conflict analysis */
5771 
5772  /* add the conflicting fixed variables of this ranged row constraint to conflict candidate queue */
5773  SCIP_CALL( addConflictFixedVars(scip, cons, NULL, NULL, -1) );
5774 
5775  /* add reasoning variables to conflict candidate queue which led to the conflict */
5776  SCIP_CALL( addConflictReasonVars(scip, vars, nvars, var, bound) );
5777 
5778  /* analyze the conflict */
5779  SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
5780 
5781  return SCIP_OKAY;
5782 }
5783 
5784 /** propagate ranged rows
5785  *
5786  * Check ranged rows for possible solutions, possibly detect infeasibility, fix variables due to having only one possible
5787  * solution, tighten bounds if having only two possible solutions or add constraints which propagate a subset of
5788  * variables better.
5789  *
5790  * Example:
5791  * c1: 12 x1 + 9 x2 - x3 = 0 with x1, x2 free and 1 <= x3 <= 2
5792  *
5793  * x3 needs to be a multiple of 3, so the instance is infeasible.
5794  *
5795  * Example:
5796  * c1: 12 x1 + 9 x2 - x3 = 1 with x1, x2 free and 1 <= x3 <= 2
5797  *
5798  * The only possible value for x3 is 2, so the variable will be fixed.
5799  *
5800  * @todo add holes if possible
5801  */
5802 static
5804  SCIP* scip, /**< SCIP data structure */
5805  SCIP_CONS* cons, /**< linear constraint */
5806  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
5807  int* nfixedvars, /**< pointer to count number of fixed variables */
5808  int* nchgbds, /**< pointer to count the number of bound changes */
5809  int* naddconss /**< pointer to count number of added constraints */
5810  )
5811 {
5812  SCIP_CONSHDLRDATA* conshdlrdata;
5813  SCIP_CONSHDLR* conshdlr;
5814  SCIP_CONSDATA* consdata;
5815  SCIP_VAR** infcheckvars;
5816  SCIP_Real* infcheckvals;
5817  SCIP_Real minactinfvars;
5818  SCIP_Real maxactinfvars;
5819  SCIP_Real lb;
5821  SCIP_Real feastol;
5822  SCIP_Real fixedact;
5823  SCIP_Real lhs;
5824  SCIP_Real rhs;
5825  SCIP_Real absminbincoef;
5826  SCIP_Longint gcd;
5827  SCIP_Longint gcdtmp;
5828  SCIP_Bool minactinfvarsinvalid;
5829  SCIP_Bool maxactinfvarsinvalid;
5830  SCIP_Bool possiblegcd;
5831  SCIP_Bool gcdisone;
5832  SCIP_Bool addartconss;
5833  int ninfcheckvars;
5834  int nunfixedvars;
5835  int nfixedconsvars;
5836  int ncontvars;
5837  int pos;
5838  int v;
5839 
5840  assert(scip != NULL);
5841  assert(cons != NULL);
5842  assert(cutoff != NULL);
5843  assert(nfixedvars != NULL);
5844  assert(nchgbds != NULL);
5845  assert(naddconss != NULL);
5846 
5847  /* modifiable constraint can be changed so we do not have all necessary information */
5848  if( SCIPconsIsModifiable(cons) )
5849  return SCIP_OKAY;
5850 
5851  consdata = SCIPconsGetData(cons);
5852  assert(consdata != NULL);
5853 
5854  /* we already did full ranged row propagation */
5855  if( consdata->rangedrowpropagated == 2 )
5856  return SCIP_OKAY;
5857 
5858  /* at least three variables are needed */
5859  if( consdata->nvars < 3 )
5860  return SCIP_OKAY;
5861 
5862  /* do nothing on normal inequalities */
5863  if( SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, consdata->rhs) )
5864  return SCIP_OKAY;
5865 
5866  /* get constraint handler data */
5867  conshdlr = SCIPconsGetHdlr(cons);
5868  assert(conshdlr != NULL);
5869  conshdlrdata = SCIPconshdlrGetData(conshdlr);
5870  assert(conshdlrdata != NULL);
5871 
5872  addartconss = conshdlrdata->rangedrowartcons && SCIPgetDepth(scip) < 1 && !SCIPinProbing(scip) && !SCIPinRepropagation(scip);
5873 
5874  /* we may add artificial constraints */
5875  if( addartconss )
5876  consdata->rangedrowpropagated = 2;
5877  /* we are not allowed to add artificial constraints during propagation; if nothing changed on this constraint since
5878  * the last rangedrowpropagation, we can stop; otherwise, we mark this constraint to be rangedrowpropagated without
5879  * artificial constraints
5880  */
5881  else
5882  {
5883  if( consdata->rangedrowpropagated > 0 )
5884  return SCIP_OKAY;
5885 
5886  consdata->rangedrowpropagated = 1;
5887  }
5888  fixedact = 0;
5889  nfixedconsvars = 0;
5890  /* calculate fixed activity and number of fixed variables */
5891  for( v = consdata->nvars - 1; v >= 0; --v )
5892  {
5893  /* all zero coefficients should be eliminated */
5894  assert(!SCIPisZero(scip, consdata->vals[v]));
5895 
5896  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5897  {
5898  fixedact += SCIPvarGetLbLocal(consdata->vars[v]) * consdata->vals[v];
5899  ++nfixedconsvars;
5900  }
5901  }
5902 
5903  /* do not work with huge fixed activities */
5904  if( SCIPisHugeValue(scip, REALABS(fixedact)) )
5905  return SCIP_OKAY;
5906 
5907  /* compute lhs and rhs for unfixed variables only and get number of unfixed variables */
5908  assert(!SCIPisInfinity(scip, -fixedact) && !SCIPisInfinity(scip, fixedact));
5909  lhs = consdata->lhs - fixedact;
5910  rhs = consdata->rhs - fixedact;
5911  nunfixedvars = consdata->nvars - nfixedconsvars;
5912 
5913  /* allocate temporary memory for variables and coefficients which may lead to infeasibility */
5914  SCIP_CALL( SCIPallocBufferArray(scip, &infcheckvars, nunfixedvars) );
5915  SCIP_CALL( SCIPallocBufferArray(scip, &infcheckvals, nunfixedvars) );
5916 
5917  absminbincoef = SCIP_REAL_MAX;
5918  ncontvars = 0;
5919  gcdisone = TRUE;
5920  possiblegcd = TRUE;
5921 
5922  /* we now partition all unfixed variables in two groups:
5923  *
5924  * the first one contains all integral variable with integral
5925  * coefficient so that all variables in this group will have a gcd greater than 1, this group will be implicitly
5926  * given
5927  *
5928  * the second group will contain all left unfixed variables and will be saved as infcheckvars with corresponding
5929  * coefficients as infcheckvals, the order of these variables should be the same as in the consdata object
5930  */
5931 
5932  /* find first integral variables with integral coefficient greater than 1, thereby collecting all other unfixed
5933  * variables
5934  */
5935  ninfcheckvars = 0;
5936  v = -1;
5937  pos = -1;
5938  do
5939  {
5940  ++v;
5941 
5942  /* partition the variables, do not change the order of collection, because it might be used later on */
5943  while( v < consdata->nvars && (SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS ||
5944  !SCIPisIntegral(scip, consdata->vals[v]) || SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0)) )
5945  {
5946  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5947  {
5948  if( SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS )
5949  {
5950  ++ncontvars;
5951  }
5952  else if( SCIPvarIsBinary(consdata->vars[v]) )
5953  {
5954  SCIP_Real absval;
5955 
5956  absval = REALABS(consdata->vals[v]);
5957 
5958  if( absminbincoef > absval )
5959  absminbincoef = absval;
5960  }
5961 
5962  gcdisone = gcdisone && SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0);
5963  possiblegcd = FALSE;
5964  infcheckvars[ninfcheckvars] = consdata->vars[v];
5965  infcheckvals[ninfcheckvars] = consdata->vals[v];
5966  ++ninfcheckvars;
5967 
5968  if( pos == -1 )
5969  pos = v;
5970  }
5971  ++v;
5972  }
5973  }
5974  while( v < consdata->nvars && SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) );
5975 
5976  /* if the first group of variables is empty, we stop */
5977  /* @todo try to propagate/split up a constraint of the form:
5978  * x_1 + ... + x_m + a_1*y_1 + ... + a_n*y_n = k + c,
5979  * 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]
5980  */
5981  if( v == consdata->nvars )
5982  goto TERMINATE;
5983 
5984  /* we need at least two non-continuous variables */
5985  if( ncontvars + 2 > nunfixedvars )
5986  goto TERMINATE;
5987 
5988  assert(!SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])));
5989  assert(SCIPisIntegral(scip, consdata->vals[v]) && SCIPvarGetType(consdata->vars[v]) != SCIP_VARTYPE_CONTINUOUS && REALABS(consdata->vals[v]) > 1.5);
5990 
5991  feastol = SCIPfeastol(scip);
5992 
5993  gcd = (SCIP_Longint)(REALABS(consdata->vals[v]) + feastol);
5994  assert(gcd >= 2);
5995 
5996  /* go on to partition the variables, do not change the order of collection, because it might be used later on;
5997  * calculate gcd over the first part of variables */
5998  for( ; v < consdata->nvars; ++v )
5999  {
6000  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6001  continue;
6002 
6003  if( SCIPvarIsBinary(consdata->vars[v]) )
6004  {
6005  SCIP_Real absval;
6006 
6007  absval = REALABS(consdata->vals[v]);
6008 
6009  if( absminbincoef > absval )
6010  absminbincoef = absval;
6011  }
6012 
6013  if( !SCIPisIntegral(scip, consdata->vals[v]) || SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS ||
6014  SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0) )
6015  {
6016  if( SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS )
6017  ++ncontvars;
6018 
6019  gcdisone = gcdisone && SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0);
6020  possiblegcd = FALSE;
6021  infcheckvars[ninfcheckvars] = consdata->vars[v];
6022  infcheckvals[ninfcheckvars] = consdata->vals[v];
6023 
6024  ++ninfcheckvars;
6025 
6026  if( pos == -1 )
6027  pos = v;
6028  }
6029  else
6030  {
6031  assert(REALABS(consdata->vals[v]) > 1.5);
6032 
6033  gcdtmp = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(consdata->vals[v]) + feastol));
6034  assert(gcdtmp >= 1);
6035 
6036  if( gcdtmp == 1 )
6037  {
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  gcd = gcdtmp;
6048  }
6049  }
6050  assert(gcd >= 2);
6051 
6052  /* it should not happen that all variables are of integral type and have a gcd >= 2, this should be done by
6053  * normalizeCons() */
6054  if( ninfcheckvars == 0 )
6055  goto TERMINATE;
6056 
6057  assert(pos >= 0);
6058 
6059  minactinfvarsinvalid = FALSE;
6060  maxactinfvarsinvalid = FALSE;
6061  maxactinfvars = 0.0;
6062  minactinfvars = 0.0;
6063 
6064  /* calculate activities over all infcheckvars */
6065  for( v = ninfcheckvars - 1; v >= 0; --v )
6066  {
6067  lb = SCIPvarGetLbLocal(infcheckvars[v]);
6068  ub = SCIPvarGetUbLocal(infcheckvars[v]);
6069 
6070  if( SCIPisInfinity(scip, -lb) )
6071  {
6072  if( infcheckvals[v] < 0.0 )
6073  maxactinfvarsinvalid = TRUE;
6074  else
6075  minactinfvarsinvalid = TRUE;
6076  }
6077  else
6078  {
6079  if( infcheckvals[v] < 0.0 )
6080  maxactinfvars += infcheckvals[v] * lb;
6081  else
6082  minactinfvars += infcheckvals[v] * lb;
6083  }
6084 
6085  if( SCIPisInfinity(scip, ub) )
6086  {
6087  if( infcheckvals[v] > 0.0 )
6088  maxactinfvarsinvalid = TRUE;
6089  else
6090  minactinfvarsinvalid = TRUE;
6091  }
6092  else
6093  {
6094  if( infcheckvals[v] > 0.0 )
6095  maxactinfvars += infcheckvals[v] * ub;
6096  else
6097  minactinfvars += infcheckvals[v] * ub;
6098  }
6099 
6100  /* better abort on to big values */
6101  if( SCIPisHugeValue(scip, -minactinfvars) )
6102  minactinfvarsinvalid = TRUE;
6103  if( SCIPisHugeValue(scip, maxactinfvars) )
6104  maxactinfvarsinvalid = TRUE;
6105 
6106  if( minactinfvarsinvalid || maxactinfvarsinvalid )
6107  goto TERMINATE;
6108  }
6109  assert(!minactinfvarsinvalid && !maxactinfvarsinvalid);
6110 
6111  SCIPdebugMsg(scip, "minactinfvarsinvalid = %u, minactinfvars = %g, maxactinfvarsinvalid = %u, maxactinfvars = %g, gcd = %lld, ninfcheckvars = %d, ncontvars = %d\n",
6112  minactinfvarsinvalid, minactinfvars, maxactinfvarsinvalid, maxactinfvars, gcd, ninfcheckvars, ncontvars);
6113 
6114  /* @todo maybe we took the wrong variables as infcheckvars we could try to exchange integer variables */
6115  /* @todo if minactinfvarsinvalid or maxactinfvarsinvalid are true, try to exchange both partitions to maybe get valid
6116  * activities */
6117  /* @todo calculate minactivity and maxactivity for all non-intcheckvars, and use this for better bounding,
6118  * !!!note!!!
6119  * that therefore the conflict variables in addConflictFixedVars() need to be extended by all variables which
6120  * are not at their global bound
6121  */
6122 
6123  /* check if between left hand side and right hand side exist a feasible point, if not the constraint leads to
6124  * infeasibility */
6125  if( !SCIPisIntegral(scip, (lhs - maxactinfvars) / gcd) &&
6126  SCIPisGT(scip, SCIPceil(scip, (lhs - maxactinfvars) / gcd) * gcd, rhs - minactinfvars) )
6127  {
6128  SCIPdebugMsg(scip, "no feasible value exist, constraint <%s> lead to infeasibility", SCIPconsGetName(cons));
6129  SCIPdebugPrintCons(scip, cons, NULL);
6130 
6131  /* start conflict analysis */
6132  /* @todo improve conflict analysis by adding relaxed bounds */
6133  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6134 
6135  *cutoff = TRUE;
6136  }
6137  else if( ncontvars == 0 )
6138  {
6139  SCIP_Longint gcdinfvars = -1;
6140 
6141  /* check for gcd over all infcheckvars */
6142  if( possiblegcd )
6143  {
6144  v = ninfcheckvars - 1;
6145  gcdinfvars = (SCIP_Longint)(REALABS(infcheckvals[v]) + feastol);
6146  assert(gcdinfvars >= 2);
6147 
6148  for( ; v >= 0 && gcdinfvars >= 2; --v )
6149  {
6150  gcdinfvars = SCIPcalcGreComDiv(gcdinfvars, (SCIP_Longint)(REALABS(infcheckvals[v]) + feastol));
6151  }
6152  }
6153  else if( gcdisone )
6154  gcdinfvars = 1;
6155 
6156  SCIPdebugMsg(scip, "gcdinfvars =%lld, possiblegcd = %u\n", gcdinfvars, possiblegcd);
6157 
6158  /* compute solutions for this ranged row, if all variables are of integral type with integral coefficients */
6159  if( gcdinfvars >= 1 )
6160  {
6161  SCIP_Real value;
6162  SCIP_Real value2;
6163  SCIP_Real minvalue = SCIP_INVALID;
6164  SCIP_Real maxvalue = SCIP_INVALID;
6165  int nsols = 0;
6166 
6167  value = SCIPceil(scip, minactinfvars - SCIPfeastol(scip));
6168 
6169  /* check how many possible solutions exist */
6170  while( SCIPisLE(scip, value, maxactinfvars) )
6171  {
6172  value2 = value + gcd * (SCIPceil(scip, (lhs - value) / gcd));
6173 
6174  /* value2 might violate lhs due to numerics, in this case take the next divisible number */
6175  if( !SCIPisGE(scip, value2, lhs) )
6176  {
6177  value2 += gcd;
6178  }
6179 
6180  if( SCIPisLE(scip, value2, rhs) )
6181  {
6182  ++nsols;
6183 
6184  /* early termination if we found more than two solutions */
6185  if( nsols == 3 )
6186  break;
6187 
6188  if( minvalue == SCIP_INVALID ) /*lint !e777*/
6189  minvalue = value;
6190 
6191  maxvalue = value;
6192  }
6193  value += gcdinfvars;
6194  }
6195  assert(nsols < 2 || minvalue <= maxvalue);
6196 
6197  /* determine last possible solution for better bounding */
6198  if( nsols == 3 )
6199  {
6200 #ifndef NDEBUG
6201  SCIP_Real secondsolval = maxvalue;
6202 #endif
6203  value = SCIPfloor(scip, maxactinfvars + SCIPfeastol(scip));
6204 
6205  /* check how many possible solutions exist */
6206  while( SCIPisGE(scip, value, minactinfvars) )
6207  {
6208  value2 = value + gcd * (SCIPfloor(scip, (rhs - value) / gcd));
6209 
6210  /* value2 might violate rhs due to numerics, in this case take the next divisible number */
6211  if( !SCIPisLE(scip, value2, rhs) )
6212  {
6213  value2 -= gcd;
6214  }
6215 
6216  if( SCIPisGE(scip, value2, lhs) )
6217  {
6218  maxvalue = value;
6219  assert(maxvalue > minvalue);
6220  break;
6221  }
6222  value -= gcdinfvars;
6223  }
6224  assert(maxvalue > secondsolval);
6225  }
6226 
6227  SCIPdebugMsg(scip, "here nsols %s %d, minsolvalue = %g, maxsolvalue = %g, ninfcheckvars = %d, nunfixedvars = %d\n",
6228  nsols > 2 ? ">=" : "=", nsols, minvalue, maxvalue, ninfcheckvars, nunfixedvars);
6229 
6230  /* no possible solution found */
6231  if( nsols == 0 )
6232  {
6233  SCIPdebugMsg(scip, "gcdinfvars = %lld, gcd = %lld, correctedlhs = %g, correctedrhs = %g\n",
6234  gcdinfvars, gcd, lhs, rhs);
6235  SCIPdebugMsg(scip, "no solution found; constraint <%s> lead to infeasibility\n", SCIPconsGetName(cons));
6236  SCIPdebugPrintCons(scip, cons, NULL);
6237 
6238  /* start conflict analysis */
6239  /* @todo improve conflict analysis by adding relaxed bounds */
6240  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6241 
6242  *cutoff = TRUE;
6243  }
6244  /* if only one solution exist we can extract a new constraint or fix variables */
6245  else if( nsols == 1 )
6246  {
6247  assert(minvalue == maxvalue); /*lint !e777*/
6248 
6249  /* we can fix the only variable in our second set of variables */
6250  if( ninfcheckvars == 1 )
6251  {
6252  SCIP_Bool fixed;
6253 
6254  assert(SCIPisEQ(scip, (SCIP_Real)gcdinfvars, REALABS(infcheckvals[0])));
6255 
6256  SCIPdebugMsg(scip, "fixing single variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
6257  SCIPvarGetName(infcheckvars[0]), SCIPvarGetLbLocal(infcheckvars[0]),
6258  SCIPvarGetUbLocal(infcheckvars[0]), maxvalue/infcheckvals[0]);
6259 
6260  /* fix variable to only possible value */
6261  SCIP_CALL( SCIPinferVarFixCons(scip, infcheckvars[0], maxvalue/infcheckvals[0], cons,
6262  getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &fixed) );
6263 
6264  if( *cutoff )
6265  {
6266  /* start conflict analysis */
6267  /* @todo improve conflict analysis by adding relaxed bounds */
6268  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6269  }
6270 
6271  if( fixed )
6272  ++(*nfixedvars);
6273  }
6274  else
6275  {
6276  /* check for exactly one unfixed variable which is not part of the infcheckvars */
6277  if( ninfcheckvars == nunfixedvars - 1 )
6278  {
6279  SCIP_Real bound;
6280  SCIP_Bool foundvar = FALSE;
6281  SCIP_Bool fixed;
6282  int w = 0;
6283 
6284  assert(ninfcheckvars > 0);
6285 
6286  /* find variable which is not an infcheckvar and fix it */
6287  for( v = 0; v < consdata->nvars - 1; ++v )
6288  {
6289  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6290  {
6291  if( w >= ninfcheckvars || consdata->vars[v] != infcheckvars[w] )
6292  {
6293 #ifndef NDEBUG
6294  int v2 = v + 1;
6295  int w2 = w;
6296 
6297  assert((nfixedconsvars == 0) ? (consdata->nvars - v - 1 == ninfcheckvars - w) : TRUE);
6298 
6299  for( ; v2 < consdata->nvars && w2 < ninfcheckvars; ++v2 )
6300  {
6301  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v2]), SCIPvarGetUbLocal(consdata->vars[v2])) )
6302  continue;
6303 
6304  assert(consdata->vars[v2] == infcheckvars[w2]);
6305  ++w2;
6306  }
6307  assert(w2 == ninfcheckvars);
6308 #endif
6309  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6310 
6311  foundvar = TRUE;
6312 
6313  if( consdata->vals[v] < 0 )
6314  {
6315  bound = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6316  }
6317  else
6318  {
6319  bound = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6320  }
6321 
6322  SCIPdebugMsg(scip, "fixing variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
6323  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]),
6324  SCIPvarGetUbLocal(consdata->vars[v]), bound);
6325 
6326  /* fix variable to only possible value */
6327  SCIP_CALL( SCIPinferVarFixCons(scip, consdata->vars[v], bound, cons,
6328  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &fixed) );
6329 
6330  if( *cutoff )
6331  {
6332  /* start conflict analysis */
6333  /* @todo improve conflict analysis by adding relaxed bounds */
6334  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6335  consdata->vars[v], bound) );
6336  }
6337 
6338  if( fixed )
6339  ++(*nfixedvars);
6340 
6341  break;
6342  }
6343 
6344  ++w;
6345  }
6346  }
6347 
6348  /* maybe last variable was the not infcheckvar */
6349  if( !foundvar )
6350  {
6351  assert(v == consdata->nvars - 1);
6352  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6353 
6354  if( consdata->vals[v] < 0 )
6355  {
6356  bound = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6357  }
6358  else
6359  {
6360  bound = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6361  }
6362 
6363  SCIPdebugMsg(scip, "fixing variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
6364  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]),
6365  SCIPvarGetUbLocal(consdata->vars[v]), bound);
6366 
6367  /* fix variable to only possible value */
6368  SCIP_CALL( SCIPinferVarFixCons(scip, consdata->vars[v], bound, cons,
6369  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &fixed) );
6370 
6371  if( *cutoff )
6372  {
6373  /* start conflict analysis */
6374  /* @todo improve conflict analysis by adding relaxed bounds */
6375  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6376  consdata->vars[v], bound) );
6377  }
6378 
6379  if( fixed )
6380  ++(*nfixedvars);
6381  }
6382  }
6383  else if( addartconss && (SCIPisGT(scip, minvalue, minactinfvars) || SCIPisLT(scip, maxvalue, maxactinfvars)) )
6384  {
6385  /* aggregation possible if we have two variables, but this will be done later on */
6386  SCIP_CONS* newcons;
6387  char name[SCIP_MAXSTRLEN];
6388 
6389  /* create, add, and release new artificial constraint */
6390  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6391  ++conshdlrdata->naddconss;
6392 
6393  SCIPdebugMsg(scip, "adding artificial constraint %s\n", name);
6394 
6395  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals,
6396  maxvalue, maxvalue, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6397  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6398 
6399  SCIPdebugPrintCons(scip, newcons, NULL);
6400 
6401  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6402 
6403  ++(*naddconss);
6404  }
6405  }
6406  }
6407  /* at least two solutions */
6408  else
6409  {
6410  /* @todo if we found more then one solution, we may reduced domains due to dualpresolving? */
6411 
6412  /* only one variable in the second set, so we can bound this variables */
6413  if( ninfcheckvars == 1 )
6414  {
6415  SCIP_Bool tightened;
6416  SCIP_Real newlb;
6417  SCIP_Real newub;
6418 
6419  assert(SCIPisEQ(scip, (SCIP_Real)gcdinfvars, REALABS(infcheckvals[0])));
6420 
6421  if( infcheckvals[0] < 0 )
6422  {
6423  newlb = maxvalue/infcheckvals[0];
6424  newub = minvalue/infcheckvals[0];
6425  }
6426  else
6427  {
6428  newlb = minvalue/infcheckvals[0];
6429  newub = maxvalue/infcheckvals[0];
6430  }
6431  assert(newlb < newub);
6432 
6433  if( newlb > SCIPvarGetLbLocal(infcheckvars[0]) )
6434  {
6435  /* update lower bound of variable */
6436  SCIPdebugMsg(scip, "tightening lower bound of variable <%s> from %g to %g\n",
6437  SCIPvarGetName(infcheckvars[0]), SCIPvarGetLbLocal(infcheckvars[0]), newlb);
6438 
6439  /* tighten variable lower bound to minimal possible value */
6440  SCIP_CALL( SCIPinferVarLbCons(scip, infcheckvars[0], newlb, cons,
6441  getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &tightened) );
6442 
6443  if( *cutoff )
6444  {
6445  /* start conflict analysis */
6446  /* @todo improve conflict analysis by adding relaxed bounds */
6447  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6448  }
6449 
6450  if( tightened )
6451  ++(*nchgbds);
6452  }
6453 
6454  if( newub < SCIPvarGetUbLocal(infcheckvars[0]) )
6455  {
6456  /* update upper bound of variable */
6457  SCIPdebugMsg(scip, "tightening upper bound of variable <%s> from %g to %g\n",
6458  SCIPvarGetName(infcheckvars[0]), SCIPvarGetUbLocal(infcheckvars[0]), newub);
6459 
6460  /* tighten variable upper bound to maximal possible value */
6461  SCIP_CALL( SCIPinferVarUbCons(scip, infcheckvars[0], newub, cons,
6462  getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &tightened) );
6463 
6464  if( *cutoff )
6465  {
6466  /* start conflict analysis */
6467  /* @todo improve conflict analysis by adding relaxed bounds */
6468  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6469  }
6470 
6471  if( tightened )
6472  ++(*nchgbds);
6473  }
6474  }
6475  /* check if we have only one not infcheckvars, if so we can tighten this variable */
6476  else if( ninfcheckvars == nunfixedvars - 1 )
6477  {
6478  SCIP_Bool foundvar = FALSE;
6479  SCIP_Bool tightened;
6480  SCIP_Real newlb;
6481  SCIP_Real newub;
6482  int w = 0;
6483 
6484  assert(ninfcheckvars > 0);
6485  assert(minvalue < maxvalue);
6486 
6487  /* find variable which is not an infcheckvar and fix it */
6488  for( v = 0; v < consdata->nvars - 1; ++v )
6489  {
6490  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6491  {
6492  if( w >= ninfcheckvars || consdata->vars[v] != infcheckvars[w] )
6493  {
6494 #ifndef NDEBUG
6495  int v2 = v + 1;
6496  int w2 = w;
6497 
6498  assert((nfixedconsvars == 0) ? (consdata->nvars - v - 1 == ninfcheckvars - w) : TRUE);
6499 
6500  for( ; v2 < consdata->nvars && w2 < ninfcheckvars; ++v2 )
6501  {
6502  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v2]), SCIPvarGetUbLocal(consdata->vars[v2])) )
6503  continue;
6504 
6505  assert(consdata->vars[v2] == infcheckvars[w2]);
6506  ++w2;
6507  }
6508  assert(w2 == ninfcheckvars);
6509 #endif
6510 
6511  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6512  foundvar = TRUE;
6513 
6514  if( consdata->vals[v] < 0 )
6515  {
6516  newlb = SCIPfloor(scip, (rhs - minvalue) / consdata->vals[v]);
6517  newub = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6518  }
6519  else
6520  {
6521  newlb = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6522  newub = SCIPceil(scip, (rhs - minvalue) / consdata->vals[v]);
6523  }
6524  assert(SCIPisLE(scip, newlb, newub));
6525 
6526  if( newlb > SCIPvarGetLbLocal(consdata->vars[v]) )
6527  {
6528  /* update lower bound of variable */
6529  SCIPdebugMsg(scip, "tightening lower bound of variable <%s> from %g to %g\n",
6530  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]), newlb);
6531 
6532  /* tighten variable lower bound to minimal possible value */
6533  SCIP_CALL( SCIPinferVarLbCons(scip, consdata->vars[v], newlb, cons,
6534  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6535 
6536  if( *cutoff )
6537  {
6538  /* start conflict analysis */
6539  /* @todo improve conflict analysis by adding relaxed bounds */
6540  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6541  consdata->vars[v], newlb) );
6542  }
6543 
6544  if( tightened )
6545  ++(*nchgbds);
6546  }
6547 
6548  if( newub < SCIPvarGetUbLocal(consdata->vars[v]) )
6549  {
6550  /* update upper bound of variable */
6551  SCIPdebugMsg(scip, "tightening upper bound of variable <%s> from %g to %g\n",
6552  SCIPvarGetName(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v]), newub);
6553 
6554  /* tighten variable upper bound to maximal possible value */
6555  SCIP_CALL( SCIPinferVarUbCons(scip, consdata->vars[v], newub, cons,
6556  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6557 
6558  if( *cutoff )
6559  {
6560  /* start conflict analysis */
6561  /* @todo improve conflict analysis by adding relaxed bounds */
6562  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6563  consdata->vars[v], newub) );
6564  }
6565 
6566  if( tightened )
6567  ++(*nchgbds);
6568  }
6569 
6570  break;
6571  }
6572 
6573  ++w;
6574  }
6575  }
6576 
6577  /* maybe last variable was the not infcheckvar */
6578  if( !foundvar )
6579  {
6580  assert(v == consdata->nvars - 1);
6581  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6582 
6583  if( consdata->vals[v] < 0 )
6584  {
6585  newlb = SCIPfloor(scip, (rhs - minvalue) / consdata->vals[v]);
6586  newub = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6587  }
6588  else
6589  {
6590  newlb = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6591  newub = SCIPceil(scip, (rhs - minvalue) / consdata->vals[v]);
6592  }
6593  assert(SCIPisLE(scip, newlb, newub));
6594 
6595  if( newlb > SCIPvarGetLbLocal(consdata->vars[v]) )
6596  {
6597  /* update lower bound of variable */
6598  SCIPdebugMsg(scip, "tightening lower bound of variable <%s> from %g to %g\n",
6599  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]), newlb);
6600 
6601  /* tighten variable lower bound to minimal possible value */
6602  SCIP_CALL( SCIPinferVarLbCons(scip, consdata->vars[v], newlb, cons,
6603  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6604 
6605  if( *cutoff )
6606  {
6607  /* start conflict analysis */
6608  /* @todo improve conflict analysis by adding relaxed bounds */
6609  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, consdata->vars[v], newlb) );
6610  }
6611 
6612  if( tightened )
6613  ++(*nchgbds);
6614  }
6615 
6616  if( newub < SCIPvarGetUbLocal(consdata->vars[v]) )
6617  {
6618  /* update upper bound of variable */
6619  SCIPdebugMsg(scip, "tightening upper bound of variable <%s> from %g to %g\n",
6620  SCIPvarGetName(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v]), newub);
6621 
6622  /* tighten variable upper bound to maximal possible value */
6623  SCIP_CALL( SCIPinferVarUbCons(scip, consdata->vars[v], newub, cons,
6624  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6625 
6626  if( *cutoff )
6627  {
6628  /* start conflict analysis */
6629  /* @todo improve conflict analysis by adding relaxed bounds */
6630  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, consdata->vars[v], newub) );
6631  }
6632 
6633  if( tightened )
6634  ++(*nchgbds);
6635  }
6636  }
6637  }
6638  /* at least two solutions and more than one variable, so we add a new constraint which bounds the feasible
6639  * region for our infcheckvars, if possible
6640  */
6641  else if( addartconss && (SCIPisGT(scip, minvalue, minactinfvars) || SCIPisLT(scip, maxvalue, maxactinfvars)) )
6642  {
6643  SCIP_CONS* newcons;
6644  char name[SCIP_MAXSTRLEN];
6645  SCIP_Real newlhs;
6646  SCIP_Real newrhs;
6647 
6648  assert(maxvalue > minvalue);
6649 
6650  if( SCIPisGT(scip, minvalue, minactinfvars) )
6651  newlhs = minvalue;
6652  else
6653  newlhs = -SCIPinfinity(scip);
6654 
6655  if( SCIPisLT(scip, maxvalue, maxactinfvars) )
6656  newrhs = maxvalue;
6657  else
6658  newrhs = SCIPinfinity(scip);
6659 
6660  if( !SCIPisInfinity(scip, -newlhs) || !SCIPisInfinity(scip, newrhs) )
6661  {
6662  /* create, add, and release new artificial constraint */
6663  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons1_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6664  ++conshdlrdata->naddconss;
6665 
6666  SCIPdebugMsg(scip, "adding artificial constraint %s\n", name);
6667 
6668  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals, newlhs, newrhs,
6669  TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6670  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6671 
6672  SCIPdebugPrintCons(scip, newcons, NULL);
6673  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6674 
6675  ++(*naddconss);
6676  }
6677  /* @todo maybe add constraint for all variables which are not infcheckvars, lhs should be minvalue, rhs
6678  * should be maxvalue */
6679  }
6680  }
6681  }
6682  }
6683  else if( addartconss && ncontvars < ninfcheckvars )
6684  {
6685  SCIP_Real maxact = 0.0;
6686  SCIP_Real minact = 0.0;
6687  int w = 0;
6688 
6689  /* compute activities of non-infcheckvars */
6690  for( v = 0; v < consdata->nvars; ++v )
6691  {
6692  if( w < ninfcheckvars && consdata->vars[v] == infcheckvars[w] )
6693  {
6694  ++w;
6695  continue;
6696  }
6697 
6698  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6699  {
6700  if( SCIPvarIsBinary(consdata->vars[v]) )
6701  {
6702  if( consdata->vals[v] > 0.0 )
6703  maxact += consdata->vals[v];
6704  else
6705  minact += consdata->vals[v];
6706  }
6707  else
6708  {
6709  SCIP_Real tmpval;
6710 
6711  assert(SCIPvarIsIntegral(consdata->vars[v]));
6712 
6713  if( consdata->vals[v] > 0.0 )
6714  {
6715  tmpval = consdata->vals[v] * SCIPvarGetLbLocal(consdata->vars[v]);
6716 
6717  if( SCIPisHugeValue(scip, -tmpval) )
6718  break;
6719 
6720  minact += tmpval;
6721 
6722  tmpval = consdata->vals[v] * SCIPvarGetUbLocal(consdata->vars[v]);
6723 
6724  if( SCIPisHugeValue(scip, tmpval) )
6725  break;
6726 
6727  maxact += tmpval;
6728  }
6729  else
6730  {
6731  tmpval = consdata->vals[v] * SCIPvarGetUbLocal(consdata->vars[v]);
6732 
6733  if( SCIPisHugeValue(scip, -tmpval) )
6734  break;
6735 
6736  minact += tmpval;
6737 
6738  tmpval = consdata->vals[v] * SCIPvarGetLbLocal(consdata->vars[v]);
6739 
6740  if( SCIPisHugeValue(scip, tmpval) )
6741  break;
6742 
6743  maxact += tmpval;
6744  }
6745  }
6746  }
6747  }
6748  if( v == consdata->nvars && !SCIPisHugeValue(scip, -minact) && !SCIPisHugeValue(scip, maxact) )
6749  {
6750  SCIP_CONS* newcons;
6751  char name[SCIP_MAXSTRLEN];
6752  SCIP_Real newlhs;
6753  SCIP_Real newrhs;
6754 
6755  assert(maxact > minact);
6756  assert(w == ninfcheckvars);
6757 
6758  newlhs = lhs - maxact;
6759  newrhs = rhs - minact;
6760  assert(newlhs < newrhs);
6761 
6762  /* create, add, and release new artificial constraint */
6763  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons2_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6764  ++conshdlrdata->naddconss;
6765 
6766  SCIPdebugMsg(scip, "adding artificial constraint %s\n", name);
6767 
6768  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals, newlhs, newrhs,
6769  TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6770  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6771 
6772  SCIPdebugPrintCons(scip, newcons, NULL);
6773  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6774 
6775  ++(*naddconss);
6776  }
6777  }
6778 
6779  TERMINATE:
6780  SCIPfreeBufferArray(scip, &infcheckvals);
6781  SCIPfreeBufferArray(scip, &infcheckvars);
6782 
6783  return SCIP_OKAY;
6784 }
6785 
6786 /** tightens bounds of a single variable due to activity bounds */
6787 static
6789  SCIP* scip, /**< SCIP data structure */
6790  SCIP_CONS* cons, /**< linear constraint */
6791  int pos, /**< position of the variable in the vars array */
6792  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
6793  int* nchgbds, /**< pointer to count the total number of tightened bounds */
6794  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
6795  )
6796 {
6797  SCIP_CONSDATA* consdata;
6798  SCIP_VAR* var;
6799  SCIP_Real val;
6800  SCIP_Real lb;
6801  SCIP_Real ub;
6802  SCIP_Real minresactivity;
6803  SCIP_Real maxresactivity;
6804  SCIP_Real lhs;
6806  SCIP_Bool infeasible;
6807  SCIP_Bool tightened;
6808  SCIP_Bool minisrelax;
6809  SCIP_Bool maxisrelax;
6810  SCIP_Bool isminsettoinfinity;
6811  SCIP_Bool ismaxsettoinfinity;
6812 
6813  assert(scip != NULL);
6814  assert(cons != NULL);
6815  assert(cutoff != NULL);
6816  assert(nchgbds != NULL);
6817 
6818  /* we cannot tighten variables' bounds, if the constraint may be not complete */
6819  if( SCIPconsIsModifiable(cons) )
6820  return SCIP_OKAY;
6821 
6822  consdata = SCIPconsGetData(cons);
6823  assert(consdata != NULL);
6824  assert(0 <= pos && pos < consdata->nvars);
6825 
6826  *cutoff = FALSE;
6827 
6828  var = consdata->vars[pos];
6829 
6830  /* we cannot tighten bounds of multi-aggregated variables */
6832  return SCIP_OKAY;
6833 
6834  val = consdata->vals[pos];
6835  lhs = consdata->lhs;
6836  rhs = consdata->rhs;
6837  consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
6838  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
6839  assert(var != NULL);
6840  assert(!SCIPisZero(scip, val));
6841  assert(!SCIPisInfinity(scip, lhs));
6842  assert(!SCIPisInfinity(scip, -rhs));
6843 
6844  lb = SCIPvarGetLbLocal(var);
6845  ub = SCIPvarGetUbLocal(var);
6846  assert(SCIPisLE(scip, lb, ub));
6847 
6848  if( val > 0.0 )
6849  {
6850  /* check, if we can tighten the variable's bounds */
6851  if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && !minisrelax )
6852  {
6853  SCIP_Real newub;
6854 
6855  newub = (rhs - minresactivity)/val;
6856 
6857  if( !SCIPisInfinity(scip, newub) &&
6858  ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
6859  {
6860  SCIP_Bool activityunreliable;
6861  activityunreliable = SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity);
6862 
6863  /* check minresactivities for reliability */
6864  if( activityunreliable )
6865  {
6866  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
6867  newub = (rhs - minresactivity)/val;
6868  activityunreliable = SCIPisInfinity(scip, -minresactivity) ||
6869  (!SCIPisUbBetter(scip, newub, lb, ub) && (!SCIPisFeasLT(scip, newub, ub) || !SCIPvarIsIntegral(var))
6870  && (!force || !SCIPisLT(scip, newub, ub)));
6871  }
6872 
6873  if( !activityunreliable )
6874  {
6875  /* tighten upper bound */
6876  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newub=%.15g\n",
6877  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newub);
6878  SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_RHS, pos), force,
6879  &infeasible, &tightened) );
6880  if( infeasible )
6881  {
6882  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
6883  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
6884 
6885  /* analyze conflict */
6886  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
6887 
6888  *cutoff = TRUE;
6889  return SCIP_OKAY;
6890  }
6891  if( tightened )
6892  {
6893  ub = SCIPvarGetUbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6894  assert(SCIPisFeasLE(scip, ub, newub));
6895  (*nchgbds)++;
6896 
6897  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6898  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6899  }
6900  }
6901  }
6902  }
6903 
6904  if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && !maxisrelax )
6905  {
6906  SCIP_Real newlb;
6907 
6908  newlb = (lhs - maxresactivity)/val;
6909  if( !SCIPisInfinity(scip, -newlb) &&
6910  ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
6911  {
6912  /* check maxresactivities for reliability */
6913  if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
6914  {
6915  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
6916  newlb = (lhs - maxresactivity)/val;
6917 
6918  if( SCIPisInfinity(scip, maxresactivity) || (!SCIPisLbBetter(scip, newlb, lb, ub)
6919  && (!SCIPisFeasGT(scip, newlb, lb) || !SCIPvarIsIntegral(var))
6920  && (!force || !SCIPisGT(scip, newlb, lb))) )
6921  return SCIP_OKAY;
6922  }
6923 
6924  /* tighten lower bound */
6925  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
6926  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newlb);
6927  SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_LHS, pos), force,
6928  &infeasible, &tightened) );
6929  if( infeasible )
6930  {
6931  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
6932  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
6933 
6934  /* analyze conflict */
6935  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
6936 
6937  *cutoff = TRUE;
6938  return SCIP_OKAY;
6939  }
6940  if( tightened )
6941  {
6942  lb = SCIPvarGetLbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6943  assert(SCIPisFeasGE(scip, lb, newlb));
6944  (*nchgbds)++;
6945  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6946  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6947  }
6948  }
6949  }
6950  }
6951  else
6952  {
6953  /* check, if we can tighten the variable's bounds */
6954  if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && !minisrelax )
6955  {
6956  SCIP_Real newlb;
6957 
6958  newlb = (rhs - minresactivity)/val;
6959  if( !SCIPisInfinity(scip, -newlb) &&
6960  ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
6961  {
6962  SCIP_Bool activityunreliable;
6963  activityunreliable = SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity);
6964  /* check minresactivities for reliability */
6965  if( activityunreliable )
6966  {
6967  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
6968  newlb = (rhs - minresactivity)/val;
6969 
6970  activityunreliable = SCIPisInfinity(scip, -minresactivity)
6971  || (!SCIPisLbBetter(scip, newlb, lb, ub) && (!SCIPisFeasGT(scip, newlb, lb) || !SCIPvarIsIntegral(var))
6972  && (!force || !SCIPisGT(scip, newlb, lb)));
6973  }
6974 
6975  if( !activityunreliable )
6976  {
6977  /* tighten lower bound */
6978  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
6979  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newlb);
6980  SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_RHS, pos), force,
6981  &infeasible, &tightened) );
6982  if( infeasible )
6983  {
6984  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
6985  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
6986 
6987  /* analyze conflict */
6988  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
6989 
6990  *cutoff = TRUE;
6991  return SCIP_OKAY;
6992  }
6993  if( tightened )
6994  {
6995  lb = SCIPvarGetLbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6996  assert(SCIPisFeasGE(scip, lb, newlb));
6997  (*nchgbds)++;
6998  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6999  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
7000  }
7001  }
7002  }
7003  }
7004 
7005  if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && !maxisrelax )
7006  {
7007  SCIP_Real newub;
7008 
7009  newub = (lhs - maxresactivity)/val;
7010  if( !SCIPisInfinity(scip, newub) &&
7011  ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
7012  {
7013  /* check maxresactivities for reliability */
7014  if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
7015  {
7016  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
7017  newub = (lhs - maxresactivity)/val;
7018 
7019  if( SCIPisInfinity(scip, maxresactivity) || (!SCIPisUbBetter(scip, newub, lb, ub)
7020  && (!SCIPisFeasLT(scip, newub, ub) && !SCIPvarIsIntegral(var))
7021  && (!force || !SCIPisLT(scip, newub, ub))) )
7022  return SCIP_OKAY;
7023  }
7024 
7025  /* tighten upper bound */
7026  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g], newub=%.15g\n",
7027  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newub);
7028  SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_LHS, pos), force,
7029  &infeasible, &tightened) );
7030  if( infeasible )
7031  {
7032  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
7033  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
7034 
7035  /* analyze conflict */
7036  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
7037 
7038  *cutoff = TRUE;
7039  return SCIP_OKAY;
7040  }
7041  if( tightened )
7042  {
7043  ub = SCIPvarGetUbLocal(var); /* get bound again: it may be additionally modified due to integrality */
7044  assert(SCIPisFeasLE(scip, ub, newub));
7045  (*nchgbds)++;
7046  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
7047  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
7048  }
7049  }
7050  }
7051  }
7052 
7053  return SCIP_OKAY;
7054 }
7055 
7056 #define MAXTIGHTENROUNDS 10
7057 
7058 /** tightens bounds of variables in constraint due to activity bounds */
7059 static
7061  SCIP* scip, /**< SCIP data structure */
7062  SCIP_CONS* cons, /**< linear constraint */
7063  SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
7064  SCIP_Bool sortvars, /**< should variables be used in sorted order? */
7065  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
7066  int* nchgbds /**< pointer to count the total number of tightened bounds */
7067  )
7068 {
7069  SCIP_CONSDATA* consdata;
7070  unsigned int tightenmode;
7071  int nvars;
7072  int nrounds;
7073  int lastchange;
7074  int oldnchgbds;
7075 #ifndef SCIP_DEBUG
7076  int oldnchgbdstotal;
7077 #endif
7078  int v;
7079  SCIP_Bool force;
7080  SCIP_Bool easycase;
7081 
7082  assert(scip != NULL);
7083  assert(cons != NULL);
7084  assert(nchgbds != NULL);
7085  assert(cutoff != NULL);
7086 
7087  *cutoff = FALSE;
7088 
7089  /* we cannot tighten variables' bounds, if the constraint may be not complete */
7090  if( SCIPconsIsModifiable(cons) )
7091  return SCIP_OKAY;
7092 
7093  /* if a constraint was created after presolve, then it may hold fixed variables
7094  * if there are even multi-aggregated variables, then we cannot do bound tightening on these
7095  * thus, ensure here again that variable fixings have been applied
7096  */
7097  SCIP_CALL( applyFixings(scip, cons, cutoff) );
7098  if( *cutoff )
7099  return SCIP_OKAY;
7100 
7101  /* check if constraint has any chances of tightening bounds */
7102  if( !canTightenBounds(cons) )
7103  return SCIP_OKAY;
7104 
7105  consdata = SCIPconsGetData(cons);
7106  assert(consdata != NULL);
7107 
7108  nvars = consdata->nvars;
7109  force = (nvars == 1) && !SCIPconsIsModifiable(cons);
7110 
7111  /* we are at the root node or during presolving */
7112  if( SCIPgetDepth(scip) < 1 )
7113  tightenmode = 2;
7114  else
7115  tightenmode = 1;
7116 
7117  /* stop if we already tightened the constraint and the tightening is not forced */
7118  if( !force && (consdata->boundstightened >= tightenmode) ) /*lint !e574*/
7119  return SCIP_OKAY;
7120 
7121  /* ensure that the variables are properly sorted */
7122  if( sortvars && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE && !consdata->coefsorted )
7123  {
7124  SCIP_CALL( consdataSort(scip, consdata) );
7125  assert(consdata->coefsorted);
7126  }
7127 
7128  /* update maximal activity delta if necessary */
7129  if( consdata->maxactdelta == SCIP_INVALID ) /*lint !e777*/
7130  consdataRecomputeMaxActivityDelta(scip, consdata);
7131 
7132  assert(consdata->maxactdelta != SCIP_INVALID); /*lint !e777*/
7133  assert(!SCIPisFeasNegative(scip, consdata->maxactdelta));
7134  checkMaxActivityDelta(scip, consdata);
7135 
7136  /* this may happen if all variables are fixed */
7137  if( SCIPisFeasZero(scip, consdata->maxactdelta) )
7138  return SCIP_OKAY;
7139 
7140  if( !SCIPisInfinity(scip, consdata->maxactdelta) )
7141  {
7142  SCIP_Real slack;
7143  SCIP_Real surplus;
7144  SCIP_Real minactivity;
7145  SCIP_Real maxactivity;
7146  SCIP_Bool minisrelax;
7147  SCIP_Bool maxisrelax;
7148  SCIP_Bool isminsettoinfinity;
7149  SCIP_Bool ismaxsettoinfinity;
7150 
7151  /* use maximal activity delta to skip propagation (cannot deduce anything) */
7152  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minisrelax, &maxisrelax,
7153  &isminsettoinfinity, &ismaxsettoinfinity);
7154  assert(!SCIPisInfinity(scip, minactivity));
7155  assert(!SCIPisInfinity(scip, -maxactivity));
7156 
7157  slack = (SCIPisInfinity(scip, consdata->rhs) || isminsettoinfinity) ? SCIPinfinity(scip) : (consdata->rhs - minactivity);
7158  surplus = (SCIPisInfinity(scip, -consdata->lhs) || ismaxsettoinfinity) ? SCIPinfinity(scip) : (maxactivity - consdata->lhs);
7159 
7160  /* check if the constraint will propagate */
7161  if( SCIPisLE(scip, consdata->maxactdelta, MIN(slack, surplus)) )
7162  return SCIP_OKAY;
7163  }
7164 
7165  /* check if we can use fast implementation for easy and numerically well behaved cases */
7166  easycase = SCIPisLT(scip, consdata->maxactdelta, maxeasyactivitydelta);
7167 
7168  /* as long as the bounds might be tightened again, try to tighten them; abort after a maximal number of rounds */
7169  lastchange = -1;
7170  oldnchgbds = 0;
7171 
7172 #ifndef SCIP_DEBUG
7173  oldnchgbdstotal = *nchgbds;
7174 #endif
7175 
7176  for( nrounds = 0; (force || consdata->boundstightened < tightenmode) && nrounds < MAXTIGHTENROUNDS; ++nrounds ) /*lint !e574*/
7177  {
7178  /* ensure that the variables are properly sorted
7179  *
7180  * note: it might happen that integer variables become binary during bound tightening at the root node
7181  */
7182  if( sortvars && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE && !consdata->coefsorted )
7183  {
7184  SCIP_CALL( consdataSort(scip, consdata) );
7185  assert(consdata->coefsorted);
7186  }
7187 
7188  /* mark the constraint to have the variables' bounds tightened */
7189  consdata->boundstightened = (unsigned int)tightenmode;
7190 
7191  /* try to tighten the bounds of each variable in the constraint. During solving process, the binary variable
7192  * sorting enables skipping variables
7193  */
7194  v = 0;
7195  while( v < nvars && v != lastchange && !(*cutoff) )
7196  {
7197  oldnchgbds = *nchgbds;
7198 
7199  if( easycase )
7200  {
7201  SCIP_CALL( tightenVarBoundsEasy(scip, cons, v, cutoff, nchgbds, force) );
7202  }
7203  else
7204  {
7205  SCIP_CALL( tightenVarBounds(scip, cons, v, cutoff, nchgbds, force) );
7206  }
7207 
7208  /* if there was no progress, skip the rest of the binary variables */
7209  if( *nchgbds > oldnchgbds )
7210  {
7211  lastchange = v;
7212  ++v;
7213  }
7214  else if( consdata->coefsorted && v < consdata->nbinvars - 1
7215  && !SCIPisFeasEQ(scip, SCIPvarGetUbLocal(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v])) )
7216  v = consdata->nbinvars;
7217  else
7218  ++v;
7219  }
7220 
7221 #ifndef SCIP_DEBUG
7222  SCIPdebugMessage("linear constraint <%s> found %d bound changes in round %d\n", SCIPconsGetName(cons),
7223  *nchgbds - oldnchgbdstotal, nrounds);
7224  oldnchgbdstotal += oldnchgbds;
7225 #endif
7226  }
7227 
7228 #ifndef NDEBUG
7229  if( force && SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
7230  assert(*cutoff || SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->vars[0]), SCIPvarGetUbLocal(consdata->vars[0])));
7231 #endif
7232 
7233  return SCIP_OKAY;
7234 }
7235 
7236 /** checks linear constraint for feasibility of given solution or current solution */
7237 static
7239  SCIP* scip, /**< SCIP data structure */
7240  SCIP_CONS* cons, /**< linear constraint */
7241  SCIP_SOL* sol, /**< solution to be checked, or NULL for current solution */
7242  SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
7243  SCIP_Bool checkrelmaxabs, /**< Should the violation for a constraint with side 0.0 be checked relative
7244  * to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
7245  SCIP_Bool* violated /**< pointer to store whether the constraint is violated */
7246  )
7247 {
7248  SCIP_CONSDATA* consdata;
7249  SCIP_Real activity;
7250  SCIP_Real absviol;
7251  SCIP_Real relviol;
7252  SCIP_Real lhsviol;
7253  SCIP_Real rhsviol;
7254 
7255  assert(scip != NULL);
7256  assert(cons != NULL);
7257  assert(violated != NULL);
7258 
7259  SCIPdebugMsg(scip, "checking linear constraint <%s>\n", SCIPconsGetName(cons));
7260  SCIPdebugPrintCons(scip, cons, NULL);
7261 
7262  consdata = SCIPconsGetData(cons);
7263  assert(consdata != NULL);
7264 
7265  *violated = FALSE;
7266 
7267  if( consdata->row != NULL )
7268  {
7269  if( !checklprows && SCIProwIsInLP(consdata->row) )
7270  return SCIP_OKAY;
7271  else if( sol == NULL && !SCIPhasCurrentNodeLP(scip) )
7272  activity = consdataComputePseudoActivity(scip, consdata);
7273  else
7274  activity = SCIPgetRowSolActivity(scip, consdata->row, sol);
7275  }
7276  else
7277  activity = consdataGetActivity(scip, consdata, sol);
7278 
7279  SCIPdebugMsg(scip, " consdata activity=%.15g (lhs=%.15g, rhs=%.15g, row=%p, checklprows=%u, rowinlp=%u, sol=%p, hascurrentnodelp=%u)\n",
7280  activity, consdata->lhs, consdata->rhs, (void*)consdata->row, checklprows,
7281  consdata->row == NULL ? 0 : SCIProwIsInLP(consdata->row), (void*)sol,
7282  consdata->row == NULL ? FALSE : SCIPhasCurrentNodeLP(scip));
7283 
7284  /* calculate absolute and relative bound violations */
7285  lhsviol = consdata->lhs - activity;
7286  rhsviol = activity - consdata->rhs;
7287 
7288  absviol = 0.0;
7289  relviol = 0.0;
7290  if( (lhsviol > 0) && (lhsviol > rhsviol) )
7291  {
7292  absviol = lhsviol;
7293  relviol = SCIPrelDiff(consdata->lhs, activity);
7294  }
7295  else if( rhsviol > 0 )
7296  {
7297  absviol = rhsviol;
7298  relviol = SCIPrelDiff(activity, consdata->rhs);
7299  }
7300 
7301  /* the activity of pseudo solutions may be invalid if it comprises positive and negative infinity contributions; we
7302  * return infeasible for safety
7303  */
7304  if( activity == SCIP_INVALID ) /*lint !e777*/
7305  {
7306  assert(sol == NULL);
7307  *violated = TRUE;
7308 
7309  /* set violation of invalid pseudo solutions */
7310  absviol = SCIP_INVALID;
7311  relviol = SCIP_INVALID;
7312 
7313  /* reset constraint age since we are in enforcement */
7314  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7315  }
7316  /* check with relative tolerances (the default) */
7317  else if( !consdata->checkabsolute && (SCIPisFeasLT(scip, activity, consdata->lhs) || SCIPisFeasGT(scip, activity, consdata->rhs)) )
7318  {
7319  /* the "normal" check: one of the two sides is violated */
7320  if( !checkrelmaxabs )
7321  {
7322  *violated = TRUE;
7323 
7324  /* only reset constraint age if we are in enforcement */
7325  if( sol == NULL )
7326  {
7327  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7328  }
7329  }
7330  /* the (much) more complicated check: we try to disregard random noise and violations of a 0.0 side which are
7331  * small compared to the absolute values occurring in the activity
7332  */
7333  else
7334  {
7335  SCIP_Real maxabs;
7336  SCIP_Real coef;
7337  SCIP_Real absval;
7338  SCIP_Real solval;
7339  int v;
7340 
7341  maxabs = 1.0;
7342 
7343  /* compute maximum absolute value */
7344  for( v = 0; v < consdata->nvars; ++v )
7345  {
7346  if( consdata->vals != NULL )
7347  {
7348  coef = consdata->vals[v];
7349  }
7350  else
7351  coef = 1.0;
7352 
7353  solval = SCIPgetSolVal(scip, sol, consdata->vars[v]);
7354  absval = REALABS( coef * solval );
7355  maxabs = MAX( maxabs, absval );
7356  }
7357 
7358  /* regard left hand side, first */
7359  if( SCIPisFeasLT(scip, activity, consdata->lhs) )
7360  {
7361  /* check whether violation is random noise */
7362  if( (consdata->lhs - activity) <= (1e-15 * maxabs) )
7363  {
7364  SCIPdebugMsg(scip, " lhs violated due to random noise: violation=%16.9g, maxabs=%16.9g\n",
7365  consdata->lhs - activity, maxabs);
7366  SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
7367 
7368  /* only increase constraint age if we are in enforcement */
7369  if( sol == NULL )
7370  {
7371  SCIP_CALL( SCIPincConsAge(scip, cons) );
7372  }
7373  }
7374  /* lhs is violated and lhs is 0.0: use relative tolerance w.r.t. largest absolute value */
7375  else if( SCIPisZero(scip, consdata->lhs) )
7376  {
7377  if( (consdata->lhs - activity) <= (SCIPfeastol(scip) * maxabs) )
7378  {
7379  SCIPdebugMsg(scip, " lhs violated absolutely (violation=%16.9g), but feasible when using relative tolerance w.r.t. maximum absolute value (%16.9g)\n",
7380  consdata->lhs - activity, maxabs);
7381  SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
7382 
7383  /* only increase constraint age if we are in enforcement */
7384  if( sol == NULL )
7385  {
7386  SCIP_CALL( SCIPincConsAge(scip, cons) );
7387  }
7388  }
7389  else
7390  {
7391  *violated = TRUE;
7392 
7393  /* only reset constraint age if we are in enforcement */
7394  if( sol == NULL )
7395  {
7396  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7397  }
7398  }
7399  }
7400  else
7401  {
7402  *violated = TRUE;
7403 
7404  /* only reset constraint age if we are in enforcement */
7405  if( sol == NULL )
7406  {
7407  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7408  }
7409  }
7410  }
7411 
7412  /* now regard right hand side */
7413  if( SCIPisFeasGT(scip, activity, consdata->rhs) )
7414  {
7415  /* check whether violation is random noise */
7416  if( (activity - consdata->rhs) <= (1e-15 * maxabs) )
7417  {
7418  SCIPdebugMsg(scip, " rhs violated due to random noise: violation=%16.9g, maxabs=%16.9g\n",
7419  activity - consdata->rhs, maxabs);
7420  SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
7421 
7422  /* only increase constraint age if we are in enforcement */
7423  if( sol == NULL )
7424  {
7425  SCIP_CALL( SCIPincConsAge(scip, cons) );
7426  }
7427  }
7428  /* rhs is violated and rhs is 0.0, use relative tolerance w.r.t. largest absolute value */
7429  else if( SCIPisZero(scip, consdata->rhs) )
7430  {
7431  if( (activity - consdata->rhs) <= (SCIPfeastol(scip) * maxabs) )
7432  {
7433  SCIPdebugMsg(scip, " rhs violated absolutely (violation=%16.9g), but feasible when using relative tolerance w.r.t. maximum absolute value (%16.9g)\n",
7434  activity - consdata->rhs, maxabs);
7435  SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
7436 
7437  /* only increase constraint age if we are in enforcement */
7438  if( sol == NULL )
7439  {
7440  SCIP_CALL( SCIPincConsAge(scip, cons) );
7441  }
7442  }
7443  else
7444  {
7445  *violated = TRUE;
7446 
7447  /* only reset constraint age if we are in enforcement */
7448  if( sol == NULL )
7449  {
7450  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7451  }
7452  }
7453  }
7454  else
7455  {
7456  *violated = TRUE;
7457 
7458  /* only reset constraint age if we are in enforcement */
7459  if( sol == NULL )
7460  {
7461  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7462  }
7463  }
7464  }
7465  }
7466  }
7467  /* check with absolute tolerances */
7468  else if( consdata->checkabsolute &&
7469  ((!SCIPisInfinity(scip, -consdata->lhs) && SCIPisGT(scip, consdata->lhs-activity, SCIPfeastol(scip))) ||
7470  (!SCIPisInfinity(scip, consdata->rhs) && SCIPisGT(scip, activity-consdata->rhs, SCIPfeastol(scip)))) )
7471  {
7472  *violated = TRUE;
7473 
7474  /* only reset constraint age if we are in enforcement */
7475  if( sol == NULL )
7476  {
7477  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7478  }
7479  }
7480  else
7481  {
7482  /* only increase constraint age if we are in enforcement */
7483  if( sol == NULL )
7484  {
7485  SCIP_CALL( SCIPincConsAge(scip, cons) );
7486  }
7487  }
7488 
7489  /* update absolute and relative violation of the solution */
7490  if( sol != NULL )
7491  SCIPupdateSolLPConsViolation(scip, sol, absviol, relviol);
7492 
7493  return SCIP_OKAY;
7494 }
7495 
7496 /** creates an LP row in a linear constraint data */
7497 static
7499  SCIP* scip, /**< SCIP data structure */
7500  SCIP_CONS* cons /**< linear constraint */
7501  )
7502 {
7503  SCIP_CONSDATA* consdata;
7504 
7505  assert(scip != NULL);
7506  assert(cons != NULL);
7507 
7508  consdata = SCIPconsGetData(cons);
7509  assert(consdata != NULL);
7510  assert(consdata->row == NULL);
7511 
7512  SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row, cons, SCIPconsGetName(cons), consdata->lhs, consdata->rhs,
7514 
7515  SCIP_CALL( SCIPaddVarsToRow(scip, consdata->row, consdata->nvars, consdata->vars, consdata->vals) );
7516 
7517  return SCIP_OKAY;
7518 }
7519 
7520 /** adds linear constraint as cut to the LP */
7521 static
7523  SCIP* scip, /**< SCIP data structure */
7524  SCIP_CONS* cons, /**< linear constraint */
7525  SCIP_Bool* cutoff /**< pointer to store whether a cutoff was found */
7526  )
7527 {
7528  SCIP_CONSDATA* consdata;
7529 
7530  assert(scip != NULL);
7531  assert(cons != NULL);
7532 
7533  consdata = SCIPconsGetData(cons);
7534  assert(consdata != NULL);
7535 
7536  if( consdata->row == NULL )
7537  {
7538  if( !SCIPconsIsModifiable(cons) )
7539  {
7540  /* 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
7541  * removing this here will make test cons/linear/fixedvar.c fail (as of 2018-12-03)
7542  */
7543  SCIP_CALL( applyFixings(scip, cons, cutoff) );
7544  if( *cutoff )
7545  return SCIP_OKAY;
7546  }
7547 
7548  /* convert consdata object into LP row */
7549  SCIP_CALL( createRow(scip, cons) );
7550  }
7551  assert(consdata->row != NULL);
7552 
7553  if( consdata->nvars == 0 )
7554  {
7555  SCIPdebugMsg(scip, "Empty linear constraint enters LP: <%s>\n", SCIPconsGetName(cons));
7556  }
7557 
7558  /* insert LP row as cut */
7559  if( !SCIProwIsInLP(consdata->row) )
7560  {
7561  SCIPdebugMsg(scip, "adding relaxation of linear constraint <%s>: ", SCIPconsGetName(cons));
7562  SCIPdebug( SCIP_CALL( SCIPprintRow(scip, consdata->row, NULL)) );
7563  /* if presolving is turned off, the row might be trivial */
7564  if ( ! SCIPisInfinity(scip, -consdata->lhs) || ! SCIPisInfinity(scip, consdata->rhs) )
7565  {
7566  SCIP_CALL( SCIPaddRow(scip, consdata->row, FALSE, cutoff) );
7567  }
7568 #ifndef NDEBUG
7569  else
7570  {
7571  int pr;
7572  int cr;
7573  SCIP_CALL( SCIPgetIntParam(scip, "presolving/maxrounds", &pr) );
7574  SCIP_CALL( SCIPgetIntParam(scip, "constraints/linear/maxprerounds", &cr) );
7575  assert( pr == 0 || cr == 0 );
7576  }
7577 #endif
7578  }
7579 
7580  return SCIP_OKAY;
7581 }
7582 
7583 /** separates linear constraint: adds linear constraint as cut, if violated by given solution */
7584 static
7586  SCIP* scip, /**< SCIP data structure */
7587  SCIP_CONS* cons, /**< linear constraint */
7588  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
7589  SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
7590  SCIP_Bool separatecards, /**< should knapsack cardinality cuts be generated? */
7591  SCIP_Bool separateall, /**< should all constraints be subject to cardinality cut generation instead of only
7592  * the ones with non-zero dual value? */
7593  int* ncuts, /**< pointer to add up the number of found cuts */
7594  SCIP_Bool* cutoff /**< pointer to store whether a cutoff was found */
7595  )
7596 {
7597  SCIP_CONSDATA* consdata;
7598  SCIP_Bool violated;
7599  int oldncuts;
7600 
7601  assert(scip != NULL);
7602  assert(conshdlrdata != NULL);
7603  assert(cons != NULL);
7604  assert(cutoff != NULL);
7605 
7606  consdata = SCIPconsGetData(cons);
7607  assert(ncuts != NULL);
7608  assert(consdata != NULL);
7609 
7610  oldncuts = *ncuts;
7611  *cutoff = FALSE;
7612 
7613  SCIP_CALL( checkCons(scip, cons, sol, (sol != NULL), conshdlrdata->checkrelmaxabs, &violated) );
7614 
7615  if( violated )
7616  {
7617  /* insert LP row as cut */
7618  SCIP_CALL( addRelaxation(scip, cons, cutoff) );
7619  (*ncuts)++;
7620  }
7621  else if( !SCIPconsIsModifiable(cons) && separatecards )
7622  {
7623  /* relax linear constraint into knapsack constraint and separate lifted cardinality cuts */
7624  if( !separateall && sol == NULL )
7625  {
7626  /* we only want to call the knapsack cardinality cut separator for rows that have a non-zero dual solution */
7627  if( consdata->row != NULL && SCIProwIsInLP(consdata->row) )
7628  {
7629  SCIP_Real dualsol;
7630 
7631  dualsol = SCIProwGetDualsol(consdata->row);
7632  if( SCIPisFeasNegative(scip, dualsol) )
7633  {
7634  if( !SCIPisInfinity(scip, consdata->rhs) )
7635  {
7636  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7637  consdata->vals, +1.0, consdata->rhs, sol, cutoff, ncuts) );
7638  }
7639  }
7640  else if( SCIPisFeasPositive(scip, dualsol) )
7641  {
7642  if( !SCIPisInfinity(scip, -consdata->lhs) )
7643  {
7644  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7645  consdata->vals, -1.0, -consdata->lhs, sol, cutoff, ncuts) );
7646  }
7647  }
7648  }
7649  }
7650  else
7651  {
7652  if( !SCIPisInfinity(scip, consdata->rhs) )
7653  {
7654  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7655  consdata->vals, +1.0, consdata->rhs, sol, cutoff, ncuts) );
7656  }
7657  if( !SCIPisInfinity(scip, -consdata->lhs) )
7658  {
7659  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7660  consdata->vals, -1.0, -consdata->lhs, sol, cutoff, ncuts) );
7661  }
7662  }
7663  }
7664 
7665  if( *ncuts > oldncuts )
7666  {
7667  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7668  }
7669 
7670  return SCIP_OKAY;
7671 }
7672 
7673 /** propagation method for linear constraints */
7674 static
7676  SCIP* scip, /**< SCIP data structure */
7677  SCIP_CONS* cons, /**< linear constraint */
7678  SCIP_Bool tightenbounds, /**< should the variable's bounds be tightened? */
7679  SCIP_Bool rangedrowpropagation,/**< should ranged row propagation be performed? */
7680  SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
7681  SCIP_Bool sortvars, /**< should variable sorting for faster propagation be used? */
7682  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
7683  int* nchgbds /**< pointer to count the total number of tightened bounds */
7684  )
7685 {
7686  SCIP_CONSDATA* consdata;
7687  SCIP_Real minactivity;
7688  SCIP_Real maxactivity;
7689  SCIP_Bool minactisrelax;
7690  SCIP_Bool maxactisrelax;
7691  SCIP_Bool isminsettoinfinity;
7692  SCIP_Bool ismaxsettoinfinity;
7693 
7694  assert(scip != NULL);
7695  assert(cons != NULL);
7696  assert(cutoff != NULL);
7697  assert(nchgbds != NULL);
7698 
7699  /*SCIPdebugMsg(scip, "propagating linear constraint <%s>\n", SCIPconsGetName(cons));*/
7700 
7701  consdata = SCIPconsGetData(cons);
7702  assert(consdata != NULL);
7703 
7704  if( consdata->eventdata == NULL )
7705  {
7706  SCIP_CONSHDLR* conshdlr;
7707  SCIP_CONSHDLRDATA* conshdlrdata;
7708 
7709  conshdlr = SCIPconsGetHdlr(cons);
7710  assert(conshdlr != NULL);
7711 
7712  conshdlrdata = SCIPconshdlrGetData(conshdlr);
7713  assert(conshdlrdata != NULL);
7714 
7715  /* catch bound change events of variables */
7716  SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
7717  assert(consdata->eventdata != NULL);
7718  }
7719 
7720  *cutoff = FALSE;
7721 
7722  /* we can only infer activity bounds of the linear constraint, if it is not modifiable */
7723  if( !SCIPconsIsModifiable(cons) )
7724  {
7725  /* increase age of constraint; age is reset to zero, if a conflict or a propagation was found */
7726  if( !SCIPinRepropagation(scip) )
7727  {
7728  SCIP_CALL( SCIPincConsAge(scip, cons) );
7729  }
7730 
7731  /* tighten the variable's bounds */
7732  if( tightenbounds )
7733  {
7734  int oldnchgbds;
7735 
7736  oldnchgbds = *nchgbds;
7737 
7738  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
7739 
7740  if( *nchgbds > oldnchgbds )
7741  {
7742  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7743  }
7744  }
7745 
7746  /* propagate ranged rows */
7747  if( rangedrowpropagation && tightenbounds && !(*cutoff) )
7748  {
7749  int nfixedvars;
7750  int naddconss;
7751  SCIPdebug( int oldnchgbds = *nchgbds; )
7752 
7753  nfixedvars = 0;
7754  naddconss = 0;
7755 
7756  SCIP_CALL( rangedRowPropagation(scip, cons, cutoff, &nfixedvars, nchgbds, &naddconss) );
7757 
7758  if( *cutoff )
7759  {
7760  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible\n", SCIPconsGetName(cons));
7761  }
7762  else
7763  {
7764  SCIPdebug( SCIPdebugMsg(scip, "linear constraint <%s> found %d bound changes and %d fixings\n", SCIPconsGetName(cons), *nchgbds - oldnchgbds, nfixedvars); )
7765  }
7766 
7767  if( nfixedvars > 0 )
7768  *nchgbds += 2*nfixedvars;
7769  } /*lint !e438*/
7770 
7771  /* check constraint for infeasibility and redundancy */
7772  if( !(*cutoff) )
7773  {
7774  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
7775  &isminsettoinfinity, &ismaxsettoinfinity);
7776 
7777  if( SCIPisFeasGT(scip, minactivity, consdata->rhs) )
7778  {
7779  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible (rhs): activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7780  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7781 
7782  /* analyze conflict */
7783  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
7784 
7785  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7786  *cutoff = TRUE;
7787  }
7788  else if( SCIPisFeasLT(scip, maxactivity, consdata->lhs) )
7789  {
7790  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible (lhs): activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7791  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7792 
7793  /* analyze conflict */
7794  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
7795 
7796  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7797  *cutoff = TRUE;
7798  }
7799  else if( SCIPisGE(scip, minactivity, consdata->lhs) && SCIPisLE(scip, maxactivity, consdata->rhs) )
7800  {
7801  SCIPdebugMsg(scip, "linear constraint <%s> is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7802  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7803 
7804  /* remove the constraint locally unless it has become empty, in which case it is removed globally */
7805  if( consdata->nvars > 0 )
7806  SCIP_CALL( SCIPdelConsLocal(scip, cons) );
7807  else
7808  SCIP_CALL( SCIPdelCons(scip, cons) );
7809  }
7810  }
7811  }
7812 
7813  return SCIP_OKAY;
7814 }
7815 
7816 
7817 /*
7818  * Presolving methods
7819  */
7820 
7821 /** converts all variables with fixed domain into FIXED variables */
7822 static
7824  SCIP* scip, /**< SCIP data structure */
7825  SCIP_CONS* cons, /**< linear constraint */
7826  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
7827  int* nfixedvars /**< pointer to count the total number of fixed variables */
7828  )
7829 {
7830  SCIP_CONSDATA* consdata;
7831  SCIP_VAR* var;
7832  SCIP_VARSTATUS varstatus;
7833  SCIP_Real lb;
7834  SCIP_Real ub;
7835  SCIP_Bool fixed;
7836  SCIP_Bool infeasible;
7837  int v;
7838 
7839  assert(scip != NULL);
7840  assert(cons != NULL);
7841  assert(cutoff != NULL);
7842  assert(nfixedvars != NULL);
7843 
7844  consdata = SCIPconsGetData(cons);
7845  assert(consdata != NULL);
7846 
7847  for( v = 0; v < consdata->nvars; ++v )
7848  {
7849  assert(consdata->vars != NULL);
7850  var = consdata->vars[v];
7851  varstatus = SCIPvarGetStatus(var);
7852 
7853  if( varstatus != SCIP_VARSTATUS_FIXED )
7854  {
7855  lb = SCIPvarGetLbGlobal(var);
7856  ub = SCIPvarGetUbGlobal(var);
7857  if( SCIPisEQ(scip, lb, ub) )
7858  {
7859  SCIP_Real fixval;
7860 
7861  fixval = SCIPselectSimpleValue(lb, ub, MAXDNOM);
7862  SCIPdebugMsg(scip, "converting variable <%s> with fixed bounds [%.15g,%.15g] into fixed variable fixed at %.15g\n",
7863  SCIPvarGetName(var), lb, ub, fixval);
7864  SCIP_CALL( SCIPfixVar(scip, var, fixval, &infeasible, &fixed) );
7865  if( infeasible )
7866  {
7867  SCIPdebugMsg(scip, " -> infeasible fixing\n");
7868  *cutoff = TRUE;
7869  return SCIP_OKAY;
7870  }
7871  if( fixed )
7872  (*nfixedvars)++;
7873  }
7874  }
7875  }
7876 
7877  SCIP_CALL( applyFixings(scip, cons, &infeasible) );
7878 
7879  if( infeasible )
7880  {
7881  SCIPdebugMsg(scip, " -> infeasible fixing\n");
7882  *cutoff = TRUE;
7883  return SCIP_OKAY;
7884  }
7885 
7886  assert(consdata->removedfixings);
7887 
7888  return SCIP_OKAY;
7889 }
7890 
7891 #define MAX_CLIQUE_NONZEROS_PER_CONS 1000000
7892 
7893 /** extracts cliques of the constraint and adds them to SCIP
7894  *
7895  * The following clique extraction mechanism are implemeneted
7896  *
7897  * 1. collect binary variables and sort them in non increasing order, then
7898  *
7899  * a) if the constraint has a finite right hand side and the negative infinity counters for the minactivity are zero
7900  * then add the variables as a clique for which all successive pairs of coefficients fullfill the following
7901  * condition
7902  *
7903  * minactivity + vals[i] + vals[i+1] > rhs
7904  *
7905  * and also add the binary to binary implication also for non-successive variables for which the same argument
7906  * holds
7907  *
7908  * minactivity + vals[i] + vals[j] > rhs
7909  *
7910  * 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
7911  * binary to binary implications x1 = 1 => x4 = 0 and x2 = 1 => x4 = 0
7912  *
7913  * b) if the constraint has a finite left hand side and the positive infinity counters for the maxactivity are zero
7914  * then add the variables as a clique for which all successive pairs of coefficients fullfill the follwoing
7915  * condition
7916  *
7917  * maxactivity + vals[i] + vals[i-1] < lhs
7918  *
7919  * and also add the binary to binary implication also for non-successive variables for which the same argument
7920  * holds
7921  *
7922  * maxactivity + vals[i] + vals[j] < lhs
7923  *
7924  * e.g. you could multiply the above example by -1
7925  *
7926  * c) the constraint has a finite right hand side and a finite minactivity then add the variables as a negated
7927  * clique(clique on the negated variables) for which all successive pairs of coefficients fullfill the following
7928  * condition
7929  *
7930  * minactivity - vals[i] - vals[i-1] > rhs
7931  *
7932  * and also add the binary to binary implication also for non-successive variables for which the
7933  * same argument holds
7934  *
7935  * minactivity - vals[i] - vals[j] > rhs
7936  *
7937  * e.g. -4 x1 -3 x2 - 2 x3 + 2 x4 <= -4 would lead to the (negated) clique (~x1, ~x2) and the binary to binary
7938  * implication x1 = 0 => x3 = 1
7939  *
7940  * d) the constraint has a finite left hand side and a finite maxactivity then add the variables as a negated
7941  * clique(clique on the negated variables) for which all successive pairs of coefficients fullfill the following
7942  * condition
7943  *
7944  * maxactivity - vals[i] - vals[i+1] < lhs
7945  *
7946  * and also add the binary to binary implication also for non-successive variables for which the same argument
7947  * holds
7948  *
7949  * maxactivity - vals[i] - vals[j] < lhs
7950  *
7951  * e.g. you could multiply the above example by -1
7952  *
7953  * 2. if the linear constraint represents a set-packing or set-partitioning constraint, the whole constraint is added
7954  * as clique, (this part is done at the end of the method)
7955  *
7956  */
7957 static
7959  SCIP* scip, /**< SCIP data structure */
7960  SCIP_CONS* cons, /**< linear constraint */
7961  SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
7962  SCIP_Bool sortvars, /**< should variables be used in sorted order? */
7963  int* nfixedvars, /**< pointer to count number of fixed variables */
7964  int* nchgbds, /**< pointer to count the total number of tightened bounds */
7965  SCIP_Bool* cutoff /**< pointer to store TRUE, if a cutoff was found */
7966  )
7967 {
7968  SCIP_VAR** vars;
7969  SCIP_Real* vals;
7970  SCIP_CONSDATA* consdata;
7971  SCIP_Bool lhsclique;
7972  SCIP_Bool rhsclique;
7973  SCIP_Bool finitelhs;
7974  SCIP_Bool finiterhs;
7975  SCIP_Bool finiteminact;
7976  SCIP_Bool finitemaxact;
7977  SCIP_Bool finitenegminact;
7978  SCIP_Bool finitenegmaxact;
7979  SCIP_Bool finiteposminact;
7980  SCIP_Bool finiteposmaxact;
7981  SCIP_Bool infeasible;
7982  SCIP_Bool stopped;
7983  int cliquenonzerosadded;
7984  int v;
7985  int i;
7986  int nposcoefs;
7987  int nnegcoefs;
7988  int nvars;
7989 
7990  assert(scip != NULL);
7991  assert(cons != NULL);
7992  assert(nfixedvars != NULL);
7993  assert(nchgbds != NULL);
7994  assert(cutoff != NULL);
7995  assert(!SCIPconsIsDeleted(cons));
7996 
7997  consdata = SCIPconsGetData(cons);
7998  assert(consdata != NULL);
7999 
8000  if( consdata->nvars < 2 )
8001  return SCIP_OKAY;
8002 
8003  /* add implications if posibble
8004  *
8005  * for now we only add binary to non-binary implications, and this is only done for the binary variable with the
8006  * maximal absolute contribution and also only if this variable would force all other variables to their bound
8007  * corresponding to the global minimal activity of the constraint
8008  */
8009  if( !consdata->implsadded )
8010  {
8011  /* sort variables by variable type */
8012  SCIP_CALL( consdataSort(scip, consdata) );
8013 
8014  /* @todo we might extract implications/cliques if SCIPvarIsBinary() variables exist and we have integer variables
8015  * up front, might change sorting correspondingly
8016  */
8017  /* fast abort if no binaries exist */
8018  if( !SCIPvarIsBinary(consdata->vars[0]) )
8019  {
8020 #ifndef NDEBUG
8021  for( i = 1; i < consdata->nvars; i++ )
8022  assert(!SCIPvarIsBinary(consdata->vars[i]));
8023 #endif
8024  return SCIP_OKAY;
8025  }
8026  nvars = consdata->nvars;
8027  vars = consdata->vars;
8028  vals = consdata->vals;
8029 
8030  /* recompute activities if needed */
8031  if( !consdata->validactivities )
8032  consdataCalcActivities(scip, consdata);
8033  assert(consdata->validactivities);
8034 
8035  finitelhs = !SCIPisInfinity(scip, -consdata->lhs);
8036  finiterhs = !SCIPisInfinity(scip, consdata->rhs);
8037  finitenegminact = (consdata->glbminactivityneginf == 0 && consdata->glbminactivityneghuge == 0);
8038  finitenegmaxact = (consdata->glbmaxactivityneginf == 0 && consdata->maxactivityneghuge == 0);
8039  finiteposminact = (consdata->glbminactivityposinf == 0 && consdata->glbminactivityposhuge == 0);
8040  finiteposmaxact = (consdata->glbmaxactivityposinf == 0 && consdata->glbmaxactivityposhuge == 0);
8041  finiteminact = (finitenegminact && finiteposminact);
8042  finitemaxact = (finitenegmaxact && finiteposmaxact);
8043 
8044  if( (finiterhs || finitelhs) && (finitenegminact || finiteposminact || finitenegmaxact || finiteposmaxact) )
8045  {
8046  SCIP_Real maxabscontrib = -1.0;
8047  SCIP_Bool posval = FALSE;
8048  SCIP_Bool allbinary = TRUE;
8049  int oldnchgbds = *nchgbds;
8050  int nbdchgs = 0;
8051  int nimpls = 0;
8052  int position = -1;
8053 
8054  /* we need a valid minimal/maximal activity to add cliques */
8055  if( (finitenegminact || finiteposminact) && !consdata->validglbminact )
8056  {
8057  consdataRecomputeGlbMinactivity(scip, consdata);
8058  assert(consdata->validglbminact);
8059  }
8060 
8061  if( (finitenegmaxact || finiteposmaxact) && !consdata->validglbmaxact )
8062  {
8063  consdataRecomputeGlbMaxactivity(scip, consdata);
8064  assert(consdata->validglbmaxact);
8065  }
8066  assert(consdata->validglbminact || consdata->validglbmaxact);
8067 
8068  /* @todo extend this to local/constraint probing */
8069 
8070  /* determine maximal contribution to the activity */
8071  for( v = nvars - 1; v >= 0; --v )
8072  {
8073  if( SCIPvarIsBinary(vars[v]) )
8074  {
8075  if( vals[v] > 0 )
8076  {
8077  SCIP_Real value = vals[v] * SCIPvarGetUbGlobal(vars[v]);
8078 
8079  if( value > maxabscontrib )
8080  {
8081  maxabscontrib = value;
8082  position = v;
8083  posval = TRUE;
8084  }
8085  }
8086  else
8087  {
8088  SCIP_Real value = vals[v] * SCIPvarGetLbGlobal(vars[v]);
8089 
8090  value = REALABS(value);
8091 
8092  if( value > maxabscontrib )
8093  {
8094  maxabscontrib = value;
8095  position = v;
8096  posval = FALSE;
8097  }
8098  }
8099  }
8100  else
8101  allbinary = FALSE;
8102  }
8103  assert(0 <= position && position < nvars);
8104 
8105  if( !SCIPisEQ(scip, maxabscontrib, 1.0) && !allbinary )
8106  {
8107  /* if the right hand side and the minimal activity are finite and changing the variable with the biggest
8108  * influence to their bound forces all other variables to be at their minimal contribution, we can add these
8109  * implications
8110  */
8111  if( finiterhs && finiteminact && SCIPisEQ(scip, consdata->glbminactivity, consdata->rhs - maxabscontrib) )
8112  {
8113  for( v = nvars - 1; v >= 0; --v )
8114  {
8115  /* binary to binary implications will be collected when extrating cliques */
8116  if( !SCIPvarIsBinary(vars[v]) )
8117  {
8118  if( v != position )
8119  {
8120  if( vals[v] > 0 )
8121  {
8122  /* add implications */
8123  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_UPPER, SCIPvarGetLbGlobal(vars[v]), &infeasible, &nbdchgs) );
8124  ++nimpls;
8125  *nchgbds += nbdchgs;
8126  }
8127  else
8128  {
8129  /* add implications */
8130  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_LOWER, SCIPvarGetUbGlobal(vars[v]), &infeasible, &nbdchgs) );
8131  ++nimpls;
8132  *nchgbds += nbdchgs;
8133  }
8134 
8135  if( infeasible )
8136  {
8137  *cutoff = TRUE;
8138  break;
8139  }
8140  }
8141  }
8142  /* stop when reaching a 'real' binary variable because the variables are sorted after their type */
8143  else if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_BINARY )
8144  break;
8145  }
8146  }
8147 
8148  /* if the left hand side and the maximal activity are finite and changing the variable with the biggest
8149  * influence to their bound forces all other variables to be at their minimal contribution, we can add these
8150  * implications
8151  */
8152  if( finitelhs && finitemaxact && SCIPisEQ(scip, consdata->glbmaxactivity, consdata->lhs - maxabscontrib) )
8153  {
8154  for( v = nvars - 1; v >= 0; --v )
8155  {
8156  /* binary to binary implications will be collected when extrating cliques */
8157  if( !SCIPvarIsBinary(vars[v]) )
8158  {
8159  if( v != position )
8160  {
8161  if( vals[v] > 0 )
8162  {
8163  /* add implications */
8164  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_LOWER, SCIPvarGetUbGlobal(vars[v]), &infeasible, &nbdchgs) );
8165  ++nimpls;
8166  *nchgbds += nbdchgs;
8167  }
8168  else
8169  {
8170  /* add implications */
8171  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_UPPER, SCIPvarGetLbGlobal(vars[v]), &infeasible, &nbdchgs) );
8172  ++nimpls;
8173  *nchgbds += nbdchgs;
8174  }
8175 
8176  if( infeasible )
8177  {
8178  *cutoff = TRUE;
8179  break;
8180  }
8181  }
8182  }
8183  /* stop when reaching a 'real' binary variable because the variables are sorted after their type */
8184  else if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_BINARY )
8185  break;
8186  }
8187  }
8188 
8189  /* did we find some implications */
8190  if( nimpls > 0 )
8191  {
8192  SCIPdebugMsg(scip, "extracted %d implications from constraint %s which led to %d bound changes, %scutoff detetcted\n", nimpls, SCIPconsGetName(cons), *nchgbds - oldnchgbds, *cutoff ? "" : "no ");
8193 
8194  if( *cutoff )
8195  return SCIP_OKAY;
8196 
8197  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8198  if( *nchgbds - oldnchgbds > 0 )
8199  {
8200  /* check for fixed variables */
8201  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8202  if( *cutoff )
8203  return SCIP_OKAY;
8204 
8205  /* tighten variable's bounds */
8206  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8207  if( *cutoff )
8208  return SCIP_OKAY;
8209 
8210  /* check for fixed variables */
8211  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8212  if( *cutoff )
8213  return SCIP_OKAY;
8214  }
8215  }
8216  }
8217  }
8218 
8219  consdata->implsadded = TRUE;
8220  }
8221 
8222  /* check if we already added the cliques of this constraint */
8223  if( consdata->cliquesadded )
8224  return SCIP_OKAY;
8225 
8226  consdata->cliquesadded = TRUE;
8227  cliquenonzerosadded = 0;
8228  stopped = FALSE;
8229 
8230  /* sort variables by variable type */
8231  SCIP_CALL( consdataSort(scip, consdata) );
8232 
8233  nvars = consdata->nvars;
8234  vars = consdata->vars;
8235  vals = consdata->vals;
8236 
8237  /**@todo extract more cliques, implications and variable bounds from linear constraints */
8238 
8239  /* recompute activities if needed */
8240  if( !consdata->validactivities )
8241  consdataCalcActivities(scip, consdata);
8242  assert(consdata->validactivities);
8243 
8244  finitelhs = !SCIPisInfinity(scip, -consdata->lhs);
8245  finiterhs = !SCIPisInfinity(scip, consdata->rhs);
8246  finitenegminact = (consdata->glbminactivityneginf == 0 && consdata->glbminactivityneghuge == 0);
8247  finitenegmaxact = (consdata->glbmaxactivityneginf == 0 && consdata->maxactivityneghuge == 0);
8248  finiteposminact = (consdata->glbminactivityposinf == 0 && consdata->glbminactivityposhuge == 0);
8249  finiteposmaxact = (consdata->glbmaxactivityposinf == 0 && consdata->glbmaxactivityposhuge == 0);
8250  finiteminact = (finitenegminact && finiteposminact);
8251  finitemaxact = (finitenegmaxact && finiteposmaxact);
8252 
8253  /* 1. we wheck whether some variables do not fit together into this constraint and add the corresponding clique
8254  * information
8255  */
8256  if( (finiterhs || finitelhs) && (finitenegminact || finiteposminact || finitenegmaxact || finiteposmaxact) )
8257  {
8258  SCIP_VAR** binvars;
8259  SCIP_Real* binvarvals;
8260  int nposbinvars = 0;
8261  int nnegbinvars = 0;
8262  int allonebinary = 0;
8263 
8264  SCIP_CALL( SCIPallocBufferArray(scip, &binvars, nvars) );
8265  SCIP_CALL( SCIPallocBufferArray(scip, &binvarvals, nvars) );
8266 
8267  /* collect binary variables */
8268  for( i = 0; i < nvars; ++i )
8269  {
8270  if( SCIPvarIsBinary(vars[i]) )
8271  {
8272  assert(!SCIPisZero(scip, vals[i]));
8273 
8274  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8275  ++allonebinary;
8276 
8277  binvars[nposbinvars + nnegbinvars] = vars[i];
8278  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8279 
8280  if( SCIPisPositive(scip, vals[i]) )
8281  ++nposbinvars;
8282  else
8283  ++nnegbinvars;
8284 
8285  assert(nposbinvars + nnegbinvars <= nvars);
8286  }
8287  /* stop searching for binary variables, because the constraint data is sorted */
8288  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8289  break;
8290  }
8291  assert(nposbinvars + nnegbinvars <= nvars);
8292 
8293  /* setppc constraints will be handled later; we need at least two binary variables with same sign to extract
8294  * cliques
8295  */
8296  if( allonebinary < nvars && (nposbinvars >= 2 || nnegbinvars >= 2) )
8297  {
8298  SCIP_Real threshold;
8299  int oldnchgbds = *nchgbds;
8300  int nbdchgs;
8301  int jstart;
8302  int j;
8303 
8304  /* we need a valid minimal/maximal activity to add cliques */
8305  if( (finitenegminact || finiteposminact) && !consdata->validglbminact )
8306  {
8307  consdataRecomputeGlbMinactivity(scip, consdata);
8308  assert(consdata->validglbminact);
8309  }
8310 
8311  if( (finitenegmaxact || finiteposmaxact) && !consdata->validglbmaxact )
8312  {
8313  consdataRecomputeGlbMaxactivity(scip, consdata);
8314  assert(consdata->validglbmaxact);
8315  }
8316  assert(consdata->validglbminact || consdata->validglbmaxact);
8317 
8318  /* sort coefficients non-increasing to be faster in the clique search */
8319  SCIPsortDownRealPtr(binvarvals, (void**) binvars, nposbinvars + nnegbinvars);
8320 
8321  /* case a) */
8322  if( finiterhs && finitenegminact && nposbinvars >= 2 )
8323  {
8324  /* compute value that needs to be exceeded */
8325  threshold = consdata->rhs - consdata->glbminactivity;
8326 
8327  j = 1;
8328 #ifdef SCIP_DISABLED_CODE /* assertion should only hold when constraints were fully propagated and boundstightened */
8329  /* check that it is possible to choose binvar[i], otherwise it should have been fixed to zero */
8330  assert(SCIPisFeasLE(scip, binvarvals[0], threshold));
8331 #endif
8332  /* check if at least two variables are in a clique */
8333  if( SCIPisFeasGT(scip, binvarvals[0] + binvarvals[j], threshold) )
8334  {
8335  ++j;
8336  /* check for extending the clique */
8337  while( j < nposbinvars )
8338  {
8339  if( !SCIPisFeasGT(scip, binvarvals[j-1] + binvarvals[j], threshold) )
8340  break;
8341  ++j;
8342  }
8343  assert(j >= 2);
8344 
8345  /* add clique with at least two variables */
8346  SCIP_CALL( SCIPaddClique(scip, binvars, NULL, j, FALSE, &infeasible, &nbdchgs) );
8347 
8348  if( infeasible )
8349  *cutoff = TRUE;
8350 
8351  *nchgbds += nbdchgs;
8352 
8353  cliquenonzerosadded += j;
8354  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8355  stopped = TRUE;
8356 
8357  /* exchange the last variable in the clique if possible and add all new ones */
8358  if( !stopped && !(*cutoff) && j < nposbinvars )
8359  {
8360  SCIP_VAR** clqvars;
8361  int lastfit = j - 2;
8362  assert(lastfit >= 0);
8363 
8364  /* copy all 'main'-clique variables */
8365  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, binvars, j) );
8366 
8367  /* iterate up to the end with j and up to the front with lastfit, and check for different cliques */
8368  while( lastfit >= 0 && j < nposbinvars )
8369  {
8370  /* check if two variables are in a clique */
8371  if( SCIPisFeasGT(scip, binvarvals[lastfit] + binvarvals[j], threshold) )
8372  {
8373  clqvars[lastfit + 1] = binvars[j];
8374 
8375  /* add clique with at least two variables */
8376  SCIP_CALL( SCIPaddClique(scip, clqvars, NULL, lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8377 
8378  if( infeasible )
8379  {
8380  *cutoff = TRUE;
8381  break;
8382  }
8383 
8384  *nchgbds += nbdchgs;
8385 
8386  cliquenonzerosadded += (lastfit + 2);
8387  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8388  {
8389  stopped = TRUE;
8390  break;
8391  }
8392 
8393  ++j;
8394  }
8395  else
8396  --lastfit;
8397  }
8398 
8399  SCIPfreeBufferArray(scip, &clqvars);
8400  }
8401  }
8402  }
8403 
8404  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8405  if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8406  {
8407  /* check for fixed variables */
8408  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8409 
8410  if( !*cutoff )
8411  {
8412  /* tighten variable's bounds */
8413  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8414 
8415  if( !*cutoff )
8416  {
8417  /* check for fixed variables */
8418  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8419 
8420  if( !*cutoff )
8421  {
8422  /* sort variables by variable type */
8423  SCIP_CALL( consdataSort(scip, consdata) );
8424 
8425  /* recompute activities if needed */
8426  if( !consdata->validactivities )
8427  consdataCalcActivities(scip, consdata);
8428  assert(consdata->validactivities);
8429 
8430  nvars = consdata->nvars;
8431  vars = consdata->vars;
8432  vals = consdata->vals;
8433  nposbinvars = 0;
8434  nnegbinvars = 0;
8435  allonebinary = 0;
8436 
8437  /* update binary variables */
8438  for( i = 0; i < nvars; ++i )
8439  {
8440  if( SCIPvarIsBinary(vars[i]) )
8441  {
8442  assert(!SCIPisZero(scip, vals[i]));
8443 
8444  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8445  ++allonebinary;
8446 
8447  binvars[nposbinvars + nnegbinvars] = vars[i];
8448  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8449 
8450  if( SCIPisPositive(scip, vals[i]) )
8451  ++nposbinvars;
8452  else
8453  ++nnegbinvars;
8454 
8455  assert(nposbinvars + nnegbinvars <= nvars);
8456  }
8457  /* stop searching for binary variables, because the constraint data is sorted */
8458  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8459  break;
8460  }
8461  assert(nposbinvars + nnegbinvars <= nvars);
8462  }
8463  }
8464  }
8465 
8466  oldnchgbds = *nchgbds;
8467  }
8468 
8469  /* case b) */
8470  if( !stopped && !(*cutoff) && finitelhs && finiteposmaxact && nnegbinvars >= 2 )
8471  {
8472  /* compute value that needs to be deceeded */
8473  threshold = consdata->lhs - consdata->glbmaxactivity;
8474 
8475  i = nposbinvars + nnegbinvars - 1;
8476  j = i - 1;
8477 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8478  /* check that it is possible to choose binvar[i], otherwise it should have been fixed to zero */
8479  assert(SCIPisFeasGE(scip, binvarvals[i], threshold));
8480 #endif
8481  /* check if two variables are in a clique */
8482  if( SCIPisFeasLT(scip, binvarvals[i] + binvarvals[j], threshold) )
8483  {
8484  --j;
8485  /* check for extending the clique */
8486  while( j >= nposbinvars )
8487  {
8488  if( !SCIPisFeasLT(scip, binvarvals[j+1] + binvarvals[j], threshold) )
8489  break;
8490  --j;
8491  }
8492  jstart = j;
8493 
8494  assert(i - j >= 2);
8495  /* add clique with at least two variables */
8496  SCIP_CALL( SCIPaddClique(scip, &(binvars[j+1]), NULL, i - j, FALSE, &infeasible, &nbdchgs) );
8497 
8498  if( infeasible )
8499  *cutoff = TRUE;
8500 
8501  *nchgbds += nbdchgs;
8502 
8503  cliquenonzerosadded += (i - j);
8504  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8505  stopped = TRUE;
8506 
8507  /* exchange the last variable in the clique if possible and add all new ones */
8508  if( !stopped && !(*cutoff) && jstart >= nposbinvars )
8509  {
8510  SCIP_VAR** clqvars;
8511  int lastfit = jstart + 1;
8512  assert(lastfit < i);
8513 
8514  /* copy all 'main'-clique variables */
8515  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[lastfit]), i - j) );
8516  ++lastfit;
8517 
8518  /* iterate up to the front with j and up to the end with lastfit, and check for different cliques */
8519  while( lastfit <= i && j >= nposbinvars )
8520  {
8521  /* check if two variables are in a clique */
8522  if( SCIPisFeasLT(scip, binvarvals[lastfit] + binvarvals[j], threshold) )
8523  {
8524  assert(lastfit - jstart - 2 >= 0 && lastfit - jstart - 2 < i);
8525  clqvars[lastfit - jstart - 2] = binvars[j];
8526 
8527  assert(i - lastfit + 2 >= 2);
8528  /* add clique with at least two variables */
8529  SCIP_CALL( SCIPaddClique(scip, &(clqvars[lastfit - jstart - 2]), NULL, i - lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8530 
8531  if( infeasible )
8532  {
8533  *cutoff = TRUE;
8534  break;
8535  }
8536 
8537  *nchgbds += nbdchgs;
8538 
8539  cliquenonzerosadded += (i - lastfit + 2);
8540  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8541  {
8542  stopped = TRUE;
8543  break;
8544  }
8545 
8546  --j;
8547  }
8548  else
8549  ++lastfit;
8550  }
8551 
8552  SCIPfreeBufferArray(scip, &clqvars);
8553  }
8554  }
8555  }
8556 
8557  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8558  if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8559  {
8560  /* check for fixed variables */
8561  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8562 
8563  if( !*cutoff )
8564  {
8565  /* tighten variable's bounds */
8566  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8567 
8568  if( !*cutoff )
8569  {
8570  /* check for fixed variables */
8571  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8572 
8573  if( !*cutoff )
8574  {
8575  /* sort variables by variable type */
8576  SCIP_CALL( consdataSort(scip, consdata) );
8577 
8578  /* recompute activities if needed */
8579  if( !consdata->validactivities )
8580  consdataCalcActivities(scip, consdata);
8581  assert(consdata->validactivities);
8582 
8583  nvars = consdata->nvars;
8584  vars = consdata->vars;
8585  vals = consdata->vals;
8586  nposbinvars = 0;
8587  nnegbinvars = 0;
8588  allonebinary = 0;
8589 
8590  /* update binary variables */
8591  for( i = 0; i < nvars; ++i )
8592  {
8593  if( SCIPvarIsBinary(vars[i]) )
8594  {
8595  assert(!SCIPisZero(scip, vals[i]));
8596 
8597  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8598  ++allonebinary;
8599 
8600  binvars[nposbinvars + nnegbinvars] = vars[i];
8601  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8602 
8603  if( SCIPisPositive(scip, vals[i]) )
8604  ++nposbinvars;
8605  else
8606  ++nnegbinvars;
8607 
8608  assert(nposbinvars + nnegbinvars <= nvars);
8609  }
8610  /* stop searching for binary variables, because the constraint data is sorted */
8611  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8612  break;
8613  }
8614  assert(nposbinvars + nnegbinvars <= nvars);
8615  }
8616  }
8617  }
8618 
8619  oldnchgbds = *nchgbds;
8620  }
8621 
8622  /* case c) */
8623  if( !(*cutoff) && finiterhs && finiteminact && nnegbinvars >= 2 )
8624  {
8625  SCIP_Bool* values;
8626 
8627  /* initialize clique values array for adding a negated clique */
8628  SCIP_CALL( SCIPallocBufferArray(scip, &values, nnegbinvars) );
8629  BMSclearMemoryArray(values, nnegbinvars);
8630 
8631  /* compute value that needs to be exceeded */
8632  threshold = consdata->rhs - consdata->glbminactivity;
8633 
8634  i = nposbinvars + nnegbinvars - 1;
8635  j = i - 1;
8636 
8637 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8638  /* check if the variable should not have already been fixed to one */
8639  assert(!SCIPisFeasGT(scip, binvarvals[i], threshold));
8640 #endif
8641 
8642  if( SCIPisFeasGT(scip, -binvarvals[i] - binvarvals[j], threshold) )
8643  {
8644  --j;
8645  /* check for extending the clique */
8646  while( j >= nposbinvars )
8647  {
8648  if( !SCIPisFeasGT(scip, -binvarvals[j+1] - binvarvals[j], threshold) )
8649  break;
8650  --j;
8651  }
8652  jstart = j;
8653 
8654  assert(i - j >= 2);
8655  /* add negated clique with at least two variables */
8656  SCIP_CALL( SCIPaddClique(scip, &(binvars[j+1]), values, i - j, FALSE, &infeasible, &nbdchgs) );
8657 
8658  if( infeasible )
8659  *cutoff = TRUE;
8660 
8661  *nchgbds += nbdchgs;
8662 
8663  cliquenonzerosadded += (i - j);
8664  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8665  stopped = TRUE;
8666 
8667  /* exchange the last variable in the clique if possible and add all new ones */
8668  if( !stopped && !(*cutoff) && jstart >= nposbinvars )
8669  {
8670  SCIP_VAR** clqvars;
8671  int lastfit = j + 1;
8672  assert(lastfit < i);
8673 
8674  /* copy all 'main'-clique variables */
8675  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[lastfit]), i - j) );
8676  ++lastfit;
8677 
8678  /* iterate up to the front with j and up to the end with lastfit, and check for different cliques */
8679  while( lastfit <= i && j >= nposbinvars )
8680  {
8681  /* check if two variables are in a negated clique */
8682  if( SCIPisFeasGT(scip, -binvarvals[lastfit] - binvarvals[j], threshold) )
8683  {
8684  assert(lastfit - jstart - 2 >= 0 && lastfit - jstart - 2 < i);
8685  clqvars[lastfit - jstart - 2] = binvars[j];
8686 
8687  assert(i - lastfit + 2 >= 2);
8688  /* add clique with at least two variables */
8689  SCIP_CALL( SCIPaddClique(scip, &(clqvars[lastfit - jstart - 2]), values, i - lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8690 
8691  if( infeasible )
8692  {
8693  *cutoff = TRUE;
8694  break;
8695  }
8696 
8697  *nchgbds += nbdchgs;
8698 
8699  cliquenonzerosadded += (i - lastfit + 2);
8700  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8701  {
8702  stopped = TRUE;
8703  break;
8704  }
8705 
8706  --j;
8707  }
8708  else
8709  ++lastfit;
8710  }
8711 
8712  SCIPfreeBufferArray(scip, &clqvars);
8713  }
8714  }
8715 
8716  SCIPfreeBufferArray(scip, &values);
8717  }
8718 
8719  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8720  if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8721  {
8722  /* check for fixed variables */
8723  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8724 
8725  if( !*cutoff )
8726  {
8727  /* tighten variable's bounds */
8728  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8729 
8730  if( !*cutoff )
8731  {
8732  /* check for fixed variables */
8733  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8734 
8735  if( !*cutoff )
8736  {
8737  /* sort variables by variable type */
8738  SCIP_CALL( consdataSort(scip, consdata) );
8739 
8740  /* recompute activities if needed */
8741  if( !consdata->validactivities )
8742  consdataCalcActivities(scip, consdata);
8743  assert(consdata->validactivities);
8744 
8745  nvars = consdata->nvars;
8746  vars = consdata->vars;
8747  vals = consdata->vals;
8748  nposbinvars = 0;
8749  nnegbinvars = 0;
8750  allonebinary = 0;
8751 
8752  /* update binary variables */
8753  for( i = 0; i < nvars; ++i )
8754  {
8755  if( SCIPvarIsBinary(vars[i]) )
8756  {
8757  assert(!SCIPisZero(scip, vals[i]));
8758 
8759  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8760  ++allonebinary;
8761 
8762  binvars[nposbinvars + nnegbinvars] = vars[i];
8763  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8764 
8765  if( SCIPisPositive(scip, vals[i]) )
8766  ++nposbinvars;
8767  else
8768  ++nnegbinvars;
8769 
8770  assert(nposbinvars + nnegbinvars <= nvars);
8771  }
8772  /* stop searching for binary variables, because the constraint data is sorted */
8773  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8774  break;
8775  }
8776  assert(nposbinvars + nnegbinvars <= nvars);
8777  }
8778  }
8779  }
8780  }
8781 
8782  /* case d) */
8783  if( !stopped && !(*cutoff) && finitelhs && finitemaxact && nposbinvars >= 2 )
8784  {
8785  SCIP_Bool* values;
8786 
8787  /* initialize clique values array for adding a negated clique */
8788  SCIP_CALL( SCIPallocBufferArray(scip, &values, nposbinvars) );
8789  BMSclearMemoryArray(values, nposbinvars);
8790 
8791  /* compute value that needs to be exceeded */
8792  threshold = consdata->lhs - consdata->glbmaxactivity;
8793 
8794  j = 1;
8795 
8796 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8797  /* check if the variable should not have already been fixed to one */
8798  assert(!SCIPisFeasLT(scip, -binvarvals[0], threshold));
8799 #endif
8800 
8801  if( SCIPisFeasLT(scip, -binvarvals[0] - binvarvals[j], threshold) )
8802  {
8803  ++j;
8804  /* check for extending the clique */
8805  while( j < nposbinvars )
8806  {
8807  if( !SCIPisFeasLT(scip, -binvarvals[j-1] - binvarvals[j], threshold) )
8808  break;
8809  ++j;
8810  }
8811  assert(j >= 2);
8812 
8813  /* add negated clique with at least two variables */
8814  SCIP_CALL( SCIPaddClique(scip, binvars, values, j, FALSE, &infeasible, &nbdchgs) );
8815 
8816  if( infeasible )
8817  *cutoff = TRUE;
8818 
8819  *nchgbds += nbdchgs;
8820 
8821  cliquenonzerosadded += j;
8822  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8823  stopped = TRUE;
8824 
8825  /* exchange the last variable in the clique if possible and add all new ones */
8826  if( !stopped && !(*cutoff) && j < nposbinvars )
8827  {
8828  SCIP_VAR** clqvars;
8829  int lastfit = j - 2;
8830  assert(lastfit >= 0);
8831 
8832  /* copy all 'main'-clique variables */
8833  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, binvars, j) );
8834 
8835  /* iterate up to the end with j and up to the front with lastfit, and check for different cliques */
8836  while( lastfit >= 0 && j < nposbinvars )
8837  {
8838  /* check if two variables are in a negated clique */
8839  if( SCIPisFeasLT(scip, -binvarvals[lastfit] - binvarvals[j], threshold) )
8840  {
8841  clqvars[lastfit + 1] = binvars[j];
8842 
8843  /* add clique with at least two variables */
8844  SCIP_CALL( SCIPaddClique(scip, clqvars, values, lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8845 
8846  if( infeasible )
8847  {
8848  *cutoff = TRUE;
8849  break;
8850  }
8851 
8852  *nchgbds += nbdchgs;
8853 
8854  cliquenonzerosadded += lastfit + 2;
8855  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8856  break;
8857 
8858  ++j;
8859  }
8860  else
8861  --lastfit;
8862  }
8863 
8864  SCIPfreeBufferArray(scip, &clqvars);
8865  }
8866  }
8867 
8868  SCIPfreeBufferArray(scip, &values);
8869  }
8870  }
8871 
8872  SCIPfreeBufferArray(scip, &binvarvals);
8873  SCIPfreeBufferArray(scip, &binvars);
8874 
8875  if( *cutoff )
8876  return SCIP_OKAY;
8877  }
8878 
8879  /* 2. we only check if the constraint is a set packing / partitioning constraint */
8880 
8881  /* check if all variables are binary, if the coefficients are +1 or -1, and if the right hand side is equal
8882  * to 1 - number of negative coefficients, or if the left hand side is equal to number of positive coefficients - 1
8883  */
8884  nposcoefs = 0;
8885  nnegcoefs = 0;
8886  for( i = 0; i < nvars; ++i )
8887  {
8888  if( !SCIPvarIsBinary(vars[i]) )
8889  return SCIP_OKAY;
8890  else if( SCIPisEQ(scip, vals[i], +1.0) )
8891  nposcoefs++;
8892  else if( SCIPisEQ(scip, vals[i], -1.0) )
8893  nnegcoefs++;
8894  else
8895  return SCIP_OKAY;
8896  }
8897 
8898  lhsclique = SCIPisEQ(scip, consdata->lhs, (SCIP_Real)nposcoefs - 1.0);
8899  rhsclique = SCIPisEQ(scip, consdata->rhs, 1.0 - (SCIP_Real)nnegcoefs);
8900 
8901  if( lhsclique || rhsclique )
8902  {
8903  SCIP_Bool* values;
8904  int nbdchgs;
8905 
8906  SCIPdebugMsg(scip, "linear constraint <%s>: adding clique with %d vars (%d pos, %d neg)\n",
8907  SCIPconsGetName(cons), nvars, nposcoefs, nnegcoefs);
8908  SCIP_CALL( SCIPallocBufferArray(scip, &values, nvars) );
8909 
8910  for( i = 0; i < nvars; ++i )
8911  values[i] = (rhsclique == (vals[i] > 0.0));
8912 
8913  SCIP_CALL( SCIPaddClique(scip, vars, values, nvars, SCIPisEQ(scip, consdata->lhs, consdata->rhs), &infeasible, &nbdchgs) );
8914 
8915  if( infeasible )
8916  *cutoff = TRUE;
8917 
8918  *nchgbds += nbdchgs;
8919  SCIPfreeBufferArray(scip, &values);
8920  }
8921 
8922  return SCIP_OKAY;
8923 }
8924 
8925 /** tightens left and right hand side of constraint due to integrality */
8926 static
8928  SCIP* scip, /**< SCIP data structure */
8929  SCIP_CONS* cons, /**< linear constraint */
8930  int* nchgsides, /**< pointer to count number of side changes */
8931  SCIP_Bool* infeasible /**< pointer to store whether infeasibility was detected */
8932  )
8933 {
8934  SCIP_CONSDATA* consdata;
8935  SCIP_Real newlhs;
8936  SCIP_Real newrhs;
8937  SCIP_Bool chglhs;
8938  SCIP_Bool chgrhs;
8939  SCIP_Bool integral;
8940  int i;
8941 
8942  assert(scip != NULL);
8943  assert(cons != NULL);
8944  assert(nchgsides != NULL);
8945  assert(infeasible != NULL);
8946 
8947  consdata = SCIPconsGetData(cons);
8948  assert(consdata != NULL);
8949 
8950  *infeasible = FALSE;
8951 
8952  chglhs = FALSE;
8953  chgrhs = FALSE;
8954  newlhs = -SCIPinfinity(scip);
8955  newrhs = SCIPinfinity(scip);
8956 
8957  if( !SCIPisIntegral(scip, consdata->lhs) || !SCIPisIntegral(scip, consdata->rhs) )
8958  {
8959  integral = TRUE;
8960  for( i = 0; i < consdata->nvars && integral; ++i )
8961  {
8962  integral = SCIPisIntegral(scip, consdata->vals[i])
8963  && (SCIPvarGetType(consdata->vars[i]) != SCIP_VARTYPE_CONTINUOUS);
8964  }
8965  if( integral )
8966  {
8967  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisIntegral(scip, consdata->lhs) )
8968  {
8969  newlhs = SCIPfeasCeil(scip, consdata->lhs);
8970  chglhs = TRUE;
8971  }
8972  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisIntegral(scip, consdata->rhs) )
8973  {
8974  newrhs = SCIPfeasFloor(scip, consdata->rhs);
8975  chgrhs = TRUE;
8976  }
8977 
8978  /* check whether rounding would lead to an unsatisfiable constraint */
8979  if( SCIPisGT(scip, newlhs, newrhs) )
8980  {
8981  SCIPdebugMsg(scip, "rounding sides=[%.15g,%.15g] of linear constraint <%s> with integral coefficients and variables only "
8982  "is infeasible\n", consdata->lhs, consdata->rhs, SCIPconsGetName(cons));
8983 
8984  *infeasible = TRUE;
8985  return SCIP_OKAY;
8986  }
8987 
8988  SCIPdebugMsg(scip, "linear constraint <%s>: make sides integral: sides=[%.15g,%.15g]\n",
8989  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
8990 
8991  if( chglhs )
8992  {
8993  assert(!SCIPisInfinity(scip, -newlhs));
8994 
8995  SCIP_CALL( chgLhs(scip, cons, newlhs) );
8996  if( !consdata->upgraded )
8997  (*nchgsides)++;
8998  }
8999  if( chgrhs )
9000  {
9001  assert(!SCIPisInfinity(scip, newrhs));
9002 
9003  SCIP_CALL( chgRhs(scip, cons, newrhs) );
9004  if( !consdata->upgraded )
9005  (*nchgsides)++;
9006  }
9007  SCIPdebugMsg(scip, "linear constraint <%s>: new integral sides: sides=[%.15g,%.15g]\n",
9008  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
9009  }
9010  }
9011 
9012  return SCIP_OKAY;
9013 }
9014 
9015 /** tightens coefficients of binary, integer, and implicit integer variables due to activity bounds in presolving:
9016  * given an inequality lhs <= a*x + ai*xi <= rhs, with a non-continuous variable li <= xi <= ui
9017  * let minact := min{a*x + ai*xi}, maxact := max{a*x + ai*xi}
9018  * (i) ai >= 0:
9019  * if minact + ai >= lhs and maxact - ai <= rhs: (**)
9020  * - a deviation from the lower/upper bound of xi would make the left/right hand side redundant
9021  * - ai, lhs and rhs can be changed to have the same redundancy effect and the same results for
9022  * xi fixed to its bounds, but with a reduced ai and tightened sides to tighten the LP relaxation
9023  * - change coefficients:
9024  * ai' := max(lhs - minact, maxact - rhs)
9025  * lhs' := lhs - (ai - ai')*li
9026  * rhs' := rhs - (ai - ai')*ui
9027  * (ii) ai < 0:
9028  * if minact - ai >= lhs and maxact + ai <= rhs: (***)
9029  * - a deviation from the upper/lower bound of xi would make the left/right hand side redundant
9030  * - ai, lhs and rhs can be changed to have the same redundancy effect and the same results for
9031  * xi fixed to its bounds, but with a reduced ai and tightened sides to tighten the LP relaxation
9032  * - change coefficients:
9033  * ai' := min(rhs - maxact, minact - lhs)
9034  * lhs' := lhs - (ai - ai')*ui
9035  * rhs' := rhs - (ai - ai')*li
9036  *
9037  * We further try to remove redundant variable from the constraint;
9038  * Variables which fulfill conditions (**) or (***) are called surely non-redundant variables.
9039  * A deviation of only one from their bound makes the lhs/rhs feasible (i.e., redundant), even if all other
9040  * variables are set to their "worst" bound. If all variables which are not surely non-redundant cannot make
9041  * the lhs/rhs redundant, even if they are set to their "best" bound, they can be removed from the constraint.
9042  * 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
9043  * suffices to fulfill the inequality, whereas the x_i do not contribute to feasibility and can be removed.
9044  *
9045  * @todo use also some tightening procedures for (knapsack) constraints with non-integer coefficients, see
9046  * cons_knapsack.c the following methods detectRedundantVars() and tightenWeights()
9047  */
9048 static
9050  SCIP* scip, /**< SCIP data structure */
9051  SCIP_CONS* cons, /**< linear constraint */
9052  int* nchgcoefs, /**< pointer to count total number of changed coefficients */
9053  int* nchgsides /**< pointer to count number of side changes */
9054  )
9055 {
9056  SCIP_CONSDATA* consdata;
9057  SCIP_VAR* var;
9058  SCIP_Real minactivity; /* minimal value w.r.t. the variable's local bounds for the constraint's
9059  * activity, ignoring the coefficients contributing with infinite value */
9060  SCIP_Real maxactivity; /* maximal value w.r.t. the variable's local bounds for the constraint's
9061  * activity, ignoring the coefficients contributing with infinite value */
9062  SCIP_Bool minactisrelax; /* do huge finite values contribute to the minactivity? */
9063  SCIP_Bool maxactisrelax; /* do huge finite values contribute to the maxactivity? */
9064  SCIP_Bool isminsettoinfinity;
9065  SCIP_Bool ismaxsettoinfinity;
9066  SCIP_Real minleftactivity; /* minimal activity without surely non-redundant variables. */
9067  SCIP_Real maxleftactivity; /* maximal activity without surely non-redundant variables. */
9068  SCIP_Real aggrlhs; /* lhs without minimal activity of surely non-redundant variables. */
9069  SCIP_Real aggrrhs; /* rhs without maximal activity of surely non-redundant variables. */
9070  SCIP_Real lval; /* candidate for new value arising from considering the left hand side */
9071  SCIP_Real rval; /* candidate for new value arising from considering the left hand side */
9072  SCIP_Real val;
9073  SCIP_Real newval;
9074  SCIP_Real newlhs;
9075  SCIP_Real newrhs;
9076  SCIP_Real lb;
9077  SCIP_Real ub;
9078  int i;
9079 
9080  assert(scip != NULL);
9081  assert(cons != NULL);
9082  assert(nchgcoefs != NULL);
9083  assert(nchgsides != NULL);
9084 
9085  consdata = SCIPconsGetData(cons);
9086  assert(consdata != NULL);
9087 
9088  /* @todo Is this still needed with automatic recomputation of activities? */
9089  /* if the maximal coefficient is too large, recompute the activities */
9090  if( (consdata->validmaxabsval && consdata->maxabsval > MAXVALRECOMP)
9091  || (consdata->validminabsval && consdata->minabsval < MINVALRECOMP) )
9092  {
9093  consdataRecomputeMinactivity(scip, consdata);
9094  consdataRecomputeMaxactivity(scip, consdata);
9095  }
9096 
9097  /* get the minimal and maximal activity of the constraint */
9098  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9099  &isminsettoinfinity, &ismaxsettoinfinity);
9100 
9101  minleftactivity = 0.0;
9102  maxleftactivity = 0.0;
9103 
9104  /* try to tighten each coefficient */
9105  i = 0;
9106  while( i < consdata->nvars )
9107  {
9108  var = consdata->vars[i];
9109 
9110  /* get coefficient and variable's bounds */
9111  lb = SCIPvarGetLbLocal(var);
9112  ub = SCIPvarGetUbLocal(var);
9113  val = consdata->vals[i];
9114  assert(!SCIPisZero(scip, val));
9115 
9116  /* check sign of coefficient */
9117  if( val >= 0.0 )
9118  {
9119  /* check, if a deviation from lower/upper bound would make lhs/rhs redundant */
9121  SCIPisGE(scip, minactivity + val, consdata->lhs) && SCIPisLE(scip, maxactivity - val, consdata->rhs) )
9122  {
9123  /* change coefficients:
9124  * ai' := max(lhs - minact, maxact - rhs)
9125  * lhs' := lhs - (ai - ai')*li
9126  * rhs' := rhs - (ai - ai')*ui
9127  */
9128 
9129  lval = consdata->lhs - minactivity;
9130  rval = maxactivity - consdata->rhs;
9131 
9132  /* Try to avoid cancellation, if there are only two variables */
9133  if( consdata->nvars == 2 )
9134  {
9135  SCIP_Real otherval;
9136  otherval = consdata->vals[1-i];
9137 
9138  if( !SCIPisInfinity(scip, -consdata->lhs) && !isminsettoinfinity )
9139  {
9140  lval = consdata->lhs - val*lb;
9141  lval -= otherval > 0.0 ? otherval * SCIPvarGetLbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetUbLocal(consdata->vars[1-i]);
9142  }
9143 
9144  if( !SCIPisInfinity(scip, consdata->rhs) && !ismaxsettoinfinity )
9145  {
9146  rval = val*ub - consdata->rhs;
9147  rval += otherval > 0.0 ? otherval * SCIPvarGetUbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetLbLocal(consdata->vars[1-i]);
9148  }
9149  }
9150 
9151  newval = MAX(lval, rval);
9152  assert(SCIPisSumRelLE(scip, newval, val));
9153 
9154  /* Try to avoid cancellation in computation of lhs/rhs */
9155  newlhs = consdata->lhs - val * lb;
9156  newlhs += newval * lb;
9157  newrhs = consdata->rhs - val * ub;
9158  newrhs += newval * ub;
9159 
9160  if( !SCIPisSumRelEQ(scip, newval, val) )
9161  {
9162  SCIPdebugMsg(scip, "linear constraint <%s>: change coefficient %+.15g<%s> to %+.15g<%s>, act=[%.15g,%.15g], side=[%.15g,%.15g]\n",
9163  SCIPconsGetName(cons), val, SCIPvarGetName(var), newval, SCIPvarGetName(var),
9164  minactivity, maxactivity, consdata->lhs, consdata->rhs);
9165 
9166  /* update the coefficient and the activity bounds */
9167  if( SCIPisZero(scip, newval) )
9168  {
9169  SCIP_CALL( delCoefPos(scip, cons, i) );
9170  i--;
9171  }
9172  else
9173  {
9174  SCIP_CALL( chgCoefPos(scip, cons, i, newval) );
9175  }
9176  (*nchgcoefs)++;
9177 
9178  /* get the new minimal and maximal activity of the constraint */
9179  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9180  &isminsettoinfinity, &ismaxsettoinfinity);
9181 
9182  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisEQ(scip, newlhs, consdata->lhs) )
9183  {
9184  SCIPdebugMsg(scip, "linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
9185 
9186  SCIP_CALL( chgLhs(scip, cons, newlhs) );
9187  (*nchgsides)++;
9188  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
9189  }
9190 
9191  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisEQ(scip, newrhs, consdata->rhs) )
9192  {
9193  SCIPdebugMsg(scip, "linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
9194 
9195  SCIP_CALL( chgRhs(scip, cons, newrhs) );
9196  (*nchgsides)++;
9197  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
9198  }
9199  }
9200  }
9201  else
9202  {
9203  if( !SCIPisInfinity(scip, -minleftactivity) )
9204  {
9205  assert(!SCIPisInfinity(scip, val));
9206  assert(!SCIPisInfinity(scip, lb));
9207  if( SCIPisInfinity(scip, -lb) )
9208  minleftactivity = -SCIPinfinity(scip);
9209  else
9210  minleftactivity += val * lb;
9211  }
9212 
9213  if( !SCIPisInfinity(scip, maxleftactivity) )
9214  {
9215  assert(!SCIPisInfinity(scip, val));
9216  assert(!SCIPisInfinity(scip, -ub));
9217  if( SCIPisInfinity(scip,ub) )
9218  maxleftactivity = SCIPinfinity(scip);
9219  else
9220  maxleftactivity += val * ub;
9221  }
9222  }
9223  }
9224  else
9225  {
9226  /* check, if a deviation from lower/upper bound would make lhs/rhs redundant */
9228  SCIPisGE(scip, minactivity - val, consdata->lhs) && SCIPisLE(scip, maxactivity + val, consdata->rhs) )
9229  {
9230  /* change coefficients:
9231  * ai' := min(rhs - maxact, minact - lhs)
9232  * lhs' := lhs - (ai - ai')*ui
9233  * rhs' := rhs - (ai - ai')*li
9234  */
9235 
9236  lval = minactivity - consdata->lhs;
9237  rval = consdata->rhs - maxactivity;
9238 
9239  /* Try to avoid cancellation, if there are only two variables */
9240  if( consdata->nvars == 2 )
9241  {
9242  SCIP_Real otherval;
9243  otherval = consdata->vals[1-i];
9244 
9245  if( !SCIPisInfinity(scip, -consdata->lhs) && !isminsettoinfinity )
9246  {
9247  lval = val*ub - consdata->lhs;
9248  lval += otherval > 0.0 ? otherval * SCIPvarGetLbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetUbLocal(consdata->vars[1-i]);
9249  }
9250 
9251  if( !SCIPisInfinity(scip, consdata->rhs) && !ismaxsettoinfinity )
9252  {
9253  rval = consdata->rhs - val*lb;
9254  rval -= otherval > 0.0 ? otherval * SCIPvarGetUbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetLbLocal(consdata->vars[1-i]);
9255  }
9256  }
9257 
9258  newval = MIN(lval, rval);
9259  assert(SCIPisSumRelGE(scip, newval, val));
9260 
9261  /* Try to avoid cancellation in computation of lhs/rhs */
9262  newlhs = consdata->lhs - val * ub;
9263  newlhs += newval * ub;
9264  newrhs = consdata->rhs - val * lb;
9265  newrhs += newval * lb;
9266 
9267  if( !SCIPisSumRelEQ(scip, newval, val) )
9268  {
9269  SCIPdebugMsg(scip, "linear constraint <%s>: change coefficient %+.15g<%s> to %+.15g<%s>, act=[%.15g,%.15g], side=[%.15g,%.15g]\n",
9270  SCIPconsGetName(cons), val, SCIPvarGetName(var), newval, SCIPvarGetName(var),
9271  minactivity, maxactivity, consdata->lhs, consdata->rhs);
9272 
9273  /* update the coefficient and the activity bounds */
9274  if( SCIPisZero(scip, newval) )
9275  {
9276  SCIP_CALL( delCoefPos(scip, cons, i) );
9277  i--;
9278  }
9279  else
9280  {
9281  SCIP_CALL( chgCoefPos(scip, cons, i, newval) );
9282  }
9283  (*nchgcoefs)++;
9284 
9285  /* get the new minimal and maximal activity of the constraint */
9286  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9287  &isminsettoinfinity, &ismaxsettoinfinity);
9288 
9289  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisEQ(scip, newlhs, consdata->lhs) )
9290  {
9291  SCIPdebugMsg(scip, "linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
9292 
9293  SCIP_CALL( chgLhs(scip, cons, newlhs) );
9294  (*nchgsides)++;
9295  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
9296  }
9297 
9298  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisEQ(scip, newrhs, consdata->rhs) )
9299  {
9300  SCIPdebugMsg(scip, "linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
9301 
9302  SCIP_CALL( chgRhs(scip, cons, newrhs) );
9303  (*nchgsides)++;
9304  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
9305  }
9306  }
9307  }
9308  else
9309  {
9310  if( !SCIPisInfinity(scip, -minleftactivity) )
9311  {
9312  assert(!SCIPisInfinity(scip, -val));
9313  assert(!SCIPisInfinity(scip, -ub));
9314  if( SCIPisInfinity(scip, ub) )
9315  minleftactivity = -SCIPinfinity(scip);
9316  else
9317  minleftactivity += val * ub;
9318  }
9319 
9320  if( !SCIPisInfinity(scip, maxleftactivity) )
9321  {
9322  assert(!SCIPisInfinity(scip, -val));
9323  assert(!SCIPisInfinity(scip, lb));
9324  if( SCIPisInfinity(scip, -lb) )
9325  maxleftactivity = SCIPinfinity(scip);
9326  else
9327  maxleftactivity += val * lb;
9328  }
9329  }
9330  }
9331  ++i;
9332  }
9333 
9334  SCIPdebugMsg(scip, "minleftactivity = %.15g, rhs = %.15g\n",
9335  minleftactivity, consdata->rhs);
9336  SCIPdebugMsg(scip, "maxleftactivity = %.15g, lhs = %.15g\n",
9337  maxleftactivity, consdata->lhs);
9338 
9339  /* minleft == \infty ==> minactivity == \infty */
9340  assert(!SCIPisInfinity(scip, -minleftactivity) || SCIPisInfinity(scip, -minactivity));
9341  assert(!SCIPisInfinity(scip, maxleftactivity) || SCIPisInfinity(scip, maxactivity));
9342 
9343  /* if the lhs is finite, we will check in the following whether the not non-redundant variables can make lhs feasible;
9344  * this is not valid, if the minactivity is -\infty (aggrlhs would be minus infinity in the following computation)
9345  * or if huge values contributed to the minactivity, because the minactivity is then just a relaxation
9346  * (<= the exact minactivity), and we might falsely claim variables to be redundant in the following
9347  */
9348  assert(!SCIPisInfinity(scip, minactivity));
9349  if( !SCIPisInfinity(scip, -consdata->lhs) && (SCIPisInfinity(scip, -minactivity) || minactisrelax) )
9350  return SCIP_OKAY;
9351 
9352  /* if the rhs is finite, we will check in the following whether the not non-redundant variables can make rhs feasible;
9353  * this is not valid, if the maxactivity is \infty (aggrrhs would be infinity in the following computation)
9354  * or if huge values contributed to the maxactivity, because the maxactivity is then just a relaxation
9355  * (>= the exact maxactivity), and we might falsely claim variables to be redundant in the following
9356  */
9357  assert(!SCIPisInfinity(scip, -maxactivity));
9358  if( !SCIPisInfinity(scip, consdata->rhs) && (SCIPisInfinity(scip, maxactivity) || maxactisrelax) )
9359  return SCIP_OKAY;
9360 
9361  /* correct lhs and rhs by min/max activity of surely non-redundant variables
9362  * surely non-redundant variables are all those where a deviation from the bound makes the lhs/rhs redundant
9363  */
9364  aggrlhs = consdata->lhs - minactivity + minleftactivity;
9365  aggrrhs = consdata->rhs - maxactivity + maxleftactivity;
9366 
9367  /* check if the constraint contains variables which are redundant. The reasoning is the following:
9368  * Each non-redundant variable can make the lhs/rhs feasible with a deviation of only one in the bound.
9369  * If _all_ variables which are not non-redundant together cannot make lhs/rhs feasible,
9370  * they can be removed from the constraint.
9371  * aggrrhs may contain some near-infinity value, but only if rhs is infinity.
9372  */
9373  if( (SCIPisInfinity(scip, -consdata->lhs) || SCIPisFeasLT(scip, maxleftactivity, aggrlhs))
9374  && (SCIPisInfinity(scip, consdata->rhs) || SCIPisFeasGT(scip, minleftactivity, aggrrhs)) )
9375  {
9376  SCIP_Real minleftactivitypart;
9377  SCIP_Real maxleftactivitypart;
9378 
9379  assert(!SCIPisInfinity(scip, -consdata->lhs) || !SCIPisInfinity(scip, consdata->rhs));
9380 
9381  /* try to remove redundant variables from constraint */
9382  i = 0;
9383  while( i < consdata->nvars )
9384  {
9385  var = consdata->vars[i];
9386  minleftactivitypart = 0.0;
9387  maxleftactivitypart = 0.0;
9388  lb = SCIPvarGetLbLocal(var);
9389  ub = SCIPvarGetUbLocal(var);
9390 
9391  /* get coefficient and variable's bounds */
9392  val = consdata->vals[i];
9393  assert(!SCIPisZero(scip, val));
9394 
9395  /* check sign of coefficient */
9396  if( val >= 0.0 )
9397  {
9398  /* negation of condition above in case of positive val */
9400  SCIPisLT(scip, minactivity + val, consdata->lhs) || SCIPisGT(scip, maxactivity - val, consdata->rhs) )
9401  {
9402  SCIPdebugMsg(scip, "minactivity = %g\tval = %g\tlhs = %g\n", minactivity, val, consdata->lhs);
9403  SCIPdebugMsg(scip, "maxactivity = %g\tval = %g\trhs = %g\n", maxactivity, val, consdata->rhs);
9404  SCIPdebugMsg(scip, "linear constraint <%s>: remove variable <%s> with coefficient <%g> from constraint since it is redundant\n",
9405  SCIPconsGetName(cons), SCIPvarGetName(consdata->vars[i]), val);
9406 
9407  minleftactivitypart = val * lb;
9408  maxleftactivitypart = val * ub;
9409 
9410  SCIP_CALL( delCoefPos(scip, cons, i) );
9411  i--;
9412 
9413  /* get the new minimal and maximal activity of the constraint */
9414  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9415  &isminsettoinfinity, &ismaxsettoinfinity);
9416 
9417  /* we return above if the condition does not hold and deleting a variable cannot increase the number of
9418  * huge contributions
9419  */
9420  assert(!minactisrelax || SCIPisInfinity(scip, -consdata->lhs));
9421  assert(!maxactisrelax || SCIPisInfinity(scip, consdata->rhs));
9422  }
9423  }
9424  else
9425  {
9426  /* negation of condition above in case of negative val */
9428  SCIPisLT(scip, minactivity - val, consdata->lhs) || SCIPisGT(scip, maxactivity + val, consdata->rhs) )
9429  {
9430  SCIPdebugMsg(scip, "linear constraint <%s>: remove variable <%s> with coefficient <%g> from constraint since it is redundant\n",
9431  SCIPconsGetName(cons), SCIPvarGetName(consdata->vars[i]), val);
9432 
9433  minleftactivitypart = val * ub;
9434  maxleftactivitypart = val * lb;
9435 
9436  SCIP_CALL( delCoefPos(scip, cons, i) );
9437  i--;
9438 
9439  /* get the new minimal and maximal activity of the constraint */
9440  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9441  &isminsettoinfinity, &ismaxsettoinfinity);
9442 
9443  /* we return above if the condition does not hold and deleting a variable cannot increase the number of
9444  * huge contributions
9445  */
9446  assert(!minactisrelax || SCIPisInfinity(scip, -consdata->lhs));
9447  assert(!maxactisrelax || SCIPisInfinity(scip, consdata->rhs));
9448  }
9449  }
9450 
9451  /* the following update step is needed in every iteration cause otherwise it is possible that the surely none-
9452  * redundant variables could get deleted,
9453  * e.g. y_1 + 16y_2 >= 25, y1 with bounds [9,12], y2 with bounds [0,2], minactivity would be 9, it follows that
9454  * y_2 is surely not redundant and y_1 is redundant so we would first delete y1 and without updating the sides
9455  * we would also delete y2 and as a result we would have gotten infeasibility */
9456  /* adjust lhs and right hand side */
9457  newlhs = consdata->lhs - minleftactivitypart;
9458  newrhs = consdata->rhs - maxleftactivitypart;
9459 
9460  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisFeasEQ(scip, newlhs, consdata->lhs) )
9461  {
9462  SCIPdebugMsg(scip, "linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
9463  SCIP_CALL( chgLhs(scip, cons, newlhs) );
9464  ++(*nchgsides);
9465  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
9466  }
9467  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisFeasEQ(scip, newrhs, consdata->rhs) )
9468  {
9469  SCIPdebugMsg(scip, "linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
9470  SCIP_CALL( chgRhs(scip, cons, newrhs) );
9471  ++(*nchgsides);
9472  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
9473  }
9474  ++i;
9475  }
9476  }
9477 
9478  return SCIP_OKAY;
9479 }
9480 
9481 /** processes equality with only one variable by fixing the variable and deleting the constraint */
9482 static
9484  SCIP* scip, /**< SCIP data structure */
9485  SCIP_CONS* cons, /**< linear constraint */
9486  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
9487  int* nfixedvars, /**< pointer to count number of fixed variables */
9488  int* ndelconss /**< pointer to count number of deleted constraints */
9489  )
9490 {
9491  SCIP_CONSDATA* consdata;
9492  SCIP_VAR* var;
9493  SCIP_Real val;
9494  SCIP_Real fixval;
9495  SCIP_Bool infeasible;
9496  SCIP_Bool fixed;
9497 
9498  assert(scip != NULL);
9499  assert(cons != NULL);
9500  assert(cutoff != NULL);
9501  assert(nfixedvars != NULL);
9502  assert(ndelconss != NULL);
9503 
9504  consdata = SCIPconsGetData(cons);
9505  assert(consdata != NULL);
9506  assert(consdata->nvars == 1);
9507  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9508 
9509  /* calculate the value to fix the variable to */
9510  var = consdata->vars[0];
9511  val = consdata->vals[0];
9512  assert(!SCIPisZero(scip, val));
9513  fixval = SCIPselectSimpleValue(consdata->lhs/val - 0.9 * SCIPepsilon(scip),
9514  consdata->rhs/val + 0.9 * SCIPepsilon(scip), MAXDNOM);
9515  SCIPdebugMsg(scip, "linear equality <%s>: fix <%s> == %.15g\n",
9516  SCIPconsGetName(cons), SCIPvarGetName(var), fixval);
9517 
9518  /* fix variable */
9519  SCIP_CALL( SCIPfixVar(scip, var, fixval, &infeasible, &fixed) );
9520  if( infeasible )
9521  {
9522  SCIPdebugMsg(scip, " -> infeasible fixing\n");
9523  *cutoff = TRUE;
9524  return SCIP_OKAY;
9525  }
9526  if( fixed )
9527  (*nfixedvars)++;
9528 
9529  /* disable constraint */
9530  SCIP_CALL( SCIPdelCons(scip, cons) );
9531  if( !consdata->upgraded )
9532  (*ndelconss)++;
9533 
9534  return SCIP_OKAY;
9535 }
9536 
9537 /** processes equality with exactly two variables by aggregating one of the variables and deleting the constraint */
9538 static
9540  SCIP* scip, /**< SCIP data structure */
9541  SCIP_CONS* cons, /**< linear constraint */
9542  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
9543  int* naggrvars, /**< pointer to count number of aggregated variables */
9544  int* ndelconss /**< pointer to count number of deleted constraints */
9545  )
9546 {
9547  SCIP_CONSDATA* consdata;
9548  SCIP_Bool infeasible;
9549  SCIP_Bool redundant;
9550  SCIP_Bool aggregated;
9551 
9552  assert(scip != NULL);
9553  assert(cons != NULL);
9554  assert(cutoff != NULL);
9555  assert(naggrvars != NULL);
9556  assert(ndelconss != NULL);
9557 
9558  consdata = SCIPconsGetData(cons);
9559  assert(consdata != NULL);
9560  assert(consdata->nvars == 2);
9561  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9562 
9563  SCIPdebugMsg(scip, "linear constraint <%s>: aggregate %.15g<%s> + %.15g<%s> == %.15g\n",
9564  SCIPconsGetName(cons), consdata->vals[0], SCIPvarGetName(consdata->vars[0]),
9565  consdata->vals[1], SCIPvarGetName(consdata->vars[1]), consdata->rhs);
9566 
9567  /* aggregate the equality */
9568  SCIP_CALL( SCIPaggregateVars(scip, consdata->vars[0], consdata->vars[1], consdata->vals[0], consdata->vals[1],
9569  consdata->rhs, &infeasible, &redundant, &aggregated) );
9570 
9571  /* check for infeasibility of aggregation */
9572  if( infeasible )
9573  {
9574  SCIPdebugMsg(scip, " -> infeasible aggregation\n");
9575  *cutoff = TRUE;
9576  return SCIP_OKAY;
9577  }
9578 
9579  /* count the aggregation */
9580  if( aggregated )
9581  (*naggrvars)++;
9582 
9583  /* delete the constraint, if it is redundant */
9584  if( redundant )
9585  {
9586  SCIP_CALL( SCIPdelCons(scip, cons) );
9587 
9588  if( !consdata->upgraded )
9589  (*ndelconss)++;
9590  }
9591 
9592  return SCIP_OKAY;
9593 }
9594 
9595 /** calculates the new lhs and rhs of the constraint after the given variable is aggregated out */
9596 static
9598  SCIP* scip, /**< SCIP data structure */
9599  SCIP_CONSDATA* consdata, /**< linear constraint data */
9600  SCIP_VAR* slackvar, /**< variable to be aggregated out */
9601  SCIP_Real slackcoef, /**< coefficient of variable in constraint */
9602  SCIP_Real* newlhs, /**< pointer to store new lhs of constraint */
9603  SCIP_Real* newrhs /**< pointer to store new rhs of constraint */
9604  )
9605 {
9606  SCIP_Real slackvarlb;
9607  SCIP_Real slackvarub;
9608 
9609  assert(scip != NULL);
9610  assert(consdata != NULL);
9611  assert(newlhs != NULL);
9612  assert(newrhs != NULL);
9613  assert(!SCIPisInfinity(scip, -consdata->lhs));
9614  assert(!SCIPisInfinity(scip, consdata->rhs));
9615 
9616  slackvarlb = SCIPvarGetLbGlobal(slackvar);
9617  slackvarub = SCIPvarGetUbGlobal(slackvar);
9618  if( slackcoef > 0.0 )
9619  {
9620  if( SCIPisInfinity(scip, -slackvarlb) )
9621  *newrhs = SCIPinfinity(scip);
9622  else
9623  *newrhs = consdata->rhs - slackcoef * slackvarlb;
9624  if( SCIPisInfinity(scip, slackvarub) )
9625  *newlhs = -SCIPinfinity(scip);
9626  else
9627  *newlhs = consdata->lhs - slackcoef * slackvarub;
9628  }
9629  else
9630  {
9631  if( SCIPisInfinity(scip, -slackvarlb) )
9632  *newlhs = -SCIPinfinity(scip);
9633  else
9634  *newlhs = consdata->rhs - slackcoef * slackvarlb;
9635  if( SCIPisInfinity(scip, slackvarub) )
9636  *newrhs = SCIPinfinity(scip);
9637  else
9638  *newrhs = consdata->lhs - slackcoef * slackvarub;
9639  }
9640  assert(SCIPisLE(scip, *newlhs, *newrhs));
9641 }
9642 
9643 /** processes equality with more than two variables by multi-aggregating one of the variables and converting the equality
9644  * into an inequality; if multi-aggregation is not possible, tries to identify one continuous or integer variable that
9645  * is implicitly integral by this constraint
9646  *
9647  * @todo Check whether a more clever way of avoiding aggregation of variables containing implicitly integer variables
9648  * can help.
9649  */
9650 static
9652  SCIP* scip, /**< SCIP data structure */
9653  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
9654  SCIP_CONS* cons, /**< linear constraint */
9655  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
9656  int* naggrvars, /**< pointer to count number of aggregated variables */
9657  int* ndelconss /**< pointer to count number of deleted constraints */
9658  )
9659 {
9660  SCIP_CONSDATA* consdata;
9661  SCIP_VAR** vars;
9662  SCIP_Real* vals;
9663  SCIP_VARTYPE bestslacktype;
9664  SCIP_VARTYPE slacktype;
9665  SCIP_Real lhs;
9666  SCIP_Real rhs;
9667  SCIP_Real bestslackdomrng;
9668  SCIP_Real minabsval;
9669  SCIP_Real maxabsval;
9670  SCIP_Bool bestremovescons;
9671  SCIP_Bool coefszeroone;
9672  SCIP_Bool coefsintegral;
9673  SCIP_Bool varsintegral;
9674  SCIP_Bool infeasible;
9675  SCIP_Bool samevar;
9676  int supinf; /* counter for infinite contributions to the supremum of a possible
9677  * multi-aggregation
9678  */
9679  int infinf; /* counter for infinite contributions to the infimum of a possible
9680  * multi-aggregation
9681  */
9682  int maxnlocksstay;
9683  int maxnlocksremove;
9684  int bestslackpos;
9685  int bestnlocks;
9686  int ncontvars;
9687  int contvarpos;
9688  int nintvars;
9689  int nimplvars;
9690  int intvarpos;
9691  int v;
9692 
9693  assert(scip != NULL);
9694  assert(cons != NULL);
9695  assert(cutoff != NULL);
9696  assert(naggrvars != NULL);
9697 
9698  consdata = SCIPconsGetData(cons);
9699  assert(consdata != NULL);
9700  assert(consdata->nvars > 2);
9701  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9702 
9703  SCIPdebugMsg(scip, "linear constraint <%s>: try to multi-aggregate equality\n", SCIPconsGetName(cons));
9704 
9705  /* We do not want to increase the total number of non-zeros due to the multi-aggregation.
9706  * Therefore, we have to restrict the number of locks of a variable that is aggregated out.
9707  * maxnlocksstay: maximal sum of lock numbers if the constraint does not become redundant after the aggregation
9708  * maxnlocksremove: maximal sum of lock numbers if the constraint can be deleted after the aggregation
9709  */
9710  lhs = consdata->lhs;
9711  rhs = consdata->rhs;
9712  maxnlocksstay = 0;
9713  if( consdata->nvars == 3 )
9714  {
9715  /* If the constraint becomes redundant, 3 non-zeros are removed, and we get 1 additional non-zero for each
9716  * constraint the variable appears in. Thus, the variable must appear in at most 3 other constraints.
9717  */
9718  maxnlocksremove = 3;
9719  }
9720  else if( consdata->nvars == 4 )
9721  {
9722  /* If the constraint becomes redundant, 4 non-zeros are removed, and we get 2 additional non-zeros for each
9723  * constraint the variable appears in. Thus, the variable must appear in at most 2 other constraints.
9724  */
9725  maxnlocksremove = 2;
9726  }
9727  else
9728  {
9729  /* If the constraint is redundant but has more than 4 variables, we can only accept one other constraint. */
9730  maxnlocksremove = 1;
9731  }
9732 
9733  /* the locks on this constraint can be ignored */
9734  if( SCIPconsIsChecked(cons) )
9735  {
9736  if( !SCIPisInfinity(scip, -lhs) )
9737  {
9738  maxnlocksstay++;
9739  maxnlocksremove++;
9740  }
9741  if( !SCIPisInfinity(scip, rhs) )
9742  {
9743  maxnlocksstay++;
9744  maxnlocksremove++;
9745  }
9746  }
9747 
9748  /* look for a slack variable s to convert a*x + s == b into lhs <= a*x <= rhs */
9749  vars = consdata->vars;
9750  vals = consdata->vals;
9751  bestslackpos = -1;
9752  bestslacktype = SCIP_VARTYPE_BINARY;
9753  bestnlocks = INT_MAX;
9754  bestremovescons = FALSE;
9755  bestslackdomrng = 0.0;
9756  coefszeroone = TRUE;
9757  coefsintegral = TRUE;
9758  varsintegral = TRUE;
9759  ncontvars = 0;
9760  contvarpos = -1;
9761  nintvars = 0;
9762  nimplvars = 0;
9763  intvarpos = -1;
9764  minabsval = SCIPinfinity(scip);
9765  maxabsval = -1.0;
9766  for( v = 0; v < consdata->nvars; ++v )
9767  {
9768  SCIP_VAR* var;
9769  SCIP_Real val;
9770  SCIP_Real absval;
9771  SCIP_Real varlb;
9772  SCIP_Real varub;
9773  SCIP_Bool iscont;
9774  int nlocks;
9775 
9776  assert(vars != NULL);
9777  assert(vals != NULL);
9778 
9779  var = vars[v];
9780  assert(!SCIPconsIsChecked(cons) || SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) >= 1); /* because variable is locked in this equality */
9781  assert(!SCIPconsIsChecked(cons) || SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) >= 1);
9782  varlb = SCIPvarGetLbGlobal(var);
9783  varub = SCIPvarGetUbGlobal(var);
9784 
9785  val = vals[v];
9786  absval = REALABS(val);
9787  assert(SCIPisPositive(scip, absval));
9788 
9789  /* calculate minimal and maximal absolute value */
9790  if( absval < minabsval )
9791  minabsval = absval;
9792  if( absval > maxabsval )
9793  maxabsval = absval;
9794 
9795  /* do not try to multi aggregate, when numerical bad */
9796  if( maxabsval / minabsval > conshdlrdata->maxmultaggrquot )
9797  return SCIP_OKAY;
9798 
9799  slacktype = SCIPvarGetType(var);
9800  coefszeroone = coefszeroone && SCIPisEQ(scip, absval, 1.0);
9801  coefsintegral = coefsintegral && SCIPisIntegral(scip, val);
9802  varsintegral = varsintegral && (slacktype != SCIP_VARTYPE_CONTINUOUS);
9803  iscont = (slacktype == SCIP_VARTYPE_CONTINUOUS || slacktype == SCIP_VARTYPE_IMPLINT);
9804 
9805  /* update candidates for continuous -> implint and integer -> implint conversion */
9806  if( slacktype == SCIP_VARTYPE_CONTINUOUS )
9807  {
9808  ncontvars++;
9809  contvarpos = v;
9810  }
9811  else if( slacktype == SCIP_VARTYPE_IMPLINT )
9812  {
9813  ++nimplvars;
9814  }
9815  else if( slacktype == SCIP_VARTYPE_INTEGER )
9816  {
9817  nintvars++;
9818  intvarpos = v;
9819  }
9820 
9821  /* check, if variable is already fixed or aggregated */
9822  if( !SCIPvarIsActive(var) )
9823  continue;
9824 
9825  /* check, if variable is used in too many other constraints, even if this constraint could be deleted */
9827 
9828  if( nlocks > maxnlocksremove )
9829  continue;
9830 
9831  /* check, if variable can be used as a slack variable */
9832  if( (iscont || (coefsintegral && varsintegral && SCIPisEQ(scip, absval, 1.0))) &&
9833  !SCIPdoNotMultaggrVar(scip, var) )
9834  {
9835  SCIP_Bool better;
9836  SCIP_Bool equal;
9837  SCIP_Real slackdomrng;
9838 
9839  if( SCIPisInfinity(scip, varub) || SCIPisInfinity(scip, -varlb) )
9840  slackdomrng = SCIPinfinity(scip);
9841  /* we do not want to perform multi-aggregation due to numerics, if the bounds are huge */
9842  else if( SCIPisHugeValue(scip, varub) || SCIPisHugeValue(scip, -varlb) )
9843  return SCIP_OKAY;
9844  else
9845  {
9846  slackdomrng = (varub - varlb)*absval;
9847  assert(!SCIPisInfinity(scip, slackdomrng));
9848  }
9849  equal = FALSE;
9850  better = (slacktype > bestslacktype) || (bestslackpos == -1);
9851  if( !better && slacktype == bestslacktype )
9852  {
9853  better = (nlocks < bestnlocks);
9854  if( nlocks == bestnlocks && !bestremovescons )
9855  {
9856  better = SCIPisGT(scip, slackdomrng, bestslackdomrng);
9857  equal = !better && SCIPisGE(scip, slackdomrng, bestslackdomrng);
9858  }
9859  }
9860 
9861  if( better || equal )
9862  {
9863  SCIP_Real minresactivity;
9864  SCIP_Real maxresactivity;
9865  SCIP_Real newlhs;
9866  SCIP_Real newrhs;
9867  SCIP_Bool removescons;
9868  SCIP_Bool minisrelax;
9869  SCIP_Bool maxisrelax;
9870  SCIP_Bool isminsettoinfinity;
9871  SCIP_Bool ismaxsettoinfinity;
9872 
9873  /* check if the constraint becomes redundant after multi-aggregation */
9874  consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
9875  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
9876 
9877  /* do not perform the multi-aggregation due to numerics, if we have huge contributions in the residual
9878  * activity
9879  */
9880  if( minisrelax || maxisrelax )
9881  continue;
9882 
9883  getNewSidesAfterAggregation(scip, consdata, var, val, &newlhs, &newrhs);
9884  removescons = (SCIPisFeasLE(scip, newlhs, minresactivity) && SCIPisFeasLE(scip, maxresactivity, newrhs));
9885 
9886  /* check resactivities for reliability */
9887  if( removescons )
9888  {
9889  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
9890  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
9891 
9892  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity)
9893  && SCIPisFeasLE(scip, newlhs, minresactivity))
9894  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
9895 
9896  removescons = (SCIPisFeasLE(scip, newlhs, minresactivity) && SCIPisFeasLE(scip, maxresactivity, newrhs));
9897  }
9898 
9899  /* if parameter multaggrremove is set to TRUE, only aggregate when this removes constraint */
9900  if( conshdlrdata->multaggrremove && !removescons )
9901  continue;
9902 
9903  /* prefer variables that make the constraints redundant */
9904  if( bestremovescons && !removescons )
9905  continue;
9906 
9907  /* if the constraint does not become redundant, only accept the variable if it does not appear in
9908  * other constraints
9909  */
9910  if( !removescons && nlocks > maxnlocksstay )
9911  continue;
9912 
9913  better = better || (!bestremovescons && removescons);
9914  if( better )
9915  {
9916  bestslackpos = v;
9917  bestslacktype = slacktype;
9918  bestnlocks = nlocks;
9919  bestslackdomrng = slackdomrng;
9920  bestremovescons = removescons;
9921  }
9922  }
9923  }
9924  }
9925 
9926  /* if all coefficients and variables are integral, the right hand side must also be integral */
9927  if( coefsintegral && varsintegral && !SCIPisFeasIntegral(scip, consdata->rhs) )
9928  {
9929  SCIPdebugMsg(scip, "linear equality <%s> is integer infeasible\n", SCIPconsGetName(cons));
9930  SCIPdebugPrintCons(scip, cons, NULL);
9931  *cutoff = TRUE;
9932  return SCIP_OKAY;
9933  }
9934 
9935  supinf = 0;
9936  infinf = 0;
9937  samevar = FALSE;
9938 
9939  /* check whether the the infimum and the supremum of the multi-aggregation can be get infinite */
9940  for( v = 0; v < consdata->nvars; ++v )
9941  {
9942  if( v != bestslackpos )
9943  {
9944  if( SCIPisPositive(scip, consdata->vals[v]) )
9945  {
9946  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
9947  {
9948  ++supinf;
9949  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
9950  {
9951  ++infinf;
9952  samevar = TRUE;
9953  }
9954  }
9955  else if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
9956  ++infinf;
9957  }
9958  else if( SCIPisNegative(scip, consdata->vals[v]) )
9959  {
9960  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
9961  {
9962  ++supinf;
9963  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
9964  {
9965  ++infinf;
9966  samevar = TRUE;
9967  }
9968  }
9969  else if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
9970  ++infinf;
9971  }
9972  }
9973  }
9974  assert(!samevar || (supinf > 0 && infinf > 0));
9975 
9976  /* If the infimum and the supremum of a multi-aggregation are both infinite, then the multi-aggregation might not be resolvable.
9977  * E.g., consider the equality z = x-y. If x and y are both fixed to +infinity, the value for z is not determined */
9978  if( (samevar && (supinf > 1 || infinf > 1)) || (!samevar && supinf > 0 && infinf > 0) )
9979  {
9980  SCIPdebugMsg(scip, "do not perform multi-aggregation: infimum and supremum are both infinite\n");
9981  return SCIP_OKAY;
9982  }
9983 
9984  /* if the slack variable is of integer type, and the constraint itself may take fractional values,
9985  * we cannot aggregate the variable, because the integrality condition would get lost
9986  * Similarly, if there are implicitly integral variables we cannot aggregate, since we might
9987  * loose the integrality condition for this variable.
9988  */
9989  if( bestslackpos >= 0
9990  && (bestslacktype == SCIP_VARTYPE_CONTINUOUS || bestslacktype == SCIP_VARTYPE_IMPLINT
9991  || (coefsintegral && varsintegral && nimplvars == 0)) )
9992  {
9993  SCIP_VAR* slackvar;
9994  SCIP_Real* scalars;
9995  SCIP_Real slackcoef;
9996  SCIP_Real aggrconst;
9997  SCIP_Real newlhs;
9998  SCIP_Real newrhs;
9999  SCIP_Bool aggregated;
10000 
10001  /* we found a slack variable that only occurs in at most one other constraint:
10002  * a_1*x_1 + ... + a_k*x_k + a'*s == rhs -> s == rhs - a_1/a'*x_1 - ... - a_k/a'*x_k
10003  */
10004  assert(bestslackpos < consdata->nvars);
10005 
10006  /* do not multi aggregate binary variables */
10007  if( SCIPvarIsBinary(vars[bestslackpos]) )
10008  return SCIP_OKAY;
10009 
10010  /* convert equality into inequality by deleting the slack variable:
10011  * x + a*s == b, l <= s <= u -> b - a*u <= x <= b - a*l
10012  */
10013  slackvar = vars[bestslackpos];
10014  slackcoef = vals[bestslackpos];
10015  assert(!SCIPisZero(scip, slackcoef));
10016  aggrconst = consdata->rhs/slackcoef;
10017 
10018  getNewSidesAfterAggregation(scip, consdata, slackvar, slackcoef, &newlhs, &newrhs);
10019  assert(SCIPisLE(scip, newlhs, newrhs));
10020  SCIP_CALL( chgLhs(scip, cons, newlhs) );
10021  SCIP_CALL( chgRhs(scip, cons, newrhs) );
10022  SCIP_CALL( delCoefPos(scip, cons, bestslackpos) );
10023 
10024  /* allocate temporary memory */
10025  SCIP_CALL( SCIPallocBufferArray(scip, &scalars, consdata->nvars) );
10026 
10027  /* set up the multi-aggregation */
10028  SCIPdebugMsg(scip, "linear constraint <%s>: multi-aggregate <%s> ==", SCIPconsGetName(cons), SCIPvarGetName(slackvar));
10029  for( v = 0; v < consdata->nvars; ++v )
10030  {
10031  scalars[v] = -consdata->vals[v]/slackcoef;
10032  SCIPdebugMsgPrint(scip, " %+.15g<%s>", scalars[v], SCIPvarGetName(vars[v]));
10033  }
10034  SCIPdebugMsgPrint(scip, " %+.15g, bounds of <%s>: [%.15g,%.15g], nlocks=%d, maxnlocks=%d, removescons=%u\n",
10035  aggrconst, SCIPvarGetName(slackvar), SCIPvarGetLbGlobal(slackvar), SCIPvarGetUbGlobal(slackvar),
10036  bestnlocks, bestremovescons ? maxnlocksremove : maxnlocksstay, bestremovescons);
10037 
10038  /* perform the multi-aggregation */
10039  SCIP_CALL( SCIPmultiaggregateVar(scip, slackvar, consdata->nvars, vars, scalars, aggrconst,
10040  &infeasible, &aggregated) );
10041  assert(aggregated);
10042 
10043  /* free temporary memory */
10044  SCIPfreeBufferArray(scip, &scalars);
10045 
10046  /* check for infeasible aggregation */
10047  if( infeasible )
10048  {
10049  SCIPdebugMsg(scip, "linear constraint <%s>: infeasible multi-aggregation\n", SCIPconsGetName(cons));
10050  *cutoff = TRUE;
10051  return SCIP_OKAY;
10052  }
10053 
10054  (*naggrvars)++;
10055 
10056  /* delete the constraint if it became redundant */
10057  if( bestremovescons )
10058  {
10059  SCIPdebugMsg(scip, "linear constraint <%s>: redundant after multi-aggregation\n", SCIPconsGetName(cons));
10060  SCIP_CALL( SCIPdelCons(scip, cons) );
10061 
10062  if( !consdata->upgraded )
10063  (*ndelconss)++;
10064  }
10065  }
10066  else if( ncontvars == 1 )
10067  {
10068  SCIP_VAR* var;
10069 
10070  assert(0 <= contvarpos && contvarpos < consdata->nvars);
10071  var = vars[contvarpos];
10072  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
10073 
10074  if( coefsintegral && SCIPisFeasIntegral(scip, consdata->rhs) )
10075  {
10076  /* upgrade continuous variable to an implicit one, if the absolute value of the coefficient is one */
10077  if( SCIPisEQ(scip, REALABS(vals[contvarpos]), 1.0) )
10078  {
10079  /* convert the continuous variable with coefficient 1.0 into an implicit integer variable */
10080  SCIPdebugMsg(scip, "linear constraint <%s>: converting continuous variable <%s> to implicit integer variable\n",
10081  SCIPconsGetName(cons), SCIPvarGetName(var));
10082  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
10083  if( infeasible )
10084  {
10085  SCIPdebugMsg(scip, "infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
10086  *cutoff = TRUE;
10087 
10088  return SCIP_OKAY;
10089  }
10090  }
10091  /* aggregate continuous variable to an implicit one, if the absolute value of the coefficient is unequal to one */
10092  /* @todo check if the aggregation coefficient should be in some range(, which is not too big) */
10093  else if( !SCIPdoNotAggr(scip) )
10094  {
10095  SCIP_VAR* newvar;
10096  SCIP_Real absval;
10097  char newvarname[SCIP_MAXSTRLEN];
10098  SCIP_Bool redundant;
10099  SCIP_Bool aggregated;
10100 
10101  absval = REALABS(vals[contvarpos]);
10102 
10103  (void) SCIPsnprintf(newvarname, SCIP_MAXSTRLEN, "%s_impl", SCIPvarGetName(var));
10104 
10105  /* create new implicit variable for aggregation */
10106  SCIP_CALL( SCIPcreateVar(scip, &newvar, newvarname, -SCIPinfinity(scip), SCIPinfinity(scip), 0.0,
10108 
10109  /* add new variable to problem */
10110  SCIP_CALL( SCIPaddVar(scip, newvar) );
10111 
10112 #ifdef WITH_DEBUG_SOLUTION
10113  if( SCIPdebugIsMainscip(scip) )
10114  {
10115  SCIP_Real varval;
10116  SCIP_CALL( SCIPdebugGetSolVal(scip, var, &varval) );
10117  SCIP_CALL( SCIPdebugAddSolVal(scip, newvar, absval * varval) );
10118  }
10119 #endif
10120 
10121  /* convert the continuous variable with coefficient 1.0 into an implicit integer variable */
10122  SCIPdebugMsg(scip, "linear constraint <%s>: aggregating continuous variable <%s> to newly created implicit integer variable <%s>, aggregation factor = %g\n",
10123  SCIPconsGetName(cons), SCIPvarGetName(var), SCIPvarGetName(newvar), absval);
10124 
10125  /* aggregate continuous and implicit variable */
10126  SCIP_CALL( SCIPaggregateVars(scip, var, newvar, absval, -1.0, 0.0, &infeasible, &redundant, &aggregated) );
10127 
10128  if( infeasible )
10129  {
10130  SCIPdebugMsg(scip, "infeasible aggregation of variable <%s> to implicit variable <%s>, domain is empty\n",
10131  SCIPvarGetName(var), SCIPvarGetName(newvar));
10132  *cutoff = TRUE;
10133 
10134  /* release implicit variable */
10135  SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
10136 
10137  return SCIP_OKAY;
10138  }
10139 
10140  /* release implicit variable */
10141  SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
10142 
10143  if( aggregated )
10144  (*naggrvars)++;
10145  else
10146  return SCIP_OKAY;
10147  }
10148 
10149  /* we do not have any event on vartype changes, so we need to manually force this constraint to be presolved
10150  * again
10151  */
10152  consdata->boundstightened = 0;
10153  consdata->rangedrowpropagated = 0;
10154  consdata->presolved = FALSE;
10155  }
10156  }
10157  else if( ncontvars == 0 && nimplvars == 0 && nintvars == 1 && !coefszeroone )
10158  {
10159  SCIP_VAR* var;
10160 
10161  /* this seems to help for rococo instances, but does not for rout (where all coefficients are +/- 1.0)
10162  * -> we don't convert integers into implints if the row is a 0/1-row
10163  */
10164  assert(varsintegral);
10165  assert(0 <= intvarpos && intvarpos < consdata->nvars);
10166  var = vars[intvarpos];
10167  assert(SCIPvarGetType(var) == SCIP_VARTYPE_INTEGER);
10168 
10169  if( coefsintegral
10170  && SCIPisEQ(scip, REALABS(vals[intvarpos]), 1.0)
10171  && SCIPisFeasIntegral(scip, consdata->rhs) )
10172  {
10173  /* convert the integer variable with coefficient 1.0 into an implicit integer variable */
10174  SCIPdebugMsg(scip, "linear constraint <%s>: converting integer variable <%s> to implicit integer variable\n",
10175  SCIPconsGetName(cons), SCIPvarGetName(var));
10176  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
10177  if( infeasible )
10178  {
10179  SCIPdebugMsg(scip, "infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
10180  *cutoff = TRUE;
10181 
10182  return SCIP_OKAY;
10183  }
10184  }
10185  }
10186 
10187  return SCIP_OKAY;
10188 }
10189 
10190 /** checks if the given variables and their coefficient are equal (w.r.t. scaling factor) to the objective function */
10191 static
10193  SCIP* scip, /**< SCIP data structure */
10194  SCIP_CONSDATA* consdata, /**< linear constraint data */
10195  SCIP_Real* scale, /**< pointer to store the scaling factor between the constraint and the
10196  * objective function */
10197  SCIP_Real* offset /**< pointer to store the offset of the objective function resulting by
10198  * this constraint */
10199  )
10200 {
10201  SCIP_VAR** vars;
10202  SCIP_VAR* var;
10203  SCIP_Real objval;
10204  SCIP_Bool negated;
10205  int nvars;
10206  int v;
10207 
10208  vars = consdata->vars;
10209  nvars = consdata->nvars;
10210 
10211  assert(vars != NULL);
10212 
10213  for( v = 0; v < nvars; ++v )
10214  {
10215  negated = FALSE;
10216  var = vars[v];
10217  assert(var != NULL);
10218 
10219  if( SCIPvarIsNegated(var) )
10220  {
10221  negated = TRUE;
10222  var = SCIPvarGetNegatedVar(var);
10223  assert(var != NULL);
10224  }
10225 
10226  objval = SCIPvarGetObj(var);
10227 
10228  /* if a variable has a zero objective coefficient the linear constraint is not a subset of the objective
10229  * function
10230  */
10231  if( SCIPisZero(scip, objval) )
10232  return FALSE;
10233  else
10234  {
10235  SCIP_Real val;
10236 
10237  val = consdata->vals[v];
10238 
10239  if( negated )
10240  {
10241  if( v == 0 )
10242  {
10243  /* the first variable defines the scale */
10244  (*scale) = val / -objval;
10245 
10246  (*offset) += val;
10247  }
10248  else if( SCIPisEQ(scip, -objval * (*scale), val) )
10249  (*offset) += val;
10250  else
10251  return FALSE;
10252  }
10253  else if( v == 0 )
10254  {
10255  /* the first variable defines the scale */
10256  (*scale) = val / objval;
10257  }
10258  else if( !SCIPisEQ(scip, objval * (*scale), val) )
10259  return FALSE;
10260  }
10261  }
10262 
10263  return TRUE;
10264 }
10265 
10266 /** check if the linear equality constraint is equal to a subset of the objective function; if so we can remove the
10267  * objective coefficients and add an objective offset
10268  */
10269 static
10271  SCIP* scip, /**< SCIP data structure */
10272  SCIP_CONS* cons, /**< linear equation constraint */
10273  SCIP_CONSHDLRDATA* conshdlrdata /**< linear constraint handler data */
10274  )
10275 {
10276  SCIP_CONSDATA* consdata;
10277  SCIP_Real offset;
10278  SCIP_Real scale;
10279  SCIP_Bool applicable;
10280  int nobjvars;
10281  int nvars;
10282  int v;
10283 
10284  assert(scip != NULL);
10285  assert(cons != NULL);
10286  assert(conshdlrdata != NULL);
10288  consdata = SCIPconsGetData(cons);
10289  assert(consdata != NULL);
10290  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
10291 
10292  nvars = consdata->nvars;
10293  nobjvars = SCIPgetNObjVars(scip);
10294 
10295  /* check if the linear equality constraints does not have more variables than the objective function */
10296  if( nvars > nobjvars || nvars == 0 )
10297  return SCIP_OKAY;
10298 
10299  /* check for allowance of algorithm */
10300  if( (nvars < nobjvars && !conshdlrdata->detectpartialobjective) ||
10301  (nvars == nobjvars && (!conshdlrdata->detectcutoffbound || !conshdlrdata->detectlowerbound)) )
10302  return SCIP_OKAY;
10303 
10304  offset = consdata->rhs;
10305  scale = 1.0;
10306 
10307  /* checks if the variables and their coefficients are equal (w.r.t. scaling factor) to the objective function */
10308  applicable = checkEqualObjective(scip, consdata, &scale, &offset);
10309 
10310  if( applicable )
10311  {
10312  SCIP_VAR** vars;
10313 
10314  vars = consdata->vars;
10315  assert(vars != NULL);
10316 
10317  offset /= scale;
10318 
10319  SCIPdebugMsg(scip, "linear equality constraint <%s> == %g (offset %g) is a subset of the objective function\n",
10320  SCIPconsGetName(cons), consdata->rhs, offset);
10321 
10322  /* set all objective coefficient to zero */
10323  for( v = 0; v < nvars; ++v )
10324  {
10325  SCIP_CALL( SCIPchgVarObj(scip, vars[v], 0.0) );
10326  }
10327 
10328  /* add an objective offset */
10329  SCIP_CALL( SCIPaddObjoffset(scip, offset) );
10330  }
10331 
10332  return SCIP_OKAY;
10333 }
10334 
10335 /** updates the cutoff if the given primal bound (which is implied by the given constraint) is better */
10336 static
10338  SCIP* scip, /**< SCIP data structure */
10339  SCIP_CONS* cons, /**< constraint */
10340  SCIP_Real primalbound /**< feasible primal bound */
10341  )
10342 {
10343  SCIP_Real cutoffbound;
10344 
10345  /* increase the cutoff bound value by an epsilon to ensue that solution with the value of the cutoff bound are still
10346  * accepted
10347  */
10348  cutoffbound = primalbound + SCIPcutoffbounddelta(scip);
10349 
10350  if( cutoffbound < SCIPgetCutoffbound(scip) )
10351  {
10352  SCIPdebugMsg(scip, "update cutoff bound <%g>\n", cutoffbound);
10353 
10354  SCIP_CALL( SCIPupdateCutoffbound(scip, cutoffbound) );
10355  }
10356  else
10357  {
10358  SCIP_CONSDATA* consdata;
10359 
10360  consdata = SCIPconsGetData(cons);
10361  assert(consdata != NULL);
10362 
10363  /* we cannot disable the enforcement and propagation on ranged rows, because the cutoffbound could only have
10364  * resulted from one side
10365  */
10366  if( SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, consdata->rhs) )
10367  {
10368  /* in case the cutoff bound is worse then the currently known one, we additionally avoid enforcement and
10369  * propagation
10370  */
10371  SCIP_CALL( SCIPsetConsEnforced(scip, cons, FALSE) );
10372  SCIP_CALL( SCIPsetConsPropagated(scip, cons, FALSE) );
10373  }
10374  }
10375 
10376  return SCIP_OKAY;
10377 }
10378 
10379 /** check if the linear constraint is parallel to objective function; if so update the cutoff bound and avoid that the
10380  * constraint enters the LP by setting the initial and separated flag to FALSE
10381  */
10382 static
10384  SCIP* scip, /**< SCIP data structure */
10385  SCIP_CONS* cons, /**< linear constraint */
10386  SCIP_CONSHDLRDATA* conshdlrdata /**< linear constraint handler data */
10387  )
10388 {
10389  SCIP_CONSDATA* consdata;
10390  SCIP_Real offset;
10391  SCIP_Real scale;
10392  SCIP_Bool applicable;
10393  int nobjvars;
10394  int nvars;
10395 
10396  assert(scip != NULL);
10397  assert(cons != NULL);
10398  assert(conshdlrdata != NULL);
10399 
10400  consdata = SCIPconsGetData(cons);
10401  assert(consdata != NULL);
10402 
10403  /* ignore equalities since these are covered by the method checkPartialObjective() */
10404  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
10405  return SCIP_OKAY;
10406 
10407  nvars = consdata->nvars;
10408  nobjvars = SCIPgetNObjVars(scip);
10409 
10410  /* check if the linear inequality constraints has the same number of variables as the objective function and if the
10411  * initial and/or separated flag is set to FALSE
10412  */
10413  if( nvars != nobjvars || (!SCIPconsIsInitial(cons) && !SCIPconsIsSeparated(cons)) )
10414  return SCIP_OKAY;
10415 
10416  offset = 0.0;
10417  scale = 1.0;
10418 
10419  /* There are no variables in the ojective function and in the constraint. Thus, the constraint is redundant or proves
10420  * infeasibility. Since we have a pure feasibility problem, we do not want to set a cutoff or lower bound.
10421  */
10422  if( nobjvars == 0 )
10423  return SCIP_OKAY;
10424 
10425  /* checks if the variables and their coefficients are equal (w.r.t. scaling factor) to the objective function */
10426  applicable = checkEqualObjective(scip, consdata, &scale, &offset);
10427 
10428  if( applicable )
10429  {
10430  SCIP_Bool rhsfinite = !SCIPisInfinity(scip, consdata->rhs);
10431  SCIP_Bool lhsfinite = !SCIPisInfinity(scip, -consdata->lhs);
10432 
10433  if( SCIPisPositive(scip, scale) )
10434  {
10435  if( conshdlrdata->detectcutoffbound && rhsfinite )
10436  {
10437  SCIP_Real primalbound;
10438 
10439  primalbound = (consdata->rhs - offset) / scale;
10440 
10441  SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a cutoff bound <%g>\n",
10442  SCIPconsGetName(cons), primalbound);
10443 
10444  SCIP_CALL( updateCutoffbound(scip, cons, primalbound) );
10445  }
10446 
10447  if( conshdlrdata->detectlowerbound && lhsfinite )
10448  {
10449  SCIP_Real lowerbound;
10450 
10451  lowerbound = (consdata->lhs - offset) / scale;
10452 
10453  SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a lower bound <%g>\n",
10454  SCIPconsGetName(cons), lowerbound);
10455 
10456  SCIP_CALL( SCIPupdateLocalLowerbound(scip, lowerbound) );
10457  }
10458 
10459  if( (conshdlrdata->detectcutoffbound && (conshdlrdata->detectlowerbound || !lhsfinite)) ||
10460  (conshdlrdata->detectlowerbound && !rhsfinite) )
10461  {
10462  /* avoid that the linear constraint enters the LP since it is parallel to the objective function */
10463  SCIP_CALL( SCIPsetConsInitial(scip, cons, FALSE) );
10464  SCIP_CALL( SCIPsetConsSeparated(scip, cons, FALSE) );
10465  }
10466  }
10467  else
10468  {
10469  if( conshdlrdata->detectlowerbound && rhsfinite )
10470  {
10471  SCIP_Real lowerbound;
10472 
10473  lowerbound = (consdata->rhs - offset) / scale;
10474 
10475  SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a lower bound <%g>\n",
10476  SCIPconsGetName(cons), lowerbound);
10477 
10478  SCIP_CALL( SCIPupdateLocalLowerbound(scip, lowerbound) );
10479  }
10480 
10481  if( conshdlrdata->detectcutoffbound && lhsfinite )
10482  {
10483  SCIP_Real primalbound;
10484 
10485  primalbound = (consdata->lhs - offset) / scale;
10486 
10487  SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a cutoff bound <%g>\n",
10488  SCIPconsGetName(cons), primalbound);
10489 
10490  SCIP_CALL( updateCutoffbound(scip, cons, primalbound) );
10491  }
10492 
10493  if( (conshdlrdata->detectcutoffbound && (conshdlrdata->detectlowerbound || !rhsfinite)) ||
10494  (conshdlrdata->detectlowerbound && !lhsfinite) )
10495  {
10496  /* avoid that the linear constraint enters the LP since it is parallel to the objective function */
10497  SCIP_CALL( SCIPsetConsInitial(scip, cons, FALSE) );
10498  SCIP_CALL( SCIPsetConsSeparated(scip, cons, FALSE) );
10499  }
10500  }
10501  }
10502 
10503  return SCIP_OKAY;
10504 }
10505 
10506 /** converts special equalities */
10507 static
10509  SCIP* scip, /**< SCIP data structure */
10510  SCIP_CONS* cons, /**< linear constraint */
10511  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
10512  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
10513  int* nfixedvars, /**< pointer to count number of fixed variables */
10514  int* naggrvars, /**< pointer to count number of aggregated variables */
10515  int* ndelconss /**< pointer to count number of deleted constraints */
10516  )
10517 {
10518  SCIP_CONSDATA* consdata;
10519 
10520  assert(scip != NULL);
10521  assert(cons != NULL);
10522  assert(conshdlrdata != NULL);
10523  assert(cutoff != NULL);
10524  assert(nfixedvars != NULL);
10525  assert(naggrvars != NULL);
10526  assert(ndelconss != NULL);
10527 
10528  consdata = SCIPconsGetData(cons);
10529  assert(consdata != NULL);
10530  assert(consdata->removedfixings);
10531 
10532  /* do nothing on inequalities */
10533  if( !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
10534  return SCIP_OKAY;
10535 
10536  /* depending on the number of variables, call a special conversion method */
10537  if( consdata->nvars == 1 )
10538  {
10539  /* fix variable */
10540  SCIP_CALL( convertUnaryEquality(scip, cons, cutoff, nfixedvars, ndelconss) );
10541  }
10542  else if( consdata->nvars == 2 )
10543  {
10544  /* aggregate one of the variables */
10545  SCIP_CALL( convertBinaryEquality(scip, cons, cutoff, naggrvars, ndelconss) );
10546  }
10547  else
10548  {
10549  /* check if the equality is part of the objective function */
10550  SCIP_CALL( checkPartialObjective(scip, cons, conshdlrdata) );
10551 
10552  /* try to multi-aggregate one of the variables */
10553  SCIP_CALL( convertLongEquality(scip, conshdlrdata, cons, cutoff, naggrvars, ndelconss) );
10554  }
10555 
10556  return SCIP_OKAY;
10557 }
10558 
10559 /** returns whether the linear sum of all variables/coefficients except the given one divided by the given value is always
10560  * integral
10561  */
10562 static
10564  SCIP* scip, /**< SCIP data structure */
10565  SCIP_CONSDATA* consdata, /**< linear constraint */
10566  int pos, /**< position of variable to be left out */
10567  SCIP_Real val /**< value to divide the coefficients by */
10568  )
10569 {
10570  int v;
10571 
10572  assert(scip != NULL);
10573  assert(consdata != NULL);
10574  assert(0 <= pos && pos < consdata->nvars);
10575 
10576  for( v = 0; v < consdata->nvars; ++v )
10577  {
10578  if( v != pos && (!SCIPvarIsIntegral(consdata->vars[v]) || !SCIPisIntegral(scip, consdata->vals[v]/val)) )
10579  return FALSE;
10580  }
10581 
10582  return TRUE;
10583 }
10584 
10585 /** 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$,
10586  * 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$
10587  */
10588 static
10590  SCIP* scip, /**< SCIP data structure */
10591  SCIP_Real side, /**< lhs or rhs */
10592  SCIP_Real val, /**< coefficient */
10593  SCIP_Real minresactivity, /**< minimal residual activity */
10594  SCIP_Real maxresactivity, /**< maximal residual activity */
10595  SCIP_Real* minval, /**< pointer to store calculated minval */
10596  SCIP_Real* maxval /**< pointer to store calculated maxval */
10597  )
10598 {
10599  assert(scip != NULL);
10600  assert(minval != NULL);
10601  assert(maxval != NULL);
10602 
10603  if( val > 0.0 )
10604  {
10605  if( SCIPisInfinity(scip, ABS(maxresactivity)) )
10606  *minval = -maxresactivity;
10607  else
10608  *minval = (side - maxresactivity)/val;
10609 
10610  if( SCIPisInfinity(scip, ABS(minresactivity)) )
10611  *maxval = -minresactivity;
10612  else
10613  *maxval = (side - minresactivity)/val;
10614  }
10615  else
10616  {
10617  if( SCIPisInfinity(scip, ABS(minresactivity)) )
10618  *minval = minresactivity;
10619  else
10620  *minval = (side - minresactivity)/val;
10621 
10622  if( SCIPisInfinity(scip, ABS(maxresactivity)) )
10623  *maxval = maxresactivity;
10624  else
10625  *maxval = (side - maxresactivity)/val;
10626  }
10627 }
10628 
10629 
10630 /** applies dual presolving for variables that are locked only once in a direction, and this locking is due to a
10631  * linear inequality
10632  */
10633 static
10635  SCIP* scip, /**< SCIP data structure */
10636  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
10637  SCIP_CONS* cons, /**< linear constraint */
10638  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
10639  int* nfixedvars, /**< pointer to count number of fixed variables */
10640  int* naggrvars, /**< pointer to count number of aggregated variables */
10641  int* ndelconss /**< pointer to count number of deleted constraints */
10642  )
10643 {
10644  SCIP_CONSDATA* consdata;
10645  SCIP_Bool lhsexists;
10646  SCIP_Bool rhsexists;
10647  SCIP_Bool bestisint;
10648  SCIP_Bool bestislhs;
10649  SCIP_Real minabsval;
10650  SCIP_Real maxabsval;
10651  int bestpos;
10652  int i;
10653  int maxotherlocks;
10654 
10655  assert(scip != NULL);
10656  assert(cons != NULL);
10657  assert(cutoff != NULL);
10658  assert(nfixedvars != NULL);
10659  assert(naggrvars != NULL);
10660  assert(ndelconss != NULL);
10661 
10662  /* only process checked constraints (for which the locks are increased);
10663  * otherwise we would have to check for variables with nlocks == 0, and these are already processed by the
10664  * dualfix presolver
10665  */
10666  if( !SCIPconsIsChecked(cons) )
10667  return SCIP_OKAY;
10668 
10669  consdata = SCIPconsGetData(cons);
10670  assert(consdata != NULL);
10671 
10672  lhsexists = !SCIPisInfinity(scip, -consdata->lhs);
10673  rhsexists = !SCIPisInfinity(scip, consdata->rhs);
10674 
10675  /* search for a single-locked variable which can be multi-aggregated; if a valid continuous variable was found, we
10676  * can use it safely for aggregation and break the search loop
10677  */
10678  bestpos = -1;
10679  bestisint = TRUE;
10680  bestislhs = FALSE;
10681 
10682  /* We only want to multi-aggregate variables, if they appear in maximal one additional constraint,
10683  * everything else would produce fill-in. Exceptions:
10684  * - If there are only two variables in the constraint from which the multi-aggregation arises, no fill-in will be
10685  * produced.
10686  * - If there are three variables in the constraint, multi-aggregation in three additional constraints will remove
10687  * six nonzeros (three from the constraint and the three entries of the multi-aggregated variable) and add
10688  * six nonzeros (two variables per substitution).
10689  * - If there at most four variables in the constraint, multi-aggregation in two additional constraints will remove
10690  * six nonzeros (four from the constraint and the two entries of the multi-aggregated variable) and add
10691  * six nonzeros (three variables per substitution). God exists!
10692  */
10693  if( consdata->nvars <= 2 )
10694  maxotherlocks = INT_MAX;
10695  else if( consdata->nvars == 3 )
10696  maxotherlocks = 3;
10697  else if( consdata->nvars == 4 )
10698  maxotherlocks = 2;
10699  else
10700  maxotherlocks = 1;
10701 
10702  /* if this constraint has both sides, it also provides a lock for the other side and thus we can allow one more lock */
10703  if( lhsexists && rhsexists && maxotherlocks < INT_MAX )
10704  maxotherlocks++;
10705 
10706  minabsval = SCIPinfinity(scip);
10707  maxabsval = -1.0;
10708  for( i = 0; i < consdata->nvars && bestisint; ++i )
10709  {
10710  SCIP_VAR* var;
10711  SCIP_Bool isint;
10712  SCIP_Real val;
10713  SCIP_Real absval;
10714  SCIP_Real obj;
10715  SCIP_Real lb;
10716  SCIP_Real ub;
10717  SCIP_Bool agglhs;
10718  SCIP_Bool aggrhs;
10719 
10720  val = consdata->vals[i];
10721  absval = REALABS(val);
10722 
10723  /* calculate minimal and maximal absolute value */
10724  if( absval < minabsval )
10725  minabsval = absval;
10726  if( absval > maxabsval )
10727  maxabsval = absval;
10728 
10729  /* do not try to multi aggregate, when numerical bad */
10730  if( maxabsval / minabsval > conshdlrdata->maxdualmultaggrquot )
10731  return SCIP_OKAY;
10732 
10733  var = consdata->vars[i];
10735 
10736  /* if we already found a candidate, skip integers */
10737  if( bestpos >= 0 && isint )
10738  continue;
10739 
10740  /* better do not multi-aggregate binary variables, since most plugins rely on their binary variables to be either
10741  * active, fixed, or single-aggregated with another binary variable
10742  */
10743  if( SCIPvarIsBinary(var) && consdata->nvars > 2 )
10744  continue;
10745 
10746  if ( SCIPdoNotMultaggrVar(scip, var) )
10747  continue;
10748 
10749  val = consdata->vals[i];
10750  obj = SCIPvarGetObj(var);
10751  lb = SCIPvarGetLbGlobal(var);
10752  ub = SCIPvarGetUbGlobal(var);
10753 
10754  /* lhs <= a_0 * x_0 + a_1 * x_1 + ... + a_{n-1} * x_{n-1} <= rhs
10755  *
10756  * a_i >= 0, c_i >= 0, lhs exists, nlocksdown(x_i) == 1:
10757  * - constraint is the only one that forbids fixing the variable to its lower bound
10758  * - 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
10759  *
10760  * a_i <= 0, c_i <= 0, lhs exists, nlocksup(x_i) == 1:
10761  * - constraint is the only one that forbids fixing the variable to its upper bound
10762  * - 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
10763  *
10764  * a_i >= 0, c_i <= 0, rhs exists, nlocksup(x_i) == 1:
10765  * - constraint is the only one that forbids fixing the variable to its upper bound
10766  * - 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
10767  *
10768  * a_i <= 0, c_i >= 0, rhs exists, nlocksdown(x_i) == 1:
10769  * - constraint is the only one that forbids fixing the variable to its lower bound
10770  * - 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
10771  *
10772  * but: all this is only applicable, if the aggregated value is inside x_i's bounds for all possible values
10773  * of all x_j
10774  * furthermore: we only want to apply this, if no fill-in will be produced
10775  */
10776  agglhs = lhsexists
10777  && ((val > 0.0 && !SCIPisNegative(scip, obj) && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == 1
10778  && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks)
10779  || (val < 0.0 && !SCIPisPositive(scip, obj) && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == 1
10780  && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks));
10781  aggrhs = rhsexists
10782  && ((val > 0.0 && !SCIPisPositive(scip, obj) && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == 1
10783  && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks)
10784  || (val < 0.0 && !SCIPisNegative(scip, obj) && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == 1
10785  && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks));
10786  if( agglhs || aggrhs )
10787  {
10788  SCIP_Real minresactivity;
10789  SCIP_Real maxresactivity;
10790  SCIP_Real minval;
10791  SCIP_Real maxval;
10792  SCIP_Bool minisrelax;
10793  SCIP_Bool maxisrelax;
10794  SCIP_Bool isminsettoinfinity;
10795  SCIP_Bool ismaxsettoinfinity;
10796 
10797  /* calculate bounds for \sum_{j \neq i} a_j * x_j */
10798  consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
10799  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
10800  assert(SCIPisLE(scip, minresactivity, maxresactivity));
10801 
10802  /* We called consdataGetActivityResiduals() saying that we do not need a good relaxation,
10803  * so whenever we have a relaxed activity, it should be relaxed to +/- infinity.
10804  * This is needed, because we do not want to rely on relaxed finite resactivities.
10805  */
10806  assert((!minisrelax || isminsettoinfinity) && (!maxisrelax || ismaxsettoinfinity));
10807 
10808  if( agglhs )
10809  {
10810  /* check if lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10811  calculateMinvalAndMaxval(scip, consdata->lhs, val, minresactivity, maxresactivity, &minval, &maxval);
10812 
10813  assert(SCIPisLE(scip, minval, maxval));
10814  if( (!SCIPisInfinity(scip, -minval) && SCIPisFeasGE(scip, minval, lb)) &&
10815  (!SCIPisInfinity(scip, maxval) && SCIPisFeasLE(scip, maxval, ub)) )
10816  {
10817  SCIP_Real oldmaxresactivity;
10818  SCIP_Real oldminresactivity;
10819  SCIP_Bool recalculated;
10820 
10821  recalculated = FALSE;
10822  oldmaxresactivity = maxresactivity;
10823  oldminresactivity = minresactivity;
10824 
10825  /* check minresactivity for reliability */
10826  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
10827  {
10828  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
10829  recalculated = !SCIPisEQ(scip, oldminresactivity, minresactivity);
10830  isminsettoinfinity = TRUE; /* here it means only that it was even calculated */
10831  }
10832 
10833  /* check maxresactivity for reliability */
10834  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
10835  {
10836  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
10837  recalculated = recalculated || !SCIPisEQ(scip, oldmaxresactivity, maxresactivity);
10838  ismaxsettoinfinity = TRUE; /* here it means only that it was even calculated */
10839  }
10840 
10841  /* minresactivity or maxresactivity wasn't reliable so recalculate min- and maxval*/
10842  if( recalculated )
10843  {
10844  assert(SCIPisLE(scip, minresactivity, maxresactivity));
10845 
10846  /* check again if lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10847  calculateMinvalAndMaxval(scip, consdata->lhs, val, minresactivity, maxresactivity, &minval, &maxval);
10848 
10849  assert(SCIPisLE(scip, minval, maxval));
10850  }
10851 
10852  if( !recalculated || (SCIPisFeasGE(scip, minval, lb) && SCIPisFeasLE(scip, maxval, ub)) )
10853  {
10854  /* if the variable is integer, we have to check whether the integrality condition would always be satisfied
10855  * in the multi-aggregation
10856  */
10857  if( !isint || (SCIPisIntegral(scip, consdata->lhs/val) && consdataIsResidualIntegral(scip, consdata, i, val)) )
10858  {
10859  bestpos = i;
10860  bestisint = isint;
10861  bestislhs = TRUE;
10862  continue; /* no need to also look at the right hand side */
10863  }
10864  }
10865  }
10866  }
10867 
10868  if( aggrhs )
10869  {
10870  /* check if rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10871  calculateMinvalAndMaxval(scip, consdata->rhs, val, minresactivity, maxresactivity, &minval, &maxval);
10872 
10873  assert(SCIPisLE(scip,minval,maxval));
10874  if( (!SCIPisInfinity(scip, -minval) && SCIPisFeasGE(scip, minval, lb)) &&
10875  (!SCIPisInfinity(scip, maxval) && SCIPisFeasLE(scip, maxval, ub)) )
10876  {
10877  SCIP_Real oldmaxresactivity;
10878  SCIP_Real oldminresactivity;
10879  SCIP_Bool recalculated;
10880 
10881  recalculated = FALSE;
10882  oldmaxresactivity = maxresactivity;
10883  oldminresactivity = minresactivity;
10884 
10885  /* check minresactivity for reliability */
10886  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
10887  {
10888  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
10889  recalculated = !SCIPisEQ(scip, oldminresactivity, minresactivity);
10890  }
10891 
10892  /* check maxresactivity for reliability */
10893  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
10894  {
10895  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
10896  recalculated = recalculated || !SCIPisEQ(scip, oldmaxresactivity, maxresactivity);
10897  }
10898 
10899  /* minresactivity or maxresactivity wasn't reliable so recalculate min- and maxval*/
10900  if( recalculated )
10901  {
10902  /* check again if rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10903  calculateMinvalAndMaxval(scip, consdata->rhs, val, minresactivity, maxresactivity, &minval, &maxval);
10904  assert(SCIPisLE(scip,minval,maxval));
10905  }
10906 
10907  if( !recalculated || (SCIPisFeasGE(scip, minval, lb) && SCIPisFeasLE(scip, maxval, ub)) )
10908  {
10909  /* if the variable is integer, we have to check whether the integrality condition would always be satisfied
10910  * in the multi-aggregation
10911  */
10912  if( !isint || (SCIPisIntegral(scip, consdata->rhs/val) && consdataIsResidualIntegral(scip, consdata, i, val)) )
10913  {
10914  bestpos = i;
10915  bestisint = isint;
10916  bestislhs = FALSE;
10917  }
10918  }
10919  }
10920  }
10921  }
10922  }
10923 
10924  if( bestpos >= 0 )
10925  {
10926  SCIP_VAR** aggrvars;
10927  SCIP_Real* aggrcoefs;
10928  SCIP_Real aggrconst;
10929  SCIP_VAR* bestvar;
10930  SCIP_Real bestval;
10931  SCIP_Real epsilon;
10932  int naggrs;
10933  int j;
10934  SCIP_Bool infeasible;
10935  SCIP_Bool aggregated;
10936  SCIP_Bool samevar;
10937  int supinf; /* counter for infinite contributions to the supremum of a possible
10938  * multi-aggregation
10939  */
10940  int infinf; /* counter for infinite contributions to the infimum of a possible
10941  * multi-aggregation
10942  */
10943 
10944  assert(!bestislhs || lhsexists);
10945  assert(bestislhs || rhsexists);
10946 
10947  bestvar = consdata->vars[bestpos];
10948  bestval = consdata->vals[bestpos];
10949  assert(bestisint ==
10951 
10952  /* allocate temporary memory */
10953  SCIP_CALL( SCIPallocBufferArray(scip, &aggrvars, consdata->nvars-1) );
10954  SCIP_CALL( SCIPallocBufferArray(scip, &aggrcoefs, consdata->nvars-1) );
10955 
10956  /* set up the multi-aggregation */
10957  SCIPdebugPrintCons(scip, cons, NULL);
10958  SCIPdebugMsg(scip, "linear constraint <%s> (dual): multi-aggregate <%s> ==", SCIPconsGetName(cons), SCIPvarGetName(bestvar));
10959  naggrs = 0;
10960  supinf = 0;
10961  infinf = 0;
10962  samevar = FALSE;
10963  epsilon = SCIPepsilon(scip);
10964 
10965  for( j = 0; j < consdata->nvars; ++j )
10966  {
10967  if( j != bestpos )
10968  {
10969  SCIP_Real absaggrcoef;
10970 
10971  aggrvars[naggrs] = consdata->vars[j];
10972  aggrcoefs[naggrs] = -consdata->vals[j]/consdata->vals[bestpos];
10973  SCIPdebugMsgPrint(scip, " %+.15g<%s>", aggrcoefs[naggrs], SCIPvarGetName(aggrvars[naggrs]));
10974 
10975  absaggrcoef = REALABS(aggrcoefs[naggrs]);
10976 
10977  /* do not try to multi aggregate, when numerical bad */
10978  if( absaggrcoef < epsilon )
10979  {
10980  SCIPdebugMsg(scip, "do not perform multi-aggregation: too large aggregation coefficients\n");
10981 
10982  /* free temporary memory */
10983  SCIPfreeBufferArray(scip, &aggrcoefs);
10984  SCIPfreeBufferArray(scip, &aggrvars);
10985 
10986  return SCIP_OKAY;
10987  }
10988 
10989  if( bestisint )
10990  {
10991  /* coefficient must be integral: round it to exact integral value */
10992  assert(SCIPisIntegral(scip, aggrcoefs[naggrs]));
10993  aggrcoefs[naggrs] = SCIPfloor(scip, aggrcoefs[naggrs]+0.5);
10994  }
10995 
10996  if( SCIPisPositive(scip, aggrcoefs[naggrs]) )
10997  {
10998  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
10999  {
11000  ++supinf;
11001  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
11002  {
11003  ++infinf;
11004  samevar = TRUE;
11005  }
11006  }
11007  else if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
11008  ++infinf;
11009  }
11010  else if( SCIPisNegative(scip, aggrcoefs[naggrs]) )
11011  {
11012  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
11013  {
11014  ++supinf;
11015  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
11016  {
11017  ++infinf;
11018  samevar = TRUE;
11019  }
11020  }
11021  else if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
11022  ++infinf;
11023  }
11024 
11025  naggrs++;
11026  }
11027  }
11028  assert(!samevar || (supinf > 0 && infinf > 0));
11029 
11030  aggrconst = (bestislhs ? consdata->lhs/bestval : consdata->rhs/bestval);
11031  SCIPdebugMsgPrint(scip, " %+.15g, bounds of <%s>: [%.15g,%.15g]\n", aggrconst, SCIPvarGetName(bestvar),
11032  SCIPvarGetLbGlobal(bestvar), SCIPvarGetUbGlobal(bestvar));
11033  assert(naggrs == consdata->nvars-1);
11034 
11035  /* right hand side must be integral: round it to exact integral value */
11036  if( bestisint )
11037  {
11038  assert(SCIPisIntegral(scip, aggrconst));
11039  aggrconst = SCIPfloor(scip, aggrconst+0.5);
11040  }
11041 
11042  aggregated = FALSE;
11043  infeasible = FALSE;
11044 
11045  /* perform the multi-aggregation */
11046  if( (samevar && supinf == 1 && infinf == 1) || (!samevar && (supinf == 0 || infinf == 0)) )
11047  {
11048  /* @todo if multi-aggregate makes them numerical trouble, avoid them if the coefficients differ to much, see
11049  * also convertLongEquality() early termination due to coefficients
11050  */
11051  SCIP_CALL( SCIPmultiaggregateVar(scip, bestvar, naggrs, aggrvars, aggrcoefs, aggrconst, &infeasible, &aggregated) );
11052  }
11053  else
11054  {
11055  /* If the infimum and the supremum of a multi-aggregation are both infinite, then the multi-aggregation might not be resolvable.
11056  * E.g., consider the equality z = x-y. If x and y are both fixed to +infinity, the value for z is not determined */
11057  SCIPdebugMsg(scip, "do not perform multi-aggregation: infimum and supremum are both infinite\n");
11058  }
11059  /* free temporary memory */
11060  SCIPfreeBufferArray(scip, &aggrcoefs);
11061  SCIPfreeBufferArray(scip, &aggrvars);
11062 
11063  /* check for infeasible aggregation */
11064  if( infeasible )
11065  {
11066  SCIPdebugMsg(scip, "linear constraint <%s>: infeasible multi-aggregation\n", SCIPconsGetName(cons));
11067  *cutoff = TRUE;
11068  return SCIP_OKAY;
11069  }
11070 
11071  /* delete the constraint, if the aggregation was successful */
11072  if( aggregated )
11073  {
11074  SCIP_CALL( SCIPdelCons(scip, cons) );
11075 
11076  if( !consdata->upgraded )
11077  (*ndelconss)++;
11078  (*naggrvars)++;
11079  }
11080  else
11081  {
11082  SCIPdebugMsg(scip, "aggregation non successful!\n");
11083  }
11084  }
11085 
11086  return SCIP_OKAY;
11087 }
11088 
11089 #define BINWEIGHT 1
11090 #define INTWEIGHT 4
11091 #define CONTWEIGHT 8
11092 
11093 /** gets weight for variable in a "weighted number of variables" sum */
11094 static
11095 int getVarWeight(
11096  SCIP_VAR* var /**< variable to get weight for */
11097  )
11098 {
11099  switch( SCIPvarGetType(var) )
11100  {
11101  case SCIP_VARTYPE_BINARY:
11102  return BINWEIGHT;
11103  case SCIP_VARTYPE_INTEGER:
11104  case SCIP_VARTYPE_IMPLINT:
11105  return INTWEIGHT;
11107  return CONTWEIGHT;
11108  default:
11109  SCIPerrorMessage("invalid variable type\n");
11110  SCIPABORT();
11111  return 0; /*lint !e527*/
11112  }
11113 }
11114 
11115 /** tries to aggregate variables in equations a^Tx = lhs
11116  * in case there are at most two binary variables with an odd coefficient and all other
11117  * variables are not continuous and have an even coefficient then:
11118  * - exactly one odd binary variables
11119  * this binary variables y can be fixed to 0 if the lhs is even and to 1 if the lhs is odd
11120  * - lhs is odd -> y = 1
11121  * - lhs is even -> y = 0
11122  * - exactly two odd binary variables
11123  * aggregate the two binary variables with odd coefficient
11124  * - lhs is odd -> exactly one of the variable has to be 1 -> var1 + var2 = 1
11125  * - lhs is even -> both have to take the same value -> var1 - var2 = 0
11126  */
11127 static
11129  SCIP* scip, /**< SCIP data structure */
11130  SCIP_CONS* cons, /**< linear constraint */
11131  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
11132  int* nfixedvars, /**< pointer to count number of fixed variables */
11133  int* naggrvars /**< pointer to count number of aggregated variables */
11134  )
11135 { /*lint --e{715}*/
11136  SCIP_CONSDATA* consdata;
11137  SCIP_Bool success;
11138 
11139  assert( scip != NULL );
11140  assert( cons != NULL );
11141 
11142  consdata = SCIPconsGetData(cons);
11143  assert( consdata != NULL );
11144 
11145  /* check if the linear constraint is an equation with integral right hand side */
11146  if( !SCIPisEQ(scip, consdata->lhs, consdata->rhs) || !SCIPisIntegral(scip, consdata->lhs) )
11147  return SCIP_OKAY;
11148 
11149  /* try to fix and aggregated variables until nothing is possible anymore */
11150  do
11151  {
11152  int v;
11153  int nvars;
11154  SCIP_VAR** vars;
11155  SCIP_Real* vals;
11156  SCIP_Real lhs;
11157  SCIP_Bool lhsodd;
11158 
11159  SCIP_Bool infeasible;
11160  SCIP_Bool fixed;
11161  SCIP_Bool aggregated;
11162  SCIP_Bool redundant;
11163 
11164  SCIP_VAR* var1;
11165  SCIP_VAR* var2;
11166  int noddvars;
11167 
11168  success = FALSE;
11169 
11170  lhs = consdata->lhs;
11171  vars = consdata->vars;
11172  vals = consdata->vals;
11173  nvars = consdata->nvars;
11174 
11175  assert( !SCIPisInfinity(scip, ABS(lhs)) );
11176 
11177  var1 = NULL;
11178  var2 = NULL;
11179  noddvars = 0;
11180 
11181  /* search for binary variables with an odd coefficient */
11182  for( v = 0; v < nvars && noddvars < 3; ++v )
11183  {
11184  SCIP_Longint val;
11185 
11186  /* all coefficients and variables have to be integral */
11187  if( !SCIPisIntegral(scip, vals[v]) || SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11188  return SCIP_OKAY;
11189 
11190  val = (SCIP_Longint)SCIPfeasFloor(scip, vals[v]);
11191  if( val % 2 != 0 )
11192  {
11193  /* the odd values have to belong to binary variables */
11194  if( !SCIPvarIsBinary(vars[v]) )
11195  return SCIP_OKAY;
11196 
11197  if( noddvars == 0 )
11198  var1 = vars[v];
11199  else
11200  var2 = vars[v];
11201 
11202  noddvars++;
11203  }
11204  }
11205 
11206  /* check lhs is odd or even */
11207  lhsodd = (((SCIP_Longint)SCIPfeasFloor(scip, lhs)) % 2 != 0);
11208 
11209  if( noddvars == 1 )
11210  {
11211  assert( var1 != NULL );
11212 
11213  SCIPdebugMsg(scip, "linear constraint <%s>: try fixing variable <%s> to <%g>\n",
11214  SCIPconsGetName(cons), SCIPvarGetName(var1), lhsodd ? 1.0 : 0.0);
11215 
11216  SCIP_CALL( SCIPfixVar(scip, var1, lhsodd? 1.0 : 0.0, &infeasible, &fixed) );
11217 
11218  /* check for infeasibility of fixing */
11219  if( infeasible )
11220  {
11221  SCIPdebugMsg(scip, " -> infeasible fixing\n");
11222  *cutoff = TRUE;
11223  return SCIP_OKAY;
11224  }
11225 
11226  if( fixed )
11227  {
11228  SCIPdebugMsg(scip, " -> feasible fixing\n");
11229  (*nfixedvars)++;
11230  success = TRUE;
11231  }
11232  }
11233  else if( noddvars == 2 )
11234  {
11235  assert( var1 != NULL );
11236  assert( var2 != NULL );
11237 
11238  /* aggregate the two variables with odd coefficient
11239  * - lhs is odd -> exactly one of the variable has to be 1 -> var1 + var2 = 1
11240  * - lhs is even -> both have to take the same value -> var1 - var2 = 0
11241  */
11242  SCIPdebugMsg(scip, "linear constraint <%s>: try aggregation of variables <%s> and <%s>\n",
11243  SCIPconsGetName(cons), SCIPvarGetName(var1), SCIPvarGetName(var2));
11244 
11245  SCIP_CALL( SCIPaggregateVars(scip, var1, var2, 1.0, lhsodd ? 1.0 : -1.0,
11246  lhsodd ? 1.0 : 0.0, &infeasible, &redundant, &aggregated) );
11247 
11248  /* check for infeasibility of aggregation */
11249  if( infeasible )
11250  {
11251  SCIPdebugMsg(scip, " -> infeasible aggregation\n");
11252  *cutoff = TRUE;
11253  return SCIP_OKAY;
11254  }
11255 
11256  /* count the aggregation */
11257  if( aggregated )
11258  {
11259  SCIPdebugMsg(scip, " -> feasible aggregation\n");
11260  (*naggrvars)++;
11261  success = TRUE;
11262  }
11263  }
11264 
11265  if( success )
11266  {
11267  /* apply fixings and aggregation to successfully rerun this presolving step */
11268  SCIP_CALL( applyFixings(scip, cons, &infeasible) );
11269 
11270  if( infeasible )
11271  {
11272  SCIPdebugMsg(scip, " -> infeasible fixing\n");
11273  *cutoff = TRUE;
11274  return SCIP_OKAY;
11275  }
11276 
11277  /* normalize constraint */
11278  SCIP_CALL( normalizeCons(scip, cons, &infeasible) );
11279 
11280  if( infeasible )
11281  {
11282  SCIPdebugMsg(scip, " -> infeasible normalization\n");
11283  *cutoff = TRUE;
11284  return SCIP_OKAY;
11285  }
11286  }
11287  }
11288  while( success );
11289 
11290  return SCIP_OKAY;
11291 }
11292 
11293 
11294 
11295 /** sorting method for constraint data, compares two variables on given indices, continuous variables will be sorted to
11296  * the end and for all other variables the sortation will be in non-increasing order of their absolute value of the
11297  * coefficients
11298  */
11299 static
11300 SCIP_DECL_SORTINDCOMP(consdataCompSim)
11301 { /*lint --e{715}*/
11302  SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
11303  SCIP_VARTYPE vartype1;
11304  SCIP_VARTYPE vartype2;
11305  SCIP_Real value;
11306 
11307  assert(consdata != NULL);
11308  assert(0 <= ind1 && ind1 < consdata->nvars);
11309  assert(0 <= ind2 && ind2 < consdata->nvars);
11310 
11311  vartype1 = SCIPvarGetType(consdata->vars[ind1]);
11312  vartype2 = SCIPvarGetType(consdata->vars[ind2]);
11313 
11314  if( vartype1 == SCIP_VARTYPE_CONTINUOUS )
11315  {
11316  /* continuous varibles will be sorted to the back */
11317  if( vartype2 != vartype1 )
11318  return +1;
11319  /* both variables are continuous */
11320  else
11321  return 0;
11322  }
11323  /* continuous variables will be sorted to the back */
11324  else if( vartype2 == SCIP_VARTYPE_CONTINUOUS )
11325  return -1;
11326 
11327  value = REALABS(consdata->vals[ind2]) - REALABS(consdata->vals[ind1]);
11328 
11329  /* for all non-continuous variables, the variables are sorted after decreasing absolute coefficients */
11330  return (value > 0 ? +1 : (value < 0 ? -1 : 0));
11331 }
11332 
11333 /** tries to simplify coefficients and delete variables in ranged row of the form lhs <= a^Tx <= rhs, e.g. using the greatest
11334  * common divisor
11335  *
11336  * 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
11337  * constraint to 1^Tx = 1
11338  */
11339 static
11341  SCIP* scip, /**< SCIP data structure */
11342  SCIP_CONS* cons, /**< linear constraint */
11343  int* nchgcoefs, /**< pointer to store the amount of changed coefficients */
11344  int* nchgsides /**< pointer to store the amount of changed sides */
11345  )
11346 {
11347  SCIP_CONSDATA* consdata;
11348  SCIP_VAR** vars;
11349  SCIP_Real* vals;
11350  SCIP_Real minval;
11351  SCIP_Real secondminval;
11352  SCIP_Real maxval;
11353  SCIP_Real lhs;
11354  SCIP_Real rhs;
11355  int nvars;
11356  int v;
11358  /* we must not change a modifiable constraint in any way */
11359  if( SCIPconsIsModifiable(cons) )
11360  return SCIP_OKAY;
11361 
11362  if( SCIPconsIsDeleted(cons) )
11363  return SCIP_OKAY;
11364 
11365  consdata = SCIPconsGetData(cons);
11366  assert(consdata != NULL);
11367 
11368  nvars = consdata->nvars;
11369 
11370  /* do not check empty or bound-constraints */
11371  if( nvars < 2 )
11372  return SCIP_OKAY;
11373 
11374  vals = consdata->vals;
11375  vars = consdata->vars;
11376  assert(vars != NULL);
11377  assert(vals != NULL);
11378 
11379  lhs = consdata->lhs;
11380  rhs = consdata->rhs;
11381  assert(!SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs));
11382  assert(!SCIPisNegative(scip, rhs));
11383 
11384  minval = SCIP_INVALID;
11385  secondminval = SCIP_INVALID;
11386  maxval = -SCIP_INVALID;
11387 
11388  for( v = nvars - 1; v >= 0; --v )
11389  {
11390  if( SCIPvarIsBinary(vars[v]) )
11391  {
11392  if( minval > vals[v] || minval == SCIP_INVALID ) /*lint !e777*/
11393  {
11394  secondminval = minval;
11395  minval = vals[v];
11396  }
11397  else if( secondminval > vals[v] || secondminval == SCIP_INVALID ) /*lint !e777*/
11398  secondminval = vals[v];
11399 
11400  if( maxval < vals[v] || maxval == -SCIP_INVALID ) /*lint !e777*/
11401  maxval = vals[v];
11402  }
11403  else
11404  break;
11405  }
11406 
11407  /* check if all variables are binary */
11408  if( v == -1 )
11409  {
11410  if( SCIPisEQ(scip, minval, maxval) && SCIPisEQ(scip, lhs, rhs) )
11411  return SCIP_OKAY;
11412 
11413  /* check if we can and need to choose exactly one binary variable */
11414  if( SCIPisGE(scip, minval, lhs) && SCIPisLE(scip, maxval, rhs) && SCIPisGT(scip, minval + secondminval, rhs) )
11415  {
11416  /* change all coefficients to 1.0 */
11417  for( v = nvars - 1; v >= 0; --v )
11418  {
11419  SCIP_CALL( chgCoefPos(scip, cons, v, 1.0) );
11420  }
11421  (*nchgcoefs) += nvars;
11422 
11423  /* replace old right and left hand side with 1.0 */
11424  SCIP_CALL( chgRhs(scip, cons, 1.0) );
11425  SCIP_CALL( chgLhs(scip, cons, 1.0) );
11426  (*nchgsides) += 2;
11427  }
11428  }
11429 
11430  return SCIP_OKAY;
11431 }
11432 
11433 /** tries to simplify coefficients and delete variables in constraints of the form lhs <= a^Tx <= rhs
11434  * for equations @see rangedRowSimplify() will be called
11435  *
11436  * there are several different coefficient reduction steps which will be applied
11437  *
11438  * 1. We try to determine parts of the constraint which will not change anything on (in-)feasibility of the constraint
11439  *
11440  * e.g. 5x1 + 5x2 + 3z1 <= 8 => 3z1 is redundant if all x are binary and -2 < 3z1 <= 3
11441  *
11442  * 2. We try to remove redundant fractional parts in a constraint
11443  *
11444  * e.g. 5.2x1 + 5.1x2 + 3x3 <= 8.3 => will be changed to 5x1 + 5x2 + 3x3 <= 8 if all x are binary
11445  *
11446  * 3. We are using the greatest common divisor for further reductions
11447  *
11448  * e.g. 10x1 + 5y2 + 5x3 + 3x4 <= 15 => will be changed to 2x1 + y2 + x3 + x4 <= 3 if all xi are binary and y2 is
11449  * integral
11450  */
11451 static
11453  SCIP* scip, /**< SCIP data structure */
11454  SCIP_CONS* cons, /**< linear constraint */
11455  int* nchgcoefs, /**< pointer to store the amount of changed coefficients */
11456  int* nchgsides, /**< pointer to store the amount of changed sides */
11457  SCIP_Bool* infeasible /**< pointer to store whether infeasibility was detected */
11458  )
11459 {
11460  SCIP_CONSDATA* consdata;
11461  SCIP_VAR** vars;
11462  SCIP_Real* vals;
11463  int* perm;
11464  SCIP_Real minactsub;
11465  SCIP_Real maxactsub;
11466  SCIP_Real siderest;
11467  SCIP_Real feastol;
11468  SCIP_Real newcoef;
11469  SCIP_Real absval;
11470  SCIP_Real side;
11471  SCIP_Real lhs;
11472  SCIP_Real rhs;
11473  SCIP_Real lb;
11474  SCIP_Real ub;
11475  SCIP_Longint restcoef;
11476  SCIP_Longint oldgcd;
11477  SCIP_Longint rest;
11478  SCIP_Longint gcd;
11479  SCIP_Bool isminsettoinfinity;
11480  SCIP_Bool ismaxsettoinfinity;
11481  SCIP_Bool isminrelax;
11482  SCIP_Bool ismaxrelax;
11483  SCIP_Bool allcoefintegral;
11484  SCIP_Bool onlybin;
11485  SCIP_Bool hasrhs;
11486  SCIP_Bool haslhs;
11487  int oldnchgcoefs;
11488  int oldnchgsides;
11489  int foundbin;
11490  int candpos;
11491  int candpos2;
11492  int offsetv;
11493  int nvars;
11494  int v;
11495  int w;
11496 
11497  assert(scip != NULL);
11498  assert(cons != NULL);
11499  assert(nchgcoefs != NULL);
11500  assert(nchgsides != NULL);
11501 
11502  *infeasible = FALSE;
11503 
11504  /* we must not change a modifiable constraint in any way */
11505  if( SCIPconsIsModifiable(cons) )
11506  return SCIP_OKAY;
11507 
11508  if( SCIPconsIsDeleted(cons) )
11509  return SCIP_OKAY;
11510 
11511  consdata = SCIPconsGetData(cons);
11512  assert(consdata != NULL);
11513 
11514  nvars = consdata->nvars;
11515 
11516  /* do not check empty or bound-constraints */
11517  if( nvars <= 2 )
11518  return SCIP_OKAY;
11519 
11520  /* update maximal activity delta if necessary */
11521  if( consdata->maxactdelta == SCIP_INVALID ) /*lint !e777*/
11522  consdataRecomputeMaxActivityDelta(scip, consdata);
11523 
11524  assert(consdata->maxactdelta != SCIP_INVALID); /*lint !e777*/
11525  assert(!SCIPisFeasNegative(scip, consdata->maxactdelta));
11526  checkMaxActivityDelta(scip, consdata);
11527 
11528  /* @todo the following might be too hard, check which steps can be applied and what code must be corrected
11529  * accordingly
11530  */
11531  /* can only work with valid non-infinity activities per variable */
11532  if( SCIPisInfinity(scip, consdata->maxactdelta) )
11533  return SCIP_OKAY;
11534 
11535  /* @todo: change the following: due to vartype changes, the status of the normalization can be wrong, need an event
11536  * but the eventsystem seems to be full
11537  */
11538  consdata->normalized = FALSE;
11539 
11540  /* normalize constraint */
11541  SCIP_CALL( normalizeCons(scip, cons, infeasible) );
11542  assert(nvars == consdata->nvars);
11543 
11544  if( *infeasible )
11545  return SCIP_OKAY;
11546 
11547  if( !consdata->normalized )
11548  return SCIP_OKAY;
11549 
11550  lhs = consdata->lhs;
11551  rhs = consdata->rhs;
11552  assert(!SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs));
11553  assert(!SCIPisNegative(scip, rhs));
11554 
11555  if( !SCIPisInfinity(scip, -lhs) )
11556  haslhs = TRUE;
11557  else
11558  haslhs = FALSE;
11559 
11560  if( !SCIPisInfinity(scip, rhs) )
11561  hasrhs = TRUE;
11562  else
11563  hasrhs = FALSE;
11564 
11565  SCIPdebug( oldnchgcoefs = *nchgcoefs; )
11566  SCIPdebug( oldnchgsides = *nchgsides; )
11567 
11568  /* @todo also work on ranged rows */
11569  if( haslhs && hasrhs )
11570  {
11571  SCIP_CALL( rangedRowSimplify(scip, cons, nchgcoefs, nchgsides ) );
11572 
11573  return SCIP_OKAY;
11574  }
11575  assert(haslhs != hasrhs);
11576 
11577  /* if we have a normalized inequality (not ranged) the one side should be positive, @see normalizeCons() */
11578  assert(!hasrhs || !SCIPisNegative(scip, rhs));
11579  assert(!haslhs || !SCIPisNegative(scip, lhs));
11580 
11581  /* get temporary memory to store the sorted permutation */
11582  SCIP_CALL( SCIPallocBufferArray(scip, &perm, nvars) );
11583 
11584  /* call sorting method, order continuous variables to the end and all other variables after non-increasing absolute
11585  * value of their coefficients
11586  */
11587  SCIPsort(perm, consdataCompSim, (void*)consdata, nvars);
11588 
11589  /* perform sorting after permutation array */
11590  permSortConsdata(consdata, perm, nvars);
11591  consdata->indexsorted = FALSE;
11592  consdata->coefsorted = FALSE;
11593 
11594  vars = consdata->vars;
11595  vals = consdata->vals;
11596  assert(vars != NULL);
11597  assert(vals != NULL);
11598  assert(consdata->validmaxabsval ? (SCIPisFeasEQ(scip, consdata->maxabsval, REALABS(vals[0])) || SCIPvarGetType(vars[nvars - 1]) == SCIP_VARTYPE_CONTINUOUS) : TRUE);
11599 
11600  /* free temporary memory */
11601  SCIPfreeBufferArray(scip, &perm);
11602 
11603  /* only check constraints with at least two non continuous variables */
11604  if( SCIPvarGetType(vars[1]) == SCIP_VARTYPE_CONTINUOUS )
11605  return SCIP_OKAY;
11606 
11607  /* do not process constraints when all coefficients are 1.0 */
11608  if( SCIPisEQ(scip, REALABS(vals[0]), 1.0) && ((hasrhs && SCIPisIntegral(scip, rhs)) || (haslhs && SCIPisIntegral(scip, lhs))) )
11609  return SCIP_OKAY;
11610 
11611  feastol = SCIPfeastol(scip);
11612 
11613  SCIPdebugMsg(scip, "starting simplification of coefficients\n");
11614  SCIPdebugPrintCons(scip, cons, NULL);
11615 
11616  /* get global activities */
11617  consdataGetGlbActivityBounds(scip, consdata, FALSE, &minactsub, &maxactsub,
11618  &isminrelax, &ismaxrelax, &isminsettoinfinity, &ismaxsettoinfinity);
11619 
11620  /* cannot work with infinite activities */
11621  if( isminsettoinfinity || ismaxsettoinfinity )
11622  return SCIP_OKAY;
11623 
11624  assert(!isminrelax);
11625  assert(!ismaxrelax);
11626  assert(maxactsub > minactsub);
11627  assert(!SCIPisInfinity(scip, -minactsub));
11628  assert(!SCIPisInfinity(scip, maxactsub));
11629 
11630  v = 0;
11631  offsetv = -1;
11632  side = haslhs ? lhs : rhs;
11633 
11634  /* we now determine coefficients as large as the side of the constraint to retrieve a better reduction where we
11635  * do not need to look at the large coefficients
11636  *
11637  * e.g. all x are binary, z are positive integer
11638  * c1: +5x1 + 5x2 + 3x3 + 3x4 + x5 >= 5 (x5 is redundant and does not change (in-)feasibility of this constraint)
11639  * c2: +4x1 + 4x2 + 3x3 + 3x4 + x5 >= 4 (gcd (without the coefficient of x5) after the large coefficients is 3
11640  * c3: +30x1 + 29x2 + 14x3 + 14z1 + 7x5 + 7x6 <= 30 (gcd (without the coefficient of x2) after the large coefficients is 7
11641  *
11642  * can be changed to
11643  *
11644  * c1: +6x1 + 6x2 + 3x3 + 3x4 >= 6 (will be changed to c1: +2x1 + 2x2 + x3 + x4 >= 2)
11645  * c2: +6x1 + 6x2 + 3x3 + 3x4 + 3x5 >= 6 (will be changed to c2: +2x1 + 2x2 + x3 + x4 + x5 >= 2)
11646  * c3: +28x1 + 28x2 + 14x3 + 14z1 + 7x5 + 7x6 <= 28 (will be changed to c3: +4x1 + 4x2 + 2x3 + 2z1 + x5 + x6 <= 4)
11647  */
11648 
11649  /* if the minimal activity is negative and we found more than one variable with a coefficient bigger than the left
11650  * hand side, we cannot apply the extra reduction step and need to reset v
11651  *
11652  * 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
11653  * coefficients due to the gcd on the "small" coefficients we would get 8x1 + 8x2 - 4x3 - 4x4 >= 8 were xi = 1
11654  * for all i is a solution
11655  *
11656  * also redundancy of variables would not be correctly determined in such a case
11657  */
11658  if( nvars > 2 && SCIPisEQ(scip, vals[0], side) && !SCIPisNegative(scip, minactsub) )
11659  {
11660  v = 1;
11661 
11662  while( v < nvars && SCIPisEQ(scip, side, vals[v]) )
11663  {
11664  /* if we have integer variable with "side"-coefficients but also with a lower bound greater than 0 we stop this
11665  * extra step, which might have worked
11666  */
11667  if( SCIPvarGetLbGlobal(vars[v]) > 0.5 )
11668  {
11669  v = 0;
11670  break;
11671  }
11672 
11673  ++v;
11674  }
11675 
11676  /* easy and quick fix: if all coefficients were equal to the side, we cannot apply further simplifications */
11677  /* todo find numerically stable normalization conditions to scale this cons to have coefficients almost equal to 1 */
11678  if( v == nvars )
11679  return SCIP_OKAY;
11680 
11681  /* cannot work with continuous variables which have a big coefficient */
11682  if( v > 0 && SCIPvarGetType(vars[v - 1]) == SCIP_VARTYPE_CONTINUOUS )
11683  return SCIP_OKAY;
11684 
11685  /* big negative coefficient, do not try to use the extra coefficient reduction step */
11686  if( SCIPisEQ(scip, side, -vals[v]) )
11687  v = 0;
11688 
11689  /* all but one variable are processed or the next variable is continuous we cannot perform the extra coefficient
11690  * reduction
11691  */
11692  if( v == nvars - 1 || SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11693  v = 0;
11694 
11695  if( v > 0 )
11696  {
11697  assert(v < nvars);
11698 
11699  offsetv = v - 1;
11700 
11701  for( w = 0; w < v; ++w )
11702  {
11703  lb = SCIPvarGetLbGlobal(vars[w]);
11704  ub = SCIPvarGetUbGlobal(vars[w]);
11705 
11706  assert(vals[w] > 0);
11707 
11708  /* update residual activities */
11709  maxactsub -= ub * vals[w];
11710  minactsub -= lb * vals[w];
11711  assert(maxactsub > minactsub);
11712  }
11713  }
11714  }
11715 
11716  /* find and remove redundant variables which do not interact with the (in-)feasibility of this constraint
11717  *
11718  * e.g. let all x are binary and y1 is continuous with bounds [-3,1] then we can reduce
11719  *
11720  * 15x1 + 15x2 + 7x3 + 3x4 + y1 <= 26
11721  * to
11722  * 15x1 + 15x2 <= 26 <=> x1 + x2 <= 1
11723  */
11724  if( nvars > 2 && SCIPisIntegral(scip, vals[v]) )
11725  {
11726  SCIP_Bool redundant = FALSE;
11727 
11728  gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
11729  assert(gcd >= 1);
11730 
11731  if( v == 0 )
11732  {
11733  lb = SCIPvarGetLbGlobal(vars[0]);
11734  ub = SCIPvarGetUbGlobal(vars[0]);
11735 
11736  /* update residual activities */
11737  if( vals[0] > 0 )
11738  {
11739  maxactsub -= ub * vals[0];
11740  minactsub -= lb * vals[0];
11741  }
11742  else
11743  {
11744  maxactsub -= lb * vals[0];
11745  minactsub -= ub * vals[0];
11746  }
11747  assert(maxactsub > minactsub);
11748  ++v;
11749  }
11750 
11751  siderest = -SCIP_INVALID;
11752  allcoefintegral = TRUE;
11753 
11754  /* check if some variables always fit into the given constraint */
11755  for( ; v < nvars - 1; ++v )
11756  {
11757  if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11758  break;
11759 
11760  if( !SCIPisIntegral(scip, vals[v]) )
11761  {
11762  allcoefintegral = FALSE;
11763  break;
11764  }
11765 
11766  /* calculate greatest common divisor for all general and binary variables */
11767  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
11768 
11769  if( gcd == 1 )
11770  break;
11771 
11772  lb = SCIPvarGetLbGlobal(vars[v]);
11773  ub = SCIPvarGetUbGlobal(vars[v]);
11774 
11775  assert(!SCIPisInfinity(scip, -lb));
11776  assert(!SCIPisInfinity(scip, ub));
11777 
11778  /* update residual activities */
11779  if( vals[v] > 0 )
11780  {
11781  maxactsub -= ub * vals[v];
11782  minactsub -= lb * vals[v];
11783  }
11784  else
11785  {
11786  maxactsub -= lb * vals[v];
11787  minactsub -= ub * vals[v];
11788  }
11789  assert(SCIPisGE(scip, maxactsub, minactsub));
11790 
11791  if( hasrhs )
11792  {
11793  /* determine the remainder of the right hand side and the gcd */
11794  siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11795  }
11796  else
11797  {
11798  /* determine the remainder of the left hand side and the gcd */
11799  siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11800  if( SCIPisZero(scip, siderest) )
11801  siderest = gcd;
11802  }
11803 
11804  /* early termination if the activities deceed the gcd */
11805  if( (offsetv == -1 && hasrhs && maxactsub <= siderest && SCIPisFeasGT(scip, minactsub, siderest - gcd)) ||
11806  (haslhs && SCIPisFeasLT(scip, maxactsub, siderest) && minactsub >= siderest - gcd) )
11807  {
11808  redundant = TRUE;
11809  break;
11810  }
11811  }
11812  assert(v < nvars || (offsetv >= 0 && gcd > 1));
11813 
11814  if( !redundant )
11815  {
11816  if( hasrhs )
11817  {
11818  /* determine the remainder of the right hand side and the gcd */
11819  siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11820  }
11821  else
11822  {
11823  /* determine the remainder of the left hand side and the gcd */
11824  siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11825  if( SCIPisZero(scip, siderest) )
11826  siderest = gcd;
11827  }
11828  }
11829  else
11830  ++v;
11831 
11832  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",
11833  v, nvars, minactsub, maxactsub, redundant, hasrhs, siderest, gcd, offsetv);
11834 
11835  /* check if we can remove redundant variables */
11836  if( v < nvars && (redundant ||
11837  (offsetv == -1 && hasrhs && maxactsub <= siderest && SCIPisFeasGT(scip, minactsub, siderest - gcd)) ||
11838  (haslhs && SCIPisFeasLT(scip, maxactsub, siderest) && minactsub >= siderest - gcd)) )
11839  {
11840  SCIP_Real oldcoef;
11841 
11842  /* double check the redundancy */
11843 #ifndef NDEBUG
11844  SCIP_Real tmpminactsub = 0.0;
11845  SCIP_Real tmpmaxactsub = 0.0;
11846 
11847  /* recompute residual activities */
11848  for( w = v; w < nvars; ++w )
11849  {
11850  lb = SCIPvarGetLbGlobal(vars[w]);
11851  ub = SCIPvarGetUbGlobal(vars[w]);
11852 
11853  assert(!SCIPisInfinity(scip, -lb));
11854  assert(!SCIPisInfinity(scip, ub));
11855 
11856  /* update residual activities */
11857  if( vals[w] > 0 )
11858  {
11859  tmpmaxactsub += ub * vals[w];
11860  tmpminactsub += lb * vals[w];
11861  }
11862  else
11863  {
11864  tmpmaxactsub += lb * vals[w];
11865  tmpminactsub += ub * vals[w];
11866  }
11867  assert(tmpmaxactsub >= tmpminactsub);
11868  }
11869 
11870  if( hasrhs )
11871  {
11872  assert(offsetv == -1);
11873 
11874  /* determine the remainder of the right hand side and the gcd */
11875  siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11876  }
11877  else
11878  {
11879  /* determine the remainder of the left hand side and the gcd */
11880  siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11881  if( SCIPisZero(scip, siderest) )
11882  siderest = gcd;
11883  }
11884 
11885  /* is the redundancy really fulfilled */
11886  assert((hasrhs && SCIPisFeasLE(scip, tmpmaxactsub, siderest) && tmpminactsub > siderest - gcd) ||
11887  (haslhs && tmpmaxactsub < siderest && SCIPisFeasGE(scip, tmpminactsub, siderest - gcd)));
11888 #endif
11889 
11890  SCIPdebugMsg(scip, "removing %d last variables from constraint <%s>, because they never change anything on the feasibility of this constraint\n",
11891  nvars - v, SCIPconsGetName(cons));
11892 
11893  /* remove redundant variables */
11894  for( w = nvars - 1; w >= v; --w )
11895  {
11896  SCIP_CALL( delCoefPos(scip, cons, w) );
11897  }
11898  (*nchgcoefs) += (nvars - v);
11899 
11900  assert(w >= 0);
11901 
11902  oldcoef = vals[w];
11903 
11904  /* normalize constraint */
11905  SCIP_CALL( normalizeCons(scip, cons, infeasible) );
11906  assert(vars == consdata->vars);
11907  assert(vals == consdata->vals);
11908  assert(w < consdata->nvars);
11909 
11910  if( *infeasible )
11911  return SCIP_OKAY;
11912 
11913  /* compute new greatest common divisor due to normalization */
11914  gcd = (SCIP_Longint)(gcd / (oldcoef/vals[w]) + feastol);
11915  assert(gcd >= 1);
11916 
11917  /* update side */
11918  if( hasrhs )
11919  {
11920  /* replace old with new right hand side */
11921  SCIP_CALL( chgRhs(scip, cons, SCIPfeasFloor(scip, consdata->rhs)) );
11922  rhs = consdata->rhs;
11923  }
11924  else
11925  {
11926  if( SCIPisFeasGT(scip, oldcoef/vals[w], 1.0) )
11927  {
11928  SCIP_CALL( chgLhs(scip, cons, SCIPfeasCeil(scip, consdata->lhs)) );
11929  lhs = consdata->lhs;
11930  }
11931  else
11932  assert(offsetv == -1 || SCIPisEQ(scip, vals[offsetv], consdata->lhs));
11933  }
11934  ++(*nchgsides);
11935 
11936  assert(!hasrhs || !SCIPisNegative(scip, rhs));
11937  assert(!haslhs || !SCIPisNegative(scip, lhs));
11938 
11939  /* get new constraint data */
11940  nvars = consdata->nvars;
11941  assert(nvars > 0);
11942 
11943  allcoefintegral = TRUE;
11944 
11945 #ifndef NDEBUG
11946  /* check integrality */
11947  for( w = offsetv + 1; w < nvars; ++w )
11948  {
11949  assert(SCIPisIntegral(scip, vals[w]));
11950  }
11951 #endif
11952  SCIPdebugPrintCons(scip, cons, NULL);
11953  }
11954 
11955  /* try to find a better gcd, when having large coefficients */
11956  if( offsetv >= 0 && gcd == 1 )
11957  {
11958  /* calculate greatest common divisor for all general variables */
11959  gcd = (SCIP_Longint)(REALABS(vals[nvars - 1]) + feastol);
11960 
11961  if( gcd > 1 )
11962  {
11963  gcd = -1;
11964  candpos = -1;
11965 
11966  for( v = nvars - 1; v > offsetv; --v )
11967  {
11968  assert(!SCIPisZero(scip, vals[v]));
11969  if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11970  break;
11971 
11972  if( !SCIPisIntegral(scip, vals[v]) )
11973  {
11974  allcoefintegral = FALSE;
11975  break;
11976  }
11977 
11978  oldgcd = gcd;
11979 
11980  if( gcd == -1 )
11981  {
11982  gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
11983  assert(gcd >= 1);
11984  }
11985  else
11986  {
11987  /* calculate greatest common divisor for all general and binary variables */
11988  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
11989  }
11990 
11991  /* if the greatest commmon divisor has become 1, we might have found the possible coefficient to change or we
11992  * can stop searching
11993  */
11994  if( gcd == 1 )
11995  {
11996  if( !SCIPvarIsBinary(vars[v]) )
11997  break;
11998 
11999  /* found candidate */
12000  if( candpos == -1 )
12001  {
12002  gcd = oldgcd;
12003  candpos = v;
12004  }
12005  /* two different binary variables lead to a gcd of one, so we cannot change a coefficient */
12006  else
12007  break;
12008  }
12009  }
12010  assert(v > offsetv || candpos > offsetv);
12011  }
12012  else
12013  candpos = -1;
12014  }
12015  else
12016  candpos = nvars - 1;
12017 
12018  /* check last coefficient for integrality */
12019  if( gcd > 1 && allcoefintegral && !redundant )
12020  {
12021  if( !SCIPisIntegral(scip, vals[nvars - 1]) )
12022  allcoefintegral = FALSE;
12023  }
12024 
12025  /* check for further necessary coefficient adjustments */
12026  if( offsetv >= 0 && gcd > 1 && allcoefintegral )
12027  {
12028  assert(offsetv + 1 < nvars);
12029  assert(0 <= candpos && candpos < nvars);
12030 
12031  if( SCIPvarGetType(vars[candpos]) != SCIP_VARTYPE_CONTINUOUS )
12032  {
12033  SCIP_Bool notchangable = FALSE;
12034 
12035 #ifndef NDEBUG
12036  /* check integrality */
12037  for( w = offsetv + 1; w < nvars; ++w )
12038  {
12039  assert(SCIPisIntegral(scip, vals[w]));
12040  }
12041 #endif
12042 
12043  if( vals[candpos] > 0 && SCIPvarIsBinary(vars[candpos]) &&
12044  SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) < gcd )
12045  {
12046  /* determine the remainder of the side and the gcd */
12047  if( hasrhs )
12048  rest = ((SCIP_Longint)(rhs + feastol)) % gcd;
12049  else
12050  rest = ((SCIP_Longint)(lhs + feastol)) % gcd;
12051  assert(rest >= 0);
12052  assert(rest < gcd);
12053 
12054  /* determine the remainder of the coefficient candidate and the gcd */
12055  restcoef = ((SCIP_Longint)(vals[candpos] + feastol)) % gcd;
12056  assert(restcoef >= 1);
12057  assert(restcoef < gcd);
12058 
12059  if( hasrhs )
12060  {
12061  /* calculate new coefficient */
12062  if( restcoef > rest )
12063  newcoef = vals[candpos] - restcoef + gcd;
12064  else
12065  newcoef = vals[candpos] - restcoef;
12066  }
12067  else
12068  {
12069  /* calculate new coefficient */
12070  if( rest == 0 || restcoef < rest )
12071  newcoef = vals[candpos] - restcoef;
12072  else
12073  newcoef = vals[candpos] - restcoef + gcd;
12074  }
12075 
12076  /* done */
12077 
12078  /* new coeffcient must not be zero if we would loose the implication that a variable needs to be 0 if
12079  * another with the big coefficient was set to 1
12080  */
12081  if( hasrhs && SCIPisZero(scip, newcoef) )
12082  {
12083  notchangable = TRUE;
12084  }
12085  else if( SCIPisZero(scip, newcoef) )
12086  {
12087  /* delete old redundant coefficient */
12088  SCIP_CALL( delCoefPos(scip, cons, candpos) );
12089  ++(*nchgcoefs);
12090  }
12091  else
12092  {
12093  /* replace old with new coefficient */
12094  SCIP_CALL( chgCoefPos(scip, cons, candpos, newcoef) );
12095  ++(*nchgcoefs);
12096  }
12097  }
12098  else if( vals[candpos] < 0 || !SCIPvarIsBinary(vars[candpos]) )
12099  {
12100  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol));
12101  }
12102 
12103  /* correct side and big coefficients */
12104  if( (!notchangable && hasrhs && ((!SCIPisFeasIntegral(scip, rhs) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(rhs + feastol)) < gcd) && (SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) == gcd))) ||
12105  ( haslhs && (!SCIPisFeasIntegral(scip, lhs) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(lhs + feastol)) < gcd) && (SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) == gcd)) )
12106  {
12107  if( haslhs )
12108  {
12109  newcoef = (SCIP_Real)((SCIP_Longint)(SCIPfeasCeil(scip, lhs/gcd) * gcd + feastol));
12110 
12111  SCIP_CALL( chgLhs(scip, cons, newcoef) );
12112  ++(*nchgsides);
12113  }
12114  else
12115  {
12116  assert(hasrhs);
12117  newcoef = (SCIP_Real)((SCIP_Longint)(SCIPfeasFloor(scip, rhs/gcd) * gcd + feastol));
12118 
12119  SCIP_CALL( chgRhs(scip, cons, newcoef) );
12120  ++(*nchgsides);
12121  }
12122 
12123  /* correct coefficients up front */
12124  for( w = offsetv; w >= 0; --w )
12125  {
12126  assert(vals[w] > 0);
12127 
12128  SCIP_CALL( chgCoefPos(scip, cons, w, newcoef) );
12129  }
12130  (*nchgcoefs) += (offsetv + 1);
12131  }
12132 
12133  if( !notchangable )
12134  {
12135  /* normalize constraint */
12136  SCIP_CALL( normalizeCons(scip, cons, infeasible) );
12137  assert(vars == consdata->vars);
12138  assert(vals == consdata->vals);
12139 
12140  if( *infeasible )
12141  return SCIP_OKAY;
12142 
12143  /* get new constraint data */
12144  nvars = consdata->nvars;
12145  assert(nvars >= 2);
12146 
12147  SCIPdebugPrintCons(scip, cons, NULL);
12148 
12149  lhs = consdata->lhs;
12150  rhs = consdata->rhs;
12151  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12152  assert(!haslhs || !SCIPisNegative(scip, lhs));
12153  }
12154  }
12155  }
12156  }
12157 
12158  /* @todo we still can remove continuous variables if they are redundant due to the non-integrality argument */
12159  /* no continuous variables are left over */
12160  if( SCIPvarGetType(vars[nvars - 1]) == SCIP_VARTYPE_CONTINUOUS )
12161  return SCIP_OKAY;
12162 
12163  onlybin = TRUE;
12164  allcoefintegral = TRUE;
12165  /* check if all variables are of binary type */
12166  for( v = nvars - 1; v >= 0; --v )
12167  {
12168  if( !SCIPvarIsBinary(vars[v]) )
12169  onlybin = FALSE;
12170  if( !SCIPisIntegral(scip, vals[v]) )
12171  allcoefintegral = FALSE;
12172  }
12173 
12174  /* check if the non-integrality part of all integral variables is smaller than the non-inegrality part of the right
12175  * hand side or bigger than the left hand side respectively, so we can make all of them integral
12176  *
12177  * @todo there are some steps missing ....
12178  */
12179  if( (hasrhs && !SCIPisFeasIntegral(scip, rhs)) || (haslhs && !SCIPisFeasIntegral(scip, lhs)) )
12180  {
12181  SCIP_Real val;
12182  SCIP_Real newval;
12183  SCIP_Real frac = 0.0;
12184  SCIP_Bool found = FALSE;
12185 
12186  if( hasrhs )
12187  {
12188  if( allcoefintegral )
12189  {
12190  /* replace old with new right hand side */
12191  SCIP_CALL( chgRhs(scip, cons, SCIPfloor(scip, rhs)) );
12192  ++(*nchgsides);
12193  }
12194  else
12195  {
12196  siderest = rhs - SCIPfloor(scip, rhs);
12197 
12198  /* try to round down all non-integral coefficients */
12199  for( v = nvars - 1; v >= 0; --v )
12200  {
12201  val = vals[v];
12202 
12203  /* add up all possible fractional parts */
12204  if( !SCIPisIntegral(scip, val) )
12205  {
12206  lb = SCIPvarGetLbGlobal(vars[v]);
12207  ub = SCIPvarGetUbGlobal(vars[v]);
12208 
12209  /* at least one bound need to be at zero */
12210  if( !onlybin && !SCIPisFeasZero(scip, lb) && !SCIPisFeasZero(scip, ub) )
12211  return SCIP_OKAY;
12212 
12213  /* swap bounds for 'standard' form */
12214  if( !SCIPisFeasZero(scip, lb) )
12215  {
12216  ub = lb;
12217  val *= -1;
12218  }
12219 
12220  found = TRUE;
12221 
12222  frac += (val - SCIPfloor(scip, val)) * ub;
12223 
12224  /* if we exceed the fractional part of the right hand side, we cannot tighten the coefficients
12225  *
12226  * e.g. 1.1x1 + 1.1x2 + 1.4x3 + 1.02x4 <= 2.4, here we cannot floor all fractionals because
12227  * x3, x4 set to 1 would be infeasible but feasible after flooring
12228  */
12229  if( SCIPisGT(scip, frac, siderest) )
12230  return SCIP_OKAY;
12231  }
12232  }
12233  assert(v == -1);
12234 
12235  SCIPdebugMsg(scip, "rounding all non-integral coefficients and the right hand side down\n");
12236 
12237  /* round rhs and coefficients to integral values */
12238  if( found )
12239  {
12240  for( v = nvars - 1; v >= 0; --v )
12241  {
12242  val = vals[v];
12243 
12244  /* add the whole fractional part */
12245  if( !SCIPisIntegral(scip, val) )
12246  {
12247  lb = SCIPvarGetLbGlobal(vars[v]);
12248 
12249  if( SCIPisFeasZero(scip, lb) )
12250  newval = SCIPfloor(scip, val);
12251  else
12252  newval = SCIPceil(scip, val);
12253 
12254  if( SCIPisZero(scip, newval) )
12255  {
12256  /* delete old redundant coefficient */
12257  SCIP_CALL( delCoefPos(scip, cons, v) );
12258  ++(*nchgcoefs);
12259  }
12260  else
12261  {
12262  /* replace old with new coefficient */
12263  SCIP_CALL( chgCoefPos(scip, cons, v, newval) );
12264  ++(*nchgcoefs);
12265  }
12266  }
12267  }
12268  }
12269 
12270  /* replace old with new right hand side */
12271  SCIP_CALL( chgRhs(scip, cons, SCIPfloor(scip, rhs)) );
12272  ++(*nchgsides);
12273  }
12274  }
12275  else
12276  {
12277  if( allcoefintegral )
12278  {
12279  /* replace old with new left hand side */
12280  SCIP_CALL( chgLhs(scip, cons, SCIPceil(scip, lhs)) );
12281  ++(*nchgsides);
12282  }
12283  else
12284  {
12285  /* cannot floor left hand side to zero */
12286  if( SCIPisLT(scip, lhs, 1.0) )
12287  return SCIP_OKAY;
12288 
12289  siderest = lhs - SCIPfloor(scip, lhs);
12290 
12291  /* try to round down all non-integral coefficients */
12292  for( v = nvars - 1; v >= 0; --v )
12293  {
12294  val = vals[v];
12295 
12296  /* add up all possible fractional parts */
12297  if( !SCIPisIntegral(scip, val) )
12298  {
12299  lb = SCIPvarGetLbGlobal(vars[v]);
12300  ub = SCIPvarGetUbGlobal(vars[v]);
12301 
12302  /* at least one bound need to be at zero */
12303  if( !SCIPisFeasZero(scip, lb) && !SCIPisFeasZero(scip, ub) )
12304  return SCIP_OKAY;
12305 
12306  /* swap bounds for 'standard' form */
12307  if( !SCIPisFeasZero(scip, lb) )
12308  {
12309  ub = lb;
12310  val *= -1;
12311  }
12312 
12313  /* cannot floor to zero */
12314  if( SCIPisLT(scip, val, 1.0) )
12315  return SCIP_OKAY;
12316 
12317  /* the fractional part on each variable need to exceed the fractional part on the left hand side */
12318  if( SCIPisLT(scip, val - SCIPfloor(scip, val), siderest) )
12319  return SCIP_OKAY;
12320 
12321  found = TRUE;
12322 
12323  frac += (val - SCIPfloor(scip, val)) * ub;
12324 
12325  /* if we exceed the fractional part of the left hand side plus one by summing up all maximal
12326  * fractional parts of the variables, we cannot tighten the coefficients
12327  *
12328  * e.g. 4.3x1 + 1.3x2 + 1.3x3 + 1.6x4 >= 4.2, here we cannot floor all fractionals because
12329  * x2-x4 set to 1 would be feasible but not after flooring
12330  */
12331  if( SCIPisGE(scip, frac, 1 + siderest) )
12332  return SCIP_OKAY;
12333  }
12334  /* all coefficients need to be integral, otherwise we might do an invalid reduction */
12335  else
12336  return SCIP_OKAY;
12337  }
12338  assert(v == -1);
12339 
12340  SCIPdebugMsg(scip, "rounding all non-integral coefficients and the left hand side down\n");
12341 
12342  /* round lhs and coefficients to integral values */
12343  if( found )
12344  {
12345  for( v = nvars - 1; v >= 0; --v )
12346  {
12347  val = vals[v];
12348 
12349  /* add the whole fractional part */
12350  if( !SCIPisIntegral(scip, val) )
12351  {
12352  lb = SCIPvarGetLbGlobal(vars[v]);
12353 
12354  if( SCIPisFeasZero(scip, lb) )
12355  newval = SCIPfloor(scip, val);
12356  else
12357  newval = SCIPceil(scip, val);
12358 
12359  if( SCIPisZero(scip, newval) )
12360  {
12361  /* delete old redundant coefficient */
12362  SCIP_CALL( delCoefPos(scip, cons, v) );
12363  ++(*nchgcoefs);
12364  }
12365  else
12366  {
12367  /* replace old with new coefficient */
12368  SCIP_CALL( chgCoefPos(scip, cons, v, newval) );
12369  ++(*nchgcoefs);
12370  }
12371  }
12372  }
12373  }
12374 
12375  /* replace old with new left hand side */
12376  SCIP_CALL( chgLhs(scip, cons, SCIPfloor(scip, lhs)) );
12377  ++(*nchgsides);
12378  }
12379  }
12380 
12381  /* normalize constraint */
12382  SCIP_CALL( normalizeCons(scip, cons, infeasible) );
12383  assert(vars == consdata->vars);
12384  assert(vals == consdata->vals);
12385 
12386  if( *infeasible )
12387  return SCIP_OKAY;
12388 
12389  rhs = consdata->rhs;
12390  lhs = consdata->lhs;
12391 
12392  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12393  assert(!haslhs || !SCIPisNegative(scip, lhs));
12394 
12395  SCIPdebugPrintCons(scip, cons, NULL);
12396 
12397  nvars = consdata->nvars;
12398  if( nvars < 2 )
12399  return SCIP_OKAY;
12400 
12401  allcoefintegral = TRUE;
12402 #ifndef NDEBUG
12403  /* debug check if all coefficients are really integral */
12404  for( v = nvars - 1; v >= 0; --v )
12405  assert(SCIPisIntegral(scip, vals[v]));
12406 #endif
12407  }
12408 
12409  /* @todo following can also work on non integral coefficients, need more investigation */
12410  /* only check constraints with integral coefficients on all integral variables */
12411  if( !allcoefintegral )
12412  return SCIP_OKAY;
12413 
12414  /* we want to avoid numerical troubles, therefore we do not change non-integral sides */
12415  if( (hasrhs && !SCIPisIntegral(scip, rhs)) || (haslhs && !SCIPisIntegral(scip, lhs)) )
12416  return SCIP_OKAY;
12417 
12418  /* maximal absolute value of coefficients in constraint is one, so we cannot tighten it further */
12419  if( SCIPisEQ(scip, REALABS(vals[0]), 1.0) )
12420  return SCIP_OKAY;
12421 
12422  /* stop if the last coeffcients is one in absolute value and the variable is not binary */
12423  if( !SCIPvarIsBinary(vars[nvars - 1]) && SCIPisEQ(scip, REALABS(vals[nvars - 1]), 1.0) )
12424  return SCIP_OKAY;
12425 
12426  assert(nvars >= 2);
12427 
12428  /* start gcd procedure for all variables */
12429  do
12430  {
12431  SCIPdebug( oldnchgcoefs = *nchgcoefs; )
12432  SCIPdebug( oldnchgsides = *nchgsides; )
12433 
12434  /* stop if we have two coeffcients which are one in absolute value */
12435  if( SCIPisEQ(scip, REALABS(vals[nvars - 1]), 1.0) && SCIPisEQ(scip, REALABS(vals[nvars - 2]), 1.0) )
12436  return SCIP_OKAY;
12437 
12438  gcd = -1;
12439 
12440  /* calculate greatest common divisor over all integer variables; note that the onlybin flag needs to be recomputed
12441  * because coefficients of non-binary variables might have changed to zero */
12442  if( !onlybin )
12443  {
12444  foundbin = -1;
12445  onlybin = TRUE;
12446 
12447  for( v = nvars - 1; v >= 0; --v )
12448  {
12449  assert(!SCIPisZero(scip, vals[v]));
12450  assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_CONTINUOUS);
12451 
12452  if( SCIPvarIsBinary(vars[v]) )
12453  {
12454  if( foundbin == -1 )
12455  foundbin = v;
12456  continue;
12457  }
12458  else
12459  onlybin = FALSE;
12460 
12461  absval = REALABS(vals[v]);
12462  /* arithmetic precision can lead to the absolute value only being integral up to feasibility tolerance,
12463  * even though the value itself is feasible up to epsilon, but since we add feastol later, this is enough
12464  */
12465  assert(SCIPisFeasIntegral(scip, absval));
12466 
12467  if( gcd == -1 )
12468  {
12469  gcd = (SCIP_Longint)(absval + feastol);
12470  assert(gcd >= 1);
12471  }
12472  else
12473  {
12474  /* calculate greatest common divisor for all general variables */
12475  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(absval + feastol));
12476  }
12477  if( gcd == 1 )
12478  break;
12479  }
12480  }
12481  else
12482  foundbin = nvars - 1;
12483 
12484  /* we need at least one binary variable and a gcd greater than 1 to try to perform further coefficient changes */
12485  if( gcd == 1 || foundbin == -1)
12486  return SCIP_OKAY;
12487 
12488  assert((onlybin && gcd == -1) || (!onlybin && gcd > 1));
12489 
12490  candpos = -1;
12491  candpos2 = -1;
12492 
12493  /* calculate greatest common divisor over all integer and binary variables and determine the candidate where we might
12494  * change the coefficient
12495  */
12496  for( v = foundbin; v >= 0; --v )
12497  {
12498  if( onlybin || SCIPvarIsBinary(vars[v]) )
12499  {
12500  absval = REALABS(vals[v]);
12501  /* arithmetic precision can lead to the absolute value only being integral up to feasibility tolerance,
12502  * even though the value itself is feasible up to epsilon, but since we add feastol later, this is enough
12503  */
12504  assert(SCIPisFeasIntegral(scip, absval));
12505 
12506  oldgcd = gcd;
12507 
12508  if( gcd == -1 )
12509  {
12510  gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
12511  assert(gcd >= 1);
12512  }
12513  else
12514  {
12515  /* calculate greatest common divisor for all general and binary variables */
12516  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
12517  }
12518 
12519  /* if the greatest commmon divisor has become 1, we might have found the possible coefficient to change or we
12520  * can terminate
12521  */
12522  if( gcd == 1 )
12523  {
12524  /* found candidate */
12525  if( candpos == -1 )
12526  {
12527  gcd = oldgcd;
12528  candpos = v;
12529 
12530  /* if we have only binary variables and both first coefficients have a gcd of 1, both are candidates for
12531  * the coefficient change
12532  */
12533  if( onlybin && v == foundbin - 1 )
12534  candpos2 = foundbin;
12535  }
12536  /* two different binary variables lead to a gcd of one, so we cannot change a coefficient */
12537  else
12538  {
12539  if( onlybin && candpos == v + 1 && candpos2 == v + 2 )
12540  {
12541  assert(candpos2 == nvars - 1);
12542 
12543  /* take new candidates */
12544  candpos = candpos2;
12545 
12546  /* recalculate gcd from scratch */
12547  gcd = (SCIP_Longint)(REALABS(vals[v+1]) + feastol);
12548  assert(gcd >= 1);
12549 
12550  /* calculate greatest common divisor for all general and binary variables */
12551  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
12552  if( gcd == 1 )
12553  return SCIP_OKAY;
12554  }
12555  else
12556  /* cannot determine a possible coefficient for reduction */
12557  return SCIP_OKAY;
12558  }
12559  }
12560  }
12561  }
12562  assert(gcd >= 2);
12563 
12564  /* we should have found one coefficient, that led to a gcd of 1, otherwise we could normalize the constraint
12565  * further
12566  */
12567  assert(candpos >= 0 && candpos < nvars);
12568 
12569  /* all variables and all coefficients are integral, so the side should be too */
12570  assert((hasrhs && SCIPisIntegral(scip, rhs)) || (haslhs && SCIPisIntegral(scip, lhs)));
12571 
12572  /* check again, if we have a normalized inequality (not ranged) the one side should be positive,
12573  * @see normalizeCons()
12574  */
12575  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12576  assert(!haslhs || !SCIPisNegative(scip, lhs));
12577 
12578  /* determine the remainder of the side and the gcd */
12579  if( hasrhs )
12580  rest = ((SCIP_Longint)(rhs + feastol)) % gcd;
12581  else
12582  rest = ((SCIP_Longint)(lhs + feastol)) % gcd;
12583  assert(rest >= 0);
12584  assert(rest < gcd);
12585 
12586  /* determine the remainder of the coefficient candidate and the gcd */
12587  if( vals[candpos] < 0 )
12588  {
12589  restcoef = ((SCIP_Longint)(vals[candpos] - feastol)) % gcd;
12590  assert(restcoef <= -1);
12591  restcoef += gcd;
12592  }
12593  else
12594  restcoef = ((SCIP_Longint)(vals[candpos] + feastol)) % gcd;
12595  assert(restcoef >= 1);
12596  assert(restcoef < gcd);
12597 
12598  if( hasrhs )
12599  {
12600  if( rest > 0 )
12601  {
12602  /* replace old with new right hand side */
12603  SCIP_CALL( chgRhs(scip, cons, rhs - rest) );
12604  ++(*nchgsides);
12605  }
12606 
12607  /* calculate new coefficient */
12608  if( restcoef > rest )
12609  newcoef = vals[candpos] - restcoef + gcd;
12610  else
12611  newcoef = vals[candpos] - restcoef;
12612  }
12613  else
12614  {
12615  if( rest > 0 )
12616  {
12617  /* replace old with new left hand side */
12618  SCIP_CALL( chgLhs(scip, cons, lhs - rest + gcd) );
12619  ++(*nchgsides);
12620  }
12621 
12622  /* calculate new coefficient */
12623  if( rest == 0 || restcoef < rest )
12624  newcoef = vals[candpos] - restcoef;
12625  else
12626  newcoef = vals[candpos] - restcoef + gcd;
12627  }
12628  assert(SCIPisZero(scip, newcoef) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(newcoef) + feastol)) == gcd);
12629 
12630  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));
12631 
12632  if( SCIPisZero(scip, newcoef) )
12633  {
12634  /* delete redundant coefficient */
12635  SCIP_CALL( delCoefPos(scip, cons, candpos) );
12636  }
12637  else
12638  {
12639  /* replace old with new coefficient */
12640  SCIP_CALL( chgCoefPos(scip, cons, candpos, newcoef) );
12641  }
12642  ++(*nchgcoefs);
12643 
12644  /* now constraint can be normalized, might be directly done by dividing it by the gcd */
12645  SCIP_CALL( normalizeCons(scip, cons, infeasible) );
12646  assert(vars == consdata->vars);
12647  assert(vals == consdata->vals);
12648 
12649  if( *infeasible )
12650  return SCIP_OKAY;
12651 
12652  SCIPdebugPrintCons(scip, cons, NULL);
12653 
12654  rhs = consdata->rhs;
12655  lhs = consdata->lhs;
12656  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12657  assert(!haslhs || !SCIPisNegative(scip, lhs));
12658 
12659  nvars = consdata->nvars;
12660 
12661  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));
12662  }
12663  while( nvars >= 2 );
12664 
12665  return SCIP_OKAY;
12666 }
12667 
12668 
12669 /** tries to aggregate an (in)equality and an equality in order to decrease the number of variables in the (in)equality:
12670  * cons0 := a * cons0 + b * cons1,
12671  * where a = val1[v] and b = -val0[v] for common variable v which removes most variable weight;
12672  * for numerical stability, we will only accept integral a and b;
12673  * the variable weight is a weighted sum over all included variables, where each binary variable weighs BINWEIGHT,
12674  * each integer or implicit integer variable weighs INTWEIGHT and each continuous variable weighs CONTWEIGHT
12675  */
12676 static
12678  SCIP* scip, /**< SCIP data structure */
12679  SCIP_CONS* cons0, /**< (in)equality to modify */
12680  SCIP_CONS* cons1, /**< equality to use for aggregation of cons0 */
12681  int* commonidx0, /**< array with indices of variables in cons0, that appear also in cons1 */
12682  int* commonidx1, /**< array with indices of variables in cons1, that appear also in cons0 */
12683  int* diffidx0minus1, /**< array with indices of variables in cons0, that don't appear in cons1 */
12684  int* diffidx1minus0, /**< array with indices of variables in cons1, that don't appear in cons0 */
12685  int nvarscommon, /**< number of variables, that appear in both constraints */
12686  int commonidxweight, /**< variable weight sum of common variables */
12687  int diffidx0minus1weight, /**< variable weight sum of variables in cons0, that don't appear in cons1 */
12688  int diffidx1minus0weight, /**< variable weight sum of variables in cons1, that don't appear in cons0 */
12689  SCIP_Real maxaggrnormscale, /**< maximal allowed relative gain in maximum norm for constraint aggregation */
12690  int* nchgcoefs, /**< pointer to count the number of changed coefficients */
12691  SCIP_Bool* aggregated, /**< pointer to store whether an aggregation was made */
12692  SCIP_Bool* infeasible /**< pointer to store whether infeasibility was detected */
12693  )
12695  SCIP_CONSDATA* consdata0;
12696  SCIP_CONSDATA* consdata1;
12697  SCIP_Real a;
12698  SCIP_Real b;
12699  SCIP_Real aggrcoef;
12700  SCIP_Real scalarsum;
12701  SCIP_Real bestscalarsum;
12702  SCIP_Bool betterscalarsum;
12703  SCIP_Bool commonvarlindependent; /* indicates whether coefficient vector of common variables in linearly dependent */
12704  int varweight;
12705  int nvars;
12706  int bestvarweight;
12707  int bestnvars;
12708  int bestv;
12709  int v;
12710  int i;
12711 
12712  assert(scip != NULL);
12713  assert(cons0 != NULL);
12714  assert(cons1 != NULL);
12715  assert(commonidx0 != NULL);
12716  assert(commonidx1 != NULL);
12717  assert(diffidx0minus1 != NULL);
12718  assert(diffidx1minus0 != NULL);
12719  assert(nvarscommon >= 1);
12720  assert(commonidxweight >= nvarscommon);
12721  assert(nchgcoefs != NULL);
12722  assert(aggregated != NULL);
12723 
12724  assert(SCIPconsIsActive(cons0));
12725  assert(SCIPconsIsActive(cons1));
12726 
12727  *infeasible = FALSE;
12728 
12729  SCIPdebugMsg(scip, "try aggregation of <%s> and <%s>\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
12730 
12731  /* cons0 is an (in)equality */
12732  consdata0 = SCIPconsGetData(cons0);
12733  assert(consdata0 != NULL);
12734  assert(consdata0->nvars >= 1);
12735  assert(SCIPisLE(scip, consdata0->lhs, consdata0->rhs));
12736  assert(diffidx0minus1weight >= consdata0->nvars - nvarscommon);
12737 
12738  /* cons1 is an equality */
12739  consdata1 = SCIPconsGetData(cons1);
12740  assert(consdata1 != NULL);
12741  assert(consdata1->nvars >= 1);
12742  assert(SCIPisEQ(scip, consdata1->lhs, consdata1->rhs));
12743  assert(diffidx1minus0weight >= consdata1->nvars - nvarscommon);
12744 
12745  *aggregated = FALSE;
12746 
12747  /* search for the best common variable such that
12748  * val1[var] * consdata0 - val0[var] * consdata1
12749  * has least weighted number of variables
12750  */
12751  bestvarweight = commonidxweight + diffidx0minus1weight;
12752  bestnvars = consdata0->nvars;
12753  bestv = -1;
12754  bestscalarsum = 0.0;
12755  commonvarlindependent = TRUE;
12756  for( v = 0; v < nvarscommon; ++v )
12757  {
12758  assert(consdata0->vars[commonidx0[v]] == consdata1->vars[commonidx1[v]]);
12759  a = consdata1->vals[commonidx1[v]];
12760  b = -consdata0->vals[commonidx0[v]];
12761 
12762  /* only try aggregation, if coefficients are integral (numerical stability) */
12763  if( SCIPisIntegral(scip, a) && SCIPisIntegral(scip, b) )
12764  {
12765  /* count the number of variables in the potential new constraint a * consdata0 + b * consdata1 */
12766  varweight = diffidx0minus1weight + diffidx1minus0weight;
12767  nvars = consdata0->nvars + consdata1->nvars - 2*nvarscommon;
12768  scalarsum = REALABS(a) + REALABS(b);
12769  betterscalarsum = (scalarsum < bestscalarsum);
12770  for( i = 0; i < nvarscommon
12771  && (varweight < bestvarweight || (varweight == bestvarweight && betterscalarsum)); ++i )
12772  {
12773  aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
12774  if( !SCIPisZero(scip, aggrcoef) )
12775  {
12776  varweight += getVarWeight(consdata0->vars[commonidx0[i]]);
12777  nvars++;
12778  }
12779  }
12780  if( varweight < bestvarweight || (varweight == bestvarweight && betterscalarsum) )
12781  {
12782  bestv = v;
12783  bestvarweight = varweight;
12784  bestnvars = nvars;
12785  bestscalarsum = scalarsum;
12786  }
12787  }
12788 
12789  /* update commonvarlindependent flag, if still TRUE:
12790  * 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
12791  */
12792  if( commonvarlindependent && v > 0 )
12793  commonvarlindependent = SCIPisEQ(scip,
12794  consdata1->vals[commonidx1[v]] * consdata0->vals[commonidx0[0]],
12795  consdata1->vals[commonidx1[0]] * consdata0->vals[commonidx0[v]]);
12796  }
12797 
12798  /* if better aggregation was found, create new constraint and delete old one */
12799  if( (bestv != -1 || commonvarlindependent) && SCIPconsGetNUpgradeLocks(cons0) == 0 )
12800  {
12801  SCIP_CONS* newcons;
12802  SCIP_CONSDATA* newconsdata;
12803  SCIP_VAR** newvars;
12804  SCIP_Real* newvals;
12805  SCIP_Real newlhs;
12806  SCIP_Real newrhs;
12807  int newnvars;
12808 
12809  if( bestv != -1 )
12810  {
12811  /* choose multipliers such that the multiplier for the (in)equality cons0 is positive */
12812  if( consdata1->vals[commonidx1[bestv]] > 0.0 )
12813  {
12814  a = consdata1->vals[commonidx1[bestv]];
12815  b = -consdata0->vals[commonidx0[bestv]];
12816  }
12817  else
12818  {
12819  a = -consdata1->vals[commonidx1[bestv]];
12820  b = consdata0->vals[commonidx0[bestv]];
12821  }
12822  assert(SCIPisIntegral(scip, a));
12823  assert(SCIPisPositive(scip, a));
12824  assert(SCIPisIntegral(scip, b));
12825  assert(!SCIPisZero(scip, b));
12826  }
12827  else
12828  {
12829  assert(commonvarlindependent);
12830  if( consdata1->vals[commonidx1[0]] > 0.0 )
12831  {
12832  a = consdata1->vals[commonidx1[0]];
12833  b = -consdata0->vals[commonidx0[0]];
12834  }
12835  else
12836  {
12837  a = -consdata1->vals[commonidx1[0]];
12838  b = consdata0->vals[commonidx0[0]];
12839  }
12840  assert(SCIPisPositive(scip, a));
12841  assert(!SCIPisZero(scip, b));
12842 
12843  /* if a/b is integral, then we can easily choose integer multipliers */
12844  if( SCIPisIntegral(scip, a/b) )
12845  {
12846  if( a/b > 0 )
12847  {
12848  a /= b;
12849  b = 1.0;
12850  }
12851  else
12852  {
12853  a /= -b;
12854  b = -1.0;
12855  }
12856  }
12857 
12858  /* setup best* variables that were not setup above because we are in the commonvarlindependent case */
12859  SCIPdebug( bestvarweight = diffidx0minus1weight + diffidx1minus0weight; )
12860  bestnvars = consdata0->nvars + consdata1->nvars - 2*nvarscommon;
12861  }
12862 
12863  SCIPdebugMsg(scip, "aggregate linear constraints <%s> := %.15g*<%s> + %.15g*<%s> -> nvars: %d -> %d, weight: %d -> %d\n",
12864  SCIPconsGetName(cons0), a, SCIPconsGetName(cons0), b, SCIPconsGetName(cons1),
12865  consdata0->nvars, bestnvars, commonidxweight + diffidx0minus1weight, bestvarweight);
12866  SCIPdebugPrintCons(scip, cons0, NULL);
12867  SCIPdebugPrintCons(scip, cons1, NULL);
12868 
12869  /* get temporary memory for creating the new linear constraint */
12870  SCIP_CALL( SCIPallocBufferArray(scip, &newvars, bestnvars) );
12871  SCIP_CALL( SCIPallocBufferArray(scip, &newvals, bestnvars) );
12872 
12873  /* calculate the common coefficients, if we have not recognized linear dependency */
12874  newnvars = 0;
12875  if( !commonvarlindependent )
12876  {
12877  for( i = 0; i < nvarscommon; ++i )
12878  {
12879  assert(0 <= commonidx0[i] && commonidx0[i] < consdata0->nvars);
12880  assert(0 <= commonidx1[i] && commonidx1[i] < consdata1->nvars);
12881 
12882  aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
12883  if( !SCIPisZero(scip, aggrcoef) )
12884  {
12885  assert(newnvars < bestnvars);
12886  newvars[newnvars] = consdata0->vars[commonidx0[i]];
12887  newvals[newnvars] = aggrcoef;
12888  newnvars++;
12889  }
12890  }
12891  }
12892  else
12893  {
12894  /* if we recognized linear dependency of the common coefficients, then the aggregation coefficient should be 0.0 for every common variable */
12895 #ifndef NDEBUG
12896  for( i = 0; i < nvarscommon; ++i )
12897  {
12898  assert(0 <= commonidx0[i] && commonidx0[i] < consdata0->nvars);
12899  assert(0 <= commonidx1[i] && commonidx1[i] < consdata1->nvars);
12900 
12901  aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
12902  assert(SCIPisZero(scip, aggrcoef));
12903  }
12904 #endif
12905  }
12906 
12907  /* calculate the coefficients appearing in cons0 but not in cons1 */
12908  for( i = 0; i < consdata0->nvars - nvarscommon; ++i )
12909  {
12910  assert(0 <= diffidx0minus1[i] && diffidx0minus1[i] < consdata0->nvars);
12911 
12912  aggrcoef = a * consdata0->vals[diffidx0minus1[i]];
12913  assert(!SCIPisZero(scip, aggrcoef));
12914  assert(newnvars < bestnvars);
12915  newvars[newnvars] = consdata0->vars[diffidx0minus1[i]];
12916  newvals[newnvars] = aggrcoef;
12917  newnvars++;
12918  }
12919 
12920  /* calculate the coefficients appearing in cons1 but not in cons0 */
12921  for( i = 0; i < consdata1->nvars - nvarscommon; ++i )
12922  {
12923  assert(0 <= diffidx1minus0[i] && diffidx1minus0[i] < consdata1->nvars);
12924 
12925  aggrcoef = b * consdata1->vals[diffidx1minus0[i]];
12926  assert(!SCIPisZero(scip, aggrcoef));
12927  assert(newnvars < bestnvars);
12928  newvars[newnvars] = consdata1->vars[diffidx1minus0[i]];
12929  newvals[newnvars] = aggrcoef;
12930  newnvars++;
12931  }
12932  assert(newnvars == bestnvars);
12933 
12934  /* calculate the new left and right hand side of the (in)equality */
12935  assert(!SCIPisInfinity(scip, -consdata1->lhs));
12936  assert(!SCIPisInfinity(scip, consdata1->rhs));
12937  if( SCIPisInfinity(scip, -consdata0->lhs) )
12938  newlhs = -SCIPinfinity(scip);
12939  else
12940  newlhs = a * consdata0->lhs + b * consdata1->lhs;
12941  if( SCIPisInfinity(scip, consdata0->rhs) )
12942  newrhs = SCIPinfinity(scip);
12943  else
12944  newrhs = a * consdata0->rhs + b * consdata1->rhs;
12945 
12946  /* create the new linear constraint */
12947  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, SCIPconsGetName(cons0), newnvars, newvars, newvals, newlhs, newrhs,
12949  SCIPconsIsChecked(cons0), SCIPconsIsPropagated(cons0),
12950  SCIPconsIsLocal(cons0), SCIPconsIsModifiable(cons0),
12952 
12953  newconsdata = SCIPconsGetData(newcons);
12954  assert(newconsdata != NULL);
12955 
12956  /* copy the upgraded flag from the old cons0 to the new constraint */
12957  newconsdata->upgraded = consdata0->upgraded;
12958 
12959  /* normalize the new constraint */
12960  SCIP_CALL( normalizeCons(scip, newcons, infeasible) );
12961 
12962  if( *infeasible )
12963  goto TERMINATE;
12964 
12965  /* check, if we really want to use the new constraint instead of the old one:
12966  * use the new one, if the maximum norm doesn't grow too much
12967  */
12968  if( consdataGetMaxAbsval(SCIPconsGetData(newcons)) <= maxaggrnormscale * consdataGetMaxAbsval(consdata0) )
12969  {
12970  SCIPdebugMsg(scip, " -> aggregated to <%s>\n", SCIPconsGetName(newcons));
12971  SCIPdebugPrintCons(scip, newcons, NULL);
12972 
12973  /* update the statistics: we changed all coefficients */
12974  if( !consdata0->upgraded )
12975  (*nchgcoefs) += consdata0->nvars + consdata1->nvars - nvarscommon;
12976  *aggregated = TRUE;
12977 
12978  /* delete the old constraint, and add the new linear constraint to the problem */
12979  SCIP_CALL( SCIPdelCons(scip, cons0) );
12980  SCIP_CALL( SCIPaddCons(scip, newcons) );
12981  }
12982 
12983  TERMINATE:
12984  /* release the new constraint */
12985  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
12986 
12987  /* free temporary memory */
12988  SCIPfreeBufferArray(scip, &newvals);
12989  SCIPfreeBufferArray(scip, &newvars);
12990  }
12991 
12992  return SCIP_OKAY;
12993 }
12994 
12995 /** gets the key of the given element */
12996 static
12997 SCIP_DECL_HASHGETKEY(hashGetKeyLinearcons)
12998 { /*lint --e{715}*/
12999  /* the key is the element itself */
13000  return elem;
13001 }
13002 
13003 /** returns TRUE iff both keys are equal; two constraints are equal if they have the same variables and the
13004  * coefficients are either equal or negated
13005  */
13006 static
13007 SCIP_DECL_HASHKEYEQ(hashKeyEqLinearcons)
13008 {
13009  SCIP* scip;
13010  SCIP_CONSDATA* consdata1;
13011  SCIP_CONSDATA* consdata2;
13012  SCIP_Real cons1scale;
13013  SCIP_Real cons2scale;
13014  int i;
13015 
13016  assert(key1 != NULL);
13017  assert(key2 != NULL);
13018  consdata1 = SCIPconsGetData((SCIP_CONS*)key1);
13019  consdata2 = SCIPconsGetData((SCIP_CONS*)key2);
13020  assert(consdata1->indexsorted);
13021  assert(consdata2->indexsorted);
13022 
13023  scip = (SCIP*)userptr;
13024  assert(scip != NULL);
13025 
13026  /* if it is the same constraint we dont need to check anything */
13027  if( key1 == key2 )
13028  return TRUE;
13029 
13030  /* checks trivial case */
13031  if( consdata1->nvars != consdata2->nvars )
13032  return FALSE;
13033 
13034  /* tests if variables are equal */
13035  for( i = 0; i < consdata1->nvars; ++i )
13036  {
13037  if( consdata1->vars[i] != consdata2->vars[i] )
13038  {
13039  assert(SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == 1 ||
13040  SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == -1);
13041  return FALSE;
13042  }
13043  assert(SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == 0);
13044  }
13045 
13046  /* compute scale before comparing coefficients of constraints */
13047  cons1scale = COPYSIGN(1.0/consdata1->maxabsval, consdata1->vals[0]);
13048  cons2scale = COPYSIGN(1.0/consdata2->maxabsval, consdata2->vals[0]);
13049 
13050  /* tests if coefficients are equal with the computed scale */
13051  for( i = 0; i < consdata1->nvars; ++i )
13052  {
13053  SCIP_Real val1;
13054  SCIP_Real val2;
13055 
13056  val1 = consdata1->vals[i] * cons1scale;
13057  val2 = consdata2->vals[i] * cons2scale;
13058 
13059  if( !SCIPisEQ(scip, val1, val2) )
13060  return FALSE;
13061  }
13062 
13063  return TRUE;
13064 }
13065 
13066 /** returns the hash value of the key */
13067 static
13068 SCIP_DECL_HASHKEYVAL(hashKeyValLinearcons)
13069 {
13070  SCIP_CONSDATA* consdata;
13071  int minidx;
13072  int mididx;
13073  int maxidx;
13074  SCIP_Real scale;
13075 #ifndef NDEBUG
13076  SCIP* scip;
13077 
13078  scip = (SCIP*)userptr;
13079  assert(scip != NULL);
13080 #endif
13081 
13082  assert(key != NULL);
13083  consdata = SCIPconsGetData((SCIP_CONS*)key);
13084  assert(consdata != NULL);
13085  assert(consdata->nvars > 0);
13086 
13087  assert(consdata->indexsorted);
13088 
13089  minidx = SCIPvarGetIndex(consdata->vars[0]);
13090  mididx = SCIPvarGetIndex(consdata->vars[consdata->nvars / 2]);
13091  maxidx = SCIPvarGetIndex(consdata->vars[consdata->nvars - 1]);
13092  scale = COPYSIGN(1.0/consdata->maxabsval, consdata->vals[0]);
13093 
13094  /* using only the variable indices as hash, since the values are compared by epsilon */
13095  return SCIPhashSeven(consdata->nvars, minidx, SCIPrealHashCode(consdata->vals[0] * scale),
13096  mididx, SCIPrealHashCode(consdata->vals[consdata->nvars / 2] * scale),
13097  maxidx, SCIPrealHashCode(consdata->vals[consdata->nvars - 1] * scale));
13098 }
13099 
13100 /** returns the key for deciding which of two parallel constraints should be kept (smaller key should be kept);
13101  * prefers non-upgraded constraints and as second criterion the constraint with the smallest position
13102  */
13103 static
13104 unsigned int getParallelConsKey(
13105  SCIP_CONS* cons /**< linear constraint */
13106  )
13107 {
13108  SCIP_CONSDATA* consdata;
13109 
13110  assert(cons != NULL);
13111 
13112  consdata = SCIPconsGetData(cons);
13113  assert(consdata != NULL);
13114 
13115  return (((unsigned int)consdata->upgraded)<<31) + (unsigned int)SCIPconsGetPos(cons); /*lint !e571*/
13116 }
13117 
13118 /** updates the hashtable such that out of all constraints in the hashtable that are detected
13119  * to be parallel to *querycons, only one is kept in the hashtable and stored into *querycons,
13120  * and all others are removed from the hashtable and stored in the given array
13121  */
13122 static
13124  SCIP_HASHTABLE* hashtable, /**< hashtable containing linear constraints */
13125  SCIP_CONS** querycons, /**< pointer to linear constraint used to look for duplicates in the hash table;
13126  * upon return will contain the constraint that should be kept */
13127  SCIP_CONS** parallelconss, /**< array to return constraints that are parallel to the given;
13128  * these constraints where removed from the hashtable */
13129  int* nparallelconss /**< pointer to return number of parallel constraints */
13130  )
13131 {
13132  SCIP_CONS* parallelcons;
13133  unsigned int querykey;
13134 
13135  *nparallelconss = 0;
13136  querykey = getParallelConsKey(*querycons);
13137 
13138  while( (parallelcons = (SCIP_CONS*)SCIPhashtableRetrieve(hashtable, (void*)(*querycons))) != NULL )
13139  {
13140  unsigned int conskey = getParallelConsKey(parallelcons);
13141 
13142  if( conskey < querykey )
13143  {
13144  parallelconss[(*nparallelconss)++] = *querycons;
13145  *querycons = parallelcons;
13146  querykey = conskey;
13147  }
13148  else
13149  {
13150  parallelconss[(*nparallelconss)++] = parallelcons;
13151  }
13152 
13153  /* if the constraint that just came out of the hash table is the one that is kept,
13154  * we do not need to look into the hashtable again, since the invariant is that
13155  * in the hashtable only pair-wise non-parallel constraints are contained.
13156  * For the original querycons, however, multiple constraints that compare equal (=parallel)
13157  * could be contained due to non-transitivity of the equality comparison.
13158  * Also we can return immediately, since parallelcons is already contained in the
13159  * hashtable and we do not need to remove and reinsert it.
13160  */
13161  if( *querycons == parallelcons )
13162  return SCIP_OKAY;
13163 
13164  /* remove parallelcons from the hashtable, since it will be replaced by querycons */
13165  SCIP_CALL( SCIPhashtableRemove(hashtable, (void*) parallelcons) );
13166  }
13167 
13168  /* in debug mode we make sure, that the hashtable cannot contain a constraint that
13169  * comnpares equal to querycons at this point
13170  */
13171 #ifndef NDEBUG
13172  SCIP_CALL_ABORT( SCIPhashtableSafeInsert(hashtable, *querycons) );
13173 #else
13174  SCIP_CALL( SCIPhashtableInsert(hashtable, *querycons) );
13175 #endif
13176 
13177  return SCIP_OKAY;
13178 }
13179 
13180 /** compares each constraint with all other constraints for possible redundancy and removes or changes constraint
13181  * accordingly; in contrast to preprocessConstraintPairs(), it uses a hash table
13182  */
13183 static
13185  SCIP* scip, /**< SCIP data structure */
13186  BMS_BLKMEM* blkmem, /**< block memory */
13187  SCIP_CONS** conss, /**< constraint set */
13188  int nconss, /**< number of constraints in constraint set */
13189  int* firstchange, /**< pointer to store first changed constraint */
13190  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
13191  int* ndelconss, /**< pointer to count number of deleted constraints */
13192  int* nchgsides /**< pointer to count number of changed left/right hand sides */
13193  )
13194 {
13195  SCIP_HASHTABLE* hashtable;
13196  SCIP_CONS** parallelconss;
13197  int nparallelconss;
13198  int hashtablesize;
13199  int c;
13200 
13201  assert(scip != NULL);
13202  assert(blkmem != NULL);
13203  assert(conss != NULL);
13204  assert(firstchange != NULL);
13205  assert(cutoff != NULL);
13206  assert(ndelconss != NULL);
13207  assert(nchgsides != NULL);
13208 
13209  /* create a hash table for the constraint set */
13210  hashtablesize = nconss;
13211  SCIP_CALL( SCIPhashtableCreate(&hashtable, blkmem, hashtablesize,
13212  hashGetKeyLinearcons, hashKeyEqLinearcons, hashKeyValLinearcons, (void*) scip) );
13213 
13214  SCIP_CALL( SCIPallocBufferArray(scip, &parallelconss, nconss) );
13215 
13216  /* check all constraints in the given set for redundancy */
13217  for( c = 0; c < nconss; ++c )
13218  {
13219  SCIP_CONS* cons0;
13220  SCIP_CONSDATA* consdata0;
13221 
13222  cons0 = conss[c];
13223 
13224  if( !SCIPconsIsActive(cons0) || SCIPconsIsModifiable(cons0) )
13225  continue;
13226 
13227  /* check for interuption */
13228  if( c % 1000 == 0 && SCIPisStopped(scip) )
13229  break;
13230 
13231  /* sorts the constraint */
13232  consdata0 = SCIPconsGetData(cons0);
13233  assert(consdata0 != NULL);
13234  SCIP_CALL( consdataSort(scip, consdata0) );
13235  assert(consdata0->indexsorted);
13236 
13237  /* get constraints from current hash table with same variables as cons0 and with coefficients equal
13238  * to the ones of cons0 when both are scaled such that maxabsval is 1.0 and the coefficient of the
13239  * first variable is positive
13240  * Also inserts cons0 into the hashtable.
13241  */
13242  SCIP_CALL( retrieveParallelConstraints(hashtable, &cons0, parallelconss, &nparallelconss) );
13243 
13244  if( nparallelconss != 0 )
13245  {
13246  SCIP_Real lhs;
13247  SCIP_Real rhs;
13248 
13249  int i;
13250 
13251  /* cons0 may have been changed in retrieveParallelConstraints() */
13252  consdata0 = SCIPconsGetData(cons0);
13253 
13254  lhs = consdata0->lhs;
13255  rhs = consdata0->rhs;
13256 
13257  for( i = 0; i < nparallelconss; ++i )
13258  {
13259  SCIP_CONS* consdel;
13260  SCIP_CONSDATA* consdatadel;
13261  SCIP_Real scale;
13262 
13263  consdel = parallelconss[i];
13264  consdatadel = SCIPconsGetData(consdel);
13265 
13266  assert(SCIPconsIsActive(consdel));
13267  assert(!SCIPconsIsModifiable(consdel));
13268 
13269  /* constraint found: create a new constraint with same coefficients and best left and right hand side;
13270  * delete old constraints afterwards
13271  */
13272  assert(consdatadel != NULL);
13273  assert(consdata0->nvars >= 1 && consdata0->nvars == consdatadel->nvars);
13274 
13275  assert(consdatadel->indexsorted);
13276  assert(consdata0->vars[0] == consdatadel->vars[0]);
13277 
13278  scale = consdata0->vals[0] / consdatadel->vals[0];
13279  assert(scale != 0.0);
13280 
13281  /* in debug mode, check that all coefficients are equal with respect to epsilon
13282  * if the constraints are in equilibrium scale
13283  */
13284 #ifndef NDEBUG
13285  {
13286  int k;
13287  SCIP_Real scale0 = 1.0 / consdata0->maxabsval;
13288  SCIP_Real scaledel = COPYSIGN(1.0 / consdatadel->maxabsval, scale);
13289 
13290  for( k = 0; k < consdata0->nvars; ++k )
13291  {
13292  assert(SCIPisEQ(scip, scale0 * consdata0->vals[k], scaledel * consdatadel->vals[k]));
13293  }
13294  }
13295 #endif
13296 
13297  if( scale > 0.0 )
13298  {
13299  /* the coefficients of both constraints are parallel with a positive scale */
13300  SCIPdebugMsg(scip, "aggregate linear constraints <%s> and <%s> with equal coefficients into single ranged row\n",
13301  SCIPconsGetName(cons0), SCIPconsGetName(consdel));
13302  SCIPdebugPrintCons(scip, cons0, NULL);
13303  SCIPdebugPrintCons(scip, consdel, NULL);
13304 
13305  if( ! SCIPisInfinity(scip, -consdatadel->lhs) )
13306  lhs = MAX(scale * consdatadel->lhs, lhs);
13307 
13308  if( ! SCIPisInfinity(scip, consdatadel->rhs) )
13309  rhs = MIN(scale * consdatadel->rhs, rhs);
13310  }
13311  else
13312  {
13313  /* the coefficients of both rows are negations */
13314  SCIPdebugMsg(scip, "aggregate linear constraints <%s> and <%s> with negated coefficients into single ranged row\n",
13315  SCIPconsGetName(cons0), SCIPconsGetName(consdel));
13316  SCIPdebugPrintCons(scip, cons0, NULL);
13317  SCIPdebugPrintCons(scip, consdel, NULL);
13318 
13319  if( ! SCIPisInfinity(scip, consdatadel->rhs) )
13320  lhs = MAX(scale * consdatadel->rhs, lhs);
13321 
13322  if( ! SCIPisInfinity(scip, -consdatadel->lhs) )
13323  rhs = MIN(scale * consdatadel->lhs, rhs);
13324  }
13325 
13326  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13327  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, consdel) );
13328 
13329  /* delete consdel */
13330  assert( ! consdata0->upgraded || consdatadel->upgraded );
13331  SCIP_CALL( SCIPdelCons(scip, consdel) );
13332  if( !consdatadel->upgraded )
13333  (*ndelconss)++;
13334  }
13335 
13336  if( SCIPisFeasLT(scip, rhs, lhs) )
13337  {
13338  SCIPdebugMsg(scip, "aggregated linear constraint <%s> is infeasible\n", SCIPconsGetName(cons0));
13339  *cutoff = TRUE;
13340  break;
13341  }
13342 
13343  /* ensure that lhs <= rhs holds without tolerances as we only allow such rows to enter the LP */
13344  if( lhs > rhs )
13345  {
13346  rhs = (lhs + rhs)/2;
13347  lhs = rhs;
13348  }
13349 
13350  /* update lhs and rhs of cons0 */
13351  SCIP_CALL( chgLhs(scip, cons0, lhs) );
13352  SCIP_CALL( chgRhs(scip, cons0, rhs) );
13353 
13354  /* update the first changed constraint to begin the next aggregation round with */
13355  if( consdata0->changed && SCIPconsGetPos(cons0) < *firstchange )
13356  *firstchange = SCIPconsGetPos(cons0);
13357 
13358  assert(SCIPconsIsActive(cons0));
13359  }
13360  }
13361 #ifdef SCIP_MORE_DEBUG
13362  SCIPinfoMessage(scip, NULL, "linear pairwise comparison hashtable statistics:\n");
13364 #endif
13365 
13366  SCIPfreeBufferArray(scip, &parallelconss);
13367 
13368  /* free hash table */
13369  SCIPhashtableFree(&hashtable);
13370 
13371  return SCIP_OKAY;
13372 }
13373 
13374 /** compares constraint with all prior constraints for possible redundancy or aggregation,
13375  * and removes or changes constraint accordingly
13376  */
13377 static
13379  SCIP* scip, /**< SCIP data structure */
13380  SCIP_CONS** conss, /**< constraint set */
13381  int firstchange, /**< first constraint that changed since last pair preprocessing round */
13382  int chkind, /**< index of constraint to check against all prior indices upto startind */
13383  SCIP_Real maxaggrnormscale, /**< maximal allowed relative gain in maximum norm for constraint aggregation */
13384  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
13385  int* ndelconss, /**< pointer to count number of deleted constraints */
13386  int* nchgsides, /**< pointer to count number of changed left/right hand sides */
13387  int* nchgcoefs /**< pointer to count number of changed coefficients */
13388  )
13389 {
13390  SCIP_CONS* cons0;
13391  SCIP_CONSDATA* consdata0;
13392  int* commonidx0;
13393  int* commonidx1;
13394  int* diffidx0minus1;
13395  int* diffidx1minus0;
13396  uint64_t possignature0;
13397  uint64_t negsignature0;
13398  SCIP_Bool cons0changed;
13399  SCIP_Bool cons0isequality;
13400  int diffidx1minus0size;
13401  int c;
13402  SCIP_Real cons0lhs;
13403  SCIP_Real cons0rhs;
13404  SCIP_Bool cons0upgraded;
13405 
13406  assert(scip != NULL);
13407  assert(conss != NULL);
13408  assert(firstchange <= chkind);
13409  assert(cutoff != NULL);
13410  assert(ndelconss != NULL);
13411  assert(nchgsides != NULL);
13412  assert(nchgcoefs != NULL);
13413 
13414  /* get the constraint to be checked against all prior constraints */
13415  cons0 = conss[chkind];
13416  assert(cons0 != NULL);
13417  assert(SCIPconsIsActive(cons0));
13418  assert(!SCIPconsIsModifiable(cons0));
13419 
13420  consdata0 = SCIPconsGetData(cons0);
13421  assert(consdata0 != NULL);
13422  assert(consdata0->nvars >= 1);
13423  cons0isequality = SCIPisEQ(scip, consdata0->lhs, consdata0->rhs);
13424 
13425  /* sort the constraint */
13426  SCIP_CALL( consdataSort(scip, consdata0) );
13427 
13428  /* calculate bit signatures of cons0 for potentially positive and negative coefficients */
13429  consdataCalcSignatures(consdata0);
13430  possignature0 = consdata0->possignature;
13431  negsignature0 = consdata0->negsignature;
13432 
13433  /* get temporary memory for indices of common variables */
13434  SCIP_CALL( SCIPallocBufferArray(scip, &commonidx0, consdata0->nvars) );
13435  SCIP_CALL( SCIPallocBufferArray(scip, &commonidx1, consdata0->nvars) );
13436  SCIP_CALL( SCIPallocBufferArray(scip, &diffidx0minus1, consdata0->nvars) );
13437  SCIP_CALL( SCIPallocBufferArray(scip, &diffidx1minus0, consdata0->nvars) );
13438  diffidx1minus0size = consdata0->nvars;
13439 
13440  cons0lhs = consdata0->lhs;
13441  cons0rhs = consdata0->rhs;
13442  cons0upgraded = consdata0->upgraded;
13443 
13444  /* check constraint against all prior constraints */
13445  cons0changed = consdata0->changed;
13446  consdata0->changed = FALSE;
13447  for( c = (cons0changed ? 0 : firstchange); c < chkind && !(*cutoff) && conss[chkind] != NULL; ++c )
13448  {
13449  SCIP_CONS* cons1;
13450  SCIP_CONSDATA* consdata1;
13451  uint64_t possignature1;
13452  uint64_t negsignature1;
13453  SCIP_Bool cons0dominateslhs;
13454  SCIP_Bool cons1dominateslhs;
13455  SCIP_Bool cons0dominatesrhs;
13456  SCIP_Bool cons1dominatesrhs;
13457  SCIP_Bool cons1isequality;
13458  SCIP_Bool coefsequal;
13459  SCIP_Bool coefsnegated;
13460  SCIP_Bool tryaggregation;
13461  int nvarscommon;
13462  int nvars0minus1;
13463  int nvars1minus0;
13464  int commonidxweight;
13465  int diffidx0minus1weight;
13466  int diffidx1minus0weight;
13467  int v0;
13468  int v1;
13469 
13470  assert(cons0lhs == consdata0->lhs); /*lint !e777*/
13471  assert(cons0rhs == consdata0->rhs); /*lint !e777*/
13472  assert(cons0upgraded == consdata0->upgraded);
13473 
13474  cons1 = conss[c];
13475 
13476  /* cons1 has become inactive during presolving of constraint pairs */
13477  if( cons1 == NULL )
13478  continue;
13479 
13480  assert(SCIPconsIsActive(cons0) && !SCIPconsIsModifiable(cons0));
13481  assert(SCIPconsIsActive(cons1) && !SCIPconsIsModifiable(cons1));
13482 
13483  consdata1 = SCIPconsGetData(cons1);
13484  assert(consdata1 != NULL);
13485 
13486  /* SCIPdebugMsg(scip, "preprocess linear constraint pair <%s>[chgd:%d, upgd:%d] and <%s>[chgd:%d, upgd:%d]\n",
13487  SCIPconsGetName(cons0), cons0changed, cons0upgraded,
13488  SCIPconsGetName(cons1), consdata1->changed, consdata1->upgraded); */
13489 
13490  /* if both constraints didn't change since last pair processing, we can ignore the pair */
13491  if( !cons0changed && !consdata1->changed )
13492  continue;
13493 
13494  /* if both constraints are already upgraded, skip the pair;
13495  * because changes on these constraints cannot be applied to the instance anymore */
13496  if( cons0upgraded && consdata1->upgraded )
13497  continue;
13498 
13499  assert(consdata1->nvars >= 1);
13500 
13501  /* sort the constraint */
13502  SCIP_CALL( consdataSort(scip, consdata1) );
13503 
13504  /* calculate bit signatures of cons1 for potentially positive and negative coefficients */
13505  consdataCalcSignatures(consdata1);
13506  possignature1 = consdata1->possignature;
13507  negsignature1 = consdata1->negsignature;
13508 
13509  /* the signatures give a quick test to check for domination and equality of coefficients */
13510  coefsequal = (possignature0 == possignature1) && (negsignature0 == negsignature1);
13511  coefsnegated = (possignature0 == negsignature1) && (negsignature0 == possignature1);
13512  cons0dominateslhs = SCIPisGE(scip, cons0lhs, consdata1->lhs)
13513  && ((possignature0 | possignature1) == possignature1) /* possignature0 <= possignature1 (as bit vector) */
13514  && ((negsignature0 | negsignature1) == negsignature0); /* negsignature0 >= negsignature1 (as bit vector) */
13515  cons1dominateslhs = SCIPisGE(scip, consdata1->lhs, cons0lhs)
13516  && ((possignature0 | possignature1) == possignature0) /* possignature0 >= possignature1 (as bit vector) */
13517  && ((negsignature0 | negsignature1) == negsignature1); /* negsignature0 <= negsignature1 (as bit vector) */
13518  cons0dominatesrhs = SCIPisLE(scip, cons0rhs, consdata1->rhs)
13519  && ((possignature0 | possignature1) == possignature0) /* possignature0 >= possignature1 (as bit vector) */
13520  && ((negsignature0 | negsignature1) == negsignature1); /* negsignature0 <= negsignature1 (as bit vector) */
13521  cons1dominatesrhs = SCIPisLE(scip, consdata1->rhs, cons0rhs)
13522  && ((possignature0 | possignature1) == possignature1) /* possignature0 <= possignature1 (as bit vector) */
13523  && ((negsignature0 | negsignature1) == negsignature0); /* negsignature0 >= negsignature1 (as bit vector) */
13524  cons1isequality = SCIPisEQ(scip, consdata1->lhs, consdata1->rhs);
13525  tryaggregation = (cons0isequality || cons1isequality) && (maxaggrnormscale > 0.0);
13526  if( !cons0dominateslhs && !cons1dominateslhs && !cons0dominatesrhs && !cons1dominatesrhs
13527  && !coefsequal && !coefsnegated && !tryaggregation )
13528  continue;
13529 
13530  /* make sure, we have enough memory for the index set of V_1 \ V_0 */
13531  if( tryaggregation && consdata1->nvars > diffidx1minus0size )
13532  {
13533  SCIP_CALL( SCIPreallocBufferArray(scip, &diffidx1minus0, consdata1->nvars) );
13534  diffidx1minus0size = consdata1->nvars;
13535  }
13536 
13537  /* check consdata0 against consdata1:
13538  * - if lhs0 >= lhs1 and for each variable v and each solution value x_v val0[v]*x_v <= val1[v]*x_v,
13539  * consdata0 dominates consdata1 w.r.t. left hand side
13540  * - if rhs0 <= rhs1 and for each variable v and each solution value x_v val0[v]*x_v >= val1[v]*x_v,
13541  * consdata0 dominates consdata1 w.r.t. right hand side
13542  * - if val0[v] == -val1[v] for all variables v, the two inequalities can be replaced by a single
13543  * ranged row (or equality)
13544  * - if at least one constraint is an equality, count the weighted number of common variables W_c
13545  * and the weighted number of variable in the difference sets W_0 = w(V_0 \ V_1), W_1 = w(V_1 \ V_0),
13546  * where the weight of each variable depends on its type, such that aggregations in order to remove the
13547  * number of continuous and integer variables are preferred:
13548  * - if W_c > W_1, try to aggregate consdata0 := a * consdata0 + b * consdata1 in order to decrease the
13549  * variable weight in consdata0, where a = +/- val1[v] and b = -/+ val0[v] for common v which leads to
13550  * the smallest weight; for numerical stability, we will only accept integral a and b; the sign of a has
13551  * to be positive to not switch the sense of the (in)equality cons0
13552  * - if W_c > W_0, try to aggregate consdata1 := a * consdata1 + b * consdata0 in order to decrease the
13553  * variable weight in consdata1, where a = +/- val0[v] and b = -/+ val1[v] for common v which leads to
13554  * the smallest weight; for numerical stability, we will only accept integral a and b; the sign of a has
13555  * to be positive to not switch the sense of the (in)equality cons1
13556  */
13557 
13558  /* check consdata0 against consdata1 for redundancy, or ranged row accumulation */
13559  nvarscommon = 0;
13560  commonidxweight = 0;
13561  nvars0minus1 = 0;
13562  diffidx0minus1weight = 0;
13563  nvars1minus0 = 0;
13564  diffidx1minus0weight = 0;
13565  v0 = 0;
13566  v1 = 0;
13567  while( (v0 < consdata0->nvars || v1 < consdata1->nvars)
13568  && (cons0dominateslhs || cons1dominateslhs || cons0dominatesrhs || cons1dominatesrhs
13569  || coefsequal || coefsnegated || tryaggregation) )
13570  {
13571  SCIP_VAR* var;
13572  SCIP_Real val0;
13573  SCIP_Real val1;
13574  int varcmp;
13575 
13576  /* test, if variable appears in only one or in both constraints */
13577  if( v0 < consdata0->nvars && v1 < consdata1->nvars )
13578  varcmp = SCIPvarCompare(consdata0->vars[v0], consdata1->vars[v1]);
13579  else if( v0 < consdata0->nvars )
13580  varcmp = -1;
13581  else
13582  varcmp = +1;
13583 
13584  switch( varcmp )
13585  {
13586  case -1:
13587  /* variable doesn't appear in consdata1 */
13588  var = consdata0->vars[v0];
13589  val0 = consdata0->vals[v0];
13590  val1 = 0.0;
13591  if( tryaggregation )
13592  {
13593  diffidx0minus1[nvars0minus1] = v0;
13594  nvars0minus1++;
13595  diffidx0minus1weight += getVarWeight(var);
13596  }
13597  v0++;
13598  coefsequal = FALSE;
13599  coefsnegated = FALSE;
13600  break;
13601 
13602  case +1:
13603  /* variable doesn't appear in consdata0 */
13604  var = consdata1->vars[v1];
13605  val0 = 0.0;
13606  val1 = consdata1->vals[v1];
13607  if( tryaggregation )
13608  {
13609  diffidx1minus0[nvars1minus0] = v1;
13610  nvars1minus0++;
13611  diffidx1minus0weight += getVarWeight(var);
13612  }
13613  v1++;
13614  coefsequal = FALSE;
13615  coefsnegated = FALSE;
13616  break;
13617 
13618  case 0:
13619  /* variable appears in both constraints */
13620  assert(consdata0->vars[v0] == consdata1->vars[v1]);
13621  var = consdata0->vars[v0];
13622  val0 = consdata0->vals[v0];
13623  val1 = consdata1->vals[v1];
13624  if( tryaggregation )
13625  {
13626  commonidx0[nvarscommon] = v0;
13627  commonidx1[nvarscommon] = v1;
13628  nvarscommon++;
13629  commonidxweight += getVarWeight(var);
13630  }
13631  v0++;
13632  v1++;
13633  coefsequal = coefsequal && (SCIPisEQ(scip, val0, val1));
13634  coefsnegated = coefsnegated && (SCIPisEQ(scip, val0, -val1));
13635  break;
13636 
13637  default:
13638  SCIPerrorMessage("invalid comparison result\n");
13639  SCIPABORT();
13640  var = NULL;
13641  val0 = 0.0;
13642  val1 = 0.0;
13643  }
13644  assert(var != NULL);
13645 
13646  /* update domination criteria w.r.t. the coefficient and the variable's bounds */
13647  if( SCIPisGT(scip, val0, val1) )
13648  {
13649  if( SCIPisNegative(scip, SCIPvarGetLbGlobal(var)) )
13650  {
13651  cons0dominatesrhs = FALSE;
13652  cons1dominateslhs = FALSE;
13653  }
13654  if( SCIPisPositive(scip, SCIPvarGetUbGlobal(var)) )
13655  {
13656  cons0dominateslhs = FALSE;
13657  cons1dominatesrhs = FALSE;
13658  }
13659  }
13660  else if( SCIPisLT(scip, val0, val1) )
13661  {
13662  if( SCIPisNegative(scip, SCIPvarGetLbGlobal(var)) )
13663  {
13664  cons0dominateslhs = FALSE;
13665  cons1dominatesrhs = FALSE;
13666  }
13667  if( SCIPisPositive(scip, SCIPvarGetUbGlobal(var)) )
13668  {
13669  cons0dominatesrhs = FALSE;
13670  cons1dominateslhs = FALSE;
13671  }
13672  }
13673  }
13674 
13675  /* check for disaggregated ranged rows */
13676  if( coefsequal || coefsnegated )
13677  {
13678  SCIP_CONS* consstay;
13679  SCIP_CONS* consdel;
13680 #ifndef NDEBUG
13681  SCIP_CONSDATA* consdatastay;
13682 #endif
13683  SCIP_CONSDATA* consdatadel;
13684  SCIP_Real lhs;
13685  SCIP_Real rhs;
13686  int consinddel;
13687 
13688  /* the coefficients in both rows are either equal or negated: create a new constraint with same coefficients and
13689  * best left and right hand sides; delete the old constraints afterwards
13690  */
13691  SCIPdebugMsg(scip, "aggregate linear constraints <%s> and <%s> with %s coefficients into single ranged row\n",
13692  SCIPconsGetName(cons0), SCIPconsGetName(cons1), coefsequal ? "equal" : "negated");
13693  SCIPdebugPrintCons(scip, cons0, NULL);
13694  SCIPdebugPrintCons(scip, cons1, NULL);
13695 
13696  if( coefsequal )
13697  {
13698  /* the coefficients of both rows are equal */
13699  lhs = MAX(consdata0->lhs, consdata1->lhs);
13700  rhs = MIN(consdata0->rhs, consdata1->rhs);
13701  }
13702  else
13703  {
13704  /* the coefficients of both rows are negations */
13705  lhs = MAX(consdata0->lhs, -consdata1->rhs);
13706  rhs = MIN(consdata0->rhs, -consdata1->lhs);
13707  }
13708  if( SCIPisFeasLT(scip, rhs, lhs) )
13709  {
13710  SCIPdebugMsg(scip, "aggregated linear constraint <%s> is infeasible\n", SCIPconsGetName(cons0));
13711  *cutoff = TRUE;
13712  break;
13713  }
13714 
13715  /* check which constraint has to stay;
13716  * changes applied to an upgraded constraint will not be considered in the instance */
13717  if( consdata0->upgraded )
13718  {
13719  assert(!consdata1->upgraded);
13720  consstay = cons1;
13721 #ifndef NDEBUG
13722  consdatastay = consdata1;
13723 #endif
13724 
13725  consdel = cons0;
13726  consdatadel = consdata0;
13727  consinddel = chkind;
13728  }
13729  else
13730  {
13731  consstay = cons0;
13732 #ifndef NDEBUG
13733  consdatastay = consdata0;
13734 #endif
13735 
13736  consdel = cons1;
13737  consdatadel = consdata1;
13738  consinddel = c;
13739  }
13740 
13741  /* update the sides of consstay */
13742  SCIP_CALL( chgLhs(scip, consstay, lhs) );
13743  SCIP_CALL( chgRhs(scip, consstay, rhs) );
13744  if( !consdata0->upgraded )
13745  {
13746  assert(consstay == cons0);
13747  cons0lhs = consdata0->lhs;
13748  cons0rhs = consdata0->rhs;
13749  }
13750 
13751  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13752  SCIP_CALL( SCIPupdateConsFlags(scip, consstay, consdel) );
13753 
13754  assert( !consdatastay->upgraded );
13755  /* delete consdel */
13756  SCIP_CALL( SCIPdelCons(scip, consdel) );
13757  conss[consinddel] = NULL;
13758  if( !consdatadel->upgraded )
13759  (*ndelconss)++;
13760  continue;
13761  }
13762 
13763  /* check for domination: remove dominated sides, but don't touch equalities as long as they are not totally
13764  * redundant
13765  */
13766  if( cons1dominateslhs && (!cons0isequality || cons1dominatesrhs || SCIPisInfinity(scip, consdata0->rhs) ) )
13767  {
13768  /* left hand side is dominated by consdata1: delete left hand side of consdata0 */
13769  SCIPdebugMsg(scip, "left hand side of linear constraint <%s> is dominated by <%s>:\n",
13770  SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13771  SCIPdebugPrintCons(scip, cons0, NULL);
13772  SCIPdebugPrintCons(scip, cons1, NULL);
13773 
13774  /* check for infeasibility */
13775  if( SCIPisFeasGT(scip, consdata1->lhs, consdata0->rhs) )
13776  {
13777  SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13778  *cutoff = TRUE;
13779  break;
13780  }
13781 
13782  /* remove redundant left hand side */
13783  if( !SCIPisInfinity(scip, -consdata0->lhs) )
13784  {
13785  SCIP_CALL( chgLhs(scip, cons0, -SCIPinfinity(scip)) );
13786  cons0lhs = consdata0->lhs;
13787  cons0isequality = FALSE;
13788  if( !consdata0->upgraded )
13789  {
13790  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13791  SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
13792 
13793  (*nchgsides)++;
13794  }
13795  }
13796  }
13797  else if( cons0dominateslhs && (!cons1isequality || cons0dominatesrhs || SCIPisInfinity(scip, consdata1->rhs)) )
13798  {
13799  /* left hand side is dominated by consdata0: delete left hand side of consdata1 */
13800  SCIPdebugMsg(scip, "left hand side of linear constraint <%s> is dominated by <%s>:\n",
13801  SCIPconsGetName(cons1), SCIPconsGetName(cons0));
13802  SCIPdebugPrintCons(scip, cons1, NULL);
13803  SCIPdebugPrintCons(scip, cons0, NULL);
13804 
13805  /* check for infeasibility */
13806  if( SCIPisFeasGT(scip, consdata0->lhs, consdata1->rhs) )
13807  {
13808  SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13809  *cutoff = TRUE;
13810  break;
13811  }
13812 
13813  /* remove redundant left hand side */
13814  if( !SCIPisInfinity(scip, -consdata1->lhs) )
13815  {
13816  SCIP_CALL( chgLhs(scip, cons1, -SCIPinfinity(scip)) );
13817  cons1isequality = FALSE;
13818  if( !consdata1->upgraded )
13819  {
13820  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13821  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
13822 
13823  (*nchgsides)++;
13824  }
13825  }
13826  }
13827  if( cons1dominatesrhs && (!cons0isequality || cons1dominateslhs || SCIPisInfinity(scip, -consdata0->lhs)) )
13828  {
13829  /* right hand side is dominated by consdata1: delete right hand side of consdata0 */
13830  SCIPdebugMsg(scip, "right hand side of linear constraint <%s> is dominated by <%s>:\n",
13831  SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13832  SCIPdebugPrintCons(scip, cons0, NULL);
13833  SCIPdebugPrintCons(scip, cons1, NULL);
13834 
13835  /* check for infeasibility */
13836  if( SCIPisFeasLT(scip, consdata1->rhs, consdata0->lhs) )
13837  {
13838  SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13839  *cutoff = TRUE;
13840  break;
13841  }
13842 
13843  /* remove redundant right hand side */
13844  if( !SCIPisInfinity(scip, consdata0->rhs) )
13845  {
13846  SCIP_CALL( chgRhs(scip, cons0, SCIPinfinity(scip)) );
13847  cons0rhs = consdata0->rhs;
13848  cons0isequality = FALSE;
13849  if( !consdata0->upgraded )
13850  {
13851  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13852  SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
13853 
13854  (*nchgsides)++;
13855  }
13856  }
13857  }
13858  else if( cons0dominatesrhs && (!cons1isequality || cons0dominateslhs || SCIPisInfinity(scip, -consdata1->lhs)) )
13859  {
13860  /* right hand side is dominated by consdata0: delete right hand side of consdata1 */
13861  SCIPdebugMsg(scip, "right hand side of linear constraint <%s> is dominated by <%s>:\n",
13862  SCIPconsGetName(cons1), SCIPconsGetName(cons0));
13863  SCIPdebugPrintCons(scip, cons1, NULL);
13864  SCIPdebugPrintCons(scip, cons0, NULL);
13865 
13866  /* check for infeasibility */
13867  if( SCIPisFeasLT(scip, consdata0->rhs, consdata1->lhs) )
13868  {
13869  SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13870  *cutoff = TRUE;
13871  break;
13872  }
13873 
13874  /* remove redundant right hand side */
13875  if( !SCIPisInfinity(scip, consdata1->rhs) )
13876  {
13877  SCIP_CALL( chgRhs(scip, cons1, SCIPinfinity(scip)) );
13878  cons1isequality = FALSE;
13879  if( !consdata1->upgraded )
13880  {
13881  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13882  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
13883 
13884  (*nchgsides)++;
13885  }
13886  }
13887  }
13888 
13889  /* check for now redundant constraints */
13890  if( SCIPisInfinity(scip, -consdata0->lhs) && SCIPisInfinity(scip, consdata0->rhs) )
13891  {
13892  /* consdata0 became redundant */
13893  SCIPdebugMsg(scip, "linear constraint <%s> is redundant\n", SCIPconsGetName(cons0));
13894  SCIP_CALL( SCIPdelCons(scip, cons0) );
13895  conss[chkind] = NULL;
13896  if( !consdata0->upgraded )
13897  {
13898  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13899  SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
13900 
13901  (*ndelconss)++;
13902  }
13903  continue;
13904  }
13905  if( SCIPisInfinity(scip, -consdata1->lhs) && SCIPisInfinity(scip, consdata1->rhs) )
13906  {
13907  /* consdata1 became redundant */
13908  SCIPdebugMsg(scip, "linear constraint <%s> is redundant\n", SCIPconsGetName(cons1));
13909  SCIP_CALL( SCIPdelCons(scip, cons1) );
13910  conss[c] = NULL;
13911  if( !consdata1->upgraded )
13912  {
13913  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13914  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
13915 
13916  (*ndelconss)++;
13917  }
13918  continue;
13919  }
13920 
13921  /* check, if we want to aggregate an (in)equality with an equality:
13922  * consdata0 := a * consdata0 + b * consdata1 or consdata1 := a * consdata1 + b * consdata0
13923  */
13924  if( tryaggregation )
13925  {
13926  SCIP_Bool aggregated;
13927 
13928  assert(consdata0->nvars == nvarscommon + nvars0minus1);
13929  assert(consdata1->nvars == nvarscommon + nvars1minus0);
13930 
13931  aggregated = FALSE;
13932  if( cons1isequality && !consdata0->upgraded && commonidxweight > diffidx1minus0weight )
13933  {
13934  /* W_c > W_1: try to aggregate consdata0 := a * consdata0 + b * consdata1 */
13935  SCIP_CALL( aggregateConstraints(scip, cons0, cons1, commonidx0, commonidx1, diffidx0minus1, diffidx1minus0,
13936  nvarscommon, commonidxweight, diffidx0minus1weight, diffidx1minus0weight, maxaggrnormscale,
13937  nchgcoefs, &aggregated, cutoff) );
13938 
13939  if( *cutoff )
13940  break;
13941 
13942  /* update array of active constraints */
13943  if( aggregated )
13944  {
13945  assert(!SCIPconsIsActive(cons0));
13946  assert(SCIPconsIsActive(cons1));
13947  conss[chkind] = NULL;
13948  }
13949  }
13950  if( !aggregated && cons0isequality && !consdata1->upgraded && commonidxweight > diffidx0minus1weight )
13951  {
13952  /* W_c > W_0: try to aggregate consdata1 := a * consdata1 + b * consdata0 */
13953  SCIP_CALL( aggregateConstraints(scip, cons1, cons0, commonidx1, commonidx0, diffidx1minus0, diffidx0minus1,
13954  nvarscommon, commonidxweight, diffidx1minus0weight, diffidx0minus1weight, maxaggrnormscale,
13955  nchgcoefs, &aggregated, cutoff) );
13956 
13957  if( *cutoff )
13958  break;
13959 
13960  /* update array of active constraints */
13961  if( aggregated )
13962  {
13963  assert(!SCIPconsIsActive(cons1));
13964  assert(SCIPconsIsActive(cons0));
13965  conss[c] = NULL;
13966  }
13967  }
13968  }
13969  }
13970 
13971  /* free temporary memory */
13972  SCIPfreeBufferArray(scip, &diffidx1minus0);
13973  SCIPfreeBufferArray(scip, &diffidx0minus1);
13974  SCIPfreeBufferArray(scip, &commonidx1);
13975  SCIPfreeBufferArray(scip, &commonidx0);
13976 
13977  return SCIP_OKAY;
13978 }
13979 
13980 /** do stuffing presolving on a single constraint */
13981 static
13983  SCIP* scip, /**< SCIP data structure */
13984  SCIP_CONS* cons, /**< linear constraint */
13985  SCIP_Bool singletonstuffing, /**< should stuffing of singleton continuous variables be performed? */
13986  SCIP_Bool singlevarstuffing, /**< should single variable stuffing be performed, which tries to fulfill
13987  * constraints using the cheapest variable? */
13988  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
13989  int* nfixedvars, /**< pointer to count the total number of fixed variables */
13990  int* nchgbds /**< pointer to count the total number of tightened bounds */
13991  )
13992 {
13993  SCIP_CONSDATA* consdata;
13994  SCIP_Real* ratios;
13995  int* varpos;
13996  SCIP_Bool* swapped;
13997  SCIP_VAR** vars;
13998  SCIP_Real* vals;
13999  SCIP_VAR* var;
14000  SCIP_Real lb;
14001  SCIP_Real ub;
14002  SCIP_Real minactivity;
14003  SCIP_Real maxactivity;
14004  SCIP_Real maxcondactivity;
14005  SCIP_Real mincondactivity;
14006  SCIP_Real rhs;
14007  SCIP_Real val;
14008  SCIP_Real obj;
14009  SCIP_Real factor;
14010  SCIP_Bool minactisrelax;
14011  SCIP_Bool maxactisrelax;
14012  SCIP_Bool isminsettoinfinity;
14013  SCIP_Bool ismaxsettoinfinity;
14014  SCIP_Bool tryfixing;
14015  int nsingletons;
14016  int idx;
14017  int v;
14018  int nvars;
14019 
14020  assert(scip != NULL);
14021  assert(cons != NULL);
14022  assert(nfixedvars != NULL);
14023 
14024  consdata = SCIPconsGetData(cons);
14025 
14026  /* we only want to run for inequalities */
14027  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, -consdata->lhs) )
14028  return SCIP_OKAY;
14029 
14030  if( singlevarstuffing )
14031  {
14032  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
14033  &isminsettoinfinity, &ismaxsettoinfinity);
14034  }
14035  else
14036  {
14037  minactivity = SCIP_INVALID;
14038  maxactivity = SCIP_INVALID;
14039  isminsettoinfinity = FALSE;
14040  ismaxsettoinfinity = FALSE;
14041  }
14042 
14043  /* we want to have a <= constraint, if the rhs is infinite, we implicitly multiply the constraint by -1,
14044  * the new maxactivity is minus the old minactivity then
14045  */
14046  if( SCIPisInfinity(scip, consdata->rhs) )
14047  {
14048  rhs = -consdata->lhs;
14049  factor = -1.0;
14050  maxactivity = -minactivity;
14051  ismaxsettoinfinity = isminsettoinfinity;
14052  }
14053  else
14054  {
14055  assert(SCIPisInfinity(scip, -consdata->lhs));
14056  rhs = consdata->rhs;
14057  factor = 1.0;
14058  }
14059 
14060  nvars = consdata->nvars;
14061  vars = consdata->vars;
14062  vals = consdata->vals;
14063 
14064  /* check for continuous singletons */
14065  if( singletonstuffing )
14066  {
14067  for( v = 0; v < nvars; ++v )
14068  {
14069  var = vars[v];
14070 
14073  break;
14074  }
14075  }
14076  else
14077  /* we don't want to go into the next block */
14078  v = nvars;
14079 
14080  /* a singleton was found -> perform singleton variable stuffing */
14081  if( v < nvars )
14082  {
14083  assert(singletonstuffing);
14084 
14085  SCIP_CALL( SCIPallocBufferArray(scip, &varpos, nvars) );
14086  SCIP_CALL( SCIPallocBufferArray(scip, &ratios, nvars) );
14087  SCIP_CALL( SCIPallocBufferArray(scip, &swapped, nvars) );
14088 
14089  tryfixing = TRUE;
14090  nsingletons = 0;
14091  mincondactivity = 0.0;
14092  maxcondactivity = 0.0;
14093 
14094  for( v = 0; v < nvars; ++v )
14095  {
14096  var = vars[v];
14097  lb = SCIPvarGetLbGlobal(var);
14098  ub = SCIPvarGetUbGlobal(var);
14099  obj = SCIPvarGetObj(var);
14100  val = factor * vals[v];
14101 
14102  assert(!SCIPisZero(scip, val));
14103 
14104  /* the variable is a singleton and continuous */
14107  {
14108  if( SCIPisNegative(scip, obj) && val > 0 )
14109  {
14110  /* case 1: obj < 0 and coef > 0 */
14111  if( SCIPisInfinity(scip, -lb) )
14112  {
14113  tryfixing = FALSE;
14114  break;
14115  }
14116 
14117  maxcondactivity += val * lb;
14118  mincondactivity += val * lb;
14119  swapped[v] = FALSE;
14120  ratios[nsingletons] = obj / val;
14121  varpos[nsingletons] = v;
14122  nsingletons++;
14123  }
14124  else if( SCIPisPositive(scip, obj) && val < 0 )
14125  {
14126  /* case 2: obj > 0 and coef < 0 */
14127  if( SCIPisInfinity(scip, ub) )
14128  {
14129  tryfixing = FALSE;
14130  break;
14131  }
14132  /* multiply column by (-1) to become case 1.
14133  * now bounds are swapped: ub := -lb, lb := -ub
14134  */
14135 
14136  maxcondactivity += val * ub;
14137  mincondactivity += val * ub;
14138  swapped[v] = TRUE;
14139  ratios[nsingletons] = obj / val;
14140  varpos[nsingletons] = v;
14141  nsingletons++;
14142  }
14143  else if( val > 0 )
14144  {
14145  /* case 3: obj >= 0 and coef >= 0 is handled by duality fixing.
14146  * we only consider the lower bound for the constants
14147  */
14148  assert(!SCIPisNegative(scip, obj));
14149 
14150  if( SCIPisInfinity(scip, -lb) )
14151  {
14152  /* maybe unbounded */
14153  tryfixing = FALSE;
14154  break;
14155  }
14156 
14157  maxcondactivity += val * lb;
14158  mincondactivity += val * lb;
14159  }
14160  else
14161  {
14162  /* case 4: obj <= 0 and coef <= 0 is also handled by duality fixing.
14163  * we only consider the upper bound for the constants
14164  */
14165  assert(!SCIPisPositive(scip, obj));
14166  assert(val < 0);
14167 
14168  if( SCIPisInfinity(scip, ub) )
14169  {
14170  /* maybe unbounded */
14171  tryfixing = FALSE;
14172  break;
14173  }
14174 
14175  maxcondactivity += val * ub;
14176  mincondactivity += val * ub;
14177  }
14178  }
14179  else
14180  {
14181  /* consider contribution of discrete variables, non-singleton
14182  * continuous variables and variables with more than one lock
14183  */
14184  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
14185  {
14186  tryfixing = FALSE;
14187  break;
14188  }
14189 
14190  if( val > 0 )
14191  {
14192  maxcondactivity += val * ub;
14193  mincondactivity += val * lb;
14194  }
14195  else
14196  {
14197  maxcondactivity += val * lb;
14198  mincondactivity += val * ub;
14199  }
14200  }
14201  }
14202  if( tryfixing && nsingletons > 0 && (SCIPisGT(scip, rhs, maxcondactivity) || SCIPisLE(scip, rhs, mincondactivity)) )
14203  {
14204  SCIP_Real delta;
14205  SCIP_Bool tightened;
14206 #ifdef SCIP_DEBUG
14207  int oldnfixedvars = *nfixedvars;
14208  int oldnchgbds = *nchgbds;
14209 #endif
14210 
14211  SCIPsortRealInt(ratios, varpos, nsingletons);
14212 
14213  /* verify which singleton continuous variables can be fixed */
14214  for( v = 0; v < nsingletons; ++v )
14215  {
14216  idx = varpos[v];
14217  var = vars[idx];
14218  val = factor * vals[idx];
14219  lb = SCIPvarGetLbGlobal(var);
14220  ub = SCIPvarGetUbGlobal(var);
14221 
14222  assert(val > 0 || SCIPisPositive(scip, SCIPvarGetObj(var)));
14223  assert((val < 0) == swapped[idx]);
14224  val = REALABS(val);
14225 
14226  /* stop fixing if variable bounds are not finite */
14227  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
14228  break;
14229 
14232  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
14233 
14234  /* calculate the change in the row activities if this variable changes
14235  * its value from its worst to its best bound
14236  */
14237  if( swapped[idx] )
14238  delta = -(lb - ub) * val;
14239  else
14240  delta = (ub - lb) * val;
14241 
14242  assert(!SCIPisNegative(scip, delta));
14243 
14244  if( SCIPisLE(scip, delta, rhs - maxcondactivity) )
14245  {
14246  if( swapped[idx] )
14247  {
14248  SCIPdebugMsg(scip, "fix <%s> to its lower bound %g\n", SCIPvarGetName(var), lb);
14249  SCIP_CALL( SCIPfixVar(scip, var, lb, cutoff, &tightened) );
14250  }
14251  else
14252  {
14253  SCIPdebugMsg(scip, "fix <%s> to its upper bound %g\n", SCIPvarGetName(var), ub);
14254  SCIP_CALL( SCIPfixVar(scip, var, ub, cutoff, &tightened) );
14255  }
14256 
14257  if( *cutoff )
14258  break;
14259  if( tightened )
14260  {
14261  (*nfixedvars)++;
14262  }
14263  }
14264  /* @note: we could in theory tighten the bound of the first singleton variable which does not fall into the above case,
14265  * since it cannot be fully fixed. However, this is not needed and should be done by activity-based bound tightening
14266  * anyway after all other continuous singleton columns were fixed; doing it here may introduce numerical
14267  * troubles in case of large bounds.
14268  */
14269  else if( SCIPisLE(scip, rhs, mincondactivity) )
14270  {
14271  if( swapped[idx] )
14272  {
14273  SCIPdebugMsg(scip, "fix <%s> to its upper bound %g\n", SCIPvarGetName(var), ub);
14274  SCIP_CALL( SCIPfixVar(scip, var, ub, cutoff, &tightened) );
14275  }
14276  else
14277  {
14278  SCIPdebugMsg(scip, "fix <%s> to its lower bound %g\n", SCIPvarGetName(var), lb);
14279  SCIP_CALL( SCIPfixVar(scip, var, lb, cutoff, &tightened) );
14280  }
14281 
14282  if( *cutoff )
14283  break;
14284  if( tightened )
14285  {
14286  (*nfixedvars)++;
14287  }
14288  }
14289 
14290  maxcondactivity += delta;
14291  mincondactivity += delta;
14292  }
14293 
14294 #ifdef SCIP_DEBUG
14295  if( *nfixedvars - oldnfixedvars > 0 || *nchgbds - oldnchgbds > 0 )
14296  {
14297  SCIPdebugMsg(scip, "### stuffing fixed %d variables and changed %d bounds\n", *nfixedvars - oldnfixedvars, *nchgbds - oldnchgbds);
14298  }
14299 #endif
14300  }
14301 
14302  SCIPfreeBufferArray(scip, &swapped);
14303  SCIPfreeBufferArray(scip, &ratios);
14304  SCIPfreeBufferArray(scip, &varpos);
14305  }
14306 
14307  /* perform single-variable stuffing:
14308  * for a linear inequality
14309  * a_1 x_1 + a_2 x_2 + ... + a_n x_n <= b
14310  * with a_i > 0 and objective coefficients c_i < 0,
14311  * setting all variables to their upper bound (giving us the maximal activity of the constraint) is worst w.r.t.
14312  * feasibility of the constraint. On the other hand, this gives the best objective function contribution of the
14313  * variables contained in the constraint. The maximal activity should be larger than the rhs, otherwise the constraint
14314  * is redundant.
14315  * Now we are searching for a variable x_k with maximal ratio c_k / a_k (note that all these ratios are negative), so
14316  * that by reducing the value of this variable we reduce the activity of the constraint while having the smallest
14317  * objective deterioration per activity unit. If x_k has no downlocks, is continuous, and can be reduced enough to
14318  * render the constraint feasible, and ALL other variables have only the one uplock installed by the current constraint,
14319  * we can reduce the upper bound of x_k such that the maxactivity equals the rhs and fix all other variables to their
14320  * upper bound.
14321  * Note that the others variables may have downlocks from other constraints, which we do not need to care
14322  * about since we are setting them to the highest possible value. Also, they may be integer or binary, because the
14323  * computed ratio is still a lower bound on the change in the objective caused by reducing those variable to reach
14324  * constraint feasibility. On the other hand, uplocks on x_k from other constraint do no interfer with the method.
14325  * With a slight adjustment, the procedure even works for integral x_k. If (maxactivity - rhs)/val is integral,
14326  * the variable gets an integral value in order to fulfill the constraint tightly, and we can just apply the procedure.
14327  * If (maxactivity - rhs)/val is fractional, we need to check, if overfulfilling the constraint by setting x_k to
14328  * ceil((maxactivity - rhs)/val) is still better than setting x_k to ceil((maxactivity - rhs)/val) - 1 and
14329  * filling the remaining gap in the constraint with the next-best variable. For this, we check that
14330  * c_k * ceil((maxactivity - rhs)/val) is still better than
14331  * c_k * floor((maxactivity - rhs)/val) + c_j * ((maxactivity - rhs) - (floor((maxactivity - rhs)/val) * val))/a_j.
14332  * In this case, the upper bound of x_k is decreased to ub_k - ceil(maxactivity - rhs).
14333  * If there are variables with a_i < 0 and c_i > 0, they are negated to obtain the above form, variables with same
14334  * sign of coefficients in constraint and objective prevent the use of this method.
14335  */
14336  if( singlevarstuffing && !ismaxsettoinfinity )
14337  {
14338  SCIP_Real bestratio = -SCIPinfinity(scip);
14339  SCIP_Real secondbestratio = -SCIPinfinity(scip);
14340  SCIP_Real ratio;
14341  int bestindex = -1;
14342  int bestuplocks = 0;
14343  int bestdownlocks = 1;
14344  int downlocks;
14345  int uplocks;
14346  SCIPdebug( int oldnfixedvars = *nfixedvars; )
14347  SCIPdebug( int oldnchgbds = *nchgbds; )
14348 
14349  /* loop over all variables to identify the best and second-best ratio */
14350  for( v = 0; v < nvars; ++v )
14351  {
14352  var = vars[v];
14353  obj = SCIPvarGetObj(var);
14354  val = factor * vals[v];
14355 
14356  assert(!SCIPisZero(scip, val));
14357 
14358  ratio = obj / val;
14359 
14360  /* if both objective and constraint push the variable to the same direction, we can do nothing here */
14361  if( !SCIPisNegative(scip, ratio) )
14362  {
14363  bestindex = -1;
14364  break;
14365  }
14366 
14367  if( val > 0 )
14368  {
14371  }
14372  else
14373  {
14374  downlocks = SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL);
14376  }
14377 
14378  /* better ratio, update best candidate
14379  * @todo use some tolerance
14380  * @todo check size of domain and updated ratio for integer variables already?
14381  */
14382  if( ratio > bestratio || ((ratio == bestratio) && downlocks == 0 && (bestdownlocks > 0 /*lint !e777*/
14383  || (SCIPvarGetType(vars[bestindex]) != SCIP_VARTYPE_CONTINUOUS
14384  && SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS))) )
14385  {
14386  /* best index becomes second-best*/
14387  if( bestindex != -1 )
14388  {
14389  /* second-best index must not have more than 1 uplock */
14390  if( bestuplocks > 1 )
14391  {
14392  bestindex = -1;
14393  break;
14394  }
14395  else
14396  {
14397  secondbestratio = bestratio;
14398  }
14399  }
14400  bestdownlocks = downlocks;
14401  bestuplocks = uplocks;
14402  bestratio = ratio;
14403  bestindex = v;
14404 
14405  /* if this variable is the best in the end, we cannot do reductions since it has a downlocks,
14406  * if it is not the best, it has too many uplocks -> not applicable
14407  */
14408  if( bestdownlocks > 0 && bestuplocks > 1 )
14409  {
14410  bestindex = -1;
14411  break;
14412  }
14413  }
14414  else
14415  {
14416  /* non-best index must not have more than 1 uplock */
14417  if( uplocks > 1 )
14418  {
14419  bestindex = -1;
14420  break;
14421  }
14422  /* update second-best ratio */
14423  if( ratio > secondbestratio )
14424  {
14425  secondbestratio = ratio;
14426  }
14427  }
14428  }
14429 
14430  /* check if we can apply single variable stuffing */
14431  if( bestindex != -1 && bestdownlocks == 0 )
14432  {
14433  SCIP_Bool tightened = FALSE;
14434  SCIP_Real bounddelta;
14435 
14436  var = vars[bestindex];
14437  obj = SCIPvarGetObj(var);
14438  val = factor * vals[bestindex];
14439  lb = SCIPvarGetLbGlobal(var);
14440  ub = SCIPvarGetUbGlobal(var);
14441  tryfixing = TRUE;
14442 
14443  if( val < 0 )
14444  {
14445  assert(!SCIPisNegative(scip, obj));
14446 
14447  /* the best variable is integer, and we need to overfulfill the constraint when using just the variable */
14448  if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisIntegral(scip, (maxactivity - rhs)/-val) )
14449  {
14450  SCIP_Real bestvarfloor = SCIPfloor(scip, (maxactivity - rhs)/-val);
14451  SCIP_Real activitydelta = (maxactivity - rhs) - (bestvarfloor * -val);
14452  assert(SCIPisPositive(scip, activitydelta));
14453 
14454  tryfixing = SCIPisLE(scip, obj, -activitydelta * secondbestratio);
14455 
14456  bounddelta = SCIPceil(scip, (maxactivity - rhs)/-val);
14457  assert(SCIPisPositive(scip, bounddelta));
14458  }
14459  else
14460  bounddelta = (maxactivity - rhs)/-val;
14461 
14462  tryfixing = tryfixing && SCIPisLE(scip, bounddelta, ub - lb);
14463 
14464  if( tryfixing )
14465  {
14466  assert(SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == 0);
14467 
14468  if( SCIPisEQ(scip, lb + bounddelta, ub) )
14469  {
14470  SCIPdebugMsg(scip, "fix var <%s> to %g\n", SCIPvarGetName(var), lb + bounddelta);
14471  SCIP_CALL( SCIPfixVar(scip, var, lb + bounddelta, cutoff, &tightened) );
14472  }
14473  else
14474  {
14475  SCIPdebugMsg(scip, "tighten the lower bound of <%s> from %g to %g (ub=%g)\n", SCIPvarGetName(var), lb, lb + bounddelta, ub);
14476  SCIP_CALL( SCIPtightenVarLb(scip, var, lb + bounddelta, FALSE, cutoff, &tightened) );
14477  }
14478  }
14479  }
14480  else
14481  {
14482  assert(!SCIPisPositive(scip, obj));
14483 
14484  /* the best variable is integer, and we need to overfulfill the constraint when using just the variable */
14485  if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisIntegral(scip, (maxactivity - rhs)/val))
14486  {
14487  SCIP_Real bestvarfloor = SCIPfloor(scip, (maxactivity - rhs)/val);
14488  SCIP_Real activitydelta = (maxactivity - rhs) - (bestvarfloor * val);
14489  assert(SCIPisPositive(scip, activitydelta));
14490 
14491  tryfixing = SCIPisLE(scip, -obj, activitydelta * secondbestratio);
14492 
14493  bounddelta = SCIPceil(scip, (maxactivity - rhs)/val);
14494  assert(SCIPisPositive(scip, bounddelta));
14495  }
14496  else
14497  bounddelta = (maxactivity - rhs)/val;
14498 
14499  tryfixing = tryfixing && SCIPisLE(scip, bounddelta, ub - lb);
14500 
14501  if( tryfixing )
14502  {
14503  assert(SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == 0);
14504 
14505  if( SCIPisEQ(scip, ub - bounddelta, lb) )
14506  {
14507  SCIPdebugMsg(scip, "fix var <%s> to %g\n", SCIPvarGetName(var), ub - bounddelta);
14508  SCIP_CALL( SCIPfixVar(scip, var, ub - bounddelta, cutoff, &tightened) );
14509  }
14510  else
14511  {
14512  SCIPdebugMsg(scip, "tighten the upper bound of <%s> from %g to %g (lb=%g)\n", SCIPvarGetName(var), ub, ub - bounddelta, lb);
14513  SCIP_CALL( SCIPtightenVarUb(scip, var, ub - bounddelta, FALSE, cutoff, &tightened) );
14514  }
14515  }
14516  }
14517 
14518  if( *cutoff )
14519  return SCIP_OKAY;
14520  if( tightened )
14521  {
14522  if( SCIPisEQ(scip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)) )
14523  ++(*nfixedvars);
14524  else
14525  ++(*nchgbds);
14526 
14527  SCIPdebugMsg(scip, "cons <%s>: %g <=\n", SCIPconsGetName(cons), factor > 0 ? consdata->lhs : -consdata->rhs);
14528  for( v = 0; v < nvars; ++v )
14529  {
14530  SCIPdebugMsg(scip, "%+g <%s>([%g,%g],%g,[%d,%d],%s)\n", factor * vals[v], SCIPvarGetName(vars[v]),
14531  SCIPvarGetLbGlobal(vars[v]), SCIPvarGetUbGlobal(vars[v]), SCIPvarGetObj(vars[v]),
14534  SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS ? "C" : "I");
14535  }
14536  SCIPdebugMsg(scip, "<= %g\n", factor > 0 ? consdata->rhs : -consdata->lhs);
14537 
14538  for( v = 0; v < nvars; ++v )
14539  {
14540  if( v == bestindex )
14541  continue;
14542 
14543  if( factor * vals[v] < 0 )
14544  {
14545  assert(SCIPvarGetNLocksDownType(vars[v], SCIP_LOCKTYPE_MODEL) == 1);
14546  SCIPdebugMsg(scip, "fix <%s> to its lower bound (%g)\n",
14547  SCIPvarGetName(vars[v]), SCIPvarGetLbGlobal(vars[v]));
14548  SCIP_CALL( SCIPfixVar(scip, vars[v], SCIPvarGetLbGlobal(vars[v]), cutoff, &tightened) );
14549  }
14550  else
14551  {
14552  assert(SCIPvarGetNLocksUpType(vars[v], SCIP_LOCKTYPE_MODEL) == 1);
14553  SCIPdebugMsg(scip, "fix <%s> to its upper bound (%g)\n",
14554  SCIPvarGetName(vars[v]), SCIPvarGetUbGlobal(vars[v]));
14555  SCIP_CALL( SCIPfixVar(scip, vars[v], SCIPvarGetUbGlobal(vars[v]), cutoff, &tightened) );
14556  }
14557 
14558  if( *cutoff )
14559  return SCIP_OKAY;
14560  if( tightened )
14561  ++(*nfixedvars);
14562  }
14563  SCIPdebug( SCIPdebugMsg(scip, "### new stuffing fixed %d vars, tightened %d bounds\n", *nfixedvars - oldnfixedvars, *nchgbds - oldnchgbds); )
14564  }
14565  }
14566  }
14567 
14568  return SCIP_OKAY;
14569 }
14570 
14571 /** applies full dual presolving on variables that only appear in linear constraints */
14572 static
14574  SCIP* scip, /**< SCIP data structure */
14575  SCIP_CONS** conss, /**< constraint set */
14576  int nconss, /**< number of constraints */
14577  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
14578  int* nchgbds /**< pointer to count the number of bound changes */
14579  )
14580 {
14581  SCIP_Real* redlb;
14582  SCIP_Real* redub;
14583  int* nlocksdown;
14584  int* nlocksup;
14585  SCIP_Bool* isimplint;
14586  SCIP_VAR** origvars;
14587  SCIP_VAR** vars;
14588  SCIP_VAR** conscontvars;
14589  int nvars;
14590  int nbinvars;
14591  int nintvars;
14592  int ncontvars;
14593  int v;
14594  int c;
14595 
14596  /* we calculate redundancy bounds with the following meaning:
14597  * redlb[v] == k : if x_v >= k, we can always round x_v down to x_v == k without violating any constraint
14598  * redub[v] == k : if x_v <= k, we can always round x_v up to x_v == k without violating any constraint
14599  * then:
14600  * c_v >= 0 : x_v <= redlb[v] is feasible due to optimality
14601  * c_v <= 0 : x_v >= redub[v] is feasible due to optimality
14602  */
14603 
14604  /* Additionally, we detect continuous variables that are implicitly integral.
14605  * A continuous variable j is implicit integral if it only has only +/-1 coefficients,
14606  * and all constraints (including the bounds as trivial constraints) in which:
14607  * c_j > 0: the variable is down-locked,
14608  * c_j < 0: the variable is up-locked,
14609  * c_j = 0: the variable appears
14610  * have, apart from j, only integer variables with integral coefficients and integral sides.
14611  * This is because then, the value of the variable is either determined by one of its bounds or
14612  * by one of these constraints, and in all cases, the value of the variable is integral.
14613  */
14614 
14615  assert(scip != NULL);
14616  assert(nconss == 0 || conss != NULL);
14617  assert(nchgbds != NULL);
14618  assert(!SCIPinProbing(scip));
14619 
14620  /* get active variables */
14621  nvars = SCIPgetNVars(scip);
14622  origvars = SCIPgetVars(scip);
14623 
14624  /* if the problem is a pure binary program, nothing can be achieved by full dual presolve */
14625  nbinvars = SCIPgetNBinVars(scip);
14626  if( nbinvars == nvars )
14627  return SCIP_OKAY;
14628 
14629  /* get number of continuous variables */
14630  ncontvars = SCIPgetNContVars(scip);
14631  nintvars = nvars - ncontvars;
14632 
14633  /* copy the variable array since this array might change during the curse of this algorithm */
14634  nvars = nvars - nbinvars;
14635  SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, &(origvars[nbinvars]), nvars) );
14636 
14637  /* allocate temporary memory */
14638  SCIP_CALL( SCIPallocBufferArray(scip, &redlb, nvars) );
14639  SCIP_CALL( SCIPallocBufferArray(scip, &redub, nvars) );
14640  SCIP_CALL( SCIPallocBufferArray(scip, &nlocksdown, nvars) );
14641  SCIP_CALL( SCIPallocBufferArray(scip, &nlocksup, nvars) );
14642  SCIP_CALL( SCIPallocBufferArray(scip, &isimplint, ncontvars) );
14643  SCIP_CALL( SCIPallocBufferArray(scip, &conscontvars, ncontvars) );
14644 
14645  /* initialize redundancy bounds */
14646  for( v = 0; v < nvars; ++v )
14647  {
14648  assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_BINARY);
14649  redlb[v] = SCIPvarGetLbGlobal(vars[v]);
14650  redub[v] = SCIPvarGetUbGlobal(vars[v]);
14651  }
14652  BMSclearMemoryArray(nlocksdown, nvars);
14653  BMSclearMemoryArray(nlocksup, nvars);
14654 
14655  /* Initialize isimplint array: variable may be implied integer if rounded to their best bound they are integral.
14656  * We better not use SCIPisFeasIntegral() in these checks.
14657  */
14658  for( v = 0; v < ncontvars; v++ )
14659  {
14660  SCIP_VAR* var;
14661  SCIP_Real obj;
14662  SCIP_Real lb;
14663  SCIP_Real ub;
14664 
14665  var = vars[v + nintvars - nbinvars];
14666  lb = SCIPvarGetLbGlobal(var);
14667  ub = SCIPvarGetUbGlobal(var);
14668 
14669  obj = SCIPvarGetObj(var);
14670  if( SCIPisZero(scip, obj) )
14671  isimplint[v] = (SCIPisInfinity(scip, -lb) || SCIPisIntegral(scip, lb)) && (SCIPisInfinity(scip, ub) || SCIPisIntegral(scip, ub));
14672  else
14673  {
14674  if( SCIPisPositive(scip, obj) )
14675  isimplint[v] = (SCIPisInfinity(scip, -lb) || SCIPisIntegral(scip, lb));
14676  else
14677  {
14678  assert(SCIPisNegative(scip, obj));
14679  isimplint[v] = (SCIPisInfinity(scip, ub) || SCIPisIntegral(scip, ub));
14680  }
14681  }
14682  }
14683 
14684  /* scan all constraints */
14685  for( c = 0; c < nconss; ++c )
14686  {
14687  /* we only need to consider constraints that have been locked (i.e., checked constraints or constraints that are
14688  * part of checked disjunctions)
14689  */
14690  if( SCIPconsIsLocked(conss[c]) )
14691  {
14692  SCIP_CONSDATA* consdata;
14693  SCIP_Bool lhsexists;
14694  SCIP_Bool rhsexists;
14695  SCIP_Bool hasimpliedpotential;
14696  SCIP_Bool integralcoefs;
14697  int nlockspos;
14698  int contvarpos;
14699  int nconscontvars;
14700  int i;
14701 
14702  consdata = SCIPconsGetData(conss[c]);
14703  assert(consdata != NULL);
14704 
14705  /* get number of times the constraint was locked */
14706  nlockspos = SCIPconsGetNLocksPos(conss[c]);
14707 
14708  /* we do not want to include constraints with locked negation (this would be too weird) */
14709  if( SCIPconsGetNLocksNeg(conss[c]) > 0 )
14710  {
14711  /* mark all continuous variables as not being implicit integral */
14712  for( i = 0; i < consdata->nvars; ++i )
14713  {
14714  SCIP_VAR* var;
14715 
14716  var = consdata->vars[i];
14718  {
14719  int contv;
14720  contv = SCIPvarGetProbindex(var) - nintvars;
14721  assert(0 <= contv && contv < ncontvars); /* variable should be active due to applyFixings() */
14722  isimplint[contv] = FALSE;
14723  }
14724  }
14725  continue;
14726  }
14727 
14728  /* check for existing sides */
14729  lhsexists = !SCIPisInfinity(scip, -consdata->lhs);
14730  rhsexists = !SCIPisInfinity(scip, consdata->rhs);
14731 
14732  /* count locks and update redundancy bounds */
14733  contvarpos = -1;
14734  nconscontvars = 0;
14735  hasimpliedpotential = FALSE;
14736  integralcoefs = !SCIPconsIsModifiable(conss[c]);
14737 
14738  for( i = 0; i < consdata->nvars; ++i )
14739  {
14740  SCIP_VAR* var;
14741  SCIP_Real val;
14742  SCIP_Real minresactivity;
14743  SCIP_Real maxresactivity;
14744  SCIP_Real newredlb;
14745  SCIP_Real newredub;
14746  SCIP_Bool minisrelax;
14747  SCIP_Bool maxisrelax;
14748  SCIP_Bool isminsettoinfinity;
14749  SCIP_Bool ismaxsettoinfinity;
14750  int arrayindex;
14751 
14752  var = consdata->vars[i];
14753  val = consdata->vals[i];
14754 
14755  /* check if still all integer variables have integral coefficients */
14756  if( SCIPvarIsIntegral(var) )
14757  integralcoefs = integralcoefs && SCIPisIntegral(scip, val);
14758 
14759  /* we do not need to process binary variables */
14760  if( SCIPvarIsBinary(var) )
14761  continue;
14762 
14763  if( SCIPconsIsModifiable(conss[c]) )
14764  {
14765  minresactivity = -SCIPinfinity(scip);
14766  maxresactivity = SCIPinfinity(scip);
14767  isminsettoinfinity = TRUE;
14768  ismaxsettoinfinity = TRUE;
14769  }
14770  else
14771  {
14772  /* calculate residual activity bounds if variable would be fixed to zero */
14773  consdataGetGlbActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
14774  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
14775 
14776  /* We called consdataGetGlbActivityResiduals() saying that we do not need a good relaxation,
14777  * so whenever we have a relaxed activity, it should be relaxed to +/- infinity.
14778  * This is needed, because we do not want to rely on relaxed finite resactivities.
14779  */
14780  assert((!minisrelax || isminsettoinfinity) && (!maxisrelax || ismaxsettoinfinity));
14781 
14782  /* check minresactivity for reliability */
14783  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastglbminactivity) )
14784  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, TRUE);
14785 
14786  /* check maxresactivity for reliability */
14787  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastglbmaxactivity) )
14788  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, TRUE);
14789  }
14790 
14791  arrayindex = SCIPvarGetProbindex(var) - nbinvars;
14792 
14793  assert(0 <= arrayindex && arrayindex < nvars); /* variable should be active due to applyFixings() */
14794 
14795  newredlb = redlb[arrayindex];
14796  newredub = redub[arrayindex];
14797  if( val > 0.0 )
14798  {
14799  if( lhsexists )
14800  {
14801  /* lhs <= d*x + a*y, d > 0 -> redundant in y if x >= (lhs - min{a*y})/d */
14802  nlocksdown[arrayindex] += nlockspos;
14803  newredlb = (isminsettoinfinity ? SCIPinfinity(scip) : (consdata->lhs - minresactivity)/val);
14804  }
14805  if( rhsexists )
14806  {
14807  /* d*x + a*y <= rhs, d > 0 -> redundant in y if x <= (rhs - max{a*y})/d */
14808  nlocksup[arrayindex] += nlockspos;
14809  newredub = (ismaxsettoinfinity ? -SCIPinfinity(scip) : (consdata->rhs - maxresactivity)/val);
14810  }
14811  }
14812  else
14813  {
14814  if( lhsexists )
14815  {
14816  /* lhs <= d*x + a*y, d < 0 -> redundant in y if x <= (lhs - min{a*y})/d */
14817  nlocksup[arrayindex] += nlockspos;
14818  newredub = (isminsettoinfinity ? -SCIPinfinity(scip) : (consdata->lhs - minresactivity)/val);
14819  }
14820  if( rhsexists )
14821  {
14822  /* d*x + a*y <= rhs, d < 0 -> redundant in y if x >= (rhs - max{a*y})/d */
14823  nlocksdown[arrayindex] += nlockspos;
14824  newredlb = (ismaxsettoinfinity ? SCIPinfinity(scip) : (consdata->rhs - maxresactivity)/val);
14825  }
14826  }
14827 
14828  /* if the variable is integer, we have to round the value to the next integral value */
14829  if( SCIPvarIsIntegral(var) )
14830  {
14831  if( !SCIPisInfinity(scip, newredlb) )
14832  newredlb = SCIPceil(scip, newredlb);
14833  if( !SCIPisInfinity(scip, -newredub) )
14834  newredub = SCIPfloor(scip, newredub);
14835  }
14836 
14837  /* update redundancy bounds */
14838  redlb[arrayindex] = MAX(redlb[arrayindex], newredlb);
14839  redub[arrayindex] = MIN(redub[arrayindex], newredub);
14840 
14841  /* collect the continuous variables of the constraint */
14843  {
14844  int contv;
14845 
14846  assert(nconscontvars < ncontvars);
14847  contvarpos = i;
14848  conscontvars[nconscontvars] = var;
14849  nconscontvars++;
14850 
14851  contv = SCIPvarGetProbindex(var) - nintvars;
14852  assert(0 <= contv && contv < ncontvars);
14853  hasimpliedpotential = hasimpliedpotential || isimplint[contv];
14854  }
14855  }
14856 
14857  /* update implied integer status of continuous variables */
14858  if( hasimpliedpotential )
14859  {
14860  if( nconscontvars > 1 || !integralcoefs )
14861  {
14862  /* there is more than one continuous variable or the integer variables have fractional coefficients:
14863  * none of the continuous variables is implied integer
14864  */
14865  for( i = 0; i < nconscontvars; i++ )
14866  {
14867  int contv;
14868  contv = SCIPvarGetProbindex(conscontvars[i]) - nintvars;
14869  assert(0 <= contv && contv < ncontvars);
14870  isimplint[contv] = FALSE;
14871  }
14872  }
14873  else
14874  {
14875  SCIP_VAR* var;
14876  SCIP_Real val;
14877  SCIP_Real absval;
14878  int contv;
14879 
14880  /* there is exactly one continuous variable and the integer variables have integral coefficients:
14881  * this is the interesting case, and we have to check whether the coefficient is +/-1 and the corresponding
14882  * side(s) of the constraint is integral
14883  */
14884  assert(nconscontvars == 1);
14885  assert(0 <= contvarpos && contvarpos < consdata->nvars);
14886  var = consdata->vars[contvarpos];
14887  val = consdata->vals[contvarpos];
14888  contv = SCIPvarGetProbindex(var) - nintvars;
14889  assert(0 <= contv && contv < ncontvars);
14890  assert(isimplint[contv]);
14891 
14892  absval = REALABS(val);
14893  if( !SCIPisEQ(scip, absval, 1.0) )
14894  isimplint[contv] = FALSE;
14895  else
14896  {
14897  SCIP_Real obj;
14898 
14899  obj = SCIPvarGetObj(var);
14900  if( obj * val >= 0.0 && lhsexists )
14901  {
14902  /* the variable may be blocked by the constraint's left hand side */
14903  isimplint[contv] = isimplint[contv] && SCIPisIntegral(scip, consdata->lhs);
14904  }
14905  if( obj * val <= 0.0 && rhsexists )
14906  {
14907  /* the variable may be blocked by the constraint's left hand side */
14908  isimplint[contv] = isimplint[contv] && SCIPisIntegral(scip, consdata->rhs);
14909  }
14910  }
14911  }
14912  }
14913  }
14914  }
14915 
14916  /* check if any bounds can be tightened due to optimality */
14917  for( v = 0; v < nvars; ++v )
14918  {
14919  SCIP_VAR* var;
14920  SCIP_Real obj;
14921  SCIP_Bool infeasible;
14922  SCIP_Bool tightened;
14923 
14924  assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_BINARY);
14925  assert(SCIPvarGetNLocksDownType(vars[v], SCIP_LOCKTYPE_MODEL) >= nlocksdown[v]);
14926  assert(SCIPvarGetNLocksUpType(vars[v], SCIP_LOCKTYPE_MODEL) >= nlocksup[v]);
14927 
14928  var = vars[v];
14929  obj = SCIPvarGetObj(var);
14930  if( obj >= 0.0 )
14931  {
14932  /* making the variable as small as possible does not increase the objective:
14933  * check if all down locks of the variables are due to linear constraints;
14934  * if largest bound to make constraints redundant is -infinity, we better do nothing for numerical reasons
14935  */
14936  if( SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == nlocksdown[v]
14937  && !SCIPisInfinity(scip, -redlb[v])
14938  && redlb[v] < SCIPvarGetUbGlobal(var) )
14939  {
14940  SCIP_Real ub;
14941 
14942  /* if x_v >= redlb[v], we can always round x_v down to x_v == redlb[v] without violating any constraint
14943  * -> tighten upper bound to x_v <= redlb[v]
14944  */
14945  SCIPdebugMsg(scip, "variable <%s> only locked down in linear constraints: dual presolve <%s>[%.15g,%.15g] <= %.15g\n",
14947  redlb[v]);
14948  SCIP_CALL( SCIPtightenVarUb(scip, var, redlb[v], FALSE, &infeasible, &tightened) );
14949  assert(!infeasible);
14950 
14951  ub = SCIPvarGetUbGlobal(var);
14952  redub[v] = MIN(redub[v], ub);
14953  if( tightened )
14954  (*nchgbds)++;
14955  }
14956  }
14957  if( obj <= 0.0 )
14958  {
14959  /* making the variable as large as possible does not increase the objective:
14960  * check if all up locks of the variables are due to linear constraints;
14961  * if smallest bound to make constraints redundant is +infinity, we better do nothing for numerical reasons
14962  */
14963  if( SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == nlocksup[v]
14964  && !SCIPisInfinity(scip, redub[v])
14965  && redub[v] > SCIPvarGetLbGlobal(var) )
14966  {
14967  SCIP_Real lb;
14968 
14969  /* if x_v <= redub[v], we can always round x_v up to x_v == redub[v] without violating any constraint
14970  * -> tighten lower bound to x_v >= redub[v]
14971  */
14972  SCIPdebugMsg(scip, "variable <%s> only locked up in linear constraints: dual presolve <%s>[%.15g,%.15g] >= %.15g\n",
14974  redub[v]);
14975  SCIP_CALL( SCIPtightenVarLb(scip, var, redub[v], FALSE, &infeasible, &tightened) );
14976  assert(!infeasible);
14977 
14978  lb = SCIPvarGetLbGlobal(var);
14979  redlb[v] = MAX(redlb[v], lb);
14980  if( tightened )
14981  (*nchgbds)++;
14982  }
14983  }
14984  }
14985 
14986  /* upgrade continuous variables to implied integers */
14987  for( v = nintvars - nbinvars; v < nvars; ++v )
14988  {
14989  SCIP_VAR* var;
14990  SCIP_Bool infeasible;
14991 
14992  var = vars[v];
14993  assert(var != NULL);
14994 
14995  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
14996  assert(SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) >= nlocksdown[v]);
14997  assert(SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) >= nlocksup[v]);
14998  assert(0 <= v - nintvars + nbinvars && v - nintvars + nbinvars < ncontvars);
14999 
15000  /* we can only conclude implied integrality if the variable appears in no other constraint */
15001  if( isimplint[v - nintvars + nbinvars]
15002  && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == nlocksdown[v]
15003  && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == nlocksup[v] )
15004  {
15005  /* since we locally copied the variable array we can change the variable type immediately */
15006  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
15007 
15008  if( infeasible )
15009  {
15010  SCIPdebugMsg(scip, "infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
15011  *cutoff = TRUE;
15012 
15013  break;
15014  }
15015 
15016  SCIPdebugMsg(scip, "dual presolve: converting continuous variable <%s>[%g,%g] to implicit integer\n",
15018  }
15019  }
15020 
15021  /* free temporary memory */
15022  SCIPfreeBufferArray(scip, &conscontvars);
15023  SCIPfreeBufferArray(scip, &isimplint);
15024  SCIPfreeBufferArray(scip, &nlocksup);
15025  SCIPfreeBufferArray(scip, &nlocksdown);
15026  SCIPfreeBufferArray(scip, &redub);
15027  SCIPfreeBufferArray(scip, &redlb);
15028 
15029  SCIPfreeBufferArray(scip, &vars);
15030 
15031  return SCIP_OKAY;
15032 }
15033 
15034 /** helper function to enforce constraints */
15035 static
15037  SCIP* scip, /**< SCIP data structure */
15038  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
15039  SCIP_CONS** conss, /**< constraints to process */
15040  int nconss, /**< number of constraints */
15041  int nusefulconss, /**< number of useful (non-obsolete) constraints to process */
15042  SCIP_SOL* sol, /**< solution to enforce (NULL for the LP solution) */
15043  SCIP_RESULT* result /**< pointer to store the result of the enforcing call */
15044  )
15045 {
15046  SCIP_CONSHDLRDATA* conshdlrdata;
15047  SCIP_Bool checkrelmaxabs;
15048  SCIP_Bool violated;
15049  SCIP_Bool cutoff = FALSE;
15050  int c;
15051 
15052  assert(scip != NULL);
15053  assert(conshdlr != NULL);
15054  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15055  assert(result != NULL);
15056 
15057  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15058  assert(conshdlrdata != NULL);
15059 
15060  checkrelmaxabs = conshdlrdata->checkrelmaxabs;
15061 
15062  SCIPdebugMsg(scip, "Enforcement method of linear constraints for %s solution\n", sol == NULL ? "LP" : "relaxation");
15063 
15064  /* check for violated constraints
15065  * LP is processed at current node -> we can add violated linear constraints to the SCIP_LP
15066  */
15067  *result = SCIP_FEASIBLE;
15068 
15069  /* check all useful linear constraints for feasibility */
15070  for( c = 0; c < nusefulconss; ++c )
15071  {
15072  SCIP_CALL( checkCons(scip, conss[c], sol, FALSE, checkrelmaxabs, &violated) );
15073 
15074  if( violated )
15075  {
15076  /* insert LP row as cut */
15077  SCIP_CALL( addRelaxation(scip, conss[c], &cutoff) );
15078  if ( cutoff )
15079  *result = SCIP_CUTOFF;
15080  else
15081  *result = SCIP_SEPARATED;
15082  }
15083  }
15084 
15085  /* check all obsolete linear constraints for feasibility */
15086  for( c = nusefulconss; c < nconss && *result == SCIP_FEASIBLE; ++c )
15087  {
15088  SCIP_CALL( checkCons(scip, conss[c], sol, FALSE, checkrelmaxabs, &violated) );
15089 
15090  if( violated )
15091  {
15092  /* insert LP row as cut */
15093  SCIP_CALL( addRelaxation(scip, conss[c], &cutoff) );
15094  if ( cutoff )
15095  *result = SCIP_CUTOFF;
15096  else
15097  *result = SCIP_SEPARATED;
15098  }
15099  }
15100 
15101  SCIPdebugMsg(scip, "-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
15102 
15103  return SCIP_OKAY;
15104 }
15105 
15106 /*
15107  * Callback methods of constraint handler
15108  */
15109 
15110 /** copy method for constraint handler plugins (called when SCIP copies plugins) */
15111 static
15112 SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinear)
15113 { /*lint --e{715}*/
15114  assert(scip != NULL);
15115  assert(conshdlr != NULL);
15116  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15117 
15118  /* call inclusion method of constraint handler */
15120 
15121  *valid = TRUE;
15122 
15123  return SCIP_OKAY;
15124 }
15125 
15126 /** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
15127 static
15128 SCIP_DECL_CONSFREE(consFreeLinear)
15129 { /*lint --e{715}*/
15130  SCIP_CONSHDLRDATA* conshdlrdata;
15131 
15132  assert(scip != NULL);
15133  assert(conshdlr != NULL);
15134  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15135 
15136  /* free constraint handler data */
15137  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15138  assert(conshdlrdata != NULL);
15139 
15140  conshdlrdataFree(scip, &conshdlrdata);
15141 
15142  SCIPconshdlrSetData(conshdlr, NULL);
15143 
15144  return SCIP_OKAY;
15146 
15147 
15148 /** initialization method of constraint handler (called after problem was transformed) */
15149 static
15150 SCIP_DECL_CONSINIT(consInitLinear)
15151 {
15152  SCIP_CONSHDLRDATA* conshdlrdata;
15153  int c;
15154 
15155  assert(scip != NULL);
15156 
15157  /* check for event handler */
15158  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15159  assert(conshdlrdata != NULL);
15160  assert(conshdlrdata->eventhdlr != NULL);
15161  assert(nconss == 0 || conss != NULL);
15162 
15163  /* catch events for the constraints */
15164  for( c = 0; c < nconss; ++c )
15165  {
15166  /* catch all events */
15167  SCIP_CALL( consCatchAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
15168  }
15169 
15170  return SCIP_OKAY;
15171 }
15172 
15173 
15174 /** deinitialization method of constraint handler (called before transformed problem is freed) */
15175 static
15176 SCIP_DECL_CONSEXIT(consExitLinear)
15177 {
15178  SCIP_CONSHDLRDATA* conshdlrdata;
15179  int c;
15180 
15181  assert(scip != NULL);
15182 
15183  /* check for event handler */
15184  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15185  assert(conshdlrdata != NULL);
15186  assert(conshdlrdata->eventhdlr != NULL);
15187 
15188  /* drop events for the constraints */
15189  for( c = nconss - 1; c >= 0; --c )
15190  {
15191  SCIP_CONSDATA* consdata;
15192 
15193  consdata = SCIPconsGetData(conss[c]);
15194  assert(consdata != NULL);
15195 
15196  if( consdata->eventdata != NULL )
15197  {
15198  /* drop all events */
15199  SCIP_CALL( consDropAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
15200  assert(consdata->eventdata == NULL);
15201  }
15202  }
15203 
15204  return SCIP_OKAY;
15205 }
15206 
15207 /** is constraint ranged row, i.e., -inf < lhs < rhs < inf? */
15208 static
15210  SCIP* scip, /**< SCIP data structure */
15211  SCIP_Real lhs, /**< left hand side */
15212  SCIP_Real rhs /**< right hand side */
15213  )
15214 {
15215  assert(scip != NULL);
15216 
15217  return !(SCIPisEQ(scip, lhs, rhs) || SCIPisInfinity(scip, -lhs) || SCIPisInfinity(scip, rhs) );
15218 }
15219 
15220 /** is constraint ranged row, i.e., -inf < lhs < rhs < inf? */
15221 static
15223  SCIP* scip, /**< SCIP data structure */
15224  SCIP_Real x /**< value */
15225  )
15227  assert(scip != NULL);
15228 
15229  return (!SCIPisInfinity(scip, x) && !SCIPisNegative(scip, x) && SCIPisIntegral(scip, x));
15230 }
15231 
15232 /** performs linear constraint type classification as used for MIPLIB
15233  *
15234  * iterates through all linear constraints and stores relevant statistics in the linear constraint statistics \p linconsstats.
15235  *
15236  * @note only constraints are iterated that belong to the linear constraint handler. If the problem has been presolved already,
15237  * constraints that were upgraded to more special types such as, e.g., varbound constraints, will not be shown correctly anymore.
15238  * Similarly, if specialized constraints were created through the API, these are currently not present.
15239  */
15241  SCIP* scip, /**< SCIP data structure */
15242  SCIP_LINCONSSTATS* linconsstats /**< linear constraint type classification */
15243  )
15244 {
15245  int c;
15246  SCIP_CONSHDLR* conshdlr;
15247  SCIP_CONS** conss;
15248  int nconss;
15249 
15250  assert(scip != NULL);
15251  assert(linconsstats != NULL);
15252  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
15253  assert(conshdlr != NULL);
15254 
15255  if( SCIPgetStage(scip) == SCIP_STAGE_PROBLEM )
15256  {
15257  conss = SCIPgetConss(scip);
15258  nconss = SCIPgetNConss(scip);
15259  }
15260  else
15261  {
15262  conss = SCIPconshdlrGetConss(conshdlr);
15263  nconss = SCIPconshdlrGetNConss(conshdlr);
15264  }
15265 
15266  /* reset linear constraint type classification */
15267  SCIPlinConsStatsReset(linconsstats);
15268 
15269  /* loop through all constraints */
15270  for( c = 0; c < nconss; c++ )
15271  {
15272  SCIP_CONS* cons;
15273  SCIP_CONSDATA* consdata;
15274  SCIP_Real lhs;
15275  SCIP_Real rhs;
15276  int i;
15277 
15278  /* get constraint */
15279  cons = conss[c];
15280  assert(cons != NULL);
15281 
15282  /* skip constraints that are not handled by the constraint handler */
15283  if( SCIPconsGetHdlr(cons) != conshdlr )
15284  continue;
15285 
15286  /* get constraint data */
15287  consdata = SCIPconsGetData(cons);
15288  assert(consdata != NULL);
15289  rhs = consdata->rhs;
15290  lhs = consdata->lhs;
15291 
15292  /* merge multiples and delete variables with zero coefficient */
15293  SCIP_CALL( mergeMultiples(scip, cons) );
15294  for( i = 0; i < consdata->nvars; i++ )
15295  {
15296  assert(!SCIPisZero(scip, consdata->vals[i]));
15297  }
15298 
15299  /* is constraint of type SCIP_CONSTYPE_EMPTY? */
15300  if( consdata->nvars == 0 )
15301  {
15302  SCIPdebugMsg(scip, "classified as EMPTY: ");
15303  SCIPdebugPrintCons(scip, cons, NULL);
15305 
15306  continue;
15307  }
15308 
15309  /* is constraint of type SCIP_CONSTYPE_FREE? */
15310  if( SCIPisInfinity(scip, rhs) && SCIPisInfinity(scip, -lhs) )
15311  {
15312  SCIPdebugMsg(scip, "classified as FREE: ");
15313  SCIPdebugPrintCons(scip, cons, NULL);
15315 
15316  continue;
15317  }
15318 
15319  /* is constraint of type SCIP_CONSTYPE_SINGLETON? */
15320  if( consdata->nvars == 1 )
15321  {
15322  SCIPdebugMsg(scip, "classified as SINGLETON: ");
15323  SCIPdebugPrintCons(scip, cons, NULL);
15324  SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_SINGLETON, isRangedRow(scip, lhs, rhs) ? 2 : 1);
15325 
15326  continue;
15327  }
15328 
15329  /* is constraint of type SCIP_CONSTYPE_AGGREGATION? */
15330  if( consdata->nvars == 2 && SCIPisEQ(scip, lhs, rhs) )
15331  {
15332  SCIPdebugMsg(scip, "classified as AGGREGATION: ");
15333  SCIPdebugPrintCons(scip, cons, NULL);
15335 
15336  continue;
15337  }
15338 
15339  /* is constraint of type SCIP_CONSTYPE_{VARBOUND,PRECEDENCE}? */
15340  if( consdata->nvars == 2 )
15341  {
15342  SCIP_LINCONSTYPE constype;
15343 
15344  /* precedence constraints have the same coefficient, but with opposite sign for the same variable type */
15345  if( SCIPisEQ(scip, consdata->vals[0], -consdata->vals[1])
15346  && SCIPvarGetType(consdata->vars[0]) == SCIPvarGetType(consdata->vars[1]))
15347  {
15348  constype = SCIP_LINCONSTYPE_PRECEDENCE;
15349  SCIPdebugMsg(scip, "classified as PRECEDENCE: ");
15350  }
15351  else
15352  {
15353  constype = SCIP_LINCONSTYPE_VARBOUND;
15354  SCIPdebugMsg(scip, "classified as VARBOUND: ");
15355  }
15356  SCIPdebugPrintCons(scip, cons, NULL);
15357 
15358  SCIPlinConsStatsIncTypeCount(linconsstats, constype, isRangedRow(scip, lhs, rhs) ? 2 : 1);
15359 
15360  continue;
15361  }
15362 
15363  /* is constraint of type SCIP_CONSTYPE_{SETPARTITION, SETPACKING, SETCOVERING, CARDINALITY, INVKNAPSACK}? */
15364  {
15365  SCIP_Real scale;
15366  SCIP_Real b;
15367  SCIP_Bool unmatched;
15368  int nnegbinvars;
15369 
15370  unmatched = FALSE;
15371  nnegbinvars = 0;
15372 
15373  scale = REALABS(consdata->vals[0]);
15374 
15375  /* scan through variables and detect if all variables are binary and have a coefficient +/-1 */
15376  for( i = 0; i < consdata->nvars && !unmatched; i++ )
15377  {
15378  unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
15379  unmatched = unmatched || SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0);
15380  unmatched = unmatched || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0);
15381  unmatched = unmatched || !SCIPisEQ(scip, REALABS(consdata->vals[i]), scale);
15382 
15383  if( consdata->vals[i] < 0.0 )
15384  nnegbinvars++;
15385  }
15386 
15387  if( !unmatched )
15388  {
15389  if( SCIPisEQ(scip, lhs, rhs) )
15390  {
15391  b = rhs/scale + nnegbinvars;
15392  if( SCIPisEQ(scip, 1.0, b) )
15393  {
15394  SCIPdebugMsg(scip, "classified as SETPARTITION: ");
15395  SCIPdebugPrintCons(scip, cons, NULL);
15397 
15398  continue;
15399  }
15400  else if( SCIPisIntegral(scip, b) && !SCIPisNegative(scip, b) )
15401  {
15402  SCIPdebugMsg(scip, "classified as CARDINALITY: ");
15403  SCIPdebugPrintCons(scip, cons, NULL);
15405 
15406  continue;
15407  }
15408  }
15409 
15410  /* compute right hand side divided by scale */
15411  if( !SCIPisInfinity(scip, rhs) )
15412  b = rhs/scale + nnegbinvars;
15413  else
15414  b = SCIPinfinity(scip);
15415 
15416  if( SCIPisEQ(scip, 1.0, b) )
15417  {
15418  SCIPdebugMsg(scip, "classified as SETPACKING: ");
15419  SCIPdebugPrintCons(scip, cons, NULL);
15421 
15422  /* relax right hand side to prevent further classifications */
15423  rhs = SCIPinfinity(scip);
15424  }
15425  else if( !SCIPisInfinity(scip, b) && SCIPisIntegral(scip, b) && !SCIPisNegative(scip, b) )
15426  {
15427  SCIPdebugMsg(scip, "classified as INVKNAPSACK: ");
15428  SCIPdebugPrintCons(scip, cons, NULL);
15429 
15431 
15432  /* relax right hand side to prevent further classifications */
15433  rhs = SCIPinfinity(scip);
15434  }
15435 
15436  if( !SCIPisInfinity(scip, lhs) )
15437  b = lhs/scale + nnegbinvars;
15438  else
15439  b = SCIPinfinity(scip);
15440 
15441  if( SCIPisEQ(scip, 1.0, b) )
15442  {
15443  SCIPdebugMsg(scip, "classified as SETCOVERING: ");
15444  SCIPdebugPrintCons(scip, cons, NULL);
15446 
15447  /* relax left hand side to prevent further classifications */
15448  lhs = -SCIPinfinity(scip);
15449  }
15450 
15451  /* if both sides are infinite at this point, no further classification is necessary for this constraint */
15452  if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
15453  continue;
15454  }
15455  }
15456 
15457  /* is constraint of type SCIP_CONSTYPE_{EQKNAPSACK, BINPACKING, KNAPSACK}? */
15458  /* @todo If coefficients or rhs are not integral, we currently do not check
15459  * if the constraint could be scaled (finitely), such that they are.
15460  */
15461  {
15462  SCIP_Real b;
15463  SCIP_Bool unmatched;
15464 
15465  b = rhs;
15466  unmatched = FALSE;
15467  for( i = 0; i < consdata->nvars && !unmatched; i++ )
15468  {
15469  unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
15470  unmatched = unmatched || SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0);
15471  unmatched = unmatched || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0);
15472  unmatched = unmatched || !SCIPisIntegral(scip, consdata->vals[i]);
15473 
15474  if( SCIPisNegative(scip, consdata->vals[i]) )
15475  b -= consdata->vals[i];
15476  }
15477  unmatched = unmatched || !isFiniteNonnegativeIntegral(scip, b);
15478 
15479  if( !unmatched )
15480  {
15481  if( SCIPisEQ(scip, lhs, rhs) )
15482  {
15483  SCIPdebugMsg(scip, "classified as EQKNAPSACK: ");
15484  SCIPdebugPrintCons(scip, cons, NULL);
15485 
15487 
15488  continue;
15489  }
15490  else
15491  {
15492  SCIP_Bool matched;
15493 
15494  matched = FALSE;
15495  for( i = 0; i < consdata->nvars && !matched; i++ )
15496  {
15497  matched = matched || SCIPisEQ(scip, b, REALABS(consdata->vals[i]));
15498  }
15499 
15500  SCIPdebugMsg(scip, "classified as %s: ", matched ? "BINPACKING" : "KNAPSACK");
15501  SCIPdebugPrintCons(scip, cons, NULL);
15503  }
15504 
15505  /* check if finite left hand side allows for a second classification, relax already used right hand side */
15506  if( SCIPisInfinity(scip, -lhs) )
15507  continue;
15508  else
15509  rhs = SCIPinfinity(scip);
15510  }
15511  }
15512 
15513  /* is constraint of type SCIP_CONSTYPE_{INTKNAPSACK}? */
15514  {
15515  SCIP_Real b;
15516  SCIP_Bool unmatched;
15517 
15518  unmatched = FALSE;
15519 
15520  b = rhs;
15521  unmatched = unmatched || !isFiniteNonnegativeIntegral(scip, b);
15522 
15523  for( i = 0; i < consdata->nvars && !unmatched; i++ )
15524  {
15525  unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
15526  unmatched = unmatched || SCIPisNegative(scip, SCIPvarGetLbGlobal(consdata->vars[i]));
15527  unmatched = unmatched || !SCIPisIntegral(scip, consdata->vals[i]);
15528  unmatched = unmatched || SCIPisNegative(scip, consdata->vals[i]);
15529  }
15530 
15531  if( !unmatched )
15532  {
15533  SCIPdebugMsg(scip, "classified as INTKNAPSACK: ");
15534  SCIPdebugPrintCons(scip, cons, NULL);
15536 
15537  /* check if finite left hand side allows for a second classification, relax already used right hand side */
15538  if( SCIPisInfinity(scip, -lhs) )
15539  continue;
15540  else
15541  rhs = SCIPinfinity(scip);
15542  }
15543  }
15544 
15545  /* is constraint of type SCIP_CONSTYPE_{MIXEDBINARY}? */
15546  {
15547  SCIP_Bool unmatched;
15548 
15549  unmatched = FALSE;
15550  for( i = 0; i < consdata->nvars && !unmatched; i++ )
15551  {
15552  if( SCIPvarGetType(consdata->vars[i]) != SCIP_VARTYPE_CONTINUOUS
15553  && (SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0)
15554  || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0)) )
15555  unmatched = TRUE;
15556  }
15557 
15558  if( !unmatched )
15559  {
15560  SCIPdebugMsg(scip, "classified as MIXEDBINARY (%d): ", isRangedRow(scip, lhs, rhs) ? 2 : 1);
15561  SCIPdebugPrintCons(scip, cons, NULL);
15562  SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_MIXEDBINARY, isRangedRow(scip, lhs, rhs) ? 2 : 1);
15563 
15564  continue;
15565  }
15566  }
15567 
15568  /* no special structure detected */
15569  SCIPdebugMsg(scip, "classified as GENERAL: ");
15570  SCIPdebugPrintCons(scip, cons, NULL);
15571  SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_GENERAL, isRangedRow(scip, lhs, rhs) ? 2 : 1);
15572  }
15573 
15574  return SCIP_OKAY;
15575 }
15576 
15577 
15578 /** presolving deinitialization method of constraint handler (called after presolving has been finished) */
15579 static
15580 SCIP_DECL_CONSEXITPRE(consExitpreLinear)
15581 { /*lint --e{715}*/
15582  int c;
15583 #ifdef SCIP_STATISTIC
15584  SCIP_CONSHDLRDATA* conshdlrdata;
15585  int ngoodconss;
15586  int nallconss;
15587 #endif
15588 
15589  /* delete all linear constraints that were upgraded to a more specific constraint type;
15590  * make sure, only active variables remain in the remaining constraints
15591  */
15592  assert(scip != NULL);
15593 
15594 #ifdef SCIP_STATISTIC
15595  /* count number of well behaved linear constraints */
15596  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15597  assert(conshdlrdata != NULL);
15598 
15599  ngoodconss = 0;
15600  nallconss = 0;
15601 
15602  for( c = 0; c < nconss; ++c )
15603  {
15604  SCIP_CONSDATA* consdata;
15605 
15606  if( SCIPconsIsDeleted(conss[c]) )
15607  continue;
15608 
15609  consdata = SCIPconsGetData(conss[c]);
15610  assert(consdata != NULL);
15611 
15612  if( consdata->upgraded )
15613  continue;
15614 
15615  nallconss++;
15616 
15617  consdataRecomputeMaxActivityDelta(scip, consdata);
15618 
15619  if( SCIPisLT(scip, consdata->maxactdelta, conshdlrdata->maxeasyactivitydelta) )
15620  ngoodconss++;
15621  }
15622  if( nallconss )
15623  {
15624  SCIPstatisticMessage("below threshold: %d / %d ratio= %g\n", ngoodconss, nallconss, (100.0 * ngoodconss / nallconss));
15625  }
15626 #endif
15627 
15628  for( c = 0; c < nconss; ++c )
15629  {
15630  SCIP_CONSDATA* consdata;
15631 
15632  if( SCIPconsIsDeleted(conss[c]) )
15633  continue;
15634 
15635  consdata = SCIPconsGetData(conss[c]);
15636  assert(consdata != NULL);
15637 
15638  if( consdata->upgraded )
15639  {
15640  /* this is no problem reduction, because the upgraded constraint was added to the problem before, and the
15641  * (redundant) linear constraint was only kept in order to support presolving the the linear constraint handler
15642  */
15643  SCIP_CALL( SCIPdelCons(scip, conss[c]) );
15644  }
15645  else
15646  {
15647  /* since we are not allowed to detect infeasibility in the exitpre stage, we dont give an infeasible pointer */
15648  SCIP_CALL( applyFixings(scip, conss[c], NULL) );
15649  }
15650  }
15651 
15652  return SCIP_OKAY;
15653 }
15654 
15655 
15656 /** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
15657 static
15658 SCIP_DECL_CONSEXITSOL(consExitsolLinear)
15659 { /*lint --e{715}*/
15660  int c;
15661 
15662  assert(scip != NULL);
15663 
15664  /* release the rows of all constraints */
15665  for( c = 0; c < nconss; ++c )
15666  {
15667  SCIP_CONSDATA* consdata;
15668 
15669  consdata = SCIPconsGetData(conss[c]);
15670  assert(consdata != NULL);
15671 
15672  if( consdata->row != NULL )
15673  {
15674  SCIP_CALL( SCIPreleaseRow(scip, &consdata->row) );
15675  }
15676  }
15677 
15678  /* if this is a restart, convert cutpool rows into linear constraints */
15679  if( restart )
15680  {
15681  int ncutsadded;
15682 
15683  ncutsadded = 0;
15684 
15685  /* create out of all active cuts in cutpool linear constraints */
15686  SCIP_CALL( SCIPconvertCutsToConss(scip, NULL, NULL, TRUE, &ncutsadded) );
15687 
15688  if( ncutsadded > 0 )
15689  {
15691  "(restart) converted %d cuts from the global cut pool into linear constraints\n", ncutsadded);
15692  /* an extra blank line should be printed separately since the buffer message handler only handles up to one
15693  * line correctly
15694  */
15696  }
15697  }
15698 
15699  return SCIP_OKAY;
15700 }
15701 
15702 
15703 /** constraint deactivation notification method of constraint handler */
15704 static
15705 SCIP_DECL_CONSDEACTIVE(consDeactiveLinear)
15706 { /*lint --e{715}*/
15707  assert( cons != NULL );
15708 
15709  if( SCIPconsIsDeleted(cons) )
15710  {
15711  SCIP_CONSHDLRDATA* conshdlrdata;
15712  SCIP_CONSDATA* consdata;
15713 
15714  assert(scip != NULL);
15715  assert(conshdlr != NULL);
15716  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15717 
15718  /* get constraint data */
15719  consdata = SCIPconsGetData(cons);
15720  assert(consdata != NULL);
15721 
15722  /* check for event handler */
15723  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15724  assert(conshdlrdata != NULL);
15725  assert(conshdlrdata->eventhdlr != NULL);
15726 
15727  /* free event data */
15728  if( consdata->eventdata != NULL )
15729  {
15730  /* drop bound change events of variables */
15731  SCIP_CALL( consDropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
15732  }
15733  assert(consdata->eventdata == NULL);
15734  }
15735 
15736  return SCIP_OKAY;
15737 }
15738 
15739 
15740 /** frees specific constraint data */
15741 static
15742 SCIP_DECL_CONSDELETE(consDeleteLinear)
15743 { /*lint --e{715}*/
15744  assert(scip != NULL);
15745  assert(conshdlr != NULL);
15746  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15747 
15748  if( (*consdata)->eventdata != NULL )
15749  {
15750  SCIP_CONSHDLRDATA* conshdlrdata;
15751 
15752  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15753  assert(conshdlrdata != NULL);
15754 
15755  /* drop all events */
15756  SCIP_CALL( consDropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
15757  assert((*consdata)->eventdata == NULL);
15758  }
15760  /* free linear constraint */
15761  SCIP_CALL( consdataFree(scip, consdata) );
15762 
15763  return SCIP_OKAY;
15764 }
15765 
15766 
15767 /** transforms constraint data into data belonging to the transformed problem */
15768 static
15769 SCIP_DECL_CONSTRANS(consTransLinear)
15770 { /*lint --e{715}*/
15771  SCIP_CONSDATA* sourcedata;
15772  SCIP_CONSDATA* targetdata;
15773 
15774  /*debugMsg(scip, "Trans method of linear constraints\n");*/
15775 
15776  assert(scip != NULL);
15777  assert(conshdlr != NULL);
15778  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15779  assert(SCIPgetStage(scip) == SCIP_STAGE_TRANSFORMING);
15780  assert(sourcecons != NULL);
15781  assert(targetcons != NULL);
15782 
15783  sourcedata = SCIPconsGetData(sourcecons);
15784  assert(sourcedata != NULL);
15785  assert(sourcedata->row == NULL); /* in original problem, there cannot be LP rows */
15787  /* create linear constraint data for target constraint */
15788  SCIP_CALL( consdataCreate(scip, &targetdata, sourcedata->nvars, sourcedata->vars, sourcedata->vals, sourcedata->lhs, sourcedata->rhs) );
15789 
15790 #ifndef NDEBUG
15791  /* if this is a checked or enforced constraints, then there must be no relaxation-only variables */
15792  if( SCIPconsIsEnforced(sourcecons) || SCIPconsIsChecked(sourcecons) )
15793  {
15794  int n;
15795  for(n = targetdata->nvars - 1; n >= 0; --n )
15796  assert(!SCIPvarIsRelaxationOnly(targetdata->vars[n]));
15797  }
15798 #endif
15799 
15800  /* create target constraint */
15801  SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
15802  SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
15803  SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
15804  SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
15805  SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
15806 
15807  return SCIP_OKAY;
15808 }
15809 
15810 
15811 /** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
15812 static
15813 SCIP_DECL_CONSINITLP(consInitlpLinear)
15814 { /*lint --e{715}*/
15815  int c;
15816 
15817  assert(scip != NULL);
15818  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15819 
15820  *infeasible = FALSE;
15821 
15822  for( c = 0; c < nconss && !(*infeasible); ++c )
15823  {
15824  assert(SCIPconsIsInitial(conss[c]));
15825  SCIP_CALL( addRelaxation(scip, conss[c], infeasible) );
15826  }
15827 
15828  return SCIP_OKAY;
15829 }
15831 
15832 /** separation method of constraint handler for LP solutions */
15833 static
15834 SCIP_DECL_CONSSEPALP(consSepalpLinear)
15835 { /*lint --e{715}*/
15836  SCIP_CONSHDLRDATA* conshdlrdata;
15837  SCIP_Real loclowerbound;
15838  SCIP_Real glblowerbound;
15839  SCIP_Real cutoffbound;
15840  SCIP_Real maxbound;
15841  SCIP_Bool separatecards;
15842  SCIP_Bool cutoff;
15843  int c;
15844  int depth;
15845  int nrounds;
15846  int maxsepacuts;
15847  int ncuts;
15848 
15849  assert(scip != NULL);
15850  assert(conshdlr != NULL);
15851  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15852  assert(result != NULL);
15853 
15854  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15855  assert(conshdlrdata != NULL);
15856  depth = SCIPgetDepth(scip);
15857  nrounds = SCIPgetNSepaRounds(scip);
15858 
15859  /*debugMsg(scip, "Sepa method of linear constraints\n");*/
15860 
15861  *result = SCIP_DIDNOTRUN;
15862 
15863  /* only call the separator a given number of times at each node */
15864  if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
15865  || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
15866  return SCIP_OKAY;
15867 
15868  /* get the maximal number of cuts allowed in a separation round */
15869  maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
15870 
15871  /* check if we want to produce knapsack cardinality cuts at this node */
15872  loclowerbound = SCIPgetLocalLowerbound(scip);
15873  glblowerbound = SCIPgetLowerbound(scip);
15874  cutoffbound = SCIPgetCutoffbound(scip);
15875  maxbound = glblowerbound + conshdlrdata->maxcardbounddist * (cutoffbound - glblowerbound);
15876  separatecards = SCIPisLE(scip, loclowerbound, maxbound);
15877  separatecards = separatecards && (SCIPgetNLPBranchCands(scip) > 0);
15878 
15879  *result = SCIP_DIDNOTFIND;
15880  ncuts = 0;
15881  cutoff = FALSE;
15882 
15883  /* check all useful linear constraints for feasibility */
15884  for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
15885  {
15886  /*debugMsg(scip, "separating linear constraint <%s>\n", SCIPconsGetName(conss[c]));*/
15887  SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, NULL, separatecards, conshdlrdata->separateall, &ncuts, &cutoff) );
15888  }
15889 
15890  /* adjust return value */
15891  if( cutoff )
15892  *result = SCIP_CUTOFF;
15893  else if( ncuts > 0 )
15894  *result = SCIP_SEPARATED;
15895 
15896  /* combine linear constraints to get more cuts */
15897  /**@todo further cuts of linear constraints */
15898 
15899  return SCIP_OKAY;
15900 }
15901 
15902 
15903 /** separation method of constraint handler for arbitrary primal solutions */
15904 static
15905 SCIP_DECL_CONSSEPASOL(consSepasolLinear)
15906 { /*lint --e{715}*/
15907  SCIP_CONSHDLRDATA* conshdlrdata;
15908  int c;
15909  int depth;
15910  int nrounds;
15911  int maxsepacuts;
15912  int ncuts;
15913  SCIP_Bool cutoff;
15914 
15915  assert(scip != NULL);
15916  assert(conshdlr != NULL);
15917  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15918  assert(result != NULL);
15919 
15920  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15921  assert(conshdlrdata != NULL);
15922  depth = SCIPgetDepth(scip);
15923  nrounds = SCIPgetNSepaRounds(scip);
15924 
15925  /*debugMsg(scip, "Sepa method of linear constraints\n");*/
15926 
15927  *result = SCIP_DIDNOTRUN;
15928 
15929  /* only call the separator a given number of times at each node */
15930  if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
15931  || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
15932  return SCIP_OKAY;
15933 
15934  /* get the maximal number of cuts allowed in a separation round */
15935  maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
15936 
15937  *result = SCIP_DIDNOTFIND;
15938  ncuts = 0;
15939  cutoff = FALSE;
15940 
15941  /* check all useful linear constraints for feasibility */
15942  for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
15943  {
15944  /*debugMsg(scip, "separating linear constraint <%s>\n", SCIPconsGetName(conss[c]));*/
15945  SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, sol, TRUE, conshdlrdata->separateall, &ncuts, &cutoff) );
15946  }
15947 
15948  /* adjust return value */
15949  if( cutoff )
15950  *result = SCIP_CUTOFF;
15951  else if( ncuts > 0 )
15952  *result = SCIP_SEPARATED;
15953 
15954  /* combine linear constraints to get more cuts */
15955  /**@todo further cuts of linear constraints */
15956 
15957  return SCIP_OKAY;
15958 }
15959 
15960 
15961 /** constraint enforcing method of constraint handler for LP solutions */
15962 static
15963 SCIP_DECL_CONSENFOLP(consEnfolpLinear)
15964 { /*lint --e{715}*/
15965  SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, NULL, result) );
15966 
15967  return SCIP_OKAY;
15968 }
15969 
15970 /** constraint enforcing method of constraint handler for relaxation solutions */
15971 static
15972 SCIP_DECL_CONSENFORELAX(consEnforelaxLinear)
15973 { /*lint --e{715}*/
15974  SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, sol, result) );
15975 
15976  return SCIP_OKAY;
15977 }
15978 
15979 /** constraint enforcing method of constraint handler for pseudo solutions */
15980 static
15981 SCIP_DECL_CONSENFOPS(consEnfopsLinear)
15982 { /*lint --e{715}*/
15983  SCIP_CONSHDLRDATA* conshdlrdata;
15984  SCIP_Bool checkrelmaxabs;
15985  SCIP_Bool violated;
15986  int c;
15987 
15988  assert(scip != NULL);
15989  assert(conshdlr != NULL);
15990  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15991  assert(result != NULL);
15992 
15993  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15994  assert(conshdlrdata != NULL);
15995 
15996  checkrelmaxabs = conshdlrdata->checkrelmaxabs;
15997 
15998  SCIPdebugMsg(scip, "Enfops method of linear constraints\n");
15999 
16000  /* if the solution is infeasible anyway due to objective value, skip the enforcement */
16001  if( objinfeasible )
16002  {
16003  SCIPdebugMsg(scip, "-> pseudo solution is objective infeasible, return.\n");
16004 
16005  *result = SCIP_DIDNOTRUN;
16006  return SCIP_OKAY;
16007  }
16008 
16009  /* check all linear constraints for feasibility */
16010  violated = FALSE;
16011  for( c = 0; c < nconss && !violated; ++c )
16012  {
16013  SCIP_CALL( checkCons(scip, conss[c], NULL, TRUE, checkrelmaxabs, &violated) );
16014  }
16015 
16016  if( violated )
16017  *result = SCIP_INFEASIBLE;
16018  else
16019  *result = SCIP_FEASIBLE;
16020 
16021  SCIPdebugMsg(scip, "-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
16022 
16023  return SCIP_OKAY;
16024 }
16025 
16026 
16027 /** feasibility check method of constraint handler for integral solutions */
16028 static
16029 SCIP_DECL_CONSCHECK(consCheckLinear)
16030 { /*lint --e{715}*/
16031  SCIP_CONSHDLRDATA* conshdlrdata;
16032  SCIP_Bool checkrelmaxabs;
16033  int c;
16034 
16035  assert(scip != NULL);
16036  assert(conshdlr != NULL);
16037  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16038  assert(result != NULL);
16039 
16040  *result = SCIP_FEASIBLE;
16041 
16042  conshdlrdata = SCIPconshdlrGetData(conshdlr);
16043  assert(conshdlrdata != NULL);
16044 
16045  checkrelmaxabs = conshdlrdata->checkrelmaxabs;
16047  /*debugMsg(scip, "Check method of linear constraints\n");*/
16048 
16049  /* check all linear constraints for feasibility */
16050  for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
16051  {
16052  SCIP_Bool violated = FALSE;
16053  SCIP_CALL( checkCons(scip, conss[c], sol, checklprows, checkrelmaxabs, &violated) );
16054 
16055  if( violated )
16056  {
16057  *result = SCIP_INFEASIBLE;
16058 
16059  if( printreason )
16060  {
16061  SCIP_CONSDATA* consdata;
16062  SCIP_Real activity;
16063 
16064  consdata = SCIPconsGetData(conss[c]);
16065  assert( consdata != NULL);
16066 
16067  activity = consdataGetActivity(scip, consdata, sol);
16068 
16069  SCIP_CALL( consPrintConsSol(scip, conss[c], sol, NULL ) );
16070  SCIPinfoMessage(scip, NULL, ";\n");
16071 
16072  if( activity == SCIP_INVALID ) /*lint !e777*/
16073  SCIPinfoMessage(scip, NULL, "activity invalid due to positive and negative infinity contributions\n");
16074  else if( SCIPisFeasLT(scip, activity, consdata->lhs) )
16075  SCIPinfoMessage(scip, NULL, "violation: left hand side is violated by %.15g\n", consdata->lhs - activity);
16076  else if( SCIPisFeasGT(scip, activity, consdata->rhs) )
16077  SCIPinfoMessage(scip, NULL, "violation: right hand side is violated by %.15g\n", activity - consdata->rhs);
16078  }
16079  }
16080  }
16081 
16082  return SCIP_OKAY;
16083 }
16084 
16085 
16086 /** domain propagation method of constraint handler */
16087 static
16088 SCIP_DECL_CONSPROP(consPropLinear)
16089 { /*lint --e{715}*/
16090  SCIP_CONSHDLRDATA* conshdlrdata;
16091  SCIP_Bool rangedrowpropagation = FALSE;
16092  SCIP_Bool tightenbounds;
16093  SCIP_Bool cutoff;
16094 
16095  int nchgbds;
16096  int i;
16097 
16098  assert(scip != NULL);
16099  assert(conshdlr != NULL);
16100  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16101  assert(result != NULL);
16102 
16103  conshdlrdata = SCIPconshdlrGetData(conshdlr);
16104  assert(conshdlrdata != NULL);
16106  /*debugMsg(scip, "Prop method of linear constraints\n");*/
16107 
16108  /* check, if we want to tighten variable's bounds (in probing, we always want to tighten the bounds) */
16109  if( SCIPinProbing(scip) )
16110  tightenbounds = TRUE;
16111  else
16112  {
16113  int depth;
16114  int propfreq;
16115  int tightenboundsfreq;
16116  int rangedrowfreq;
16117 
16118  depth = SCIPgetDepth(scip);
16119  propfreq = SCIPconshdlrGetPropFreq(conshdlr);
16120  tightenboundsfreq = propfreq * conshdlrdata->tightenboundsfreq;
16121  tightenbounds = (conshdlrdata->tightenboundsfreq >= 0)
16122  && ((tightenboundsfreq == 0 && depth == 0) || (tightenboundsfreq >= 1 && (depth % tightenboundsfreq == 0)));
16123 
16124  /* check if we want to do ranged row propagation */
16125  rangedrowpropagation = conshdlrdata->rangedrowpropagation;
16126  rangedrowpropagation = rangedrowpropagation && !SCIPinRepropagation(scip);
16127  rangedrowpropagation = rangedrowpropagation && (depth <= conshdlrdata->rangedrowmaxdepth);
16128  rangedrowfreq = propfreq * conshdlrdata->rangedrowfreq;
16129  rangedrowpropagation = rangedrowpropagation && (conshdlrdata->rangedrowfreq >= 0)
16130  && ((rangedrowfreq == 0 && depth == 0) || (rangedrowfreq >= 1 && (depth % rangedrowfreq == 0)));
16131  }
16132 
16133  cutoff = FALSE;
16134  nchgbds = 0;
16135 
16136  /* process constraints marked for propagation */
16137  for( i = 0; i < nmarkedconss && !cutoff; i++ )
16138  {
16139  SCIP_CALL( SCIPunmarkConsPropagate(scip, conss[i]) );
16140  SCIP_CALL( propagateCons(scip, conss[i], tightenbounds, rangedrowpropagation,
16141  conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars, &cutoff, &nchgbds) );
16142  }
16143 
16144  /* adjust result code */
16145  if( cutoff )
16146  *result = SCIP_CUTOFF;
16147  else if( nchgbds > 0 )
16148  *result = SCIP_REDUCEDDOM;
16149  else
16150  *result = SCIP_DIDNOTFIND;
16151 
16152  return SCIP_OKAY;
16153 }
16154 
16155 
16156 #define MAXCONSPRESOLROUNDS 10
16157 /** presolving method of constraint handler */
16158 static
16159 SCIP_DECL_CONSPRESOL(consPresolLinear)
16160 { /*lint --e{715}*/
16161  SCIP_CONSHDLRDATA* conshdlrdata;
16162  SCIP_CONS* cons;
16163  SCIP_CONSDATA* consdata;
16164  SCIP_Real minactivity;
16165  SCIP_Real maxactivity;
16166  SCIP_Bool minactisrelax;
16167  SCIP_Bool maxactisrelax;
16168  SCIP_Bool isminsettoinfinity;
16169  SCIP_Bool ismaxsettoinfinity;
16170  SCIP_Bool cutoff;
16171  int oldnfixedvars;
16172  int oldnaggrvars;
16173  int oldnchgbds;
16174  int oldndelconss;
16175  int oldnupgdconss;
16176  int oldnchgcoefs;
16177  int oldnchgsides;
16178  int firstchange;
16179  int firstupgradetry;
16180  int c;
16181 
16182  assert(scip != NULL);
16183  assert(conshdlr != NULL);
16184  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16185  assert(result != NULL);
16186 
16187  /*debugMsg(scip, "Presol method of linear constraints\n");*/
16188 
16189  /* remember old preprocessing counters */
16190  cutoff = FALSE;
16191  oldnfixedvars = *nfixedvars;
16192  oldnaggrvars = *naggrvars;
16193  oldnchgbds = *nchgbds;
16194  oldndelconss = *ndelconss;
16195  oldnupgdconss = *nupgdconss;
16196  oldnchgcoefs = *nchgcoefs;
16197  oldnchgsides = *nchgsides;
16198 
16199  /* get constraint handler data */
16200  conshdlrdata = SCIPconshdlrGetData(conshdlr);
16201  assert(conshdlrdata != NULL);
16202 
16203  /* process single constraints */
16204  firstchange = INT_MAX;
16205  firstupgradetry = INT_MAX;
16206  for( c = 0; c < nconss && !cutoff && !SCIPisStopped(scip); ++c )
16207  {
16208  int npresolrounds;
16209  SCIP_Bool infeasible;
16210 
16211  infeasible = FALSE;
16212 
16213  cons = conss[c];
16214  assert(SCIPconsIsActive(cons));
16215  consdata = SCIPconsGetData(cons);
16216  assert(consdata != NULL);
16217 
16218  /* ensure that rhs >= lhs is satisfied without numerical tolerance */
16219  if( SCIPisEQ(scip, consdata->rhs, consdata->lhs) )
16220  {
16221  consdata->lhs = consdata->rhs;
16222  assert(consdata->row == NULL);
16223  }
16224 
16225  if( consdata->eventdata == NULL )
16226  {
16227  /* catch bound change events of variables */
16228  SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
16229  assert(consdata->eventdata != NULL);
16230  }
16231 
16232  /* constraint should not be already presolved in the initial round */
16233  assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || SCIPconsIsMarkedPropagate(cons));
16234  assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || consdata->boundstightened == 0);
16235  assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || !consdata->presolved);
16236  assert(!SCIPconsIsMarkedPropagate(cons) || !consdata->presolved);
16237 
16238  /* incorporate fixings and aggregations in constraint */
16239  SCIP_CALL( applyFixings(scip, cons, &infeasible) );
16240 
16241  if( infeasible )
16242  {
16243  SCIPdebugMsg(scip, " -> infeasible fixing\n");
16244  cutoff = TRUE;
16245  break;
16246  }
16247 
16248  assert(consdata->removedfixings);
16249 
16250  /* we can only presolve linear constraints, that are not modifiable */
16251  if( SCIPconsIsModifiable(cons) )
16252  continue;
16253 
16254  /* remember the first changed constraint to begin the next aggregation round with */
16255  if( firstchange == INT_MAX && consdata->changed )
16256  firstchange = c;
16257 
16258  /* remember the first constraint that was not yet tried to be upgraded, to begin the next upgrading round with */
16259  if( firstupgradetry == INT_MAX && !consdata->upgradetried )
16260  firstupgradetry = c;
16261 
16262  /* check, if constraint is already preprocessed */
16263  if( consdata->presolved )
16264  continue;
16265 
16266  assert(SCIPconsIsActive(cons));
16267 
16268  SCIPdebugMsg(scip, "presolving linear constraint <%s>\n", SCIPconsGetName(cons));
16269  SCIPdebugPrintCons(scip, cons, NULL);
16270 
16271  /* apply presolving as long as possible on the single constraint (however, abort after a certain number of rounds
16272  * to avoid nearly infinite cycling due to very small bound changes)
16273  */
16274  npresolrounds = 0;
16275  while( !consdata->presolved && npresolrounds < MAXCONSPRESOLROUNDS && !SCIPisStopped(scip) )
16276  {
16277  assert(!cutoff);
16278  npresolrounds++;
16279 
16280  /* mark constraint being presolved and propagated */
16281  consdata->presolved = TRUE;
16282  SCIP_CALL( SCIPunmarkConsPropagate(scip, cons) );
16283 
16284  /* normalize constraint */
16285  SCIP_CALL( normalizeCons(scip, cons, &infeasible) );
16286 
16287  if( infeasible )
16288  {
16289  SCIPdebugMsg(scip, " -> infeasible normalization\n");
16290  cutoff = TRUE;
16291  break;
16292  }
16293 
16294  /* tighten left and right hand side due to integrality */
16295  SCIP_CALL( tightenSides(scip, cons, nchgsides, &infeasible) );
16296 
16297  if( infeasible )
16298  {
16299  SCIPdebugMsg(scip, " -> infeasibility detected during tightening sides\n");
16300  cutoff = TRUE;
16301  break;
16302  }
16303 
16304  /* check bounds */
16305  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
16306  {
16307  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
16308  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16309  cutoff = TRUE;
16310  break;
16311  }
16312 
16313  /* tighten variable's bounds */
16314  SCIP_CALL( tightenBounds(scip, cons, conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars, &cutoff, nchgbds) );
16315  if( cutoff )
16316  break;
16317 
16318  /* check for fixed variables */
16319  SCIP_CALL( fixVariables(scip, cons, &cutoff, nfixedvars) );
16320  if( cutoff )
16321  break;
16322 
16323  /* check constraint for infeasibility and redundancy */
16324  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
16325  &isminsettoinfinity, &ismaxsettoinfinity);
16326  if( SCIPisFeasGT(scip, minactivity, consdata->rhs) || SCIPisFeasLT(scip, maxactivity, consdata->lhs) )
16327  {
16328  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
16329  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
16330  cutoff = TRUE;
16331  break;
16332  }
16333  else if( SCIPisFeasGE(scip, minactivity, consdata->lhs) && SCIPisFeasLE(scip, maxactivity, consdata->rhs) )
16334  {
16335  SCIPdebugMsg(scip, "linear constraint <%s> is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
16336  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
16337  SCIP_CALL( SCIPdelCons(scip, cons) );
16338  assert(!SCIPconsIsActive(cons));
16339 
16340  if( !consdata->upgraded )
16341  (*ndelconss)++;
16342  break;
16343  }
16344  else if( !SCIPisInfinity(scip, -consdata->lhs) && SCIPisFeasGE(scip, minactivity, consdata->lhs) )
16345  {
16346  SCIPdebugMsg(scip, "linear constraint <%s> left hand side is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
16347  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
16348  SCIP_CALL( chgLhs(scip, cons, -SCIPinfinity(scip)) );
16349  if( !consdata->upgraded )
16350  (*nchgsides)++;
16351  }
16352  else if( !SCIPisInfinity(scip, consdata->rhs) && SCIPisFeasLE(scip, maxactivity, consdata->rhs) )
16353  {
16354  SCIPdebugMsg(scip, "linear constraint <%s> right hand side is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
16355  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
16356  SCIP_CALL( chgRhs(scip, cons, SCIPinfinity(scip)) );
16357  if( !consdata->upgraded )
16358  (*nchgsides)++;
16359  }
16360  assert(consdata->nvars >= 1); /* otherwise, it should be redundant or infeasible */
16361 
16362  /* handle empty constraint */
16363  if( consdata->nvars == 0 )
16364  {
16365  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
16366  {
16367  SCIPdebugMsg(scip, "empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
16368  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16369  cutoff = TRUE;
16370  }
16371  else
16372  {
16373  SCIPdebugMsg(scip, "empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
16374  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16375  SCIP_CALL( SCIPdelCons(scip, cons) );
16376  assert(!SCIPconsIsActive(cons));
16377 
16378  if( !consdata->upgraded )
16379  (*ndelconss)++;
16380  }
16381  break;
16382  }
16383 
16384  /* reduce big-M coefficients, that make the constraint redundant if the variable is on a bound */
16385  SCIP_CALL( consdataTightenCoefs(scip, cons, nchgcoefs, nchgsides) );
16386 
16387  /* try to simplify inequalities */
16388  if( conshdlrdata->simplifyinequalities )
16389  {
16390  SCIP_CALL( simplifyInequalities(scip, cons, nchgcoefs, nchgsides, &cutoff) );
16391 
16392  if( cutoff )
16393  break;
16394  }
16395 
16396  /* aggregation variable in equations */
16397  if( conshdlrdata->aggregatevariables )
16398  {
16399  SCIP_CALL( aggregateVariables(scip, cons, &cutoff, nfixedvars, naggrvars) );
16400  if( cutoff )
16401  break;
16402  }
16403  }
16404 
16405  if( !cutoff && !SCIPisStopped(scip) )
16406  {
16407  /* perform ranged row propagation */
16408  if( conshdlrdata->rangedrowpropagation )
16409  {
16410  int lastnfixedvars;
16411 
16412  lastnfixedvars = *nfixedvars;
16413 
16414  SCIP_CALL( rangedRowPropagation(scip, cons, &cutoff, nfixedvars, nchgbds, naddconss) );
16415  if( !cutoff )
16416  {
16417  if( lastnfixedvars < *nfixedvars )
16418  {
16419  SCIP_CALL( applyFixings(scip, cons, &cutoff) );
16420  }
16421  }
16422  }
16423 
16424  /* extract cliques from constraint */
16425  if( conshdlrdata->extractcliques && !cutoff && SCIPconsIsActive(cons) )
16426  {
16427  SCIP_CALL( extractCliques(scip, cons, conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars,
16428  nfixedvars, nchgbds, &cutoff) );
16429 
16430  /* check if the constraint got redundant or infeasible */
16431  if( !cutoff && SCIPconsIsActive(cons) && consdata->nvars == 0 )
16432  {
16433  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
16434  {
16435  SCIPdebugMsg(scip, "empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
16436  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16437  cutoff = TRUE;
16438  }
16439  else
16440  {
16441  SCIPdebugMsg(scip, "empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
16442  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16443  SCIP_CALL( SCIPdelCons(scip, cons) );
16444  assert(!SCIPconsIsActive(cons));
16445 
16446  if( !consdata->upgraded )
16447  (*ndelconss)++;
16448  }
16449  }
16450  }
16451 
16452  /* convert special equalities */
16453  if( !cutoff && SCIPconsIsActive(cons) )
16454  {
16455  SCIP_CALL( convertEquality(scip, cons, conshdlrdata, &cutoff, nfixedvars, naggrvars, ndelconss) );
16456  }
16457 
16458  /* apply dual presolving for variables that appear in only one constraint */
16459  if( !cutoff && SCIPconsIsActive(cons) && conshdlrdata->dualpresolving && SCIPallowStrongDualReds(scip) )
16460  {
16461  SCIP_CALL( dualPresolve(scip, conshdlrdata, cons, &cutoff, nfixedvars, naggrvars, ndelconss) );
16462  }
16463 
16464  /* check if an inequality is parallel to the objective function */
16465  if( !cutoff && SCIPconsIsActive(cons) )
16466  {
16467  SCIP_CALL( checkParallelObjective(scip, cons, conshdlrdata) );
16468  }
16469 
16470  /* remember the first changed constraint to begin the next aggregation round with */
16471  if( firstchange == INT_MAX && consdata->changed )
16472  firstchange = c;
16473 
16474  /* remember the first constraint that was not yet tried to be upgraded, to begin the next upgrading round with */
16475  if( firstupgradetry == INT_MAX && !consdata->upgradetried )
16476  firstupgradetry = c;
16477  }
16478 
16479  /* singleton column stuffing */
16480  if( !cutoff && SCIPconsIsActive(cons) && SCIPconsIsChecked(cons) &&
16481  (conshdlrdata->singletonstuffing || conshdlrdata->singlevarstuffing) && SCIPallowStrongDualReds(scip) )
16482  {
16483  SCIP_CALL( presolStuffing(scip, cons, conshdlrdata->singletonstuffing,
16484  conshdlrdata->singlevarstuffing, &cutoff, nfixedvars, nchgbds) );
16485 
16486  /* handle empty constraint */
16487  if( consdata->nvars == 0 )
16488  {
16489  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
16490  {
16491  SCIPdebugMsg(scip, "empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
16492  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16493  cutoff = TRUE;
16494  }
16495  else
16496  {
16497  SCIPdebugMsg(scip, "empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
16498  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16499  SCIP_CALL( SCIPdelCons(scip, cons) );
16500  assert(!SCIPconsIsActive(cons));
16501 
16502  if( !consdata->upgraded )
16503  (*ndelconss)++;
16504  }
16505  break;
16506  }
16507  }
16508  }
16509 
16510  /* process pairs of constraints: check them for redundancy and try to aggregate them;
16511  * only apply this expensive procedure in exhaustive presolving timing
16512  */
16513  if( !cutoff && (presoltiming & SCIP_PRESOLTIMING_EXHAUSTIVE) != 0 && (conshdlrdata->presolusehashing || conshdlrdata->presolpairwise) && !SCIPisStopped(scip) )
16514  {
16515  assert(firstchange >= 0);
16516 
16517  if( firstchange < nconss && conshdlrdata->presolusehashing )
16518  {
16519  /* detect redundant constraints; fast version with hash table instead of pairwise comparison */
16520  SCIP_CALL( detectRedundantConstraints(scip, SCIPblkmem(scip), conss, nconss, &firstchange, &cutoff,
16521  ndelconss, nchgsides) );
16522  }
16523 
16524  if( firstchange < nconss && conshdlrdata->presolpairwise )
16525  {
16526  SCIP_CONS** usefulconss;
16527  int nusefulconss;
16528  int firstchangenew;
16529  SCIP_Longint npaircomparisons;
16530 
16531  npaircomparisons = 0;
16532  oldndelconss = *ndelconss;
16533  oldnchgsides = *nchgsides;
16534  oldnchgcoefs = *nchgcoefs;
16535 
16536  /* allocate temporary memory */
16537  SCIP_CALL( SCIPallocBufferArray(scip, &usefulconss, nconss) );
16538 
16539  nusefulconss = 0;
16540  firstchangenew = -1;
16541  for( c = 0; c < nconss; ++c )
16542  {
16543  /* update firstchange */
16544  if( c == firstchange )
16545  firstchangenew = nusefulconss;
16546 
16547  /* ignore inactive and modifiable constraints */
16548  if( !SCIPconsIsActive(conss[c]) || SCIPconsIsModifiable(conss[c]) )
16549  continue;
16550 
16551  usefulconss[nusefulconss] = conss[c];
16552  ++nusefulconss;
16553  }
16554  firstchange = firstchangenew;
16555  assert(firstchangenew >= 0 && firstchangenew <= nusefulconss);
16556 
16557  for( c = firstchange; c < nusefulconss && !cutoff && !SCIPisStopped(scip); ++c )
16558  {
16559  /* constraint has become inactive or modifiable during pairwise presolving */
16560  if( usefulconss[c] == NULL )
16561  continue;
16562 
16563  npaircomparisons += (SCIPconsGetData(conss[c])->changed) ? c : (c - firstchange); /*lint !e776*/
16564 
16565  assert(SCIPconsIsActive(usefulconss[c]) && !SCIPconsIsModifiable(usefulconss[c]));
16566  SCIP_CALL( preprocessConstraintPairs(scip, usefulconss, firstchange, c, conshdlrdata->maxaggrnormscale,
16567  &cutoff, ndelconss, nchgsides, nchgcoefs) );
16568 
16569  if( npaircomparisons > conshdlrdata->nmincomparisons )
16570  {
16571  assert(npaircomparisons > 0);
16572  if( ((*ndelconss - oldndelconss) + (*nchgsides - oldnchgsides)/2.0 + (*nchgcoefs - oldnchgcoefs)/10.0) / ((SCIP_Real) npaircomparisons) < conshdlrdata->mingainpernmincomp )
16573  break;
16574  oldndelconss = *ndelconss;
16575  oldnchgsides = *nchgsides;
16576  oldnchgcoefs = *nchgcoefs;
16577  npaircomparisons = 0;
16578  }
16579  }
16580  /* free temporary memory */
16581  SCIPfreeBufferArray(scip, &usefulconss);
16582  }
16583  }
16584 
16585  /* before upgrading, check whether we can apply some additional dual presolving, because a variable only appears
16586  * in linear constraints and we therefore have full information about it
16587  */
16588  if( !cutoff && firstupgradetry < nconss
16589  && *nfixedvars == oldnfixedvars && *naggrvars == oldnaggrvars && *nchgbds == oldnchgbds && *ndelconss == oldndelconss
16590  && *nupgdconss == oldnupgdconss && *nchgcoefs == oldnchgcoefs && *nchgsides == oldnchgsides
16591  )
16592  {
16593  if( conshdlrdata->dualpresolving && SCIPallowStrongDualReds(scip) && !SCIPisStopped(scip) )
16594  {
16595  SCIP_CALL( fullDualPresolve(scip, conss, nconss, &cutoff, nchgbds) );
16596  }
16597  }
16598 
16599  /* try to upgrade constraints into a more specific constraint type;
16600  * only upgrade constraints, if no reductions were found in this round (otherwise, the linear constraint handler
16601  * may find additional reductions before giving control away to other (less intelligent?) constraint handlers)
16602  */
16603  if( !cutoff && (presoltiming & SCIP_PRESOLTIMING_EXHAUSTIVE) != 0 && SCIPisPresolveFinished(scip) )
16604  {
16605  for( c = firstupgradetry; c < nconss && !SCIPisStopped(scip); ++c )
16606  {
16607  cons = conss[c];
16608 
16609  /* don't upgrade modifiable constraints */
16610  if( SCIPconsIsModifiable(cons) )
16611  continue;
16612 
16613  consdata = SCIPconsGetData(cons);
16614  assert(consdata != NULL);
16615 
16616  /* only upgrade completely presolved constraints, that changed since the last upgrading call */
16617  if( consdata->upgradetried )
16618  continue;
16619  /* @todo force that upgrade will be performed later? */
16620  if( !consdata->presolved )
16621  continue;
16622 
16623  consdata->upgradetried = TRUE;
16624  if( SCIPconsIsActive(cons) )
16625  {
16626  SCIP_CONS* upgdcons;
16627 
16628  SCIP_CALL( SCIPupgradeConsLinear(scip, cons, &upgdcons) );
16629  if( upgdcons != NULL )
16630  {
16631  /* add the upgraded constraint to the problem */
16632  SCIP_CALL( SCIPaddCons(scip, upgdcons) );
16633  SCIP_CALL( SCIPreleaseCons(scip, &upgdcons) );
16634  (*nupgdconss)++;
16635 
16636  /* mark the linear constraint being upgraded and to be removed after presolving;
16637  * don't delete it directly, because it may help to preprocess other linear constraints
16638  */
16639  assert(!consdata->upgraded);
16640  consdata->upgraded = TRUE;
16641 
16642  /* delete upgraded inequalities immediately;
16643  * delete upgraded equalities, if we don't need it anymore for aggregation and redundancy checking
16644  */
16645  if( SCIPisLT(scip, consdata->lhs, consdata->rhs)
16646  || !conshdlrdata->presolpairwise
16647  || (conshdlrdata->maxaggrnormscale == 0.0) )
16648  {
16649  SCIP_CALL( SCIPdelCons(scip, cons) );
16650  }
16651  }
16652  }
16653  }
16654  }
16655 
16656  /* return the correct result code */
16657  if( cutoff )
16658  *result = SCIP_CUTOFF;
16659  else if( *nfixedvars > oldnfixedvars || *naggrvars > oldnaggrvars || *nchgbds > oldnchgbds || *ndelconss > oldndelconss
16660  || *nupgdconss > oldnupgdconss || *nchgcoefs > oldnchgcoefs || *nchgsides > oldnchgsides )
16661  *result = SCIP_SUCCESS;
16662  else
16663  *result = SCIP_DIDNOTFIND;
16664 
16665  return SCIP_OKAY;
16666 }
16667 
16668 
16669 /** propagation conflict resolving method of constraint handler */
16670 static
16671 SCIP_DECL_CONSRESPROP(consRespropLinear)
16672 { /*lint --e{715}*/
16673  assert(scip != NULL);
16674  assert(cons != NULL);
16675  assert(result != NULL);
16676 
16677  SCIP_CALL( resolvePropagation(scip, cons, infervar, intToInferInfo(inferinfo), boundtype, bdchgidx, result) );
16678 
16679  return SCIP_OKAY;
16680 }
16681 
16682 
16683 /** variable rounding lock method of constraint handler */
16684 static
16685 SCIP_DECL_CONSLOCK(consLockLinear)
16686 { /*lint --e{715}*/
16687  SCIP_CONSDATA* consdata;
16688  SCIP_Bool haslhs;
16689  SCIP_Bool hasrhs;
16690  int i;
16691 
16692  assert(scip != NULL);
16693  assert(cons != NULL);
16694  consdata = SCIPconsGetData(cons);
16695  assert(consdata != NULL);
16696 
16697  haslhs = !SCIPisInfinity(scip, -consdata->lhs);
16698  hasrhs = !SCIPisInfinity(scip, consdata->rhs);
16699 
16700  /* update rounding locks of every single variable */
16701  for( i = 0; i < consdata->nvars; ++i )
16702  {
16703  if( SCIPisPositive(scip, consdata->vals[i]) )
16704  {
16705  if( haslhs )
16706  {
16707  SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlockspos, nlocksneg) );
16708  }
16709  if( hasrhs )
16710  {
16711  SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlocksneg, nlockspos) );
16712  }
16713  }
16714  else
16715  {
16716  if( haslhs )
16717  {
16718  SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlocksneg, nlockspos) );
16719  }
16720  if( hasrhs )
16721  {
16722  SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlockspos, nlocksneg) );
16723  }
16724  }
16725  }
16726 
16727  return SCIP_OKAY;
16728 }
16729 
16730 
16731 /** variable deletion method of constraint handler */
16732 static
16733 SCIP_DECL_CONSDELVARS(consDelvarsLinear)
16734 {
16735  assert(scip != NULL);
16736  assert(conshdlr != NULL);
16737  assert(conss != NULL || nconss == 0);
16738 
16739  if( nconss > 0 )
16740  {
16741  SCIP_CALL( performVarDeletions(scip, conshdlr, conss, nconss) );
16742  }
16743 
16744  return SCIP_OKAY;
16745 }
16746 
16747 /** constraint display method of constraint handler */
16748 static
16749 SCIP_DECL_CONSPRINT(consPrintLinear)
16750 { /*lint --e{715}*/
16751  assert(scip != NULL);
16752  assert(conshdlr != NULL);
16753  assert(cons != NULL);
16754 
16755  SCIP_CALL( consdataPrint(scip, SCIPconsGetData(cons), file) );
16756 
16757  return SCIP_OKAY;
16758 }
16759 
16760 /** constraint copying method of constraint handler */
16761 static
16762 SCIP_DECL_CONSCOPY(consCopyLinear)
16763 { /*lint --e{715}*/
16764  SCIP_VAR** sourcevars;
16765  SCIP_Real* sourcecoefs;
16766  const char* consname;
16767  int nvars;
16768 
16769  assert(scip != NULL);
16770  assert(sourcescip != NULL);
16771  assert(sourcecons != NULL);
16772 
16773  /* get variables and coefficients of the source constraint */
16774  sourcevars = SCIPgetVarsLinear(sourcescip, sourcecons);
16775  sourcecoefs = SCIPgetValsLinear(sourcescip, sourcecons);
16776  nvars = SCIPgetNVarsLinear(sourcescip, sourcecons);
16777 
16778  if( name != NULL )
16779  consname = name;
16780  else
16781  consname = SCIPconsGetName(sourcecons);
16782 
16783  SCIP_CALL( SCIPcopyConsLinear(scip, cons, sourcescip, consname, nvars, sourcevars, sourcecoefs,
16784  SCIPgetLhsLinear(sourcescip, sourcecons), SCIPgetRhsLinear(sourcescip, sourcecons), varmap, consmap,
16785  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, global, valid) );
16786  assert(cons != NULL || *valid == FALSE);
16787 
16788  /* @todo should also the checkabsolute flag of the constraint be copied? */
16789 
16790  return SCIP_OKAY;
16791 }
16792 
16793 /** find operators '<=', '==', '>=', [free] in input string and return those places
16794  *
16795  * There should only be one operator, except for ranged rows for which exactly two operators '<=' must be present.
16796  */
16797 static
16798 void findOperators(
16799  const char* str, /**< null terminated input string */
16800  char** firstoperator, /**< pointer to store the string starting at the first operator */
16801  char** secondoperator, /**< pointer to store the string starting at the second operator */
16802  SCIP_Bool* success /**< pointer to store if the line contains a valid operator order */
16803  )
16804 {
16805  char* curr;
16806 
16807  assert(str != NULL);
16808  assert(firstoperator != NULL);
16809  assert(secondoperator != NULL);
16810 
16811  *firstoperator = NULL;
16812  *secondoperator = NULL;
16813 
16814  curr = (char*)str;
16815  *success = TRUE;
16816 
16817  /* loop over the input string to find all operators */
16818  while( *curr && *success )
16819  {
16820  SCIP_Bool found = FALSE;
16821  int increment = 1;
16822 
16823  /* try if we found a possible operator */
16824  switch( *curr )
16825  {
16826  case '<':
16827  case '=':
16828  case '>':
16829 
16830  /* check if the two characters curr[0,1] form an operator together */
16831  if( curr[1] == '=' )
16832  {
16833  found = TRUE;
16834 
16835  /* update increment to continue after this operator */
16836  increment = 2;
16837  }
16838  break;
16839  case '[':
16840  if( strncmp(curr, "[free]", 6) == 0 )
16841  {
16842  found = TRUE;
16843 
16844  /* update increment to continue after this operator */
16845  increment = 6;
16846  }
16847  break;
16848  default:
16849  break;
16850  }
16851 
16852  /* assign the found operator to the first or second pointer and check for violations of the linear constraint grammar */
16853  if( found )
16854  {
16855  if( *firstoperator == NULL )
16856  {
16857  *firstoperator = curr;
16858  }
16859  else
16860  {
16861  if( *secondoperator != NULL )
16862  {
16863  SCIPerrorMessage("Found more than two operators in line %s\n", str);
16864  *success = FALSE;
16865  }
16866  else if( strncmp(*firstoperator, "<=", 2) != 0 )
16867  {
16868  SCIPerrorMessage("Two operators in line that is not a ranged row: %s", str);
16869  *success = FALSE;
16870  }
16871  else if( strncmp(curr, "<=", 2) != 0 )
16872  {
16873  SCIPerrorMessage("Bad second operator, expected ranged row specification: %s", str);
16874  *success = FALSE;
16875  }
16876 
16877  *secondoperator = curr;
16878  }
16879  }
16880 
16881  curr += increment;
16882  }
16883 
16884  /* check if we did find at least one operator */
16885  if( *success )
16886  {
16887  if( *firstoperator == NULL )
16888  {
16889  SCIPerrorMessage("Could not find any operator in line %s\n", str);
16890  *success = FALSE;
16891  }
16892  }
16893 }
16894 
16895 /** constraint parsing method of constraint handler */
16896 static
16897 SCIP_DECL_CONSPARSE(consParseLinear)
16898 { /*lint --e{715}*/
16899  SCIP_VAR** vars;
16900  SCIP_Real* coefs;
16901  int nvars;
16902  int coefssize;
16903  int requsize;
16904  SCIP_Real lhs;
16905  SCIP_Real rhs;
16906  char* endptr;
16907  char* firstop;
16908  char* secondop;
16909  SCIP_Bool operatorsuccess;
16910  char* lhsstrptr;
16911  char* rhsstrptr;
16912  char* varstrptr;
16913 
16914  assert(scip != NULL);
16915  assert(success != NULL);
16916  assert(str != NULL);
16917  assert(name != NULL);
16918  assert(cons != NULL);
16919 
16920  /* set left and right hand side to their default values */
16921  lhs = -SCIPinfinity(scip);
16922  rhs = SCIPinfinity(scip);
16923 
16924  (*success) = FALSE;
16925 
16926  /* return of string empty */
16927  if( !*str )
16928  return SCIP_OKAY;
16929 
16930  /* ignore whitespace */
16931  while( isspace((unsigned char)*str) )
16932  ++str;
16933 
16934  /* find operators in the line first, all other remaining parsing depends on occurence of the operators '<=', '>=', '==',
16935  * and the special word [free]
16936  */
16937  findOperators(str, &firstop, &secondop, &operatorsuccess);
16938 
16939  /* if the grammar is not valid for parsing a linear constraint, return */
16940  if( ! operatorsuccess )
16941  return SCIP_OKAY;
16942 
16943  varstrptr = (char *)str;
16944  lhsstrptr = rhsstrptr = NULL;
16945  assert(firstop != NULL);
16946 
16947  /* assign the strings for parsing the left hand side, right hand side, and the linear variable sum */
16948  switch( *firstop )
16949  {
16950  case '<':
16951  assert(firstop[1] == '=');
16952  /* we have ranged row lhs <= a_1 x_1 + ... + a_n x_n <= rhs */
16953  if( secondop != NULL )
16954  {
16955  assert(secondop[0] == '<' && secondop[1] == '=');
16956  lhsstrptr = (char *)str;
16957  varstrptr = firstop + 2;
16958  rhsstrptr = secondop + 2;
16959  }
16960  else
16961  {
16962  /* we have an inequality with infinite left hand side a_1 x_1 + ... + a_n x_n <= rhs */
16963  lhsstrptr = NULL;
16964  varstrptr = (char *)str;
16965  rhsstrptr = firstop + 2;
16966  }
16967  break;
16968  case '>':
16969  assert(firstop[1] == '=');
16970  assert(secondop == NULL);
16971  /* we have a_1 x_1 + ... + a_n x_n >= lhs */
16972  lhsstrptr = firstop + 2;
16973  break;
16974  case '=':
16975  assert(firstop[1] == '=');
16976  assert(secondop == NULL);
16977  /* we have a_1 x_1 + ... + a_n x_n == lhs (rhs) */
16978  rhsstrptr = firstop + 2;
16979  lhsstrptr = firstop + 2;
16980  break;
16981  case '[':
16982  assert(strncmp(firstop, "[free]", 6) == 0);
16983  assert(secondop == NULL);
16984  /* nothing to assign in case of a free a_1 x_1 + ... + a_n x_n [free] */
16985  break;
16986  default:
16987  /* it should not be possible that a different character appears in that position */
16988  SCIPerrorMessage("Parsing has wrong operator character '%c', should be one of <=>[", *firstop);
16989  return SCIP_READERROR;
16990  }
16991 
16992  /* parse left hand side, if necessary */
16993  if( lhsstrptr != NULL )
16994  {
16995  if( ! SCIPparseReal(scip, lhsstrptr, &lhs, &endptr) )
16996  {
16997  SCIPerrorMessage("error parsing left hand side number from <%s>\n", lhsstrptr);
16998  return SCIP_OKAY;
16999  }
17000 
17001  /* in case of an equation, assign the left also to the right hand side */
17002  if( rhsstrptr == lhsstrptr )
17003  rhs = lhs;
17004  }
17005 
17006  /* parse right hand side, if different from left hand side */
17007  if( rhsstrptr != NULL && rhsstrptr != lhsstrptr )
17008  {
17009  if( ! SCIPparseReal(scip, rhsstrptr, &rhs, &endptr) )
17010  {
17011  SCIPerrorMessage("error parsing right hand side number from <%s>\n", lhsstrptr);
17012  return SCIP_OKAY;
17013  }
17014  }
17015 
17016  /* initialize buffers for storing the variables and coefficients */
17017  coefssize = 100;
17018  SCIP_CALL( SCIPallocBufferArray(scip, &vars, coefssize) );
17019  SCIP_CALL( SCIPallocBufferArray(scip, &coefs, coefssize) );
17020 
17021  assert(varstrptr != NULL);
17022 
17023  /* parse linear sum to get variables and coefficients */
17024  SCIP_CALL( SCIPparseVarsLinearsum(scip, varstrptr, vars, coefs, &nvars, coefssize, &requsize, &endptr, success) );
17025 
17026  if( *success && requsize > coefssize )
17027  {
17028  /* realloc buffers and try again */
17029  coefssize = requsize;
17030  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, coefssize) );
17031  SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, coefssize) );
17032 
17033  SCIP_CALL( SCIPparseVarsLinearsum(scip, varstrptr, vars, coefs, &nvars, coefssize, &requsize, &endptr, success) );
17034  assert(!*success || requsize <= coefssize); /* if successful, then should have had enough space now */
17035  }
17036 
17037  if( !*success )
17038  {
17039  SCIPerrorMessage("no luck in parsing linear sum '%s'\n", varstrptr);
17040  }
17041  else
17042  {
17043  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
17044  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
17045  }
17046 
17047  SCIPfreeBufferArray(scip, &coefs);
17048  SCIPfreeBufferArray(scip, &vars);
17049 
17050  return SCIP_OKAY;
17051 }
17052 
17053 
17054 /** constraint method of constraint handler which returns the variables (if possible) */
17055 static
17056 SCIP_DECL_CONSGETVARS(consGetVarsLinear)
17057 { /*lint --e{715}*/
17058  SCIP_CONSDATA* consdata;
17059 
17060  consdata = SCIPconsGetData(cons);
17061  assert(consdata != NULL);
17062 
17063  if( varssize < consdata->nvars )
17064  (*success) = FALSE;
17065  else
17066  {
17067  assert(vars != NULL);
17068 
17069  BMScopyMemoryArray(vars, consdata->vars, consdata->nvars);
17070  (*success) = TRUE;
17071  }
17072 
17073  return SCIP_OKAY;
17074 }
17075 
17076 /**! [Callback for the number of variables]*/
17077 /** constraint method of constraint handler which returns the number of variables (if possible) */
17078 static
17079 SCIP_DECL_CONSGETNVARS(consGetNVarsLinear)
17080 { /*lint --e{715}*/
17081  SCIP_CONSDATA* consdata;
17082 
17083  consdata = SCIPconsGetData(cons);
17084  assert(consdata != NULL);
17085 
17086  (*nvars) = consdata->nvars;
17087  (*success) = TRUE;
17088 
17089  return SCIP_OKAY;
17090 }
17091 /**! [Callback for the number of variables]*/
17092 
17093 /*
17094  * Callback methods of event handler
17095  */
17097 /** execution method of event handler */
17098 static
17099 SCIP_DECL_EVENTEXEC(eventExecLinear)
17100 { /*lint --e{715}*/
17101  SCIP_CONS* cons;
17102  SCIP_CONSDATA* consdata;
17103  SCIP_VAR* var;
17104  SCIP_EVENTTYPE eventtype;
17105 
17106  assert(scip != NULL);
17107  assert(eventhdlr != NULL);
17108  assert(eventdata != NULL);
17109  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
17110  assert(event != NULL);
17111 
17112  cons = eventdata->cons;
17113  assert(cons != NULL);
17114  consdata = SCIPconsGetData(cons);
17115  assert(consdata != NULL);
17117  /* we can skip events droped for deleted constraints */
17118  if( SCIPconsIsDeleted(cons) )
17119  return SCIP_OKAY;
17120 
17121  eventtype = SCIPeventGetType(event);
17122  var = SCIPeventGetVar(event);
17123 
17124  if( (eventtype & SCIP_EVENTTYPE_BOUNDCHANGED) != 0 )
17125  {
17126  SCIP_Real oldbound;
17127  SCIP_Real newbound;
17128  SCIP_Real val;
17129  int varpos;
17130 
17131  varpos = eventdata->varpos;
17132  assert(0 <= varpos && varpos < consdata->nvars);
17133  oldbound = SCIPeventGetOldbound(event);
17134  newbound = SCIPeventGetNewbound(event);
17135  assert(var != NULL);
17136  assert(consdata->vars[varpos] == var);
17137  val = consdata->vals[varpos];
17138 
17139  /* we only need to update the activities if the constraint is active,
17140  * otherwise we mark them to be invalid
17141  */
17142  if( SCIPconsIsActive(cons) )
17143  {
17144  /* update the activity values */
17145  if( (eventtype & SCIP_EVENTTYPE_LBCHANGED) != 0 )
17146  consdataUpdateActivitiesLb(scip, consdata, var, oldbound, newbound, val, TRUE);
17147  else
17148  {
17149  assert((eventtype & SCIP_EVENTTYPE_UBCHANGED) != 0);
17150  consdataUpdateActivitiesUb(scip, consdata, var, oldbound, newbound, val, TRUE);
17151  }
17152  }
17153  else
17154  consdataInvalidateActivities(consdata);
17155 
17156  consdata->presolved = FALSE;
17157  consdata->rangedrowpropagated = 0;
17158 
17159  /* bound change can turn the constraint infeasible or redundant only if it was a tightening */
17160  if( (eventtype & SCIP_EVENTTYPE_BOUNDTIGHTENED) != 0 )
17161  {
17162  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
17163 
17164  /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
17165  if( consdata->maxactdeltavar == var )
17166  {
17167  consdata->maxactdelta = SCIP_INVALID;
17168  consdata->maxactdeltavar = NULL;
17169  }
17170 
17171  /* check whether bound tightening might now be successful */
17172  if( consdata->boundstightened > 0)
17173  {
17174  switch( eventtype )
17175  {
17177  if( (val > 0.0 ? !SCIPisInfinity(scip, consdata->rhs) : !SCIPisInfinity(scip, -consdata->lhs)) )
17178  consdata->boundstightened = 0;
17179  break;
17181  if( (val > 0.0 ? !SCIPisInfinity(scip, -consdata->lhs) : !SCIPisInfinity(scip, consdata->rhs)) )
17182  consdata->boundstightened = 0;
17183  break;
17184  default:
17185  SCIPerrorMessage("invalid event type %ld\n", eventtype);
17186  return SCIP_INVALIDDATA;
17187  }
17188  }
17189  }
17190  /* update maximal activity delta if a bound was relaxed */
17191  else if( !SCIPisInfinity(scip, consdata->maxactdelta) )
17192  {
17193  SCIP_Real lb;
17194  SCIP_Real ub;
17195  SCIP_Real domain;
17196  SCIP_Real delta;
17197 
17198  assert((eventtype & SCIP_EVENTTYPE_BOUNDRELAXED) != 0);
17199 
17200  lb = SCIPvarGetLbLocal(var);
17201  ub = SCIPvarGetUbLocal(var);
17202 
17203  domain = ub - lb;
17204  delta = REALABS(val) * domain;
17205 
17206  if( delta > consdata->maxactdelta )
17207  {
17208  consdata->maxactdelta = delta;
17209  consdata->maxactdeltavar = var;
17210  }
17211  }
17212  }
17213  else if( (eventtype & SCIP_EVENTTYPE_VARFIXED) != 0 )
17214  {
17215  /* we want to remove the fixed variable */
17216  consdata->presolved = FALSE;
17217  consdata->removedfixings = FALSE;
17218  consdata->rangedrowpropagated = 0;
17219 
17220  /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
17221  if( consdata->maxactdeltavar == var )
17222  {
17223  consdata->maxactdelta = SCIP_INVALID;
17224  consdata->maxactdeltavar = NULL;
17225  }
17226  }
17227  else if( (eventtype & SCIP_EVENTTYPE_VARUNLOCKED) != 0 )
17228  {
17229  /* there is only one lock left: we may multi-aggregate the variable as slack of an equation */
17230  assert(SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) <= 1);
17231  assert(SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) <= 1);
17232  consdata->presolved = FALSE;
17233  }
17234  else if( (eventtype & SCIP_EVENTTYPE_GBDCHANGED) != 0 )
17235  {
17236  SCIP_Real oldbound;
17237  SCIP_Real newbound;
17238  SCIP_Real val;
17239  int varpos;
17240 
17241  varpos = eventdata->varpos;
17242  assert(0 <= varpos && varpos < consdata->nvars);
17243  oldbound = SCIPeventGetOldbound(event);
17244  newbound = SCIPeventGetNewbound(event);
17245  assert(var != NULL);
17246  assert(consdata->vars[varpos] == var);
17247  val = consdata->vals[varpos];
17248 
17249  consdata->rangedrowpropagated = 0;
17250 
17251  /* update the activity values */
17252  if( (eventtype & SCIP_EVENTTYPE_GLBCHANGED) != 0 )
17253  consdataUpdateActivitiesGlbLb(scip, consdata, oldbound, newbound, val, TRUE);
17254  else
17255  {
17256  assert((eventtype & SCIP_EVENTTYPE_GUBCHANGED) != 0);
17257  consdataUpdateActivitiesGlbUb(scip, consdata, oldbound, newbound, val, TRUE);
17258  }
17259 
17260  /* if the variable is binary but not fixed it had to become binary due to this global change */
17261  if( SCIPvarIsBinary(var) && SCIPisGT(scip, SCIPvarGetUbGlobal(var), SCIPvarGetLbGlobal(var)) )
17262  {
17263  if( SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE )
17264  consdata->indexsorted = FALSE;
17265  else
17266  consdata->coefsorted = FALSE;
17267  }
17268  }
17269  else if( (eventtype & SCIP_EVENTTYPE_TYPECHANGED) != 0 )
17270  {
17271  assert(SCIPgetStage(scip) < SCIP_STAGE_PRESOLVED);
17272 
17273  /* for presolving it only matters if a variable type changed from continuous to some kind of integer */
17274  consdata->presolved = (consdata->presolved && SCIPeventGetOldtype(event) < SCIP_VARTYPE_CONTINUOUS);
17275 
17276  /* the ordering is preserved if the type changes from something different to binary to binary but SCIPvarIsBinary() is true */
17277  consdata->indexsorted = (consdata->indexsorted && SCIPeventGetNewtype(event) == SCIP_VARTYPE_BINARY && SCIPvarIsBinary(var));
17278  }
17279  else
17280  {
17281  assert((eventtype & SCIP_EVENTTYPE_VARDELETED) != 0);
17282  consdata->varsdeleted = TRUE;
17283  }
17284 
17285  return SCIP_OKAY;
17286 }
17287 
17288 
17289 /*
17290  * Callback methods of conflict handler
17291  */
17292 
17293 /** conflict processing method of conflict handler (called when conflict was found) */
17294 static
17295 SCIP_DECL_CONFLICTEXEC(conflictExecLinear)
17296 { /*lint --e{715}*/
17297  SCIP_VAR** vars;
17298  SCIP_Real* vals;
17299  SCIP_Real lhs;
17300  int i;
17301 
17302  assert(scip != NULL);
17303  assert(conflicthdlr != NULL);
17304  assert(strcmp(SCIPconflicthdlrGetName(conflicthdlr), CONFLICTHDLR_NAME) == 0);
17305  assert(bdchginfos != NULL || nbdchginfos == 0);
17306  assert(result != NULL);
17307 
17308  /* don't process already resolved conflicts */
17309  if( resolved )
17310  {
17311  *result = SCIP_DIDNOTRUN;
17312  return SCIP_OKAY;
17313  }
17314 
17315  *result = SCIP_DIDNOTFIND;
17316 
17317  /* create array of variables and coefficients: sum_{i \in P} x_i - sum_{i \in N} x_i >= 1 - |N| */
17318  SCIP_CALL( SCIPallocBufferArray(scip, &vars, nbdchginfos) );
17319  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nbdchginfos) );
17320  lhs = 1.0;
17321  for( i = 0; i < nbdchginfos; ++i )
17322  {
17323  assert(bdchginfos != NULL);
17324 
17325  vars[i] = SCIPbdchginfoGetVar(bdchginfos[i]);
17326 
17327  /* we can only treat binary variables */
17328  /**@todo extend linear conflict constraints to some non-binary cases */
17329  if( !SCIPvarIsBinary(vars[i]) )
17330  break;
17331 
17332  /* check whether the variable is fixed to zero (P) or one (N) in the conflict set */
17333  if( SCIPbdchginfoGetNewbound(bdchginfos[i]) < 0.5 )
17334  vals[i] = 1.0;
17335  else
17336  {
17337  vals[i] = -1.0;
17338  lhs -= 1.0;
17339  }
17340  }
17341 
17342  if( i == nbdchginfos )
17343  {
17344  SCIP_CONS* cons;
17345  SCIP_CONS* upgdcons;
17346  char consname[SCIP_MAXSTRLEN];
17347 
17348  /* create a constraint out of the conflict set */
17349  (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "cf%" SCIP_LONGINT_FORMAT, SCIPgetNConflictConssApplied(scip));
17350  SCIP_CALL( SCIPcreateConsLinear(scip, &cons, consname, nbdchginfos, vars, vals, lhs, SCIPinfinity(scip),
17351  FALSE, separate, FALSE, FALSE, TRUE, local, FALSE, dynamic, removable, FALSE) );
17352 
17353  /* try to automatically convert a linear constraint into a more specific and more specialized constraint */
17354  SCIP_CALL( SCIPupgradeConsLinear(scip, cons, &upgdcons) );
17355  if( upgdcons != NULL )
17356  {
17357  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
17358  cons = upgdcons;
17359  }
17360 
17361  /* add conflict to SCIP */
17362  SCIP_CALL( SCIPaddConflict(scip, node, cons, validnode, conftype, cutoffinvolved) );
17363 
17364  *result = SCIP_CONSADDED;
17365  }
17366 
17367  /* free temporary memory */
17368  SCIPfreeBufferArray(scip, &vals);
17369  SCIPfreeBufferArray(scip, &vars);
17370 
17371  return SCIP_OKAY;
17372 }
17373 
17374 
17375 /*
17376  * Quadratic constraint upgrading
17377  */
17378 
17379 
17380 /** upgrades quadratic constraints with only and at least one linear variables into a linear constraint
17381  */
17382 static
17383 SCIP_DECL_QUADCONSUPGD(upgradeConsQuadratic)
17384 { /*lint --e{715}*/
17385  SCIP_CONSDATA* upgdconsdata;
17386 
17387  assert(scip != NULL);
17388  assert(cons != NULL);
17389  assert(nupgdconss != NULL);
17390  assert(upgdconss != NULL);
17391 
17392  *nupgdconss = 0;
17393 
17394  SCIPdebugMsg(scip, "upgradeConsQuadratic called for constraint <%s>\n", SCIPconsGetName(cons));
17395  SCIPdebugPrintCons(scip, cons, NULL);
17396 
17397  if( SCIPgetNQuadVarTermsQuadratic(scip, cons) > 0 )
17398  return SCIP_OKAY;
17399  if( SCIPgetNLinearVarsQuadratic(scip, cons) == 0 )
17400  return SCIP_OKAY;
17401 
17402  if( upgdconsssize < 1 )
17403  {
17404  /* signal that we need more memory */
17405  *nupgdconss = -1;
17406  return SCIP_OKAY;
17407  }
17408 
17409  *nupgdconss = 1;
17410  SCIP_CALL( SCIPcreateConsLinear(scip, &upgdconss[0], SCIPconsGetName(cons),
17411  SCIPgetNLinearVarsQuadratic(scip, cons),
17412  SCIPgetLinearVarsQuadratic(scip, cons),
17413  SCIPgetCoefsLinearVarsQuadratic(scip, cons),
17414  SCIPgetLhsQuadratic(scip, cons), SCIPgetRhsQuadratic(scip, cons),
17418  SCIPconsIsStickingAtNode(cons)) );
17419 
17420  upgdconsdata = SCIPconsGetData(upgdconss[0]);
17421  assert(upgdconsdata != NULL);
17422 
17423  /* check violation of this linear constraint with absolute tolerances, to be consistent with the original quadratic constraint */
17424  upgdconsdata->checkabsolute = TRUE;
17425 
17426  SCIPdebugMsg(scip, "created linear constraint:\n");
17427  SCIPdebugPrintCons(scip, upgdconss[0], NULL);
17428 
17429  return SCIP_OKAY;
17430 }
17431 
17432 /** tries to upgrade a nonlinear constraint into a linear constraint */
17433 static
17434 SCIP_DECL_NONLINCONSUPGD(upgradeConsNonlinear)
17435 {
17436  SCIP_CONSDATA* upgdconsdata;
17437 
17438  assert(nupgdconss != NULL);
17439  assert(upgdconss != NULL);
17440 
17441  *nupgdconss = 0;
17442 
17443  /* no interest in nonlinear constraints */
17444  if( SCIPgetExprgraphNodeNonlinear(scip, cons) != NULL )
17445  return SCIP_OKAY;
17446 
17447  /* no interest in constant constraints */
17448  if( SCIPgetNLinearVarsNonlinear(scip, cons) == 0 )
17449  return SCIP_OKAY;
17450 
17451  if( upgdconsssize < 1 )
17452  {
17453  /* request larger upgdconss array */
17454  *nupgdconss = -1;
17455  return SCIP_OKAY;
17456  }
17457 
17458  *nupgdconss = 1;
17459  SCIP_CALL( SCIPcreateConsLinear(scip, &upgdconss[0], SCIPconsGetName(cons),
17461  SCIPgetLhsNonlinear(scip, cons), SCIPgetRhsNonlinear(scip, cons),
17465  SCIPconsIsStickingAtNode(cons)) );
17466 
17467  upgdconsdata = SCIPconsGetData(upgdconss[0]);
17468  assert(upgdconsdata != NULL);
17469 
17470  /* check violation of this linear constraint with absolute tolerances, to be consistent with the original nonlinear constraint */
17471  upgdconsdata->checkabsolute = TRUE;
17472 
17473  SCIPdebugMsg(scip, "created linear constraint:\n");
17474  SCIPdebugPrintCons(scip, upgdconss[0], NULL);
17475 
17476  return SCIP_OKAY;
17477 }
17478 
17479 /*
17480  * constraint specific interface methods
17481  */
17482 
17483 /** creates the handler for linear constraints and includes it in SCIP */
17485  SCIP* scip /**< SCIP data structure */
17486  )
17487 {
17488  SCIP_CONSHDLRDATA* conshdlrdata;
17489  SCIP_CONSHDLR* conshdlr;
17490  SCIP_EVENTHDLR* eventhdlr;
17491  SCIP_CONFLICTHDLR* conflicthdlr;
17492 
17493  assert(scip != NULL);
17494 
17495  /* create event handler for bound change events */
17497  eventExecLinear, NULL) );
17498 
17499  /* create conflict handler for linear constraints */
17501  conflictExecLinear, NULL) );
17502 
17503  /* create constraint handler data */
17504  SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
17505 
17506  /* include constraint handler */
17509  consEnfolpLinear, consEnfopsLinear, consCheckLinear, consLockLinear,
17510  conshdlrdata) );
17511 
17512  assert(conshdlr != NULL);
17513 
17514  /* set non-fundamental callbacks via specific setter functions */
17515  SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyLinear, consCopyLinear) );
17516  SCIP_CALL( SCIPsetConshdlrDeactive(scip, conshdlr, consDeactiveLinear) );
17517  SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteLinear) );
17518  SCIP_CALL( SCIPsetConshdlrDelvars(scip, conshdlr, consDelvarsLinear) );
17519  SCIP_CALL( SCIPsetConshdlrExit(scip, conshdlr, consExitLinear) );
17520  SCIP_CALL( SCIPsetConshdlrExitpre(scip, conshdlr, consExitpreLinear) );
17521  SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolLinear) );
17522  SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeLinear) );
17523  SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsLinear) );
17524  SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsLinear) );
17525  SCIP_CALL( SCIPsetConshdlrInit(scip, conshdlr, consInitLinear) );
17526  SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpLinear) );
17527  SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseLinear) );
17528  SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolLinear, CONSHDLR_MAXPREROUNDS, CONSHDLR_PRESOLTIMING) );
17529  SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintLinear) );
17530  SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropLinear, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP,
17532  SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropLinear) );
17533  SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpLinear, consSepasolLinear, CONSHDLR_SEPAFREQ,
17535  SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransLinear) );
17536  SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxLinear) );
17537 
17538  if( SCIPfindConshdlr(scip, "quadratic") != NULL )
17539  {
17540  /* include function that upgrades quadratic constraint to linear constraints */
17542  }
17543 
17544  if( SCIPfindConshdlr(scip, "nonlinear") != NULL )
17545  {
17546  /* include the linear constraint upgrade in the nonlinear constraint handler */
17548  }
17549 
17550  /* add linear constraint handler parameters */
17551  SCIP_CALL( SCIPaddIntParam(scip,
17552  "constraints/" CONSHDLR_NAME "/tightenboundsfreq",
17553  "multiplier on propagation frequency, how often the bounds are tightened (-1: never, 0: only at root)",
17554  &conshdlrdata->tightenboundsfreq, TRUE, DEFAULT_TIGHTENBOUNDSFREQ, -1, SCIP_MAXTREEDEPTH, NULL, NULL) );
17555  SCIP_CALL( SCIPaddIntParam(scip,
17556  "constraints/" CONSHDLR_NAME "/maxrounds",
17557  "maximal number of separation rounds per node (-1: unlimited)",
17558  &conshdlrdata->maxrounds, FALSE, DEFAULT_MAXROUNDS, -1, INT_MAX, NULL, NULL) );
17559  SCIP_CALL( SCIPaddIntParam(scip,
17560  "constraints/" CONSHDLR_NAME "/maxroundsroot",
17561  "maximal number of separation rounds per node in the root node (-1: unlimited)",
17562  &conshdlrdata->maxroundsroot, FALSE, DEFAULT_MAXROUNDSROOT, -1, INT_MAX, NULL, NULL) );
17563  SCIP_CALL( SCIPaddIntParam(scip,
17564  "constraints/" CONSHDLR_NAME "/maxsepacuts",
17565  "maximal number of cuts separated per separation round",
17566  &conshdlrdata->maxsepacuts, FALSE, DEFAULT_MAXSEPACUTS, 0, INT_MAX, NULL, NULL) );
17567  SCIP_CALL( SCIPaddIntParam(scip,
17568  "constraints/" CONSHDLR_NAME "/maxsepacutsroot",
17569  "maximal number of cuts separated per separation round in the root node",
17570  &conshdlrdata->maxsepacutsroot, FALSE, DEFAULT_MAXSEPACUTSROOT, 0, INT_MAX, NULL, NULL) );
17572  "constraints/" CONSHDLR_NAME "/presolpairwise",
17573  "should pairwise constraint comparison be performed in presolving?",
17574  &conshdlrdata->presolpairwise, TRUE, DEFAULT_PRESOLPAIRWISE, NULL, NULL) );
17576  "constraints/" CONSHDLR_NAME "/presolusehashing",
17577  "should hash table be used for detecting redundant constraints in advance",
17578  &conshdlrdata->presolusehashing, TRUE, DEFAULT_PRESOLUSEHASHING, NULL, NULL) );
17579  SCIP_CALL( SCIPaddIntParam(scip,
17580  "constraints/" CONSHDLR_NAME "/nmincomparisons",
17581  "number for minimal pairwise presolve comparisons",
17582  &conshdlrdata->nmincomparisons, TRUE, DEFAULT_NMINCOMPARISONS, 1, INT_MAX, NULL, NULL) );
17584  "constraints/" CONSHDLR_NAME "/mingainpernmincomparisons",
17585  "minimal gain per minimal pairwise presolve comparisons to repeat pairwise comparison round",
17586  &conshdlrdata->mingainpernmincomp, TRUE, DEFAULT_MINGAINPERNMINCOMP, 0.0, 1.0, NULL, NULL) );
17588  "constraints/" CONSHDLR_NAME "/maxaggrnormscale",
17589  "maximal allowed relative gain in maximum norm for constraint aggregation (0.0: disable constraint aggregation)",
17590  &conshdlrdata->maxaggrnormscale, TRUE, DEFAULT_MAXAGGRNORMSCALE, 0.0, SCIP_REAL_MAX, NULL, NULL) );
17592  "constraints/" CONSHDLR_NAME "/maxeasyactivitydelta",
17593  "maximum activity delta to run easy propagation on linear constraint (faster, but numerically less stable)",
17594  &conshdlrdata->maxeasyactivitydelta, TRUE, DEFAULT_MAXEASYACTIVITYDELTA, 0.0, SCIP_REAL_MAX, NULL, NULL) );
17596  "constraints/" CONSHDLR_NAME "/maxcardbounddist",
17597  "maximal relative distance from current node's dual bound to primal bound compared to best node's dual bound for separating knapsack cardinality cuts",
17598  &conshdlrdata->maxcardbounddist, TRUE, DEFAULT_MAXCARDBOUNDDIST, 0.0, 1.0, NULL, NULL) );
17600  "constraints/" CONSHDLR_NAME "/separateall",
17601  "should all constraints be subject to cardinality cut generation instead of only the ones with non-zero dual value?",
17602  &conshdlrdata->separateall, FALSE, DEFAULT_SEPARATEALL, NULL, NULL) );
17604  "constraints/" CONSHDLR_NAME "/aggregatevariables",
17605  "should presolving search for aggregations in equations",
17606  &conshdlrdata->aggregatevariables, TRUE, DEFAULT_AGGREGATEVARIABLES, NULL, NULL) );
17608  "constraints/" CONSHDLR_NAME "/simplifyinequalities",
17609  "should presolving try to simplify inequalities",
17610  &conshdlrdata->simplifyinequalities, TRUE, DEFAULT_SIMPLIFYINEQUALITIES, NULL, NULL) );
17612  "constraints/" CONSHDLR_NAME "/dualpresolving",
17613  "should dual presolving steps be performed?",
17614  &conshdlrdata->dualpresolving, TRUE, DEFAULT_DUALPRESOLVING, NULL, NULL) );
17616  "constraints/" CONSHDLR_NAME "/singletonstuffing",
17617  "should stuffing of singleton continuous variables be performed?",
17618  &conshdlrdata->singletonstuffing, TRUE, DEFAULT_SINGLETONSTUFFING, NULL, NULL) );
17620  "constraints/" CONSHDLR_NAME "/singlevarstuffing",
17621  "should single variable stuffing be performed, which tries to fulfill constraints using the cheapest variable?",
17622  &conshdlrdata->singlevarstuffing, TRUE, DEFAULT_SINGLEVARSTUFFING, NULL, NULL) );
17624  "constraints/" CONSHDLR_NAME "/sortvars", "apply binaries sorting in decr. order of coeff abs value?",
17625  &conshdlrdata->sortvars, TRUE, DEFAULT_SORTVARS, NULL, NULL) );
17627  "constraints/" CONSHDLR_NAME "/checkrelmaxabs",
17628  "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)?",
17629  &conshdlrdata->checkrelmaxabs, TRUE, DEFAULT_CHECKRELMAXABS, NULL, NULL) );
17631  "constraints/" CONSHDLR_NAME "/detectcutoffbound",
17632  "should presolving try to detect constraints parallel to the objective function defining an upper bound and prevent these constraints from entering the LP?",
17633  &conshdlrdata->detectcutoffbound, TRUE, DEFAULT_DETECTCUTOFFBOUND, NULL, NULL) );
17635  "constraints/" CONSHDLR_NAME "/detectlowerbound",
17636  "should presolving try to detect constraints parallel to the objective function defining a lower bound and prevent these constraints from entering the LP?",
17637  &conshdlrdata->detectlowerbound, TRUE, DEFAULT_DETECTLOWERBOUND, NULL, NULL) );
17639  "constraints/" CONSHDLR_NAME "/detectpartialobjective",
17640  "should presolving try to detect subsets of constraints parallel to the objective function?",
17641  &conshdlrdata->detectpartialobjective, TRUE, DEFAULT_DETECTPARTIALOBJECTIVE, NULL, NULL) );
17643  "constraints/" CONSHDLR_NAME "/rangedrowpropagation",
17644  "should presolving and propagation try to improve bounds, detect infeasibility, and extract sub-constraints from ranged rows and equations?",
17645  &conshdlrdata->rangedrowpropagation, TRUE, DEFAULT_RANGEDROWPROPAGATION, NULL, NULL) );
17647  "constraints/" CONSHDLR_NAME "/rangedrowartcons",
17648  "should presolving and propagation extract sub-constraints from ranged rows and equations?",
17649  &conshdlrdata->rangedrowartcons, TRUE, DEFAULT_RANGEDROWARTCONS, NULL, NULL) );
17650  SCIP_CALL( SCIPaddIntParam(scip,
17651  "constraints/" CONSHDLR_NAME "/rangedrowmaxdepth",
17652  "maximum depth to apply ranged row propagation",
17653  &conshdlrdata->rangedrowmaxdepth, TRUE, DEFAULT_RANGEDROWMAXDEPTH, 0, INT_MAX, NULL, NULL) );
17654  SCIP_CALL( SCIPaddIntParam(scip,
17655  "constraints/" CONSHDLR_NAME "/rangedrowfreq",
17656  "frequency for applying ranged row propagation",
17657  &conshdlrdata->rangedrowfreq, TRUE, DEFAULT_RANGEDROWFREQ, 1, SCIP_MAXTREEDEPTH, NULL, NULL) );
17659  "constraints/" CONSHDLR_NAME "/multaggrremove",
17660  "should multi-aggregations only be performed if the constraint can be removed afterwards?",
17661  &conshdlrdata->multaggrremove, TRUE, DEFAULT_MULTAGGRREMOVE, NULL, NULL) );
17663  "constraints/" CONSHDLR_NAME "/maxmultaggrquot",
17664  "maximum coefficient dynamism (ie. maxabsval / minabsval) for primal multiaggregation",
17665  &conshdlrdata->maxmultaggrquot, TRUE, DEFAULT_MAXMULTAGGRQUOT, 1.0, SCIP_REAL_MAX, NULL, NULL) );
17667  "constraints/" CONSHDLR_NAME "/maxdualmultaggrquot",
17668  "maximum coefficient dynamism (ie. maxabsval / minabsval) for dual multiaggregation",
17669  &conshdlrdata->maxdualmultaggrquot, TRUE, DEFAULT_MAXDUALMULTAGGRQUOT, 1.0, SCIP_REAL_MAX, NULL, NULL) );
17671  "constraints/" CONSHDLR_NAME "/extractcliques",
17672  "should Cliques be extracted?",
17673  &conshdlrdata->extractcliques, TRUE, DEFAULT_EXTRACTCLIQUES, NULL, NULL) );
17674 
17675  return SCIP_OKAY;
17676 }
17677 
17678 /** includes a linear constraint update method into the linear constraint handler */
17680  SCIP* scip, /**< SCIP data structure */
17681  SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
17682  int priority, /**< priority of upgrading method */
17683  const char* conshdlrname /**< name of the constraint handler */
17684  )
17685 {
17686  SCIP_CONSHDLR* conshdlr;
17687  SCIP_CONSHDLRDATA* conshdlrdata;
17688  SCIP_LINCONSUPGRADE* linconsupgrade;
17689  char paramname[SCIP_MAXSTRLEN];
17690  char paramdesc[SCIP_MAXSTRLEN];
17691 
17692  assert(scip != NULL);
17693  assert(linconsupgd != NULL);
17694  assert(conshdlrname != NULL );
17695 
17696  /* find the linear constraint handler */
17697  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
17698  if( conshdlr == NULL )
17699  {
17700  SCIPerrorMessage("linear constraint handler not found\n");
17701  return SCIP_PLUGINNOTFOUND;
17702  }
17703 
17704  conshdlrdata = SCIPconshdlrGetData(conshdlr);
17705  assert(conshdlrdata != NULL);
17706 
17707  /* check if linear constraint update method already exists in constraint handler data */
17708  if( !conshdlrdataHasUpgrade(scip, conshdlrdata, linconsupgd, conshdlrname) )
17709  {
17710  /* create a linear constraint upgrade data object */
17711  SCIP_CALL( linconsupgradeCreate(scip, &linconsupgrade, linconsupgd, priority) );
17712 
17713  /* insert linear constraint update method into constraint handler data */
17714  SCIP_CALL( conshdlrdataIncludeUpgrade(scip, conshdlrdata, linconsupgrade) );
17715 
17716  /* adds parameter to turn on and off the upgrading step */
17717  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "constraints/linear/upgrade/%s", conshdlrname);
17718  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "enable linear upgrading for constraint handler <%s>", conshdlrname);
17720  paramname, paramdesc,
17721  &linconsupgrade->active, FALSE, TRUE, NULL, NULL) );
17722  }
17723 
17724  return SCIP_OKAY;
17725 }
17726 
17727 /** creates and captures a linear constraint
17728  *
17729  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
17730  */
17732  SCIP* scip, /**< SCIP data structure */
17733  SCIP_CONS** cons, /**< pointer to hold the created constraint */
17734  const char* name, /**< name of constraint */
17735  int nvars, /**< number of nonzeros in the constraint */
17736  SCIP_VAR** vars, /**< array with variables of constraint entries */
17737  SCIP_Real* vals, /**< array with coefficients of constraint entries */
17738  SCIP_Real lhs, /**< left hand side of constraint */
17739  SCIP_Real rhs, /**< right hand side of constraint */
17740  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
17741  * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
17742  SCIP_Bool separate, /**< should the constraint be separated during LP processing?
17743  * Usually set to TRUE. */
17744  SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
17745  * TRUE for model constraints, FALSE for additional, redundant constraints. */
17746  SCIP_Bool check, /**< should the constraint be checked for feasibility?
17747  * TRUE for model constraints, FALSE for additional, redundant constraints. */
17748  SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
17749  * Usually set to TRUE. */
17750  SCIP_Bool local, /**< is constraint only valid locally?
17751  * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
17752  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
17753  * Usually set to FALSE. In column generation applications, set to TRUE if pricing
17754  * adds coefficients to this constraint. */
17755  SCIP_Bool dynamic, /**< is constraint subject to aging?
17756  * Usually set to FALSE. Set to TRUE for own cuts which
17757  * are separated as constraints. */
17758  SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
17759  * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
17760  SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
17761  * if it may be moved to a more global node?
17762  * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
17763  )
17764 {
17765  SCIP_CONSHDLR* conshdlr;
17766  SCIP_CONSDATA* consdata;
17767 
17768  assert(scip != NULL);
17769  assert(cons != NULL);
17770 
17771  /* find the linear constraint handler */
17772  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
17773  if( conshdlr == NULL )
17774  {
17775  SCIPerrorMessage("linear constraint handler not found\n");
17776  return SCIP_PLUGINNOTFOUND;
17777  }
17778 
17779  /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
17780  * constraint after presolving we have to ensure that it holds active variables
17781  */
17782  if( SCIPgetStage(scip) >= SCIP_STAGE_EXITPRESOLVE && nvars > 0 )
17783  {
17784  SCIP_VAR** consvars;
17785  SCIP_Real* consvals;
17786  SCIP_Real constant = 0.0;
17787  int nconsvars;
17788  int requiredsize;
17789 
17790  nconsvars = nvars;
17791  SCIP_CALL( SCIPduplicateBufferArray(scip, &consvars, vars, nconsvars) );
17792  SCIP_CALL( SCIPduplicateBufferArray(scip, &consvals, vals, nconsvars) );
17793 
17794  /* get active variables for new constraint */
17795  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, nconsvars, &constant, &requiredsize, TRUE) );
17796 
17797  /* if space was not enough we need to resize the buffers */
17798  if( requiredsize > nconsvars )
17799  {
17800  SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
17801  SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
17802 
17803  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize, TRUE) );
17804  assert(requiredsize <= nconsvars);
17805  }
17806 
17807  /* adjust sides and check that we do not subtract infinity values */
17808  if( SCIPisInfinity(scip, REALABS(constant)) )
17809  {
17810  if( constant < 0.0 )
17811  {
17812  if( SCIPisInfinity(scip, lhs) )
17813  {
17814  SCIPfreeBufferArray(scip, &consvals);
17815  SCIPfreeBufferArray(scip, &consvars);
17816 
17817  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);
17818 
17819  SCIPABORT();
17820  return SCIP_INVALIDDATA; /*lint !e527*/
17821  }
17822  if( SCIPisInfinity(scip, rhs) )
17823  {
17824  SCIPfreeBufferArray(scip, &consvals);
17825  SCIPfreeBufferArray(scip, &consvars);
17826 
17827  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);
17828 
17829  SCIPABORT();
17830  return SCIP_INVALIDDATA; /*lint !e527*/
17831  }
17832 
17833  lhs = -SCIPinfinity(scip);
17834  rhs = -SCIPinfinity(scip);
17835  }
17836  else
17837  {
17838  if( SCIPisInfinity(scip, -lhs) )
17839  {
17840  SCIPfreeBufferArray(scip, &consvals);
17841  SCIPfreeBufferArray(scip, &consvars);
17842 
17843  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);
17844 
17845  SCIPABORT();
17846  return SCIP_INVALIDDATA; /*lint !e527*/
17847  }
17848  if( SCIPisInfinity(scip, -rhs) )
17849  {
17850  SCIPfreeBufferArray(scip, &consvals);
17851  SCIPfreeBufferArray(scip, &consvars);
17852 
17853  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);
17854 
17855  SCIPABORT();
17856  return SCIP_INVALIDDATA; /*lint !e527*/
17857  }
17858 
17859  lhs = SCIPinfinity(scip);
17860  rhs = SCIPinfinity(scip);
17861  }
17862  }
17863  else
17864  {
17865  if( !SCIPisInfinity(scip, REALABS(lhs)) )
17866  lhs -= constant;
17867  if( !SCIPisInfinity(scip, REALABS(rhs)) )
17868  rhs -= constant;
17869 
17870  if( SCIPisInfinity(scip, -lhs) )
17871  lhs = -SCIPinfinity(scip);
17872  else if( SCIPisInfinity(scip, lhs) )
17873  lhs = SCIPinfinity(scip);
17874 
17875  if( SCIPisInfinity(scip, rhs) )
17876  rhs = SCIPinfinity(scip);
17877  else if( SCIPisInfinity(scip, -rhs) )
17878  rhs = -SCIPinfinity(scip);
17879  }
17880 
17881  /* create constraint data */
17882  SCIP_CALL( consdataCreate(scip, &consdata, nconsvars, consvars, consvals, lhs, rhs) );
17883  assert(consdata != NULL);
17884 
17885  SCIPfreeBufferArray(scip, &consvals);
17886  SCIPfreeBufferArray(scip, &consvars);
17887  }
17888  else
17889  {
17890  /* create constraint data */
17891  SCIP_CALL( consdataCreate(scip, &consdata, nvars, vars, vals, lhs, rhs) );
17892  assert(consdata != NULL);
17893  }
17894 
17895 #ifndef NDEBUG
17896  /* if this is a checked or enforced constraints, then there must be no relaxation-only variables */
17897  if( check || enforce )
17898  {
17899  int n;
17900  for(n = consdata->nvars - 1; n >= 0; --n )
17901  assert(!SCIPvarIsRelaxationOnly(consdata->vars[n]));
17902  }
17903 #endif
17904 
17905  /* create constraint */
17906  SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
17907  local, modifiable, dynamic, removable, stickingatnode) );
17908 
17909  return SCIP_OKAY;
17910 }
17911 
17912 /** creates and captures a linear constraint
17913  * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
17914  * method SCIPcreateConsLinear(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
17915  *
17916  * @see SCIPcreateConsLinear() for information about the basic constraint flag configuration
17917  *
17918  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
17919  */
17921  SCIP* scip, /**< SCIP data structure */
17922  SCIP_CONS** cons, /**< pointer to hold the created constraint */
17923  const char* name, /**< name of constraint */
17924  int nvars, /**< number of nonzeros in the constraint */
17925  SCIP_VAR** vars, /**< array with variables of constraint entries */
17926  SCIP_Real* vals, /**< array with coefficients of constraint entries */
17927  SCIP_Real lhs, /**< left hand side of constraint */
17928  SCIP_Real rhs /**< right hand side of constraint */
17929  )
17930 {
17931  assert(scip != NULL);
17932 
17933  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, vals, lhs, rhs,
17934  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
17935 
17936  return SCIP_OKAY;
17938 
17939 /** creates by copying and captures a linear constraint */
17941  SCIP* scip, /**< target SCIP data structure */
17942  SCIP_CONS** cons, /**< pointer to store the created target constraint */
17943  SCIP* sourcescip, /**< source SCIP data structure */
17944  const char* name, /**< name of constraint */
17945  int nvars, /**< number of variables in source variable array */
17946  SCIP_VAR** sourcevars, /**< source variables of the linear constraints */
17947  SCIP_Real* sourcecoefs, /**< coefficient array of the linear constraint, or NULL if all coefficients are one */
17948  SCIP_Real lhs, /**< left hand side of the linear constraint */
17949  SCIP_Real rhs, /**< right hand side of the linear constraint */
17950  SCIP_HASHMAP* varmap, /**< a SCIP_HASHMAP mapping variables of the source SCIP to corresponding
17951  * variables of the target SCIP */
17952  SCIP_HASHMAP* consmap, /**< a hashmap to store the mapping of source constraints to the corresponding
17953  * target constraints */
17954  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP? */
17955  SCIP_Bool separate, /**< should the constraint be separated during LP processing? */
17956  SCIP_Bool enforce, /**< should the constraint be enforced during node processing? */
17957  SCIP_Bool check, /**< should the constraint be checked for feasibility? */
17958  SCIP_Bool propagate, /**< should the constraint be propagated during node processing? */
17959  SCIP_Bool local, /**< is constraint only valid locally? */
17960  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)? */
17961  SCIP_Bool dynamic, /**< is constraint subject to aging? */
17962  SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup? */
17963  SCIP_Bool stickingatnode, /**< should the constraint always be kept at the node where it was added, even
17964  * if it may be moved to a more global node? */
17965  SCIP_Bool global, /**< create a global or a local copy? */
17966  SCIP_Bool* valid /**< pointer to store if the copying was valid */
17967  )
17968 {
17969  SCIP_VAR** vars;
17970  SCIP_Real* coefs;
17971 
17972  SCIP_Real constant;
17973  int requiredsize;
17974  int v;
17975  SCIP_Bool success;
17976 
17977  if( SCIPisGT(scip, lhs, rhs) )
17978  {
17979  *valid = FALSE;
17980  return SCIP_OKAY;
17981  }
17982 
17983  (*valid) = TRUE;
17984 
17985  if( nvars == 0 )
17986  {
17987  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, 0, NULL, NULL, lhs, rhs,
17988  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
17989  return SCIP_OKAY;
17990  }
17991 
17992  /* duplicate variable array */
17993  SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, sourcevars, nvars) );
17994 
17995  /* duplicate coefficient array */
17996  if( sourcecoefs != NULL )
17997  {
17998  SCIP_CALL( SCIPduplicateBufferArray(scip, &coefs, sourcecoefs, nvars) );
17999  }
18000  else
18001  {
18002  SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
18003  for( v = 0; v < nvars; ++v )
18004  coefs[v] = 1.0;
18005  }
18006 
18007  constant = 0.0;
18008 
18009  /* transform source variable to active variables of the source SCIP since only these can be mapped to variables of
18010  * the target SCIP
18011  */
18012  if( !SCIPvarIsOriginal(vars[0]) )
18013  {
18014  SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, nvars, &constant, &requiredsize, TRUE) );
18015 
18016  if( requiredsize > nvars )
18017  {
18018  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requiredsize) );
18019  SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, requiredsize) );
18020 
18021  SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, requiredsize, &constant, &requiredsize, TRUE) );
18022  assert(requiredsize <= nvars);
18023  }
18024  }
18025  else
18026  {
18027  for( v = 0; v < nvars; ++v )
18028  {
18029  assert(SCIPvarIsOriginal(vars[v]));
18030  SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &coefs[v], &constant) );
18031  assert(vars[v] != NULL);
18032  }
18033  }
18034 
18035  success = TRUE;
18036  /* map variables of the source constraint to variables of the target SCIP */
18037  for( v = 0; v < nvars && success; ++v )
18038  {
18039  SCIP_VAR* var;
18040  var = vars[v];
18041 
18042  /* if this is a checked or enforced constraints, then there must be no relaxation-only variables */
18043  assert(!SCIPvarIsRelaxationOnly(var) || (!check && !enforce));
18044 
18045  SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, var, &vars[v], varmap, consmap, global, &success) );
18046  assert(!(success) || vars[v] != NULL);
18047  }
18048 
18049  /* only create the target constraint, if all variables could be copied */
18050  if( success )
18051  {
18052  if( !SCIPisInfinity(scip, -lhs) )
18053  lhs -= constant;
18054 
18055  if( !SCIPisInfinity(scip, rhs) )
18056  rhs -= constant;
18057 
18058  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
18059  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
18060  }
18061  else
18062  *valid = FALSE;
18063 
18064  /* free buffer array */
18065  SCIPfreeBufferArray(scip, &coefs);
18066  SCIPfreeBufferArray(scip, &vars);
18067 
18068  return SCIP_OKAY;
18069 }
18070 
18071 /** adds coefficient to linear constraint (if it is not zero) */
18073  SCIP* scip, /**< SCIP data structure */
18074  SCIP_CONS* cons, /**< constraint data */
18075  SCIP_VAR* var, /**< variable of constraint entry */
18076  SCIP_Real val /**< coefficient of constraint entry */
18077  )
18078 {
18079  assert(scip != NULL);
18080  assert(cons != NULL);
18081  assert(var != NULL);
18082 
18083  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18084  {
18085  SCIPerrorMessage("constraint is not linear\n");
18086  return SCIP_INVALIDDATA;
18087  }
18088 
18089  /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
18090  * constraint after presolving we have to ensure that it holds active variables
18091  */
18092  if( SCIPgetStage(scip) >= SCIP_STAGE_EXITPRESOLVE )
18093  {
18094  SCIP_CONSDATA* consdata;
18095  SCIP_VAR** consvars;
18096  SCIP_Real* consvals;
18097  SCIP_Real constant = 0.0;
18098  SCIP_Real rhs;
18099  SCIP_Real lhs;
18100  int nconsvars;
18101  int requiredsize;
18102  int v;
18103 
18104  nconsvars = 1;
18105  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nconsvars) );
18106  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
18107  consvars[0] = var;
18108  consvals[0] = val;
18109 
18110  /* get active variables for new constraint */
18111  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, nconsvars, &constant, &requiredsize, TRUE) );
18112 
18113  /* if space was not enough we need to resize the buffers */
18114  if( requiredsize > nconsvars )
18115  {
18116  SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
18117  SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
18118 
18119  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize, TRUE) );
18120  assert(requiredsize <= nconsvars);
18121  }
18122 
18123  consdata = SCIPconsGetData(cons);
18124  assert(consdata != NULL);
18125 
18126  lhs = consdata->lhs;
18127  rhs = consdata->rhs;
18128 
18129  /* adjust sides and check that we do not subtract infinity values */
18130  /* constant is infinite */
18131  if( SCIPisInfinity(scip, REALABS(constant)) )
18132  {
18133  if( constant < 0.0 )
18134  {
18135  if( SCIPisInfinity(scip, lhs) )
18136  {
18137  SCIPfreeBufferArray(scip, &consvals);
18138  SCIPfreeBufferArray(scip, &consvars);
18139 
18140  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));
18141 
18142  SCIPABORT();
18143  return SCIP_INVALIDDATA; /*lint !e527*/
18144  }
18145  if( SCIPisInfinity(scip, rhs) )
18146  {
18147  SCIPfreeBufferArray(scip, &consvals);
18148  SCIPfreeBufferArray(scip, &consvars);
18149 
18150  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));
18151 
18152  SCIPABORT();
18153  return SCIP_INVALIDDATA; /*lint !e527*/
18154  }
18155 
18156  lhs = -SCIPinfinity(scip);
18157  rhs = -SCIPinfinity(scip);
18158  }
18159  else
18160  {
18161  if( SCIPisInfinity(scip, -lhs) )
18162  {
18163  SCIPfreeBufferArray(scip, &consvals);
18164  SCIPfreeBufferArray(scip, &consvars);
18165 
18166  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));
18167 
18168  SCIPABORT();
18169  return SCIP_INVALIDDATA; /*lint !e527*/
18170  }
18171  if( SCIPisInfinity(scip, -rhs) )
18172  {
18173  SCIPfreeBufferArray(scip, &consvals);
18174  SCIPfreeBufferArray(scip, &consvars);
18175 
18176  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));
18177 
18178  SCIPABORT();
18179  return SCIP_INVALIDDATA; /*lint !e527*/
18180  }
18181 
18182  lhs = SCIPinfinity(scip);
18183  rhs = SCIPinfinity(scip);
18184  }
18185  }
18186  /* constant is not infinite */
18187  else
18188  {
18189  if( !SCIPisInfinity(scip, REALABS(lhs)) )
18190  lhs -= constant;
18191  if( !SCIPisInfinity(scip, REALABS(rhs)) )
18192  rhs -= constant;
18193 
18194  if( SCIPisInfinity(scip, -lhs) )
18195  lhs = -SCIPinfinity(scip);
18196  else if( SCIPisInfinity(scip, lhs) )
18197  lhs = SCIPinfinity(scip);
18198 
18199  if( SCIPisInfinity(scip, rhs) )
18200  rhs = SCIPinfinity(scip);
18201  else if( SCIPisInfinity(scip, -rhs) )
18202  rhs = -SCIPinfinity(scip);
18203  }
18204 
18205  /* add all active variables to constraint */
18206  for( v = nconsvars - 1; v >= 0; --v )
18207  {
18208  SCIP_CALL( addCoef(scip, cons, consvars[v], consvals[v]) );
18209  }
18210 
18211  /* update left and right hand sides */
18212  SCIP_CALL( chgLhs(scip, cons, lhs));
18213  SCIP_CALL( chgRhs(scip, cons, rhs));
18214 
18215  SCIPfreeBufferArray(scip, &consvals);
18216  SCIPfreeBufferArray(scip, &consvars);
18217  }
18218  else
18219  {
18220  SCIP_CALL( addCoef(scip, cons, var, val) );
18221  }
18222 
18223  return SCIP_OKAY;
18224 }
18225 
18226 /** changes coefficient of variable in linear constraint; deletes the variable if coefficient is zero; adds variable if
18227  * not yet contained in the constraint
18228  *
18229  * @note This method may only be called during problem creation stage for an original constraint and variable.
18230  *
18231  * @note This method requires linear time to search for occurences of the variable in the constraint data.
18232  */
18234  SCIP* scip, /**< SCIP data structure */
18235  SCIP_CONS* cons, /**< constraint data */
18236  SCIP_VAR* var, /**< variable of constraint entry */
18237  SCIP_Real val /**< new coefficient of constraint entry */
18238  )
18239 {
18240  SCIP_CONSDATA* consdata;
18241  SCIP_VAR** vars;
18242  SCIP_Bool found;
18243  int i;
18244 
18245  assert(scip != NULL);
18246  assert(cons != NULL);
18247  assert(var != NULL);
18248 
18249  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18250  {
18251  SCIPerrorMessage("constraint is not linear\n");
18252  return SCIP_INVALIDDATA;
18253  }
18254 
18255  if( SCIPgetStage(scip) > SCIP_STAGE_PROBLEM || !SCIPconsIsOriginal(cons) || !SCIPvarIsOriginal(var) )
18256  {
18257  SCIPerrorMessage("method may only be called during problem creation stage for original constraints and variables\n");
18258  return SCIP_INVALIDDATA;
18259  }
18260 
18261  consdata = SCIPconsGetData(cons);
18262  assert(consdata != NULL);
18263 
18264  vars = consdata->vars;
18265  found = FALSE;
18266  i = 0;
18267  while( i < consdata->nvars )
18268  {
18269  if( vars[i] == var )
18270  {
18271  if( found || SCIPisZero(scip, val) )
18272  {
18273  SCIP_CALL( delCoefPos(scip, cons, i) );
18274 
18275  /* decrease i by one since otherwise we would skip the coefficient which has been switched to position i */
18276  i--;
18277  }
18278  else
18279  {
18280  SCIP_CALL( chgCoefPos(scip, cons, i, val) );
18281  }
18282  found = TRUE;
18283  }
18284  i++;
18285  }
18286 
18287  if( !found && !SCIPisZero(scip, val) )
18288  {
18289  SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val) );
18290  }
18291 
18292  return SCIP_OKAY;
18293 }
18294 
18295 /** deletes variable from linear constraint
18296  *
18297  * @note This method may only be called during problem creation stage for an original constraint and variable.
18298  *
18299  * @note This method requires linear time to search for occurences of the variable in the constraint data.
18300  */
18302  SCIP* scip, /**< SCIP data structure */
18303  SCIP_CONS* cons, /**< constraint data */
18304  SCIP_VAR* var /**< variable of constraint entry */
18305  )
18306 {
18307  assert(scip != NULL);
18308  assert(cons != NULL);
18309  assert(var != NULL);
18310 
18311  SCIP_CALL( SCIPchgCoefLinear(scip, cons, var, 0.0) );
18312 
18313  return SCIP_OKAY;
18314 }
18315 
18316 /** gets left hand side of linear constraint */
18318  SCIP* scip, /**< SCIP data structure */
18319  SCIP_CONS* cons /**< constraint data */
18320  )
18321 {
18322  SCIP_CONSDATA* consdata;
18323 
18324  assert(scip != NULL);
18325  assert(cons != NULL);
18326 
18327  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18328  {
18329  SCIPerrorMessage("constraint is not linear\n");
18330  SCIPABORT();
18331  return SCIP_INVALID; /*lint !e527*/
18332  }
18333 
18334  consdata = SCIPconsGetData(cons);
18335  assert(consdata != NULL);
18336 
18337  return consdata->lhs;
18338 }
18339 
18340 /** gets right hand side of linear constraint */
18342  SCIP* scip, /**< SCIP data structure */
18343  SCIP_CONS* cons /**< constraint data */
18344  )
18345 {
18346  SCIP_CONSDATA* consdata;
18347 
18348  assert(scip != NULL);
18349  assert(cons != NULL);
18350 
18351  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18352  {
18353  SCIPerrorMessage("constraint is not linear\n");
18354  SCIPABORT();
18355  return SCIP_INVALID; /*lint !e527*/
18356  }
18357 
18358  consdata = SCIPconsGetData(cons);
18359  assert(consdata != NULL);
18360 
18361  return consdata->rhs;
18362 }
18363 
18364 /** changes left hand side of linear constraint */
18366  SCIP* scip, /**< SCIP data structure */
18367  SCIP_CONS* cons, /**< constraint data */
18368  SCIP_Real lhs /**< new left hand side */
18369  )
18370 {
18371  assert(scip != NULL);
18372  assert(cons != NULL);
18373 
18374  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18375  {
18376  SCIPerrorMessage("constraint is not linear\n");
18377  return SCIP_INVALIDDATA;
18378  }
18379 
18380  SCIP_CALL( chgLhs(scip, cons, lhs) );
18381 
18382  return SCIP_OKAY;
18383 }
18384 
18385 /** changes right hand side of linear constraint */
18387  SCIP* scip, /**< SCIP data structure */
18388  SCIP_CONS* cons, /**< constraint data */
18389  SCIP_Real rhs /**< new right hand side */
18390  )
18391 {
18392  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18393  {
18394  SCIPerrorMessage("constraint is not linear\n");
18395  return SCIP_INVALIDDATA;
18396  }
18397 
18398  SCIP_CALL( chgRhs(scip, cons, rhs) );
18399 
18400  return SCIP_OKAY;
18401 }
18402 
18403 /** gets the number of variables in the linear constraint */
18404 int SCIPgetNVarsLinear(
18405  SCIP* scip, /**< SCIP data structure */
18406  SCIP_CONS* cons /**< constraint data */
18407  )
18408 {
18409  SCIP_CONSDATA* consdata;
18410 
18411  assert(scip != NULL);
18412  assert(cons != NULL);
18413 
18414  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18415  {
18416  SCIPerrorMessage("constraint is not linear\n");
18417  SCIPABORT();
18418  return -1; /*lint !e527*/
18419  }
18420 
18421  consdata = SCIPconsGetData(cons);
18422  assert(consdata != NULL);
18423 
18424  return consdata->nvars;
18425 }
18426 
18427 /** gets the array of variables in the linear constraint; the user must not modify this array! */
18429  SCIP* scip, /**< SCIP data structure */
18430  SCIP_CONS* cons /**< constraint data */
18431  )
18432 {
18433  SCIP_CONSDATA* consdata;
18434 
18435  assert(scip != NULL);
18436  assert(cons != NULL);
18437 
18438  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18439  {
18440  SCIPerrorMessage("constraint is not linear\n");
18441  SCIPABORT();
18442  return NULL; /*lint !e527*/
18443  }
18444 
18445  consdata = SCIPconsGetData(cons);
18446  assert(consdata != NULL);
18447 
18448  return consdata->vars;
18449 }
18450 
18451 /** gets the array of coefficient values in the linear constraint; the user must not modify this array! */
18453  SCIP* scip, /**< SCIP data structure */
18454  SCIP_CONS* cons /**< constraint data */
18455  )
18456 {
18457  SCIP_CONSDATA* consdata;
18458 
18459  assert(scip != NULL);
18460  assert(cons != NULL);
18461 
18462  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18463  {
18464  SCIPerrorMessage("constraint is not linear\n");
18465  SCIPABORT();
18466  return NULL; /*lint !e527*/
18467  }
18468 
18469  consdata = SCIPconsGetData(cons);
18470  assert(consdata != NULL);
18471 
18472  return consdata->vals;
18473 }
18474 
18475 /** gets the activity of the linear constraint in the given solution
18476  *
18477  * @note if the solution contains values at infinity, this method will return SCIP_INVALID in case the activity
18478  * comprises positive and negative infinity contributions
18479  */
18481  SCIP* scip, /**< SCIP data structure */
18482  SCIP_CONS* cons, /**< constraint data */
18483  SCIP_SOL* sol /**< solution, or NULL to use current node's solution */
18484  )
18485 {
18486  SCIP_CONSDATA* consdata;
18487 
18488  assert(scip != NULL);
18489  assert(cons != NULL);
18490 
18491  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18492  {
18493  SCIPerrorMessage("constraint is not linear\n");
18494  SCIPABORT();
18495  return SCIP_INVALID; /*lint !e527*/
18496  }
18498  consdata = SCIPconsGetData(cons);
18499  assert(consdata != NULL);
18500 
18501  if( consdata->row != NULL )
18502  return SCIPgetRowSolActivity(scip, consdata->row, sol);
18503  else
18504  return consdataGetActivity(scip, consdata, sol);
18505 }
18506 
18507 /** gets the feasibility of the linear constraint in the given solution */
18509  SCIP* scip, /**< SCIP data structure */
18510  SCIP_CONS* cons, /**< constraint data */
18511  SCIP_SOL* sol /**< solution, or NULL to use current node's solution */
18512  )
18513 {
18514  SCIP_CONSDATA* consdata;
18515 
18516  assert(scip != NULL);
18517  assert(cons != NULL);
18518 
18519  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18520  {
18521  SCIPerrorMessage("constraint is not linear\n");
18522  SCIPABORT();
18523  return SCIP_INVALID; /*lint !e527*/
18524  }
18526  consdata = SCIPconsGetData(cons);
18527  assert(consdata != NULL);
18528 
18529  if( consdata->row != NULL )
18530  return SCIPgetRowSolFeasibility(scip, consdata->row, sol);
18531  else
18532  return consdataGetFeasibility(scip, consdata, sol);
18533 }
18534 
18535 /** gets the dual solution of the linear constraint in the current LP */
18537  SCIP* scip, /**< SCIP data structure */
18538  SCIP_CONS* cons /**< constraint data */
18539  )
18540 {
18541  SCIP_CONSDATA* consdata;
18542 
18543  assert(scip != NULL);
18544  assert(cons != NULL);
18545  assert(!SCIPconsIsOriginal(cons)); /* original constraints would always return 0 */
18546 
18547  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18548  {
18549  SCIPerrorMessage("constraint is not linear\n");
18550  SCIPABORT();
18551  return SCIP_INVALID; /*lint !e527*/
18552  }
18554  consdata = SCIPconsGetData(cons);
18555  assert(consdata != NULL);
18556 
18557  if( consdata->row != NULL )
18558  return SCIProwGetDualsol(consdata->row);
18559  else
18560  return 0.0;
18561 }
18562 
18563 /** gets the dual Farkas value of the linear constraint in the current infeasible LP */
18565  SCIP* scip, /**< SCIP data structure */
18566  SCIP_CONS* cons /**< constraint data */
18567  )
18568 {
18569  SCIP_CONSDATA* consdata;
18570 
18571  assert(scip != NULL);
18572  assert(cons != NULL);
18573  assert(!SCIPconsIsOriginal(cons)); /* original constraints would always return 0 */
18574 
18575  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18576  {
18577  SCIPerrorMessage("constraint is not linear\n");
18578  SCIPABORT();
18579  return SCIP_INVALID; /*lint !e527*/
18580  }
18582  consdata = SCIPconsGetData(cons);
18583  assert(consdata != NULL);
18584 
18585  if( consdata->row != NULL )
18586  return SCIProwGetDualfarkas(consdata->row);
18587  else
18588  return 0.0;
18589 }
18590 
18591 /** returns the linear relaxation of the given linear constraint; may return NULL if no LP row was yet created;
18592  * the user must not modify the row!
18593  */
18595  SCIP* scip, /**< SCIP data structure */
18596  SCIP_CONS* cons /**< constraint data */
18597  )
18598 {
18599  SCIP_CONSDATA* consdata;
18600 
18601  assert(scip != NULL);
18602  assert(cons != NULL);
18603 
18604  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18605  {
18606  SCIPerrorMessage("constraint is not linear\n");
18607  SCIPABORT();
18608  return NULL; /*lint !e527*/
18609  }
18610 
18611  consdata = SCIPconsGetData(cons);
18612  assert(consdata != NULL);
18613 
18614  return consdata->row;
18615 }
18616 
18617 /** tries to automatically convert a linear constraint into a more specific and more specialized constraint */
18619  SCIP* scip, /**< SCIP data structure */
18620  SCIP_CONS* cons, /**< source constraint to try to convert */
18621  SCIP_CONS** upgdcons /**< pointer to store upgraded constraint, or NULL if not successful */
18622  )
18623 {
18624  SCIP_CONSHDLR* conshdlr;
18625  SCIP_CONSHDLRDATA* conshdlrdata;
18626  SCIP_CONSDATA* consdata;
18627  SCIP_VAR* var;
18628  SCIP_Real val;
18629  SCIP_Real lb;
18630  SCIP_Real ub;
18631  SCIP_Real poscoeffsum;
18632  SCIP_Real negcoeffsum;
18633  SCIP_Bool infeasible;
18634  SCIP_Bool integral;
18635  int nchgsides = 0;
18636  int nposbin;
18637  int nnegbin;
18638  int nposint;
18639  int nnegint;
18640  int nposimpl;
18641  int nnegimpl;
18642  int nposimplbin;
18643  int nnegimplbin;
18644  int nposcont;
18645  int nnegcont;
18646  int ncoeffspone;
18647  int ncoeffsnone;
18648  int ncoeffspint;
18649  int ncoeffsnint;
18650  int ncoeffspfrac;
18651  int ncoeffsnfrac;
18652  int i;
18653 
18654  assert(scip != NULL);
18655  assert(cons != NULL);
18656  assert(upgdcons != NULL);
18657 
18658  *upgdcons = NULL;
18659 
18660  /* we cannot upgrade a modifiable linear constraint, since we don't know what additional coefficients to expect */
18661  if( SCIPconsIsModifiable(cons) )
18662  return SCIP_OKAY;
18663 
18664  /* check for upgradability */
18665  if( SCIPconsGetNUpgradeLocks(cons) > 0 )
18666  return SCIP_OKAY;
18667 
18668  /* get the constraint handler and check, if it's really a linear constraint */
18669  conshdlr = SCIPconsGetHdlr(cons);
18670  if( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) != 0 )
18671  {
18672  SCIPerrorMessage("constraint is not linear\n");
18673  return SCIP_INVALIDDATA;
18674  }
18675 
18676  /* get constraint handler data and constraint data */
18677  conshdlrdata = SCIPconshdlrGetData(conshdlr);
18678  assert(conshdlrdata != NULL);
18679  consdata = SCIPconsGetData(cons);
18680  assert(consdata != NULL);
18681 
18682  /* check, if the constraint was already upgraded and will be deleted anyway after preprocessing */
18683  if( consdata->upgraded )
18684  return SCIP_OKAY;
18685 
18686  /* check, if the constraint is already stored as LP row */
18687  if( consdata->row != NULL )
18688  {
18689  if( SCIProwIsInLP(consdata->row) )
18690  {
18691  SCIPerrorMessage("cannot upgrade linear constraint that is already stored as row in the LP\n");
18692  return SCIP_INVALIDDATA;
18693  }
18694  else
18695  {
18696  SCIP_CALL( SCIPreleaseRow(scip, &consdata->row) );
18697  }
18698  }
18699 
18700  /* normalize constraint */
18701  SCIP_CALL( normalizeCons(scip, cons, &infeasible) );
18702 
18703  /* normalizeCons() can only detect infeasibility when scaling with the gcd. in that case, the scaling was
18704  * skipped and we hope that the infeasibility gets detected later again.
18705  *
18706  * TODO: do we want to try to upgrade the constraint anyway?
18707  *
18708  * TODO: this needs to be fixed on master by changing the API and passing a pointer to whether the constraint is
18709  * proven to be infeasible.
18710  */
18711  if( infeasible ) /*lint !e774*/
18712  return SCIP_OKAY;
18713 
18714  /* tighten sides */
18715  SCIP_CALL( tightenSides(scip, cons, &nchgsides, &infeasible) );
18716 
18717  if( infeasible ) /*lint !e774*/
18718  return SCIP_OKAY;
18719 
18720  /*
18721  * calculate some statistics on linear constraint
18722  */
18723 
18724  nposbin = 0;
18725  nnegbin = 0;
18726  nposint = 0;
18727  nnegint = 0;
18728  nposimpl = 0;
18729  nnegimpl = 0;
18730  nposimplbin = 0;
18731  nnegimplbin = 0;
18732  nposcont = 0;
18733  nnegcont = 0;
18734  ncoeffspone = 0;
18735  ncoeffsnone = 0;
18736  ncoeffspint = 0;
18737  ncoeffsnint = 0;
18738  ncoeffspfrac = 0;
18739  ncoeffsnfrac = 0;
18740  integral = TRUE;
18741  poscoeffsum = 0.0;
18742  negcoeffsum = 0.0;
18743 
18744  for( i = 0; i < consdata->nvars; ++i )
18745  {
18746  var = consdata->vars[i];
18747  val = consdata->vals[i];
18748  lb = SCIPvarGetLbLocal(var);
18749  ub = SCIPvarGetUbLocal(var);
18750  assert(!SCIPisZero(scip, val));
18751 
18752  switch( SCIPvarGetType(var) )
18753  {
18754  case SCIP_VARTYPE_BINARY:
18755  if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
18756  integral = integral && SCIPisIntegral(scip, val);
18757  if( val >= 0.0 )
18758  nposbin++;
18759  else
18760  nnegbin++;
18761  break;
18762  case SCIP_VARTYPE_INTEGER:
18763  if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
18764  integral = integral && SCIPisIntegral(scip, val);
18765  if( val >= 0.0 )
18766  nposint++;
18767  else
18768  nnegint++;
18769  break;
18770  case SCIP_VARTYPE_IMPLINT:
18771  if( SCIPvarIsBinary(var) )
18772  {
18773  if( val >= 0.0 )
18774  nposimplbin++;
18775  else
18776  nnegimplbin++;
18777  }
18778  if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
18779  integral = integral && SCIPisIntegral(scip, val);
18780  if( val >= 0.0 )
18781  nposimpl++;
18782  else
18783  nnegimpl++;
18784  break;
18786  integral = integral && SCIPisEQ(scip, lb, ub) && SCIPisIntegral(scip, val * lb);
18787  if( val >= 0.0 )
18788  nposcont++;
18789  else
18790  nnegcont++;
18791  break;
18792  default:
18793  SCIPerrorMessage("unknown variable type\n");
18794  return SCIP_INVALIDDATA;
18795  }
18796  if( SCIPisEQ(scip, val, 1.0) )
18797  ncoeffspone++;
18798  else if( SCIPisEQ(scip, val, -1.0) )
18799  ncoeffsnone++;
18800  else if( SCIPisIntegral(scip, val) )
18801  {
18802  if( SCIPisPositive(scip, val) )
18803  ncoeffspint++;
18804  else
18805  ncoeffsnint++;
18806  }
18807  else
18808  {
18809  if( SCIPisPositive(scip, val) )
18810  ncoeffspfrac++;
18811  else
18812  ncoeffsnfrac++;
18813  }
18814  if( SCIPisPositive(scip, val) )
18815  poscoeffsum += val;
18816  else
18817  negcoeffsum += val;
18818  }
18819 
18820  /*
18821  * call the upgrading methods
18822  */
18823 
18824  SCIPdebugMsg(scip, "upgrading linear constraint <%s> (%d upgrade methods):\n",
18825  SCIPconsGetName(cons), conshdlrdata->nlinconsupgrades);
18826  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",
18827  nposbin, nnegbin, nposint, nnegint, nposimpl, nnegimpl, nposcont, nnegcont,
18828  ncoeffspone, ncoeffsnone, ncoeffspint, ncoeffsnint, ncoeffspfrac, ncoeffsnfrac,
18829  poscoeffsum, negcoeffsum, integral);
18830 
18831  /* try all upgrading methods in priority order in case the upgrading step is enable */
18832  for( i = 0; i < conshdlrdata->nlinconsupgrades && *upgdcons == NULL; ++i )
18833  {
18834  if( conshdlrdata->linconsupgrades[i]->active )
18835  {
18836  SCIP_CALL( conshdlrdata->linconsupgrades[i]->linconsupgd(scip, cons, consdata->nvars,
18837  consdata->vars, consdata->vals, consdata->lhs, consdata->rhs,
18838  nposbin, nnegbin, nposint, nnegint, nposimpl, nnegimpl, nposimplbin, nnegimplbin, nposcont, nnegcont,
18839  ncoeffspone, ncoeffsnone, ncoeffspint, ncoeffsnint, ncoeffspfrac, ncoeffsnfrac,
18840  poscoeffsum, negcoeffsum, integral,
18841  upgdcons) );
18842  }
18843  }
18844 
18845 #ifdef SCIP_DEBUG
18846  if( *upgdcons != NULL )
18847  {
18848  SCIPdebugPrintCons(scip, cons, NULL);
18849  SCIPdebugMsg(scip, " -> upgraded to constraint type <%s>\n", SCIPconshdlrGetName(SCIPconsGetHdlr(*upgdcons)));
18850  SCIPdebugPrintCons(scip, *upgdcons, NULL);
18851  }
18852 #endif
18853 
18854  return SCIP_OKAY; /*lint !e438*/
18855 }
18856 
18857 /** cleans up (multi-)aggregations and fixings from linear constraints */
18859  SCIP* scip, /**< SCIP data structure */
18860  SCIP_Bool onlychecked, /**< should only checked constraints be cleaned up? */
18861  SCIP_Bool* infeasible /**< pointer to return whether the problem was detected to be infeasible */
18862  )
18863 {
18864  SCIP_CONSHDLR* conshdlr;
18865  SCIP_CONS** conss;
18866  int nconss;
18867  int i;
18868 
18869  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
18870  if( conshdlr == NULL )
18871  return SCIP_OKAY;
18872 
18873  assert(infeasible != NULL);
18874  *infeasible = FALSE;
18876  nconss = onlychecked ? SCIPconshdlrGetNCheckConss(conshdlr) : SCIPconshdlrGetNActiveConss(conshdlr);
18877  conss = onlychecked ? SCIPconshdlrGetCheckConss(conshdlr) : SCIPconshdlrGetConss(conshdlr);
18878 
18879  for( i = 0; i < nconss; ++i )
18880  {
18881  SCIP_CALL( applyFixings(scip, conss[i], infeasible) );
18882 
18883  if( *infeasible )
18884  break;
18885  }
18886 
18887  return SCIP_OKAY;
18888 }
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
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:97
int SCIPconsGetPos(SCIP_CONS *cons)
Definition: cons.c:8087
#define SCIP_DECL_LINCONSUPGD(x)
Definition: cons_linear.h:111
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
SCIP_Real SCIPfeastol(SCIP *scip)
struct InferInfo INFERINFO
void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
Definition: cons.c:4197
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip_mem.h:86
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)
int SCIPconshdlrGetNCheckConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4602
int SCIPgetNContVars(SCIP *scip)
Definition: scip_prob.c:2166
enum SCIP_LinConstype SCIP_LINCONSTYPE
Definition: type_cons.h:81
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
SCIP_EXPORT SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:17159
SCIP_Real SCIPepsilon(SCIP *scip)
static SCIP_RETCODE tightenVarBounds(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool force)
Definition: cons_linear.c:6805
static void consdataCalcMinAbsval(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1438
SCIP_RETCODE SCIPhashtableSafeInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2519
SCIP_Bool SCIPconsIsLockedType(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition: cons.c:8470
SCIP_Bool SCIPisConflictAnalysisApplicable(SCIP *scip)
static SCIP_DECL_CONSDEACTIVE(consDeactiveLinear)
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip_general.c:687
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
Definition: scip_cons.c:586
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:862
static int inferInfoGetPos(INFERINFO inferinfo)
Definition: cons_linear.c:413
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE consCatchEvent(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
Definition: cons_linear.c:726
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:80
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2487
SCIP_EXPORT SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17172
static SCIP_RETCODE chgCoefPos(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Real newval)
Definition: cons_linear.c:4009
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:877
static SCIP_Real consdataGetFeasibility(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol)
Definition: cons_linear.c:3151
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
Definition: lp.c:17176
public methods for SCIP parameter handling
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
#define DEFAULT_MAXAGGRNORMSCALE
Definition: cons_linear.c:132
SCIP_EXPORT SCIP_Real SCIPvarGetAggrScalar(SCIP_VAR *var)
Definition: var.c:17413
#define DEFAULT_PRESOLPAIRWISE
Definition: cons_linear.c:120
#define SCIP_EVENTTYPE_VARFIXED
Definition: type_event.h:63
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:1989
SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
Definition: scip_var.c:221
SCIP_RETCODE SCIPsetConshdlrExitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITSOL((*consexitsol)))
Definition: scip_cons.c:453
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define CONSHDLR_NAME
Definition: cons_linear.c:90
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5177
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_Bool SCIPisUbBetter(SCIP *scip, SCIP_Real newub, SCIP_Real oldlb, SCIP_Real oldub)
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8316
#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:3172
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:1605
SCIP_EXPORT int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition: var.c:3250
public methods for memory management
#define DEFAULT_RANGEDROWFREQ
Definition: cons_linear.c:167
SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
Definition: scip_cons.c:308
static void consdataRecomputeMaxActivityDelta(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1543
#define MAXSCALEDCOEF
Definition: cons_linear.c:177
static SCIP_Bool checkEqualObjective(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real *scale, SCIP_Real *offset)
#define DEFAULT_CHECKRELMAXABS
Definition: cons_linear.c:129
static SCIP_RETCODE fixVariables(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars)
Definition: cons_linear.c:7840
#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:9500
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8276
SCIP_RETCODE SCIPmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
Definition: scip_cons.c:1951
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
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition: scip_var.c:4256
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:5416
#define SCIP_MAXSTRLEN
Definition: def.h:279
SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip_var.c:1477
public methods for conflict handler plugins and conflict analysis
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:123
static SCIP_RETCODE consDropAllEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linear.c:831
void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
Definition: misc.c:2548
SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETVARS((*consgetvars)))
Definition: scip_cons.c:816
static long bound
static void consdataUpdateActivitiesGlbUb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real oldub, SCIP_Real newub, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:2063
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1211
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1353
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5294
SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
Definition: scip_lp.c:2152
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
static SCIP_Real consdataGetMaxAbsval(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:2292
SCIP_Longint SCIPcalcGreComDiv(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:9022
static SCIP_RETCODE linconsupgradeCreate(SCIP *scip, SCIP_LINCONSUPGRADE **linconsupgrade, SCIP_DECL_LINCONSUPGD((*linconsupgd)), int priority)
Definition: cons_linear.c:516
SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
Definition: scip_cons.c:770
#define DEFAULT_MAXSEPACUTS
Definition: cons_linear.c:118
int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4582
int SCIPgetNLPBranchCands(SCIP *scip)
Definition: scip_branch.c:419
static void consdataRecomputeMinactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1306
SCIP_RETCODE SCIPinitConflictAnalysis(SCIP *scip, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
static SCIP_RETCODE normalizeCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible)
Definition: cons_linear.c:4240
#define SCIP_EVENTTYPE_TYPECHANGED
Definition: type_event.h:77
#define DEFAULT_DETECTPARTIALOBJECTIVE
Definition: cons_linear.c:161
SCIP_RETCODE SCIPsetConshdlrDelvars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELVARS((*consdelvars)))
Definition: scip_cons.c:747
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:5589
SCIP_EXPORT SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17197
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:315
int SCIPgetNConss(SCIP *scip)
Definition: scip_prob.c:3036
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:1986
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition: cons.c:8138
#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:2869
static void permSortConsdata(SCIP_CONSDATA *consdata, int *perm, int nvars)
Definition: cons_linear.c:3326
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip_message.c:216
#define DEFAULT_AGGREGATEVARIABLES
Definition: cons_linear.c:144
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:1368
#define FALSE
Definition: def.h:73
SCIP_Bool SCIPisSumRelLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
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)
static SCIP_DECL_HASHGETKEY(hashGetKeyLinearcons)
static SCIP_DECL_CONSEXITSOL(consExitsolLinear)
static void consdataInvalidateActivities(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1207
SCIP_Real SCIPgetLhsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_EXPORT SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17515
static SCIP_DECL_CONSCOPY(consCopyLinear)
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:2931
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_EXPORT SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17182
SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
static SCIP_Bool conshdlrdataHasUpgrade(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_DECL_LINCONSUPGD((*linconsupgd)), const char *conshdlrname)
Definition: cons_linear.c:597
#define TRUE
Definition: def.h:72
#define SCIPdebug(x)
Definition: pub_message.h:84
#define DEFAULT_MAXCARDBOUNDDIST
Definition: cons_linear.c:138
SCIP_CONS ** SCIPgetConss(SCIP *scip)
Definition: scip_prob.c:3082
SCIP_RETCODE SCIPdelCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:54
enum Proprule PROPRULE
#define DEFAULT_NMINCOMPARISONS
Definition: cons_linear.c:122
#define SCIPstatisticMessage
Definition: pub_message.h:114
static SCIP_DECL_CONSINITLP(consInitlpLinear)
#define SCIP_PRESOLTIMING_EXHAUSTIVE
Definition: type_timing.h:45
SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:3468
SCIP_RETCODE SCIPchgLhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
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:7602
static SCIP_Bool consdataIsResidualIntegral(SCIP *scip, SCIP_CONSDATA *consdata, int pos, SCIP_Real val)
enum SCIP_Varstatus SCIP_VARSTATUS
Definition: type_var.h:48
static SCIP_RETCODE preprocessConstraintPairs(SCIP *scip, SCIP_CONS **conss, int firstchange, int chkind, SCIP_Real maxaggrnormscale, SCIP_Bool *cutoff, int *ndelconss, int *nchgsides, int *nchgcoefs)
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:8246
SCIP_RETCODE SCIPaddConflictLb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
SCIP_Real SCIPgetRhsNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetLocalLowerbound(SCIP *scip)
Definition: scip_prob.c:3579
void SCIPupdateSolLPConsViolation(SCIP *scip, SCIP_SOL *sol, SCIP_Real absviol, SCIP_Real relviol)
Definition: scip_sol.c:277
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
Definition: scip_cons.c:563
#define SCIP_EVENTTYPE_GLBCHANGED
Definition: type_event.h:66
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static SCIP_DECL_CONSENFOPS(consEnfopsLinear)
SCIP_EXPORT SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17340
public methods for problem variables
static GRAPHNODE ** active
SCIP_Real SCIPadjustedVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real ub)
Definition: scip_var.c:4639
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
SCIP_RETCODE SCIPupdateLocalLowerbound(SCIP *scip, SCIP_Real newbound)
Definition: scip_prob.c:3690
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:95
SCIP_RETCODE SCIPhashtableRemove(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2617
#define SCIPdebugMessage
Definition: pub_message.h:87
#define DEFAULT_MINGAINPERNMINCOMP
Definition: cons_linear.c:123
SCIP_EXPORT SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17136
static SCIP_DECL_CONSEXITPRE(consExitpreLinear)
SCIP_RETCODE SCIPsetConsSeparated(SCIP *scip, SCIP_CONS *cons, SCIP_Bool separate)
Definition: scip_cons.c:1233
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:119
enum Proprule PROPRULE
Definition: cons_linear.c:363
SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
Definition: scip_cons.c:525
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:123
SCIP_RETCODE SCIPsetConshdlrInit(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINIT((*consinit)))
Definition: scip_cons.c:381
static INFERINFO getInferInfo(PROPRULE proprule, int pos)
Definition: cons_linear.c:422
SCIP_Bool SCIPinRepropagation(SCIP *scip)
Definition: scip_tree.c:136
static SCIP_RETCODE rangedRowPropagation(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *nchgbds, int *naddconss)
Definition: cons_linear.c:5820
SCIP_RETCODE SCIPsetConsEnforced(SCIP *scip, SCIP_CONS *cons, SCIP_Bool enforce)
Definition: scip_cons.c:1258
SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETNVARS((*consgetnvars)))
Definition: scip_cons.c:839
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:78
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
#define SCIPdebugPrintCons(x, y, z)
Definition: pub_message.h:93
static SCIP_RETCODE consDropEvent(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
Definition: cons_linear.c:765
public methods for SCIP variables
#define checkMaxActivityDelta(scip, consdata)
Definition: cons_linear.c:1538
SCIP_RETCODE SCIPsetConshdlrExitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITPRE((*consexitpre)))
Definition: scip_cons.c:501
#define SCIP_EVENTTYPE_BOUNDCHANGED
Definition: type_event.h:116
static SCIP_DECL_SORTINDCOMP(consdataCompVar)
Definition: cons_linear.c:3217
#define SCIPdebugMsgPrint
Definition: scip_message.h:70
#define SCIPdebugMsg
Definition: scip_message.h:69
static SCIP_Real consdataGetMinAbsval(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:2308
SCIP_Real SCIPgetRowSolFeasibility(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
Definition: scip_lp.c:2107
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
Definition: lp.c:17275
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
#define DEFAULT_SEPARATEALL
Definition: cons_linear.c:141
SCIP_VAR ** x
Definition: circlepacking.c:54
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4347
static SCIP_RETCODE tightenSides(SCIP *scip, SCIP_CONS *cons, int *nchgsides, SCIP_Bool *infeasible)
Definition: cons_linear.c:8944
#define DEFAULT_MAXSEPACUTSROOT
Definition: cons_linear.c:119
int SCIPgetNQuadVarTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE addConflictFixedVars(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *infervar, SCIP_BDCHGIDX *bdchgidx, int inferpos)
Definition: cons_linear.c:5086
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip_general.c:559
#define CONSHDLR_PRESOLTIMING
Definition: cons_linear.c:105
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
Definition: scip_cons.c:357
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition: scip_lp.c:74
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_RETCODE SCIPupdateConsFlags(SCIP *scip, SCIP_CONS *cons0, SCIP_CONS *cons1)
Definition: scip_cons.c:1461
#define CONSHDLR_PROP_TIMING
Definition: cons_linear.c:106
SCIP_EXPORT void SCIPsortDownRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
public methods for numerical tolerances
static SCIP_RETCODE rangedRowSimplify(SCIP *scip, SCIP_CONS *cons, int *nchgcoefs, int *nchgsides)
SCIP_EXPORT SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
Definition: var.c:17459
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
#define SCIP_EVENTTYPE_LBCHANGED
Definition: type_event.h:112
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2837
public methods for querying solving statistics
SCIP_Bool SCIPconsIsLocked(SCIP_CONS *cons)
Definition: cons.c:8416
static SCIP_DECL_CONSFREE(consFreeLinear)
#define CONSHDLR_SEPAFREQ
Definition: cons_linear.c:95
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:17387
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define MAXCONSPRESOLROUNDS
public methods for the branch-and-bound tree
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:697
static SCIP_DECL_EVENTEXEC(eventExecLinear)
SCIP_EXPORT SCIP_Bool SCIPvarIsInitial(SCIP_VAR *var)
Definition: var.c:17218
static void linconsupgradeFree(SCIP *scip, SCIP_LINCONSUPGRADE **linconsupgrade)
Definition: cons_linear.c:537
static SCIP_RETCODE analyzeConflict(SCIP *scip, SCIP_CONS *cons, SCIP_Bool reasonisrhs)
Definition: cons_linear.c:5295
SCIP_EXPORT SCIP_Bool SCIPvarIsRelaxationOnly(SCIP_VAR *var)
Definition: var.c:17304
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:7255
SCIP_Real SCIPgetFeasibilityLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
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:92
#define CONFLICTHDLR_NAME
Definition: cons_linear.c:111
public methods for managing constraints
Constraint handler for knapsack constraints of the form , x binary and .
SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
Definition: misc.c:10912
#define DEFAULT_DETECTCUTOFFBOUND
Definition: cons_linear.c:151
static SCIP_RETCODE updateCutoffbound(SCIP *scip, SCIP_CONS *cons, SCIP_Real primalbound)
static SCIP_DECL_CONSDELETE(consDeleteLinear)
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
#define CONFLICTHDLR_PRIORITY
Definition: cons_linear.c:113
SCIP_RETCODE SCIPsetConshdlrExit(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXIT((*consexit)))
Definition: scip_cons.c:405
static SCIP_RETCODE simplifyInequalities(SCIP *scip, SCIP_CONS *cons, int *nchgcoefs, int *nchgsides, SCIP_Bool *infeasible)
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:5347
SCIP_EXPORT const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17017
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:2489
enum SCIP_LockType SCIP_LOCKTYPE
Definition: type_var.h:87
SCIP_EXPORT SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17208
#define SCIPerrorMessage
Definition: pub_message.h:55
#define CONSHDLR_PROPFREQ
Definition: cons_linear.c:96
SCIP_EXPORT SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
Definition: var.c:17483
static SCIP_DECL_QUADCONSUPGD(upgradeConsQuadratic)
static SCIP_DECL_CONSENFOLP(consEnfolpLinear)
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition: scip_lp.c:1508
SCIP_Real SCIPgetDualfarkasLinear(SCIP *scip, SCIP_CONS *cons)
public methods for event handler plugins and event handlers
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
int SCIPgetNObjVars(SCIP *scip)
Definition: scip_prob.c:2214
SCIP_Bool SCIPisPresolveFinished(SCIP *scip)
Definition: scip_general.c:596
static SCIP_DECL_CONSSEPALP(consSepalpLinear)
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:1941
SCIP_Real SCIPgetHugeValue(SCIP *scip)
SCIP_Bool SCIPisUpdateUnreliable(SCIP *scip, SCIP_Real newvalue, SCIP_Real oldvalue)
int SCIPconshdlrGetPropFreq(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:5086
SCIP_RETCODE SCIPaddConflict(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons, SCIP_NODE *validnode, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
Definition: scip_prob.c:3222
SCIP_Bool SCIPisSumRelEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static void consdataCalcMaxAbsval(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1414
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:1436
static INLINE uint32_t SCIPrealHashCode(double x)
Definition: pub_misc.h:534
#define DEFAULT_MULTAGGRREMOVE
Definition: cons_linear.c:169
static SCIP_RETCODE chgRhs(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
Definition: cons_linear.c:3595
static SCIP_RETCODE conshdlrdataEnsureLinconsupgradesSize(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, int num)
Definition: cons_linear.c:456
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:2136
SCIP_CONS ** SCIPconshdlrGetCheckConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4559
static SCIP_RETCODE consdataSort(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:3402
static void consdataUpdateAddCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:2086
static int inferInfoGetProprule(INFERINFO inferinfo)
Definition: cons_linear.c:404
static SCIP_RETCODE consdataTightenCoefs(SCIP *scip, SCIP_CONS *cons, int *nchgcoefs, int *nchgsides)
Definition: cons_linear.c:9066
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
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:8509
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
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)
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip_probing.c:88
constraint handler for quadratic constraints
static SCIP_RETCODE addConflictReasonVars(SCIP *scip, SCIP_VAR **vars, int nvars, SCIP_VAR *var, SCIP_Real bound)
Definition: cons_linear.c:5151
#define NULL
Definition: lpi_spx1.cpp:155
SCIP_Bool SCIPdoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8559
static SCIP_RETCODE delCoefPos(SCIP *scip, SCIP_CONS *cons, int pos)
Definition: cons_linear.c:3888
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:5202
static int getInferInt(PROPRULE proprule, int pos)
Definition: cons_linear.c:441
#define SCIPhashSeven(a, b, c, d, e, f, g)
Definition: pub_misc.h:525
#define REALABS(x)
Definition: def.h:187
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:627
#define CONSHDLR_DELAYPROP
Definition: cons_linear.c:102
public methods for problem copies
SCIP_Bool SCIPisConsCompressionEnabled(SCIP *scip)
Definition: scip_copy.c:646
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition: cons.c:8107
#define SCIP_CALL(x)
Definition: def.h:370
#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:2588
SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
Definition: scip_cons.c:632
#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:5485
#define SCIPhashSignature64(a)
Definition: pub_misc.h:507
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:1021
SCIP_Real SCIPeventGetNewbound(SCIP_EVENT *event)
Definition: event.c:1233
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:2388
SCIP_RETCODE SCIPincludeQuadconsUpgrade(SCIP *scip, SCIP_DECL_QUADCONSUPGD((*quadconsupgd)), int priority, SCIP_Bool active, const char *conshdlrname)
SCIP_Real SCIPcutoffbounddelta(SCIP *scip)
static SCIP_Bool isFiniteNonnegativeIntegral(SCIP *scip, SCIP_Real x)
Definition: grphload.c:88
static SCIP_RETCODE scaleCons(SCIP *scip, SCIP_CONS *cons, SCIP_Real scalar)
Definition: cons_linear.c:4088
SCIP_VAR ** SCIPgetLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
static SCIP_DECL_CONSINIT(consInitLinear)
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
#define SCIPdebugGetSolVal(scip, var, val)
Definition: debug.h:275
SCIP_Bool SCIPisSumRelGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
struct SCIP_ConsData SCIP_CONSDATA
Definition: type_cons.h:56
SCIP_EXPORT SCIP_Real SCIPvarGetAggrConstant(SCIP_VAR *var)
Definition: var.c:17424
static SCIP_DECL_CONSTRANS(consTransLinear)
SCIP_EXPORT SCIP_Real SCIPvarGetNegationConstant(SCIP_VAR *var)
Definition: var.c:17504
#define SCIP_EVENTTYPE_BOUNDTIGHTENED
Definition: type_event.h:114
static SCIP_DECL_HASHKEYVAL(hashKeyValLinearcons)
#define SCIP_EVENTTYPE_UBCHANGED
Definition: type_event.h:113
SCIP_VARTYPE SCIPeventGetOldtype(SCIP_EVENT *event)
Definition: event.c:1257
public methods for constraint handler plugins and constraints
SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
Definition: scip_param.c:260
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:7692
SCIP_RETCODE SCIPresetConsAge(SCIP *scip, SCIP_CONS *cons)
Definition: scip_cons.c:1749
static void consdataUpdateChgCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real oldval, SCIP_Real newval, SCIP_Bool checkreliability)
Definition: cons_linear.c:2193
#define DEFAULT_DETECTLOWERBOUND
Definition: cons_linear.c:156
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:8346
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE consdataPrint(SCIP *scip, SCIP_CONSDATA *consdata, FILE *file)
Definition: cons_linear.c:1096
int SCIPgetNLinearVarsNonlinear(SCIP *scip, SCIP_CONS *cons)
#define QUADCONSUPGD_PRIORITY
Definition: cons_linear.c:188
static SCIP_RETCODE retrieveParallelConstraints(SCIP_HASHTABLE *hashtable, SCIP_CONS **querycons, SCIP_CONS **parallelconss, int *nparallelconss)
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:111
SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
Definition: lp.c:17189
SCIP_RETCODE SCIPaddConflictUb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
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)
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:130
SCIP_Real SCIPinfinity(SCIP *scip)
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
public data structures and miscellaneous methods
static SCIP_RETCODE chgLhs(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
Definition: cons_linear.c:3469
SCIP_EXPORT SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:17493
SCIP_Real SCIPeventGetOldbound(SCIP_EVENT *event)
Definition: event.c:1209
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4432
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:2286
int SCIPconsGetNLocksNeg(SCIP_CONS *cons)
Definition: cons.c:8436
int SCIPgetDepth(SCIP *scip)
Definition: scip_tree.c:638
SCIP_EXPORT void SCIPsortRealInt(SCIP_Real *realarray, int *intarray, int len)
#define SCIP_Bool
Definition: def.h:70
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_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:5406
SCIP_EXPORT SCIP_Real SCIPvarGetMultaggrConstant(SCIP_VAR *var)
Definition: var.c:17471
#define CONSHDLR_NEEDSCONS
Definition: cons_linear.c:103
#define CONSHDLR_EAGERFREQ
Definition: cons_linear.c:97
SCIP_Bool SCIPisSumGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPsetConsInitial(SCIP *scip, SCIP_CONS *cons, SCIP_Bool initial)
Definition: scip_cons.c:1208
void SCIPlinConsStatsReset(SCIP_LINCONSSTATS *linconsstats)
Definition: cons.c:7939
static SCIP_RETCODE performVarDeletions(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss)
Definition: cons_linear.c:4181
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
Definition: scip_cons.c:332
static const char * paramname[]
Definition: lpi_msk.c:4974
static void consdataRecomputeGlbMaxactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1387
SCIP_RETCODE SCIPaddObjoffset(SCIP *scip, SCIP_Real addval)
Definition: scip_prob.c:1266
SCIP_EXPORT SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17677
static SCIP_Real consdataGetActivity(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol)
Definition: cons_linear.c:3083
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip_cons.c:2473
#define MAXTIGHTENROUNDS
Definition: cons_linear.c:7073
constraint handler for nonlinear constraints
SCIP_EXPORT SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
Definition: var.c:17779
static void conshdlrdataFree(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata)
Definition: cons_linear.c:575
#define DEFAULT_SINGLEVARSTUFFING
Definition: cons_linear.c:148
static SCIP_DECL_CONSPROP(consPropLinear)
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_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
Definition: scip_message.c:91
SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4187
#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:4573
SCIP_Bool SCIPisLbBetter(SCIP *scip, SCIP_Real newlb, SCIP_Real oldlb, SCIP_Real oldub)
static SCIP_RETCODE addRelaxation(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff)
Definition: cons_linear.c:7539
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
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_EXPORT SCIP_Bool SCIPvarIsOriginal(SCIP_VAR *var)
Definition: var.c:17146
static SCIP_DECL_CONSDELVARS(consDelvarsLinear)
methods for debugging
SCIP_RETCODE SCIPsetConsPropagated(SCIP *scip, SCIP_CONS *cons, SCIP_Bool propagate)
Definition: scip_cons.c:1308
public methods for LP management
int SCIPconsGetNLocksPos(SCIP_CONS *cons)
Definition: cons.c:8426
void SCIPsort(int *perm, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
Definition: misc.c:5440
static SCIP_RETCODE presolStuffing(SCIP *scip, SCIP_CONS *cons, SCIP_Bool singletonstuffing, SCIP_Bool singlevarstuffing, SCIP_Bool *cutoff, int *nfixedvars, int *nchgbds)
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:8386
public methods for cuts and aggregation rows
SCIP_RETCODE SCIPupdateCutoffbound(SCIP *scip, SCIP_Real cutoffbound)
static void consdataUpdateActivitiesGlbLb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real oldlb, SCIP_Real newlb, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:2040
static SCIP_Real consdataComputePseudoActivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1253
static void consdataCalcActivities(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:2326
#define NONLINCONSUPGD_PRIORITY
Definition: cons_linear.c:189
static int getVarWeight(SCIP_VAR *var)
int SCIPconshdlrGetNActiveConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4616
SCIP_Real SCIPgetActivityLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
SCIP_Real SCIPgetLhsNonlinear(SCIP *scip, SCIP_CONS *cons)
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 BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:126
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8256
const char * SCIPconflicthdlrGetName(SCIP_CONFLICTHDLR *conflicthdlr)
Definition: conflict.c:763
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip_var.c:8250
int SCIPgetNSepaRounds(SCIP *scip)
#define MAXDNOM
Definition: cons_linear.c:176
SCIP_EXPORT SCIP_Bool SCIPvarIsDeleted(SCIP_VAR *var)
Definition: var.c:17238
#define SCIP_EVENTTYPE_UBTIGHTENED
Definition: type_event.h:70
Constraint handler for linear constraints in their most general form, .
int SCIPconsGetNUpgradeLocks(SCIP_CONS *cons)
Definition: cons.c:8528
SCIP_RETCODE SCIPanalyzeConflictCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
SCIP_Real * SCIPgetLinearCoefsNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1666
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#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 SCIPchgCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:8336
Proprule
SCIP_EXPORT SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17723
#define DEFAULT_TIGHTENBOUNDSFREQ
Definition: cons_linear.c:115
#define SCIP_MAXTREEDEPTH
Definition: def.h:306
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
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
SCIP_RETCODE SCIPunmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
Definition: scip_cons.c:1979
public methods for the LP relaxation, rows and columns
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2125
#define DEFAULT_SIMPLIFYINEQUALITIES
Definition: cons_linear.c:145
static SCIP_RETCODE createRow(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:7515
#define MINVALRECOMP
Definition: cons_linear.c:185
#define CONSHDLR_SEPAPRIORITY
Definition: cons_linear.c:92
SCIP_EXPORT int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition: var.c:3193
#define SCIP_REAL_MAX
Definition: def.h:164
static void consdataGetReliableResidualActivity(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *cancelvar, SCIP_Real *resactivity, SCIP_Bool isminresact, SCIP_Bool useglobalbounds)
Definition: cons_linear.c:2637
static void consdataRecomputeMaxactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1333
static SCIP_Bool canTightenBounds(SCIP_CONS *cons)
Definition: cons_linear.c:5319
static SCIP_DECL_CONSENFORELAX(consEnforelaxLinear)
#define MAXSCALEDCOEFINTEGER
Definition: cons_linear.c:178
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
SCIP_EXPORT SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17733
methods for sorting joint arrays of various types
static SCIP_DECL_CONSCHECK(consCheckLinear)
#define EPSGT(x, y, eps)
Definition: def.h:191
static SCIP_RETCODE conshdlrdataCreate(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linear.c:551
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:3197
SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
Definition: scip_cut.c:221
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:5762
static SCIP_RETCODE lockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
Definition: cons_linear.c:659
general public methods
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:5475
SCIP_EXPORT SCIP_VAR * SCIPbdchginfoGetVar(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18269
static SCIP_DECL_CONSGETVARS(consGetVarsLinear)
SCIP_Bool SCIPisFeasGT(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:2718
static SCIP_RETCODE fullDualPresolve(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool *cutoff, int *nchgbds)
SCIP_RETCODE SCIPincludeNonlinconsUpgrade(SCIP *scip, SCIP_DECL_NONLINCONSUPGD((*nonlinconsupgd)), SCIP_DECL_EXPRGRAPHNODEREFORM((*nodereform)), int priority, SCIP_Bool active, const char *conshdlrname)
public methods for solutions
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:4507
static const SCIP_Real scalars[]
Definition: lp.c:5731
SCIP_RETCODE SCIPchgRowRhs(SCIP *scip, SCIP_ROW *row, SCIP_Real rhs)
Definition: scip_lp.c:1553
#define CONTWEIGHT
SCIP_RETCODE SCIPchgRowLhs(SCIP *scip, SCIP_ROW *row, SCIP_Real lhs)
Definition: scip_lp.c:1529
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:8266
static SCIP_DECL_CONSLOCK(consLockLinear)
static void consdataCheckNonbinvar(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1467
SCIP_Bool SCIPisHugeValue(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE consCatchAllEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linear.c:799
SCIP_Real SCIPgetLowerbound(SCIP *scip)
static SCIP_DECL_CONSSEPASOL(consSepasolLinear)
SCIP_ROW * SCIPgetRowLinear(SCIP *scip, SCIP_CONS *cons)
public methods for conflict analysis handlers
int SCIPgetNLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
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:7975
SCIP_EXPORT SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17667
public methods for the probing mode
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static SCIP_DECL_CONSPRINT(consPrintLinear)
SCIP_RETCODE SCIPsetConshdlrDeactive(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDEACTIVE((*consdeactive)))
Definition: scip_cons.c:678
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
Definition: scip_lp.c:1641
SCIP_EXPORT int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
Definition: var.c:17435
static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinear)
SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4539
public methods for message output
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:6895
SCIP_VAR * a
Definition: circlepacking.c:57
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10604
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition: message.c:609
void SCIPhashtablePrintStatistics(SCIP_HASHTABLE *hashtable, SCIP_MESSAGEHDLR *messagehdlr)
Definition: misc.c:2744
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_RETCODE convertBinaryEquality(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *naggrvars, int *ndelconss)
Definition: cons_linear.c:9556
static SCIP_DECL_HASHKEYEQ(hashKeyEqLinearcons)
#define CONFLICTHDLR_DESC
Definition: cons_linear.c:112
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8077
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1245
SCIP_Real SCIPselectSimpleValue(SCIP_Real lb, SCIP_Real ub, SCIP_Longint maxdnom)
Definition: misc.c:9719
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition: cons.c:8206
#define DEFAULT_MAXDUALMULTAGGRQUOT
Definition: cons_linear.c:173
#define SCIP_Real
Definition: def.h:163
static SCIP_RETCODE tightenBounds(SCIP *scip, SCIP_CONS *cons, SCIP_Real maxeasyactivitydelta, SCIP_Bool sortvars, SCIP_Bool *cutoff, int *nchgbds)
Definition: cons_linear.c:7077
#define SCIP_EVENTTYPE_VARUNLOCKED
Definition: type_event.h:64
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
static void getNewSidesAfterAggregation(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *slackvar, SCIP_Real slackcoef, SCIP_Real *newlhs, SCIP_Real *newrhs)
Definition: cons_linear.c:9614
#define DEFAULT_SINGLETONSTUFFING
Definition: cons_linear.c:147
#define EVENTHDLR_NAME
Definition: cons_linear.c:108
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8097
#define CONSHDLR_ENFOPRIORITY
Definition: cons_linear.c:93
SCIP_Real SCIPgetDualsolLinear(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE convertEquality(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_Bool *cutoff, int *nfixedvars, int *naggrvars, int *ndelconss)
SCIP_Real SCIPgetRhsQuadratic(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE applyFixings(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible)
Definition: cons_linear.c:4644
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
public methods for message handling
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_VARTYPE SCIPeventGetNewtype(SCIP_EVENT *event)
Definition: event.c:1274
static SCIP_RETCODE consPrintConsSol(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, FILE *file)
Definition: cons_linear.c:1135
static unsigned int getParallelConsKey(SCIP_CONS *cons)
SCIP_EXPORT SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12545
#define SCIP_INVALID
Definition: def.h:183
SCIP_EXPRGRAPHNODE * SCIPgetExprgraphNodeNonlinear(SCIP *scip, SCIP_CONS *cons)
#define DEFAULT_RANGEDROWPROPAGATION
Definition: cons_linear.c:164
static SCIP_RETCODE addCoef(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
Definition: cons_linear.c:3723
static SCIP_DECL_CONFLICTEXEC(conflictExecLinear)
#define CONSHDLR_DESC
Definition: cons_linear.c:91
#define SCIP_Longint
Definition: def.h:148
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition: cons.c:8356
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4167
static SCIP_RETCODE consdataEnsureVarsSize(SCIP *scip, SCIP_CONSDATA *consdata, int num)
Definition: cons_linear.c:481
#define SCIPdebugAddSolVal(scip, var, val)
Definition: debug.h:274
SCIP_RETCODE SCIPwriteVarsLinearsum(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Bool type)
Definition: scip_var.c:334
int SCIPgetNBinVars(SCIP *scip)
Definition: scip_prob.c:2031
SCIP_RETCODE SCIPgetProbvarSum(SCIP *scip, SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: scip_var.c:1791
static SCIP_DECL_NONLINCONSUPGD(upgradeConsNonlinear)
SCIP_RETCODE SCIPcatchVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: scip_event.c:345
#define MAX_CLIQUE_NONZEROS_PER_CONS
Definition: cons_linear.c:7908
static void consdataRecomputeGlbMinactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1360
SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
Definition: event.c:1044
SCIP_Bool SCIPconsIsOriginal(SCIP_CONS *cons)
Definition: cons.c:8376
SCIP_EXPORT int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17360
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2764
SCIP_RETCODE SCIPcleanupConssLinear(SCIP *scip, SCIP_Bool onlychecked, SCIP_Bool *infeasible)
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:60
SCIP_Real * SCIPgetCoefsLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE convertLongEquality(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_CONS *cons, SCIP_Bool *cutoff, int *naggrvars, int *ndelconss)
Definition: cons_linear.c:9668
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition: type_cons.h:55
SCIP_RETCODE SCIPupgradeConsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **upgdcons)
SCIP_RETCODE SCIPincConsAge(SCIP *scip, SCIP_CONS *cons)
Definition: scip_cons.c:1721
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip_mem.h:98
static int inferInfoToInt(INFERINFO inferinfo)
Definition: cons_linear.c:395
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
static SCIP_Bool isRangedRow(SCIP *scip, SCIP_Real lhs, SCIP_Real rhs)
void SCIPlinConsStatsIncTypeCount(SCIP_LINCONSSTATS *linconsstats, SCIP_LINCONSTYPE linconstype, int increment)
Definition: cons.c:7971
#define MAXVALRECOMP
Definition: cons_linear.c:184
static SCIP_RETCODE unlockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
Definition: cons_linear.c:692
SCIP_RETCODE SCIPaddConsLocal(SCIP *scip, SCIP_CONS *cons, SCIP_NODE *validnode)
Definition: scip_prob.c:3387
static SCIP_DECL_CONSPRESOL(consPresolLinear)
SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
Definition: scip_var.c:8590
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:122
SCIP_Bool SCIPconsIsMarkedPropagate(SCIP_CONS *cons)
Definition: cons.c:8286
SCIP_RETCODE SCIPaddVarsToRow(SCIP *scip, SCIP_ROW *row, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip_lp.c:1667
SCIP_EXPORT SCIP_VAR * SCIPvarGetAggrVar(SCIP_VAR *var)
Definition: var.c:17402
#define DEFAULT_MAXEASYACTIVITYDELTA
Definition: cons_linear.c:135
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:199
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:429
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:6754
#define DEFAULT_EXTRACTCLIQUES
Definition: cons_linear.c:174
SCIP_RETCODE SCIPchgRhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
#define SCIP_EVENTTYPE_GUBCHANGED
Definition: type_event.h:67
static SCIP_RETCODE enforceConstraint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss, int nusefulconss, SCIP_SOL *sol, SCIP_RESULT *result)
SCIP_RETCODE SCIPflattenVarAggregationGraph(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1690
#define SCIP_CALL_ABORT(x)
Definition: def.h:349
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1110
static SCIP_DECL_CONSGETNVARS(consGetNVarsLinear)
SCIP_RETCODE SCIPincludeLinconsUpgrade(SCIP *scip, SCIP_DECL_LINCONSUPGD((*linconsupgd)), int priority, const char *conshdlrname)
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:8375
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8150
static SCIP_DECL_CONSEXIT(consExitLinear)
#define DEFAULT_RANGEDROWMAXDEPTH
Definition: cons_linear.c:166
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:356
SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
Definition: scip_cons.c:793
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_EXPORT SCIP_Bool SCIPvarIsRemovable(SCIP_VAR *var)
Definition: var.c:17228
SCIP_Longint SCIPcalcSmaComMul(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:9274
SCIP_Bool SCIPdoNotAggr(SCIP *scip)
Definition: scip_var.c:8539
#define SCIPABORT()
Definition: def.h:342
public methods for global and local (sub)problems
SCIP_Real SCIPadjustedVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real lb)
Definition: scip_var.c:4607
SCIP_Bool SCIPparseReal(SCIP *scip, const char *str, SCIP_Real *value, char **endptr)
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
static INFERINFO intToInferInfo(int i)
Definition: cons_linear.c:382
SCIP_VAR ** SCIPgetLinearVarsNonlinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:8296
#define INTWEIGHT
SCIP_RETCODE SCIPconvertCutsToConss(SCIP *scip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, int *ncutsadded)
Definition: scip_copy.c:2011
SCIP_RETCODE SCIPincludeConshdlrLinear(SCIP *scip)
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:4904
SCIP_EXPORT SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
Definition: var.c:17447
SCIP_EXPORT SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18259
SCIP_Longint SCIPgetNConflictConssApplied(SCIP *scip)
#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:1990
SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
Definition: scip_cons.c:609
#define DEFAULT_MAXMULTAGGRQUOT
Definition: cons_linear.c:172
SCIP_Bool SCIPisScalingIntegral(SCIP *scip, SCIP_Real val, SCIP_Real scalar)
SCIP_RETCODE SCIPclassifyConstraintTypesLinear(SCIP *scip, SCIP_LINCONSSTATS *linconsstats)
SCIP_EXPORT int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:17350
#define DEFAULT_PRESOLUSEHASHING
Definition: cons_linear.c:121
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8326
SCIP_Bool SCIPisFeasPositive(SCIP *scip, SCIP_Real val)
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:2015
static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata)
Definition: cons_linear.c:1061
SCIP_EXPORT int SCIPvarCompare(SCIP_VAR *var1, SCIP_VAR *var2)
Definition: var.c:11713
uint64_t SCIP_EVENTTYPE
Definition: type_event.h:142
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:115
SCIP_Real SCIPgetRowSolActivity(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
Definition: scip_lp.c:2084
int SCIPgetNRuns(SCIP *scip)
#define SCIP_EVENTTYPE_BOUNDRELAXED
Definition: type_event.h:115
memory allocation routines
#define DEFAULT_RANGEDROWARTCONS
Definition: cons_linear.c:165