Scippy

SCIP

Solving Constraint Integer Programs

cons_linear.c
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the program and library */
4 /* SCIP --- Solving Constraint Integer Programs */
5 /* */
6 /* Copyright 2002-2022 Zuse Institute Berlin */
7 /* */
8 /* Licensed under the Apache License, Version 2.0 (the "License"); */
9 /* you may not use this file except in compliance with the License. */
10 /* You may obtain a copy of the License at */
11 /* */
12 /* http://www.apache.org/licenses/LICENSE-2.0 */
13 /* */
14 /* Unless required by applicable law or agreed to in writing, software */
15 /* distributed under the License is distributed on an "AS IS" BASIS, */
16 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17 /* See the License for the specific language governing permissions and */
18 /* limitations under the License. */
19 /* */
20 /* You should have received a copy of the Apache-2.0 license */
21 /* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22 /* */
23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24 
25 /**@file cons_linear.c
26  * @ingroup DEFPLUGINS_CONS
27  * @brief Constraint handler for linear constraints in their most general form, \f$lhs <= a^T x <= rhs\f$.
28  * @author Tobias Achterberg
29  * @author Timo Berthold
30  * @author Marc Pfetsch
31  * @author Kati Wolter
32  * @author Michael Winkler
33  * @author Gerald Gamrath
34  * @author Domenico Salvagnin
35  *
36  * Linear constraints are separated with a high priority, because they are easy
37  * to separate. Instead of using the global cut pool, the same effect can be
38  * implemented by adding linear constraints to the root node, such that they are
39  * separated each time, the linear constraints are separated. A constraint
40  * handler, which generates linear constraints in this way should have a lower
41  * separation priority than the linear constraint handler, and it should have a
42  * separation frequency that is a multiple of the frequency of the linear
43  * constraint handler. In this way, it can be avoided to separate the same cut
44  * twice, because if a separation run of the handler is always preceded by a
45  * separation of the linear constraints, the priorily added constraints are
46  * always satisfied.
47  *
48  * Linear constraints are enforced and checked with a very low priority. Checking
49  * of (many) linear constraints is much more involved than checking the solution
50  * values for integrality. Because we are separating the linear constraints quite
51  * often, it is only necessary to enforce them for integral solutions. A constraint
52  * handler which generates pool cuts in its enforcing method should have an
53  * enforcing priority smaller than that of the linear constraint handler to avoid
54  * regenerating constraints which already exist.
55  */
56 
57 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
58 
59 #include "blockmemshell/memory.h"
60 #include "scip/cons_nonlinear.h"
61 #include "scip/cons_knapsack.h"
62 #include "scip/cons_linear.h"
63 #include "scip/debug.h"
64 #include "scip/pub_conflict.h"
65 #include "scip/pub_cons.h"
66 #include "scip/pub_event.h"
67 #include "scip/pub_expr.h"
68 #include "scip/pub_lp.h"
69 #include "scip/pub_message.h"
70 #include "scip/pub_misc.h"
71 #include "scip/pub_misc_sort.h"
72 #include "scip/pub_var.h"
73 #include "scip/scip_branch.h"
74 #include "scip/scip_conflict.h"
75 #include "scip/scip_cons.h"
76 #include "scip/scip_copy.h"
77 #include "scip/scip_cut.h"
78 #include "scip/scip_event.h"
79 #include "scip/scip_general.h"
80 #include "scip/scip_lp.h"
81 #include "scip/scip_mem.h"
82 #include "scip/scip_message.h"
83 #include "scip/scip_numerics.h"
84 #include "scip/scip_param.h"
85 #include "scip/scip_prob.h"
86 #include "scip/scip_probing.h"
87 #include "scip/scip_sol.h"
88 #include "scip/scip_solvingstats.h"
89 #include "scip/scip_tree.h"
90 #include "scip/scip_var.h"
91 #include <ctype.h>
92 #include <string.h>
93 #if defined(_WIN32) || defined(_WIN64)
94 #else
95 #include <strings.h> /*lint --e{766}*/
96 #endif
97 
98 
99 #define CONSHDLR_NAME "linear"
100 #define CONSHDLR_DESC "linear constraints of the form lhs <= a^T x <= rhs"
101 #define CONSHDLR_SEPAPRIORITY +100000 /**< priority of the constraint handler for separation */
102 #define CONSHDLR_ENFOPRIORITY -1000000 /**< priority of the constraint handler for constraint enforcing */
103 #define CONSHDLR_CHECKPRIORITY -1000000 /**< priority of the constraint handler for checking feasibility */
104 #define CONSHDLR_SEPAFREQ 0 /**< frequency for separating cuts; zero means to separate only in the root node */
105 #define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
106 #define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
107  * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
108 #define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
109 #define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
110 #define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
111 #define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
113 #define CONSHDLR_PRESOLTIMING (SCIP_PRESOLTIMING_FAST | SCIP_PRESOLTIMING_EXHAUSTIVE) /**< presolving timing of the constraint handler (fast, medium, or exhaustive) */
114 #define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP
116 #define EVENTHDLR_NAME "linear"
117 #define EVENTHDLR_DESC "bound change event handler for linear constraints"
119 #define CONFLICTHDLR_NAME "linear"
120 #define CONFLICTHDLR_DESC "conflict handler creating linear constraints"
121 #define CONFLICTHDLR_PRIORITY -1000000
123 #define DEFAULT_TIGHTENBOUNDSFREQ 1 /**< multiplier on propagation frequency, how often the bounds are tightened */
124 #define DEFAULT_MAXROUNDS 5 /**< maximal number of separation rounds per node (-1: unlimited) */
125 #define DEFAULT_MAXROUNDSROOT -1 /**< maximal number of separation rounds in the root node (-1: unlimited) */
126 #define DEFAULT_MAXSEPACUTS 50 /**< maximal number of cuts separated per separation round */
127 #define DEFAULT_MAXSEPACUTSROOT 200 /**< maximal number of cuts separated per separation round in root node */
128 #define DEFAULT_PRESOLPAIRWISE TRUE /**< should pairwise constraint comparison be performed in presolving? */
129 #define DEFAULT_PRESOLUSEHASHING TRUE /**< should hash table be used for detecting redundant constraints in advance */
130 #define DEFAULT_NMINCOMPARISONS 200000 /**< number for minimal pairwise presolving comparisons */
131 #define DEFAULT_MINGAINPERNMINCOMP 1e-06 /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise
132  * comparison round */
133 #define DEFAULT_SORTVARS TRUE /**< should variables be sorted after presolve w.r.t their coefficient absolute for faster
134  * propagation? */
135 #define DEFAULT_CHECKRELMAXABS FALSE /**< should the violation for a constraint with side 0.0 be checked relative
136  * to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
137 #define DEFAULT_MAXAGGRNORMSCALE 0.0 /**< maximal allowed relative gain in maximum norm for constraint aggregation
138  * (0.0: disable constraint aggregation) */
139 #define DEFAULT_MAXEASYACTIVITYDELTA 1e6 /**< maximum activity delta to run easy propagation on linear constraint
140  * (faster, but numerically less stable) */
141 #define DEFAULT_MAXCARDBOUNDDIST 0.0 /**< maximal relative distance from current node's dual bound to primal bound compared
142  * to best node's dual bound for separating knapsack cardinality cuts */
143 #define DEFAULT_SEPARATEALL FALSE /**< should all constraints be subject to cardinality cut generation instead of only
144  * the ones with non-zero dual value? */
145 #define DEFAULT_AGGREGATEVARIABLES TRUE /**< should presolving search for redundant variables in equations */
146 #define DEFAULT_SIMPLIFYINEQUALITIES TRUE /**< should presolving try to simplify inequalities */
147 #define DEFAULT_DUALPRESOLVING TRUE /**< should dual presolving steps be performed? */
148 #define DEFAULT_SINGLETONSTUFFING TRUE /**< should stuffing of singleton continuous variables be performed? */
149 #define DEFAULT_SINGLEVARSTUFFING FALSE /**< should single variable stuffing be performed, which tries to fulfill
150  * constraints using the cheapest variable? */
151 #define DEFAULT_DETECTCUTOFFBOUND TRUE /**< should presolving try to detect constraints parallel to the objective
152  * function defining an upper bound and prevent these constraints from
153  * entering the LP */
154 #define DEFAULT_DETECTLOWERBOUND TRUE /**< should presolving try to detect constraints parallel to the objective
155  * function defining a lower bound and prevent these constraints from
156  * entering the LP */
157 #define DEFAULT_DETECTPARTIALOBJECTIVE TRUE/**< should presolving try to detect subsets of constraints parallel to the
158  * objective function */
159 #define DEFAULT_RANGEDROWPROPAGATION TRUE /**< should we perform ranged row propagation */
160 #define DEFAULT_RANGEDROWARTCONS TRUE /**< should presolving and propagation extract sub-constraints from ranged rows and equations? */
161 #define DEFAULT_RANGEDROWMAXDEPTH INT_MAX /**< maximum depth to apply ranged row propagation */
162 #define DEFAULT_RANGEDROWFREQ 1 /**< frequency for applying ranged row propagation */
163 
164 #define DEFAULT_MULTAGGRREMOVE FALSE /**< should multi-aggregations only be performed if the constraint can be
165  * removed afterwards? */
166 #define DEFAULT_MAXMULTAGGRQUOT 1e+03 /**< maximum coefficient dynamism (ie. maxabsval / minabsval) for multiaggregation */
167 #define DEFAULT_MAXDUALMULTAGGRQUOT 1e+20 /**< maximum coefficient dynamism (ie. maxabsval / minabsval) for multiaggregation */
168 #define DEFAULT_EXTRACTCLIQUES TRUE /**< should cliques be extracted? */
169 
170 #define MAXDNOM 10000LL /**< maximal denominator for simple rational fixed values */
171 #define MAXSCALEDCOEF 0 /**< maximal coefficient value after scaling */
172 #define MAXSCALEDCOEFINTEGER 0 /**< maximal coefficient value after scaling if all variables are of integral
173  * type
174  */
175 #define MAXACTVAL 1e+09 /**< maximal absolute value of full and partial activities such that
176  * redundancy-based simplifications are allowed to be applied
177  */
179 #define MAXVALRECOMP 1e+06 /**< maximal abolsute value we trust without recomputing the activity */
180 #define MINVALRECOMP 1e-05 /**< minimal abolsute value we trust without recomputing the activity */
183 #define NONLINCONSUPGD_PRIORITY 1000000 /**< priority of the constraint handler for upgrading of expressions constraints */
184 
185 /* @todo add multi-aggregation of variables that are in exactly two equations (, if not numerically an issue),
186  * maybe in fullDualPresolve(), see convertLongEquality()
187  */
188 
189 
190 /** constraint data for linear constraints */
191 struct SCIP_ConsData
192 {
193  SCIP_Real lhs; /**< left hand side of row (for ranged rows) */
194  SCIP_Real rhs; /**< right hand side of row */
195  SCIP_Real maxabsval; /**< maximum absolute value of all coefficients */
196  SCIP_Real minabsval; /**< minimal absolute value of all coefficients */
197  SCIP_Real minactivity; /**< minimal value w.r.t. the variable's local bounds for the constraint's
198  * activity, ignoring the coefficients contributing with infinite value */
199  SCIP_Real maxactivity; /**< maximal value w.r.t. the variable's local bounds for the constraint's
200  * activity, ignoring the coefficients contributing with infinite value */
201  SCIP_Real lastminactivity; /**< last minimal activity which was computed by complete summation
202  * over all contributing values */
203  SCIP_Real lastmaxactivity; /**< last maximal activity which was computed by complete summation
204  * over all contributing values */
205  SCIP_Real glbminactivity; /**< minimal value w.r.t. the variable's global bounds for the constraint's
206  * activity, ignoring the coefficients contributing with infinite value */
207  SCIP_Real glbmaxactivity; /**< maximal value w.r.t. the variable's global bounds for the constraint's
208  * activity, ignoring the coefficients contributing with infinite value */
209  SCIP_Real lastglbminactivity; /**< last global minimal activity which was computed by complete summation
210  * over all contributing values */
211  SCIP_Real lastglbmaxactivity; /**< last global maximal activity which was computed by complete summation
212  * over all contributing values */
213  SCIP_Real maxactdelta; /**< maximal activity contribution of a single variable, or SCIP_INVALID if invalid */
214  SCIP_VAR* maxactdeltavar; /**< variable with maximal activity contribution, or NULL if invalid */
215  uint64_t possignature; /**< bit signature of coefficients that may take a positive value */
216  uint64_t negsignature; /**< bit signature of coefficients that may take a negative value */
217  SCIP_ROW* row; /**< LP row, if constraint is already stored in LP row format */
218  SCIP_NLROW* nlrow; /**< NLP row, if constraint has been added to NLP relaxation */
219  SCIP_VAR** vars; /**< variables of constraint entries */
220  SCIP_Real* vals; /**< coefficients of constraint entries */
221  SCIP_EVENTDATA** eventdata; /**< event data for bound change events of the variables */
222  int minactivityneginf; /**< number of coefficients contributing with neg. infinite value to minactivity */
223  int minactivityposinf; /**< number of coefficients contributing with pos. infinite value to minactivity */
224  int maxactivityneginf; /**< number of coefficients contributing with neg. infinite value to maxactivity */
225  int maxactivityposinf; /**< number of coefficients contributing with pos. infinite value to maxactivity */
226  int minactivityneghuge; /**< number of coefficients contributing with huge neg. value to minactivity */
227  int minactivityposhuge; /**< number of coefficients contributing with huge pos. value to minactivity */
228  int maxactivityneghuge; /**< number of coefficients contributing with huge neg. value to maxactivity */
229  int maxactivityposhuge; /**< number of coefficients contributing with huge pos. value to maxactivity */
230  int glbminactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbminactivity */
231  int glbminactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbminactivity */
232  int glbmaxactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbmaxactivity */
233  int glbmaxactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbmaxactivity */
234  int glbminactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbminactivity */
235  int glbminactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbminactivity */
236  int glbmaxactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbmaxactivity */
237  int glbmaxactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbmaxactivity */
238  int varssize; /**< size of the vars- and vals-arrays */
239  int nvars; /**< number of nonzeros in constraint */
240  int nbinvars; /**< the number of binary variables in the constraint, only valid after
241  * sorting in stage >= SCIP_STAGE_INITSOLVE
242  */
243  unsigned int boundstightened:2; /**< is constraint already propagated with bound tightening? */
244  unsigned int rangedrowpropagated:2; /**< did we perform ranged row propagation on this constraint?
245  * (0: no, 1: yes, 2: with potentially adding artificial constraint */
246  unsigned int validmaxabsval:1; /**< is the maximum absolute value valid? */
247  unsigned int validminabsval:1; /**< is the minimum absolute value valid? */
248  unsigned int validactivities:1; /**< are the activity bounds (local and global) valid? */
249  unsigned int validminact:1; /**< is the local minactivity valid? */
250  unsigned int validmaxact:1; /**< is the local maxactivity valid? */
251  unsigned int validglbminact:1; /**< is the global minactivity valid? */
252  unsigned int validglbmaxact:1; /**< is the global maxactivity valid? */
253  unsigned int presolved:1; /**< is constraint already presolved? */
254  unsigned int removedfixings:1; /**< are all fixed variables removed from the constraint? */
255  unsigned int validsignature:1; /**< is the bit signature valid? */
256  unsigned int changed:1; /**< was constraint changed since last aggregation round in preprocessing? */
257  unsigned int normalized:1; /**< is the constraint in normalized form? */
258  unsigned int upgradetried:1; /**< was the constraint already tried to be upgraded? */
259  unsigned int upgraded:1; /**< is the constraint upgraded and will it be removed after preprocessing? */
260  unsigned int indexsorted:1; /**< are the constraint's variables sorted by type and index? */
261  unsigned int merged:1; /**< are the constraint's equal variables already merged? */
262  unsigned int cliquesadded:1; /**< were the cliques of the constraint already extracted? */
263  unsigned int implsadded:1; /**< were the implications of the constraint already extracted? */
264  unsigned int coefsorted:1; /**< are variables sorted by type and their absolute activity delta? */
265  unsigned int varsdeleted:1; /**< were variables deleted after last cleanup? */
266  unsigned int hascontvar:1; /**< does the constraint contain at least one continuous variable? */
267  unsigned int hasnonbinvar:1; /**< does the constraint contain at least one non-binary variable? */
268  unsigned int hasnonbinvalid:1; /**< is the information stored in hasnonbinvar and hascontvar valid? */
269  unsigned int checkabsolute:1; /**< should the constraint be checked w.r.t. an absolute feasibilty tolerance? */
270 };
271 
272 /** event data for bound change event */
273 struct SCIP_EventData
274 {
275  SCIP_CONS* cons; /**< linear constraint to process the bound change for */
276  int varpos; /**< position of variable in vars array */
277  int filterpos; /**< position of event in variable's event filter */
278 };
279 
280 /** constraint handler data */
281 struct SCIP_ConshdlrData
282 {
283  SCIP_EVENTHDLR* eventhdlr; /**< event handler for bound change events */
284  SCIP_LINCONSUPGRADE** linconsupgrades; /**< linear constraint upgrade methods for specializing linear constraints */
285  SCIP_Real maxaggrnormscale; /**< maximal allowed relative gain in maximum norm for constraint aggregation
286  * (0.0: disable constraint aggregation) */
287  SCIP_Real maxcardbounddist; /**< maximal relative distance from current node's dual bound to primal bound compared
288  * to best node's dual bound for separating knapsack cardinality cuts */
289  SCIP_Real mingainpernmincomp; /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise comparison round */
290  SCIP_Real maxeasyactivitydelta;/**< maximum activity delta to run easy propagation on linear constraint
291  * (faster, but numerically less stable) */
292  int linconsupgradessize;/**< size of linconsupgrade array */
293  int nlinconsupgrades; /**< number of linear constraint upgrade methods */
294  int tightenboundsfreq; /**< multiplier on propagation frequency, how often the bounds are tightened */
295  int maxrounds; /**< maximal number of separation rounds per node (-1: unlimited) */
296  int maxroundsroot; /**< maximal number of separation rounds in the root node (-1: unlimited) */
297  int maxsepacuts; /**< maximal number of cuts separated per separation round */
298  int maxsepacutsroot; /**< maximal number of cuts separated per separation round in root node */
299  int nmincomparisons; /**< number for minimal pairwise presolving comparisons */
300  int naddconss; /**< number of added constraints */
301  SCIP_Bool presolpairwise; /**< should pairwise constraint comparison be performed in presolving? */
302  SCIP_Bool presolusehashing; /**< should hash table be used for detecting redundant constraints in advance */
303  SCIP_Bool separateall; /**< should all constraints be subject to cardinality cut generation instead of only
304  * the ones with non-zero dual value? */
305  SCIP_Bool aggregatevariables; /**< should presolving search for redundant variables in equations */
306  SCIP_Bool simplifyinequalities;/**< should presolving try to cancel down or delete coefficients in inequalities */
307  SCIP_Bool dualpresolving; /**< should dual presolving steps be performed? */
308  SCIP_Bool singletonstuffing; /**< should stuffing of singleton continuous variables be performed? */
309  SCIP_Bool singlevarstuffing; /**< should single variable stuffing be performed, which tries to fulfill
310  * constraints using the cheapest variable? */
311  SCIP_Bool sortvars; /**< should binary variables be sorted for faster propagation? */
312  SCIP_Bool checkrelmaxabs; /**< should the violation for a constraint with side 0.0 be checked relative
313  * to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
314  SCIP_Bool detectcutoffbound; /**< should presolving try to detect constraints parallel to the objective
315  * function defining an upper bound and prevent these constraints from
316  * entering the LP */
317  SCIP_Bool detectlowerbound; /**< should presolving try to detect constraints parallel to the objective
318  * function defining a lower bound and prevent these constraints from
319  * entering the LP */
320  SCIP_Bool detectpartialobjective;/**< should presolving try to detect subsets of constraints parallel to
321  * the objective function */
322  SCIP_Bool rangedrowpropagation;/**< should presolving and propagation try to improve bounds, detect
323  * infeasibility, and extract sub-constraints from ranged rows and
324  * equations */
325  SCIP_Bool rangedrowartcons; /**< should presolving and propagation extract sub-constraints from ranged rows and equations?*/
326  int rangedrowmaxdepth; /**< maximum depth to apply ranged row propagation */
327  int rangedrowfreq; /**< frequency for applying ranged row propagation */
328  SCIP_Bool multaggrremove; /**< should multi-aggregations only be performed if the constraint can be
329  * removed afterwards? */
330  SCIP_Real maxmultaggrquot; /**< maximum coefficient dynamism (ie. maxabsval / minabsval) for primal multiaggregation */
331  SCIP_Real maxdualmultaggrquot;/**< maximum coefficient dynamism (ie. maxabsval / minabsval) for dual multiaggregation */
332  SCIP_Bool extractcliques; /**< should cliques be extracted? */
333 };
334 
335 /** linear constraint update method */
336 struct SCIP_LinConsUpgrade
337 {
338  SCIP_DECL_LINCONSUPGD((*linconsupgd)); /**< method to call for upgrading linear constraint */
339  int priority; /**< priority of upgrading method */
340  SCIP_Bool active; /**< is upgrading enabled */
341 };
342 
343 
344 /*
345  * Propagation rules
346  */
347 
348 enum Proprule
349 {
350  PROPRULE_1_RHS = 1, /**< activity residuals of all other variables tighten bounds of single
351  * variable due to the right hand side of the inequality */
352  PROPRULE_1_LHS = 2, /**< activity residuals of all other variables tighten bounds of single
353  * variable due to the left hand side of the inequality */
354  PROPRULE_1_RANGEDROW = 3, /**< fixed variables and gcd of all left variables tighten bounds of a
355  * single variable in this reanged row */
356  PROPRULE_INVALID = 0 /**< propagation was applied without a specific propagation rule */
357 };
358 typedef enum Proprule PROPRULE;
360 /** inference information */
361 struct InferInfo
362 {
363  union
364  {
365  struct
366  {
367  unsigned int proprule:8; /**< propagation rule that was applied */
368  unsigned int pos:24; /**< variable position, the propagation rule was applied at */
369  } asbits;
370  int asint; /**< inference information as a single int value */
371  } val;
372 };
373 typedef struct InferInfo INFERINFO;
374 
375 /** converts an integer into an inference information */
376 static
378  int i /**< integer to convert */
379  )
380 {
381  INFERINFO inferinfo;
382 
383  inferinfo.val.asint = i;
384 
385  return inferinfo;
386 }
387 
388 /** converts an inference information into an int */
389 static
390 int inferInfoToInt(
391  INFERINFO inferinfo /**< inference information to convert */
392  )
393 {
394  return inferinfo.val.asint;
395 }
397 /** returns the propagation rule stored in the inference information */
398 static
400  INFERINFO inferinfo /**< inference information to convert */
401  )
402 {
403  return (int) inferinfo.val.asbits.proprule;
404 }
405 
406 /** returns the position stored in the inference information */
407 static
408 int inferInfoGetPos(
409  INFERINFO inferinfo /**< inference information to convert */
410  )
411 {
412  return (int) inferinfo.val.asbits.pos;
413 }
414 
415 /** constructs an inference information out of a propagation rule and a position number */
416 static
418  PROPRULE proprule, /**< propagation rule that deduced the value */
419  int pos /**< variable position, the propagation rule was applied at */
420  )
421 {
422  INFERINFO inferinfo;
423 
424  assert(pos >= 0);
425  /* in the inferinfo struct only 24 bits for 'pos' are reserved */
426  assert(pos < (1<<24));
428  inferinfo.val.asbits.proprule = (unsigned int) proprule; /*lint !e641*/
429  inferinfo.val.asbits.pos = (unsigned int) pos; /*lint !e732*/
430 
431  return inferinfo;
432 }
433 
434 /** constructs an inference information out of a propagation rule and a position number, returns info as int */
435 static
437  PROPRULE proprule, /**< propagation rule that deduced the value */
438  int pos /**< variable position, the propagation rule was applied at */
439  )
440 {
441  return inferInfoToInt(getInferInfo(proprule, pos));
442 }
443 
444 
445 /*
446  * memory growing methods for dynamically allocated arrays
447  */
448 
449 /** ensures, that linconsupgrades array can store at least num entries */
450 static
452  SCIP* scip, /**< SCIP data structure */
453  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
454  int num /**< minimum number of entries to store */
455  )
456 {
457  assert(scip != NULL);
458  assert(conshdlrdata != NULL);
459  assert(conshdlrdata->nlinconsupgrades <= conshdlrdata->linconsupgradessize);
460 
461  if( num > conshdlrdata->linconsupgradessize )
462  {
463  int newsize;
464 
465  newsize = SCIPcalcMemGrowSize(scip, num);
466  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &conshdlrdata->linconsupgrades, conshdlrdata->linconsupgradessize, newsize) );
467  conshdlrdata->linconsupgradessize = newsize;
468  }
469  assert(num <= conshdlrdata->linconsupgradessize);
471  return SCIP_OKAY;
472 }
473 
474 /** ensures, that vars and vals arrays can store at least num entries */
475 static
477  SCIP* scip, /**< SCIP data structure */
478  SCIP_CONSDATA* consdata, /**< linear constraint data */
479  int num /**< minimum number of entries to store */
480  )
481 {
482  assert(scip != NULL);
483  assert(consdata != NULL);
484  assert(consdata->nvars <= consdata->varssize);
485 
486  if( num > consdata->varssize )
487  {
488  int newsize;
489 
490  newsize = SCIPcalcMemGrowSize(scip, num);
491  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vars, consdata->varssize, newsize) );
492  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vals, consdata->varssize, newsize) );
493  if( consdata->eventdata != NULL )
494  {
495  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize, newsize) );
496  }
497  consdata->varssize = newsize;
498  }
499  assert(num <= consdata->varssize);
500 
501  return SCIP_OKAY;
502 }
503 
504 
505 /*
506  * local methods for managing linear constraint update methods
507  */
508 
509 /** creates a linear constraint upgrade data object */
510 static
512  SCIP* scip, /**< SCIP data structure */
513  SCIP_LINCONSUPGRADE** linconsupgrade, /**< pointer to store the linear constraint upgrade */
514  SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
515  int priority /**< priority of upgrading method */
516  )
517 {
518  assert(scip != NULL);
519  assert(linconsupgrade != NULL);
520  assert(linconsupgd != NULL);
521 
522  SCIP_CALL( SCIPallocBlockMemory(scip, linconsupgrade) );
523  (*linconsupgrade)->linconsupgd = linconsupgd;
524  (*linconsupgrade)->priority = priority;
525  (*linconsupgrade)->active = TRUE;
526 
527  return SCIP_OKAY;
528 }
529 
530 /** frees a linear constraint upgrade data object */
531 static
532 void linconsupgradeFree(
533  SCIP* scip, /**< SCIP data structure */
534  SCIP_LINCONSUPGRADE** linconsupgrade /**< pointer to the linear constraint upgrade */
535  )
536 {
537  assert(scip != NULL);
538  assert(linconsupgrade != NULL);
539  assert(*linconsupgrade != NULL);
540 
541  SCIPfreeBlockMemory(scip, linconsupgrade);
542 }
543 
544 /** creates constraint handler data for linear constraint handler */
545 static
547  SCIP* scip, /**< SCIP data structure */
548  SCIP_CONSHDLRDATA** conshdlrdata, /**< pointer to store the constraint handler data */
549  SCIP_EVENTHDLR* eventhdlr /**< event handler */
550  )
551 {
552  assert(scip != NULL);
553  assert(conshdlrdata != NULL);
554  assert(eventhdlr != NULL);
555 
556  SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
557  (*conshdlrdata)->linconsupgrades = NULL;
558  (*conshdlrdata)->linconsupgradessize = 0;
559  (*conshdlrdata)->nlinconsupgrades = 0;
560  (*conshdlrdata)->naddconss = 0;
561 
562  /* set event handler for updating linear constraint activity bounds */
563  (*conshdlrdata)->eventhdlr = eventhdlr;
564 
565  return SCIP_OKAY;
566 }
567 
568 /** frees constraint handler data for linear constraint handler */
569 static
570 void conshdlrdataFree(
571  SCIP* scip, /**< SCIP data structure */
572  SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to the constraint handler data */
573  )
574 {
575  int i;
576 
577  assert(scip != NULL);
578  assert(conshdlrdata != NULL);
579  assert(*conshdlrdata != NULL);
580 
581  for( i = 0; i < (*conshdlrdata)->nlinconsupgrades; ++i )
582  {
583  linconsupgradeFree(scip, &(*conshdlrdata)->linconsupgrades[i]);
584  }
585  SCIPfreeBlockMemoryArrayNull(scip, &(*conshdlrdata)->linconsupgrades, (*conshdlrdata)->linconsupgradessize);
586 
587  SCIPfreeBlockMemory(scip, conshdlrdata);
588 }
590 /** creates a linear constraint upgrade data object */
591 static
593  SCIP* scip, /**< SCIP data structure */
594  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
595  SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
596  const char* conshdlrname /**< name of the constraint handler */
597  )
598 {
599  int i;
600 
601  assert(scip != NULL);
602  assert(conshdlrdata != NULL);
603  assert(linconsupgd != NULL);
604  assert(conshdlrname != NULL);
605 
606  for( i = conshdlrdata->nlinconsupgrades - 1; i >= 0; --i )
607  {
608  if( conshdlrdata->linconsupgrades[i]->linconsupgd == linconsupgd )
609  {
610 #ifdef SCIP_DEBUG
611  SCIPwarningMessage(scip, "Try to add already known upgrade message for constraint handler %s.\n", conshdlrname);
612 #endif
613  return TRUE;
614  }
615  }
616 
617  return FALSE;
618 }
619 
620 /** adds a linear constraint update method to the constraint handler's data */
621 static
623  SCIP* scip, /**< SCIP data structure */
624  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
625  SCIP_LINCONSUPGRADE* linconsupgrade /**< linear constraint upgrade method */
626  )
627 {
628  int i;
629 
630  assert(scip != NULL);
631  assert(conshdlrdata != NULL);
632  assert(linconsupgrade != NULL);
633 
634  SCIP_CALL( conshdlrdataEnsureLinconsupgradesSize(scip, conshdlrdata, conshdlrdata->nlinconsupgrades+1) );
635 
636  for( i = conshdlrdata->nlinconsupgrades;
637  i > 0 && conshdlrdata->linconsupgrades[i-1]->priority < linconsupgrade->priority; --i )
638  {
639  conshdlrdata->linconsupgrades[i] = conshdlrdata->linconsupgrades[i-1];
640  }
641  assert(0 <= i && i <= conshdlrdata->nlinconsupgrades);
642  conshdlrdata->linconsupgrades[i] = linconsupgrade;
643  conshdlrdata->nlinconsupgrades++;
644 
645  return SCIP_OKAY;
646 }
647 
648 /*
649  * local methods
650  */
651 
652 /** installs rounding locks for the given variable associated to the given coefficient in the linear constraint */
653 static
655  SCIP* scip, /**< SCIP data structure */
656  SCIP_CONS* cons, /**< linear constraint */
657  SCIP_VAR* var, /**< variable of constraint entry */
658  SCIP_Real val /**< coefficient of constraint entry */
659  )
660 {
661  SCIP_CONSDATA* consdata;
662 
663  assert(scip != NULL);
664  assert(cons != NULL);
665  assert(var != NULL);
666 
667  consdata = SCIPconsGetData(cons);
668  assert(consdata != NULL);
669  assert(!SCIPisZero(scip, val));
670 
671  if( SCIPisPositive(scip, val) )
672  {
673  SCIP_CALL( SCIPlockVarCons(scip, var, cons,
674  !SCIPisInfinity(scip, -consdata->lhs), !SCIPisInfinity(scip, consdata->rhs)) );
675  }
676  else
677  {
678  SCIP_CALL( SCIPlockVarCons(scip, var, cons,
679  !SCIPisInfinity(scip, consdata->rhs), !SCIPisInfinity(scip, -consdata->lhs)) );
680  }
681 
682  return SCIP_OKAY;
683 }
684 
685 /** removes rounding locks for the given variable associated to the given coefficient in the linear constraint */
686 static
688  SCIP* scip, /**< SCIP data structure */
689  SCIP_CONS* cons, /**< linear constraint */
690  SCIP_VAR* var, /**< variable of constraint entry */
691  SCIP_Real val /**< coefficient of constraint entry */
692  )
693 {
694  SCIP_CONSDATA* consdata;
695 
696  assert(scip != NULL);
697  assert(cons != NULL);
698  assert(var != NULL);
699 
700  consdata = SCIPconsGetData(cons);
701  assert(consdata != NULL);
702  assert(!SCIPisZero(scip, val));
703 
704  if( SCIPisPositive(scip, val) )
705  {
706  SCIP_CALL( SCIPunlockVarCons(scip, var, cons, !SCIPisInfinity(scip, -consdata->lhs),
707  !SCIPisInfinity(scip, consdata->rhs)) );
708  }
709  else
710  {
711  SCIP_CALL( SCIPunlockVarCons(scip, var, cons, !SCIPisInfinity(scip, consdata->rhs),
712  !SCIPisInfinity(scip, -consdata->lhs)) );
713  }
714 
715  return SCIP_OKAY;
716 }
717 
718 /** creates event data for variable at given position, and catches events */
719 /**! [SnippetDebugAssertions] */
720 static
722  SCIP* scip, /**< SCIP data structure */
723  SCIP_CONS* cons, /**< linear constraint */
724  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
725  int pos /**< array position of variable to catch bound change events for */
726  )
727 {
728  SCIP_CONSDATA* consdata;
729  assert(scip != NULL);
730  assert(cons != NULL);
731  assert(eventhdlr != NULL);
732 
733  consdata = SCIPconsGetData(cons);
734  assert(consdata != NULL);
735 
736  assert(0 <= pos && pos < consdata->nvars);
737  assert(consdata->vars != NULL);
738  assert(consdata->vars[pos] != NULL);
739  assert(SCIPvarIsTransformed(consdata->vars[pos]));
740  assert(consdata->eventdata != NULL);
741  assert(consdata->eventdata[pos] == NULL);
742 
743  SCIP_CALL( SCIPallocBlockMemory(scip, &(consdata->eventdata[pos])) ); /*lint !e866*/
744  consdata->eventdata[pos]->cons = cons;
745  consdata->eventdata[pos]->varpos = pos;
746 
747  SCIP_CALL( SCIPcatchVarEvent(scip, consdata->vars[pos],
750  eventhdlr, consdata->eventdata[pos], &consdata->eventdata[pos]->filterpos) );
751 
752  consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(consdata->vars[pos]);
753 
754  return SCIP_OKAY;
755 }
756 /**! [SnippetDebugAssertions] */
757 
758 /** deletes event data for variable at given position, and drops events */
759 static
761  SCIP* scip, /**< SCIP data structure */
762  SCIP_CONS* cons, /**< linear constraint */
763  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
764  int pos /**< array position of variable to catch bound change events for */
765  )
766 {
767  SCIP_CONSDATA* consdata;
768  assert(scip != NULL);
769  assert(cons != NULL);
770  assert(eventhdlr != NULL);
771 
772  consdata = SCIPconsGetData(cons);
773  assert(consdata != NULL);
774 
775  assert(0 <= pos && pos < consdata->nvars);
776  assert(consdata->vars[pos] != NULL);
777  assert(consdata->eventdata != NULL);
778  assert(consdata->eventdata[pos] != NULL);
779  assert(consdata->eventdata[pos]->cons == cons);
780  assert(consdata->eventdata[pos]->varpos == pos);
781 
782  SCIP_CALL( SCIPdropVarEvent(scip, consdata->vars[pos],
785  eventhdlr, consdata->eventdata[pos], consdata->eventdata[pos]->filterpos) );
786 
787  SCIPfreeBlockMemory(scip, &consdata->eventdata[pos]); /*lint !e866*/
788 
789  return SCIP_OKAY;
790 }
791 
792 /** catches bound change events for all variables in transformed linear constraint */
793 static
795  SCIP* scip, /**< SCIP data structure */
796  SCIP_CONS* cons, /**< linear constraint */
797  SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
798  )
799 {
800  SCIP_CONSDATA* consdata;
801  int i;
802 
803  assert(scip != NULL);
804  assert(cons != NULL);
805 
806  consdata = SCIPconsGetData(cons);
807  assert(consdata != NULL);
808  assert(consdata->eventdata == NULL);
809 
810  /* allocate eventdata array */
811  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize) );
812  assert(consdata->eventdata != NULL);
813  BMSclearMemoryArray(consdata->eventdata, consdata->nvars);
814 
815  /* catch event for every single variable */
816  for( i = 0; i < consdata->nvars; ++i )
817  {
818  SCIP_CALL( consCatchEvent(scip, cons, eventhdlr, i) );
819  }
820 
821  return SCIP_OKAY;
822 }
823 
824 /** drops bound change events for all variables in transformed linear constraint */
825 static
827  SCIP* scip, /**< SCIP data structure */
828  SCIP_CONS* cons, /**< linear constraint */
829  SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
830  )
831 {
832  SCIP_CONSDATA* consdata;
833  int i;
834 
835  assert(scip != NULL);
836  assert(cons != NULL);
837 
838  consdata = SCIPconsGetData(cons);
839  assert(consdata != NULL);
840  assert(consdata->eventdata != NULL);
841 
842  /* drop event of every single variable */
843  for( i = consdata->nvars - 1; i >= 0; --i )
844  {
845  SCIP_CALL( consDropEvent(scip, cons, eventhdlr, i) );
846  }
847 
848  /* free eventdata array */
849  SCIPfreeBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize);
850  assert(consdata->eventdata == NULL);
851 
852  return SCIP_OKAY;
853 }
854 
855 /** creates a linear constraint data */
856 static
858  SCIP* scip, /**< SCIP data structure */
859  SCIP_CONSDATA** consdata, /**< pointer to linear constraint data */
860  int nvars, /**< number of nonzeros in the constraint */
861  SCIP_VAR** vars, /**< array with variables of constraint entries */
862  SCIP_Real* vals, /**< array with coefficients of constraint entries */
863  SCIP_Real lhs, /**< left hand side of row */
864  SCIP_Real rhs /**< right hand side of row */
865  )
866 {
867  int v;
868  SCIP_Real constant;
869 
870  assert(scip != NULL);
871  assert(consdata != NULL);
872  assert(nvars == 0 || vars != NULL);
873  assert(nvars == 0 || vals != NULL);
874 
875  if( SCIPisInfinity(scip, rhs) )
876  rhs = SCIPinfinity(scip);
877  else if( SCIPisInfinity(scip, -rhs) )
878  rhs = -SCIPinfinity(scip);
879 
880  if( SCIPisInfinity(scip, -lhs) )
881  lhs = -SCIPinfinity(scip);
882  else if( SCIPisInfinity(scip, lhs) )
883  lhs = SCIPinfinity(scip);
884 
885  if( SCIPisGT(scip, lhs, rhs) )
886  {
887  SCIPwarningMessage(scip, "left hand side of linear constraint greater than right hand side\n");
888  SCIPwarningMessage(scip, " -> lhs=%g, rhs=%g\n", lhs, rhs);
889  }
890 
891  SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
892 
893  (*consdata)->varssize = 0;
894  (*consdata)->nvars = nvars;
895  (*consdata)->hascontvar = FALSE;
896  (*consdata)->hasnonbinvar = FALSE;
897  (*consdata)->hasnonbinvalid = TRUE;
898  (*consdata)->vars = NULL;
899  (*consdata)->vals = NULL;
900 
901  constant = 0.0;
902  if( nvars > 0 )
903  {
904  int k;
905 
906  SCIP_VAR** varsbuffer;
907  SCIP_Real* valsbuffer;
908 
909  /* copy variables into temporary buffer */
910  SCIP_CALL( SCIPallocBufferArray(scip, &varsbuffer, nvars) );
911  SCIP_CALL( SCIPallocBufferArray(scip, &valsbuffer, nvars) );
912  k = 0;
913 
914  /* loop over variables and sort out fixed ones */
915  for( v = 0; v < nvars; ++v )
916  {
917  SCIP_VAR* var;
918  SCIP_Real val;
919 
920  var = vars[v];
921  val = vals[v];
922 
923  assert(var != NULL);
924  if( !SCIPisZero(scip, val) )
925  {
926  /* treat fixed variable as a constant if problem compression is enabled */
928  {
929  constant += SCIPvarGetLbGlobal(var) * val;
930  }
931  else
932  {
933  varsbuffer[k] = var;
934  valsbuffer[k] = val;
935  k++;
936 
937  /* update hascontvar and hasnonbinvar flags */
938  if( !(*consdata)->hascontvar )
939  {
940  SCIP_VARTYPE vartype = SCIPvarGetType(var);
941 
942  if( vartype != SCIP_VARTYPE_BINARY )
943  {
944  (*consdata)->hasnonbinvar = TRUE;
945 
946  if( vartype == SCIP_VARTYPE_CONTINUOUS )
947  (*consdata)->hascontvar = TRUE;
948  }
949  }
950  }
951  }
952  }
953  (*consdata)->nvars = k;
954 
955  if( k > 0 )
956  {
957  /* copy the possibly reduced buffer arrays into block */
958  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, varsbuffer, k) );
959  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vals, valsbuffer, k) );
960  (*consdata)->varssize = k;
961  }
962  /* free temporary buffer */
963  SCIPfreeBufferArray(scip, &valsbuffer);
964  SCIPfreeBufferArray(scip, &varsbuffer);
965  }
966 
967  (*consdata)->eventdata = NULL;
968 
969  /* due to compressed copying, we may have fixed variables contributing to the left and right hand side */
970  if( !SCIPisZero(scip, constant) )
971  {
972  if( !SCIPisInfinity(scip, REALABS(lhs)) )
973  lhs -= constant;
974 
975  if( !SCIPisInfinity(scip, REALABS(rhs)) )
976  rhs -= constant;
977  }
978 
979  (*consdata)->row = NULL;
980  (*consdata)->nlrow = NULL;
981  (*consdata)->lhs = lhs;
982  (*consdata)->rhs = rhs;
983  (*consdata)->maxabsval = SCIP_INVALID;
984  (*consdata)->minabsval = SCIP_INVALID;
985  (*consdata)->minactivity = SCIP_INVALID;
986  (*consdata)->maxactivity = SCIP_INVALID;
987  (*consdata)->lastminactivity = SCIP_INVALID;
988  (*consdata)->lastmaxactivity = SCIP_INVALID;
989  (*consdata)->maxactdelta = SCIP_INVALID;
990  (*consdata)->maxactdeltavar = NULL;
991  (*consdata)->minactivityneginf = -1;
992  (*consdata)->minactivityposinf = -1;
993  (*consdata)->maxactivityneginf = -1;
994  (*consdata)->maxactivityposinf = -1;
995  (*consdata)->minactivityneghuge = -1;
996  (*consdata)->minactivityposhuge = -1;
997  (*consdata)->maxactivityneghuge = -1;
998  (*consdata)->maxactivityposhuge = -1;
999  (*consdata)->glbminactivity = SCIP_INVALID;
1000  (*consdata)->glbmaxactivity = SCIP_INVALID;
1001  (*consdata)->lastglbminactivity = SCIP_INVALID;
1002  (*consdata)->lastglbmaxactivity = SCIP_INVALID;
1003  (*consdata)->glbminactivityneginf = -1;
1004  (*consdata)->glbminactivityposinf = -1;
1005  (*consdata)->glbmaxactivityneginf = -1;
1006  (*consdata)->glbmaxactivityposinf = -1;
1007  (*consdata)->glbminactivityneghuge = -1;
1008  (*consdata)->glbminactivityposhuge = -1;
1009  (*consdata)->glbmaxactivityneghuge = -1;
1010  (*consdata)->glbmaxactivityposhuge = -1;
1011  (*consdata)->possignature = 0;
1012  (*consdata)->negsignature = 0;
1013  (*consdata)->validmaxabsval = FALSE;
1014  (*consdata)->validminabsval = FALSE;
1015  (*consdata)->validactivities = FALSE;
1016  (*consdata)->validminact = FALSE;
1017  (*consdata)->validmaxact = FALSE;
1018  (*consdata)->validglbminact = FALSE;
1019  (*consdata)->validglbmaxact = FALSE;
1020  (*consdata)->boundstightened = 0;
1021  (*consdata)->presolved = FALSE;
1022  (*consdata)->removedfixings = FALSE;
1023  (*consdata)->validsignature = FALSE;
1024  (*consdata)->changed = TRUE;
1025  (*consdata)->normalized = FALSE;
1026  (*consdata)->upgradetried = FALSE;
1027  (*consdata)->upgraded = FALSE;
1028  (*consdata)->indexsorted = (nvars <= 1);
1029  (*consdata)->merged = (nvars <= 1);
1030  (*consdata)->cliquesadded = FALSE;
1031  (*consdata)->implsadded = FALSE;
1032  (*consdata)->coefsorted = FALSE;
1033  (*consdata)->nbinvars = -1;
1034  (*consdata)->varsdeleted = FALSE;
1035  (*consdata)->rangedrowpropagated = 0;
1036  (*consdata)->checkabsolute = FALSE;
1037 
1038  if( SCIPisTransformed(scip) )
1039  {
1040  /* get transformed variables */
1041  SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
1042  }
1043 
1044  /* capture variables */
1045  for( v = 0; v < (*consdata)->nvars; v++ )
1046  {
1047  /* likely implies a deleted variable */
1048  if( (*consdata)->vars[v] == NULL )
1049  {
1050  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vars, (*consdata)->varssize);
1051  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vals, (*consdata)->varssize);
1052  SCIPfreeBlockMemory(scip, consdata);
1053  return SCIP_INVALIDDATA;
1054  }
1055 
1056  assert(!SCIPisZero(scip, (*consdata)->vals[v]));
1057  SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->vars[v]) );
1058  }
1059 
1060  return SCIP_OKAY;
1061 }
1062 
1063 /** frees a linear constraint data */
1064 static
1066  SCIP* scip, /**< SCIP data structure */
1067  SCIP_CONSDATA** consdata /**< pointer to linear constraint data */
1068  )
1069 {
1070  int v;
1071 
1072  assert(scip != NULL);
1073  assert(consdata != NULL);
1074  assert(*consdata != NULL);
1075  assert((*consdata)->varssize >= 0);
1076 
1077  /* release the row */
1078  if( (*consdata)->row != NULL )
1079  {
1080  SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->row) );
1081  }
1082 
1083  /* release the nlrow */
1084  if( (*consdata)->nlrow != NULL )
1085  {
1086  SCIP_CALL( SCIPreleaseNlRow(scip, &(*consdata)->nlrow) );
1087  }
1088 
1089  /* release variables */
1090  for( v = 0; v < (*consdata)->nvars; v++ )
1091  {
1092  assert((*consdata)->vars[v] != NULL);
1093  assert(!SCIPisZero(scip, (*consdata)->vals[v]));
1094  SCIP_CALL( SCIPreleaseVar(scip, &((*consdata)->vars[v])) );
1095  }
1096 
1097  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vars, (*consdata)->varssize);
1098  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vals, (*consdata)->varssize);
1099  SCIPfreeBlockMemory(scip, consdata);
1100 
1101  return SCIP_OKAY;
1102 }
1103 
1104 /** prints linear constraint in CIP format to file stream */
1105 static
1107  SCIP* scip, /**< SCIP data structure */
1108  SCIP_CONSDATA* consdata, /**< linear constraint data */
1109  FILE* file /**< output file (or NULL for standard output) */
1110  )
1111 {
1112  assert(scip != NULL);
1113  assert(consdata != NULL);
1114 
1115  /* print left hand side for ranged rows */
1116  if( !SCIPisInfinity(scip, -consdata->lhs)
1117  && !SCIPisInfinity(scip, consdata->rhs)
1118  && !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1119  SCIPinfoMessage(scip, file, "%.15g <= ", consdata->lhs);
1120 
1121  /* print coefficients and variables */
1122  if( consdata->nvars == 0 )
1123  SCIPinfoMessage(scip, file, "0");
1124  else
1125  {
1126  /* post linear sum of the linear constraint */
1127  SCIP_CALL( SCIPwriteVarsLinearsum(scip, file, consdata->vars, consdata->vals, consdata->nvars, TRUE) );
1128  }
1129 
1130  /* print right hand side */
1131  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1132  SCIPinfoMessage(scip, file, " == %.15g", consdata->rhs);
1133  else if( !SCIPisInfinity(scip, consdata->rhs) )
1134  SCIPinfoMessage(scip, file, " <= %.15g", consdata->rhs);
1135  else if( !SCIPisInfinity(scip, -consdata->lhs) )
1136  SCIPinfoMessage(scip, file, " >= %.15g", consdata->lhs);
1137  else
1138  SCIPinfoMessage(scip, file, " [free]");
1139 
1140  return SCIP_OKAY;
1141 }
1142 
1143 /** prints linear constraint and contained solution values of variables to file stream */
1144 static
1146  SCIP* scip, /**< SCIP data structure */
1147  SCIP_CONS* cons, /**< linear constraint */
1148  SCIP_SOL* sol, /**< solution to print */
1149  FILE* file /**< output file (or NULL for standard output) */
1150  )
1151 {
1152  SCIP_CONSDATA* consdata;
1153 
1154  assert(scip != NULL);
1155  assert(cons != NULL);
1156 
1157  consdata = SCIPconsGetData(cons);
1158  assert(consdata != NULL);
1159 
1161 
1162  /* print left hand side for ranged rows */
1163  if( !SCIPisInfinity(scip, -consdata->lhs)
1164  && !SCIPisInfinity(scip, consdata->rhs)
1165  && !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1166  SCIPinfoMessage(scip, file, "%.15g <= ", consdata->lhs);
1167 
1168  /* print coefficients and variables */
1169  if( consdata->nvars == 0 )
1170  SCIPinfoMessage(scip, file, "0");
1171  else
1172  {
1173  int v;
1174 
1175  /* post linear sum of the linear constraint */
1176  for( v = 0; v < consdata->nvars; ++v )
1177  {
1178  if( consdata->vals != NULL )
1179  {
1180  if( consdata->vals[v] == 1.0 )
1181  {
1182  if( v > 0 )
1183  SCIPinfoMessage(scip, file, " +");
1184  }
1185  else if( consdata->vals[v] == -1.0 )
1186  SCIPinfoMessage(scip, file, " -");
1187  else
1188  SCIPinfoMessage(scip, file, " %+.9g", consdata->vals[v]);
1189  }
1190  else if( consdata->nvars > 0 )
1191  SCIPinfoMessage(scip, file, " +");
1192 
1193  /* print variable name */
1194  SCIP_CALL( SCIPwriteVarName(scip, file, consdata->vars[v], TRUE) );
1195 
1196  SCIPinfoMessage(scip, file, " (%+.9g)", SCIPgetSolVal(scip, sol, consdata->vars[v]));
1197  }
1198  }
1199 
1200  /* print right hand side */
1201  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
1202  SCIPinfoMessage(scip, file, " == %.15g", consdata->rhs);
1203  else if( !SCIPisInfinity(scip, consdata->rhs) )
1204  SCIPinfoMessage(scip, file, " <= %.15g", consdata->rhs);
1205  else if( !SCIPisInfinity(scip, -consdata->lhs) )
1206  SCIPinfoMessage(scip, file, " >= %.15g", consdata->lhs);
1207  else
1208  SCIPinfoMessage(scip, file, " [free]");
1209 
1210  SCIPinfoMessage(scip, file, ";\n");
1211 
1212  return SCIP_OKAY;
1213 }
1214 
1215 /** invalidates activity bounds, such that they are recalculated in next get */
1216 static
1218  SCIP_CONSDATA* consdata /**< linear constraint */
1219  )
1220 {
1221  assert(consdata != NULL);
1222 
1223  consdata->validactivities = FALSE;
1224  consdata->validminact = FALSE;
1225  consdata->validmaxact = FALSE;
1226  consdata->validglbminact = FALSE;
1227  consdata->validglbmaxact = FALSE;
1228  consdata->validmaxabsval = FALSE;
1229  consdata->validminabsval = FALSE;
1230  consdata->hasnonbinvalid = FALSE;
1231  consdata->minactivity = SCIP_INVALID;
1232  consdata->maxactivity = SCIP_INVALID;
1233  consdata->lastminactivity = SCIP_INVALID;
1234  consdata->lastmaxactivity = SCIP_INVALID;
1235  consdata->maxabsval = SCIP_INVALID;
1236  consdata->minabsval = SCIP_INVALID;
1237  consdata->maxactdelta = SCIP_INVALID;
1238  consdata->maxactdeltavar = NULL;
1239  consdata->minactivityneginf = -1;
1240  consdata->minactivityposinf = -1;
1241  consdata->maxactivityneginf = -1;
1242  consdata->maxactivityposinf = -1;
1243  consdata->minactivityneghuge = -1;
1244  consdata->minactivityposhuge = -1;
1245  consdata->maxactivityneghuge = -1;
1246  consdata->maxactivityposhuge = -1;
1247  consdata->glbminactivity = SCIP_INVALID;
1248  consdata->glbmaxactivity = SCIP_INVALID;
1249  consdata->lastglbminactivity = SCIP_INVALID;
1250  consdata->lastglbmaxactivity = SCIP_INVALID;
1251  consdata->glbminactivityneginf = -1;
1252  consdata->glbminactivityposinf = -1;
1253  consdata->glbmaxactivityneginf = -1;
1254  consdata->glbmaxactivityposinf = -1;
1255  consdata->glbminactivityneghuge = -1;
1256  consdata->glbminactivityposhuge = -1;
1257  consdata->glbmaxactivityneghuge = -1;
1258  consdata->glbmaxactivityposhuge = -1;
1259 }
1260 
1261 /** compute the pseudo activity of a constraint */
1262 static
1264  SCIP* scip, /**< SCIP data structure */
1265  SCIP_CONSDATA* consdata /**< linear constraint data */
1266  )
1267 {
1268  int i;
1269  int pseudoactivityposinf;
1270  int pseudoactivityneginf;
1271  SCIP_Real pseudoactivity;
1272  SCIP_Real bound;
1273  SCIP_Real val;
1274 
1275  pseudoactivity = 0;
1276  pseudoactivityposinf = 0;
1277  pseudoactivityneginf = 0;
1278 
1279  for( i = consdata->nvars - 1; i >= 0; --i )
1280  {
1281  val = consdata->vals[i];
1282  bound = (SCIPvarGetBestBoundType(consdata->vars[i]) == SCIP_BOUNDTYPE_LOWER) ? SCIPvarGetLbLocal(consdata->vars[i]) : SCIPvarGetUbLocal(consdata->vars[i]);
1283  if( SCIPisInfinity(scip, bound) )
1284  {
1285  if( val > 0.0 )
1286  pseudoactivityposinf++;
1287  else
1288  pseudoactivityneginf++;
1289  }
1290  else
1291  {
1292  if( SCIPisInfinity(scip, -bound) )
1293  {
1294  if( val > 0.0 )
1295  pseudoactivityneginf++;
1296  else
1297  pseudoactivityposinf++;
1298  }
1299  else
1300  pseudoactivity += val * bound;
1301  }
1302  }
1303 
1304  if( pseudoactivityneginf > 0 && pseudoactivityposinf > 0 )
1305  return SCIP_INVALID;
1306  else if( pseudoactivityneginf > 0 )
1307  return -SCIPinfinity(scip);
1308  else if( pseudoactivityposinf > 0 )
1309  return SCIPinfinity(scip);
1310 
1311  return pseudoactivity;
1312 }
1313 
1314 /** recompute the minactivity of a constraint */
1315 static
1317  SCIP* scip, /**< SCIP data structure */
1318  SCIP_CONSDATA* consdata /**< linear constraint data */
1319  )
1320 {
1321  int i;
1322  SCIP_Real bound;
1323 
1324  consdata->minactivity = 0;
1325 
1326  for( i = consdata->nvars - 1; i >= 0; --i )
1327  {
1328  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetLbLocal(consdata->vars[i]) : SCIPvarGetUbLocal(consdata->vars[i]);
1329  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1330  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1331  consdata->minactivity += consdata->vals[i] * bound;
1332  }
1333 
1334  /* the activity was just computed from scratch and is valid now */
1335  consdata->validminact = TRUE;
1336 
1337  /* the activity was just computed from scratch, mark it to be reliable */
1338  consdata->lastminactivity = consdata->minactivity;
1339 }
1340 
1341 /** recompute the maxactivity of a constraint */
1342 static
1344  SCIP* scip, /**< SCIP data structure */
1345  SCIP_CONSDATA* consdata /**< linear constraint data */
1346  )
1347 {
1348  int i;
1349  SCIP_Real bound;
1350 
1351  consdata->maxactivity = 0;
1352 
1353  for( i = consdata->nvars - 1; i >= 0; --i )
1354  {
1355  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetUbLocal(consdata->vars[i]) : SCIPvarGetLbLocal(consdata->vars[i]);
1356  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1357  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1358  consdata->maxactivity += consdata->vals[i] * bound;
1359  }
1360 
1361  /* the activity was just computed from scratch and is valid now */
1362  consdata->validmaxact = TRUE;
1363 
1364  /* the activity was just computed from scratch, mark it to be reliable */
1365  consdata->lastmaxactivity = consdata->maxactivity;
1366 }
1367 
1368 /** recompute the global minactivity of a constraint */
1369 static
1371  SCIP* scip, /**< SCIP data structure */
1372  SCIP_CONSDATA* consdata /**< linear constraint data */
1373  )
1374 {
1375  int i;
1376  SCIP_Real bound;
1377 
1378  consdata->glbminactivity = 0;
1379 
1380  for( i = consdata->nvars - 1; i >= 0; --i )
1381  {
1382  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetLbGlobal(consdata->vars[i]) : SCIPvarGetUbGlobal(consdata->vars[i]);
1383  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1384  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1385  consdata->glbminactivity += consdata->vals[i] * bound;
1386  }
1387 
1388  /* the activity was just computed from scratch and is valid now */
1389  consdata->validglbminact = TRUE;
1390 
1391  /* the activity was just computed from scratch, mark it to be reliable */
1392  consdata->lastglbminactivity = consdata->glbminactivity;
1393 }
1394 
1395 /** recompute the global maxactivity of a constraint */
1396 static
1398  SCIP* scip, /**< SCIP data structure */
1399  SCIP_CONSDATA* consdata /**< linear constraint data */
1400  )
1401 {
1402  int i;
1403  SCIP_Real bound;
1404 
1405  consdata->glbmaxactivity = 0;
1406 
1407  for( i = consdata->nvars - 1; i >= 0; --i )
1408  {
1409  bound = (consdata->vals[i] > 0.0 ) ? SCIPvarGetUbGlobal(consdata->vars[i]) : SCIPvarGetLbGlobal(consdata->vars[i]);
1410  if( !SCIPisInfinity(scip, bound) && !SCIPisInfinity(scip, -bound)
1411  && !SCIPisHugeValue(scip, consdata->vals[i] * bound) && !SCIPisHugeValue(scip, -consdata->vals[i] * bound) )
1412  consdata->glbmaxactivity += consdata->vals[i] * bound;
1413  }
1414 
1415  /* the activity was just computed from scratch and is valid now */
1416  consdata->validglbmaxact = TRUE;
1417 
1418  /* the activity was just computed from scratch, mark it to be reliable */
1419  consdata->lastglbmaxactivity = consdata->glbmaxactivity;
1420 }
1421 
1422 /** calculates maximum absolute value of coefficients */
1423 static
1425  SCIP_CONSDATA* consdata /**< linear constraint data */
1426  )
1427 {
1428  SCIP_Real absval;
1429  int i;
1430 
1431  assert(consdata != NULL);
1432  assert(!consdata->validmaxabsval);
1433  assert(consdata->maxabsval >= SCIP_INVALID);
1434 
1435  consdata->validmaxabsval = TRUE;
1436  consdata->maxabsval = 0.0;
1437  for( i = 0; i < consdata->nvars; ++i )
1438  {
1439  absval = consdata->vals[i];
1440  absval = REALABS(absval);
1441  if( absval > consdata->maxabsval )
1442  consdata->maxabsval = absval;
1443  }
1444 }
1445 
1446 /** calculates minimum absolute value of coefficients */
1447 static
1449  SCIP_CONSDATA* consdata /**< linear constraint data */
1450  )
1451 {
1452  SCIP_Real absval;
1453  int i;
1454 
1455  assert(consdata != NULL);
1456  assert(!consdata->validminabsval);
1457  assert(consdata->minabsval >= SCIP_INVALID);
1458 
1459  consdata->validminabsval = TRUE;
1460 
1461  if( consdata->nvars > 0 )
1462  consdata->minabsval = REALABS(consdata->vals[0]);
1463  else
1464  consdata->minabsval = 0.0;
1465 
1466  for( i = 1; i < consdata->nvars; ++i )
1467  {
1468  absval = consdata->vals[i];
1469  absval = REALABS(absval);
1470  if( absval < consdata->minabsval )
1471  consdata->minabsval = absval;
1472  }
1473 }
1474 
1475 /** checks the type of all variables of the constraint and sets hasnonbinvar and hascontvar flags accordingly */
1476 static
1478  SCIP_CONSDATA* consdata /**< linear constraint data */
1479  )
1480 {
1481  int v;
1482 
1483  assert(!consdata->hasnonbinvalid);
1484  consdata->hasnonbinvar = FALSE;
1485  consdata->hascontvar = FALSE;
1486 
1487  for( v = consdata->nvars - 1; v >= 0; --v )
1488  {
1489  SCIP_VARTYPE vartype = SCIPvarGetType(consdata->vars[v]);
1490 
1491  if( vartype != SCIP_VARTYPE_BINARY )
1492  {
1493  consdata->hasnonbinvar = TRUE;
1494 
1495  if( vartype == SCIP_VARTYPE_CONTINUOUS )
1496  {
1497  consdata->hascontvar = TRUE;
1498  break;
1499  }
1500  }
1501  }
1502  assert(consdata->hascontvar || v < 0);
1503 
1504  consdata->hasnonbinvalid = TRUE;
1505 }
1506 
1507 
1508 #ifdef CHECKMAXACTDELTA
1509 /** checks that the stored maximal activity delta (if not invalid) is correct */
1510 static
1512  SCIP* scip, /**< SCIP data structure */
1513  SCIP_CONSDATA* consdata /**< linear constraint data */
1514  )
1515 {
1516  if( consdata->maxactdelta != SCIP_INVALID )
1517  {
1518  SCIP_Real maxactdelta = 0.0;
1519  SCIP_Real domain;
1520  SCIP_Real delta;
1521  SCIP_Real lb;
1522  SCIP_Real ub;
1523  int v;
1524 
1525  for( v = consdata->nvars - 1; v >= 0; --v )
1526  {
1527  lb = SCIPvarGetLbLocal(consdata->vars[v]);
1528  ub = SCIPvarGetUbLocal(consdata->vars[v]);
1529 
1530  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
1531  {
1532  maxactdelta = SCIPinfinity(scip);
1533  break;
1534  }
1535 
1536  domain = ub - lb;
1537  delta = REALABS(consdata->vals[v]) * domain;
1538 
1539  if( delta > maxactdelta )
1540  {
1541  maxactdelta = delta;
1542  }
1543  }
1544  assert(SCIPisFeasEQ(scip, maxactdelta, consdata->maxactdelta));
1545  }
1546 }
1547 #else
1548 #define checkMaxActivityDelta(scip, consdata) /**/
1549 #endif
1550 
1551 /** recompute maximal activity contribution for a single variable */
1552 static
1554  SCIP* scip, /**< SCIP data structure */
1555  SCIP_CONSDATA* consdata /**< linear constraint data */
1556  )
1557 {
1558  SCIP_Real delta;
1559  int v;
1560 
1561  consdata->maxactdelta = 0.0;
1562 
1563  if( !consdata->hasnonbinvalid )
1564  consdataCheckNonbinvar(consdata);
1565 
1566  /* easy case, the problem consists only of binary variables */
1567  if( !consdata->hasnonbinvar )
1568  {
1569  for( v = consdata->nvars - 1; v >= 0; --v )
1570  {
1571  if( SCIPvarGetLbLocal(consdata->vars[v]) < 0.5 && SCIPvarGetUbLocal(consdata->vars[v]) > 0.5 )
1572  {
1573  delta = REALABS(consdata->vals[v]);
1574 
1575  if( delta > consdata->maxactdelta )
1576  {
1577  consdata->maxactdelta = delta;
1578  consdata->maxactdeltavar = consdata->vars[v];
1579  }
1580  }
1581  }
1582  return;
1583  }
1584 
1585  for( v = consdata->nvars - 1; v >= 0; --v )
1586  {
1587  SCIP_Real domain;
1588  SCIP_Real lb;
1589  SCIP_Real ub;
1590 
1591  lb = SCIPvarGetLbLocal(consdata->vars[v]);
1592  ub = SCIPvarGetUbLocal(consdata->vars[v]);
1593 
1594  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
1595  {
1596  consdata->maxactdelta = SCIPinfinity(scip);
1597  consdata->maxactdeltavar = consdata->vars[v];
1598  break;
1599  }
1600 
1601  domain = ub - lb;
1602  delta = REALABS(consdata->vals[v]) * domain;
1603 
1604  if( delta > consdata->maxactdelta )
1605  {
1606  consdata->maxactdelta = delta;
1607  consdata->maxactdeltavar = consdata->vars[v];
1608  }
1609  }
1610 }
1611 
1612 
1613 /** updates activities for a change in a bound */
1614 static
1616  SCIP* scip, /**< SCIP data structure */
1617  SCIP_CONSDATA* consdata, /**< linear constraint data */
1618  SCIP_VAR* var, /**< variable that has been changed; can be NULL for global bound changes */
1619  SCIP_Real oldbound, /**< old bound of variable */
1620  SCIP_Real newbound, /**< new bound of variable */
1621  SCIP_Real val, /**< coefficient of constraint entry */
1622  SCIP_BOUNDTYPE boundtype, /**< type of the bound change */
1623  SCIP_Bool global, /**< is it a global or a local bound change? */
1624  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
1625  )
1626 {
1627  SCIP_Real* activity;
1628  SCIP_Real* lastactivity;
1629  int* activityposinf;
1630  int* activityneginf;
1631  int* activityposhuge;
1632  int* activityneghuge;
1633  SCIP_Real oldcontribution;
1634  SCIP_Real newcontribution;
1635  SCIP_Real delta;
1636  SCIP_Bool validact;
1637  SCIP_Bool finitenewbound;
1638  SCIP_Bool hugevalnewcont;
1639 
1640  assert(scip != NULL);
1641  assert(consdata != NULL);
1642  assert(global || (var != NULL));
1643  assert(consdata->validactivities);
1644  assert(consdata->minactivity < SCIP_INVALID);
1645  assert(consdata->maxactivity < SCIP_INVALID);
1646  assert(consdata->lastminactivity < SCIP_INVALID);
1647  assert(consdata->lastmaxactivity < SCIP_INVALID);
1648  assert(consdata->minactivityneginf >= 0);
1649  assert(consdata->minactivityposinf >= 0);
1650  assert(consdata->maxactivityneginf >= 0);
1651  assert(consdata->maxactivityposinf >= 0);
1652  assert(consdata->minactivityneghuge >= 0);
1653  assert(consdata->minactivityposhuge >= 0);
1654  assert(consdata->maxactivityneghuge >= 0);
1655  assert(consdata->maxactivityposhuge >= 0);
1656  assert(consdata->glbminactivity < SCIP_INVALID);
1657  assert(consdata->glbmaxactivity < SCIP_INVALID);
1658  assert(consdata->lastglbminactivity < SCIP_INVALID);
1659  assert(consdata->lastglbmaxactivity < SCIP_INVALID);
1660  assert(consdata->glbminactivityneginf >= 0);
1661  assert(consdata->glbminactivityposinf >= 0);
1662  assert(consdata->glbmaxactivityneginf >= 0);
1663  assert(consdata->glbmaxactivityposinf >= 0);
1664  assert(consdata->glbminactivityneghuge >= 0);
1665  assert(consdata->glbminactivityposhuge >= 0);
1666  assert(consdata->glbmaxactivityneghuge >= 0);
1667  assert(consdata->glbmaxactivityposhuge >= 0);
1668 
1669  delta = 0.0;
1670 
1671  /* we are updating global activities */
1672  if( global )
1673  {
1674  /* depending on the boundtype and the coefficient, we choose the activity to be updated:
1675  * lower bound + pos. coef: update minactivity
1676  * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
1677  * upper bound + pos. coef: update maxactivity
1678  * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
1679  */
1680  if( boundtype == SCIP_BOUNDTYPE_LOWER )
1681  {
1682  if( val > 0.0 )
1683  {
1684  activity = &(consdata->glbminactivity);
1685  lastactivity = &(consdata->lastglbminactivity);
1686  activityposinf = &(consdata->glbminactivityposinf);
1687  activityneginf = &(consdata->glbminactivityneginf);
1688  activityposhuge = &(consdata->glbminactivityposhuge);
1689  activityneghuge = &(consdata->glbminactivityneghuge);
1690  validact = consdata->validglbminact;
1691  }
1692  else
1693  {
1694  activity = &(consdata->glbmaxactivity);
1695  lastactivity = &(consdata->lastglbmaxactivity);
1696  activityposinf = &(consdata->glbmaxactivityneginf);
1697  activityneginf = &(consdata->glbmaxactivityposinf);
1698  activityposhuge = &(consdata->glbmaxactivityposhuge);
1699  activityneghuge = &(consdata->glbmaxactivityneghuge);
1700  validact = consdata->validglbmaxact;
1701  }
1702  }
1703  else
1704  {
1705  if( val > 0.0 )
1706  {
1707  activity = &(consdata->glbmaxactivity);
1708  lastactivity = &(consdata->lastglbmaxactivity);
1709  activityposinf = &(consdata->glbmaxactivityposinf);
1710  activityneginf = &(consdata->glbmaxactivityneginf);
1711  activityposhuge = &(consdata->glbmaxactivityposhuge);
1712  activityneghuge = &(consdata->glbmaxactivityneghuge);
1713  validact = consdata->validglbmaxact;
1714  }
1715  else
1716  {
1717  activity = &(consdata->glbminactivity);
1718  lastactivity = &(consdata->lastglbminactivity);
1719  activityposinf = &(consdata->glbminactivityneginf);
1720  activityneginf = &(consdata->glbminactivityposinf);
1721  activityposhuge = &(consdata->glbminactivityposhuge);
1722  activityneghuge = &(consdata->glbminactivityneghuge);
1723  validact = consdata->validglbminact;
1724  }
1725  }
1726  }
1727  /* we are updating local activities */
1728  else
1729  {
1730  /* depending on the boundtype and the coefficient, we choose the activity to be updated:
1731  * lower bound + pos. coef: update minactivity
1732  * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
1733  * upper bound + pos. coef: update maxactivity
1734  * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
1735  */
1736  if( boundtype == SCIP_BOUNDTYPE_LOWER )
1737  {
1738  if( val > 0.0 )
1739  {
1740  activity = &(consdata->minactivity);
1741  lastactivity = &(consdata->lastminactivity);
1742  activityposinf = &(consdata->minactivityposinf);
1743  activityneginf = &(consdata->minactivityneginf);
1744  activityposhuge = &(consdata->minactivityposhuge);
1745  activityneghuge = &(consdata->minactivityneghuge);
1746  validact = consdata->validminact;
1747  }
1748  else
1749  {
1750  activity = &(consdata->maxactivity);
1751  lastactivity = &(consdata->lastmaxactivity);
1752  activityposinf = &(consdata->maxactivityneginf);
1753  activityneginf = &(consdata->maxactivityposinf);
1754  activityposhuge = &(consdata->maxactivityposhuge);
1755  activityneghuge = &(consdata->maxactivityneghuge);
1756  validact = consdata->validmaxact;
1757  }
1758  }
1759  else
1760  {
1761  if( val > 0.0 )
1762  {
1763  activity = &(consdata->maxactivity);
1764  lastactivity = &(consdata->lastmaxactivity);
1765  activityposinf = &(consdata->maxactivityposinf);
1766  activityneginf = &(consdata->maxactivityneginf);
1767  activityposhuge = &(consdata->maxactivityposhuge);
1768  activityneghuge = &(consdata->maxactivityneghuge);
1769  validact = consdata->validmaxact;
1770  }
1771  else
1772  {
1773  activity = &(consdata->minactivity);
1774  lastactivity = &(consdata->lastminactivity);
1775  activityposinf = &(consdata->minactivityneginf);
1776  activityneginf = &(consdata->minactivityposinf);
1777  activityposhuge = &(consdata->minactivityposhuge);
1778  activityneghuge = &(consdata->minactivityneghuge);
1779  validact = consdata->validminact;
1780  }
1781  }
1782  }
1783 
1784  oldcontribution = val * oldbound;
1785  newcontribution = val * newbound;
1786  hugevalnewcont = SCIPisHugeValue(scip, REALABS(newcontribution));
1787  finitenewbound = !SCIPisInfinity(scip, REALABS(newbound));
1788 
1789  if( SCIPisInfinity(scip, REALABS(oldbound)) )
1790  {
1791  /* old bound was +infinity */
1792  if( oldbound > 0.0 )
1793  {
1794  assert((*activityposinf) >= 1);
1795 
1796  /* we only have to do something if the new bound is not again +infinity */
1797  if( finitenewbound || newbound < 0.0 )
1798  {
1799  /* decrease the counter for positive infinite contributions */
1800  (*activityposinf)--;
1801 
1802  /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1803  if( !finitenewbound && newbound < 0.0 )
1804  (*activityneginf)++;
1805  else if( hugevalnewcont )
1806  {
1807  /* if the contribution of this variable is too large, increase the counter for huge values */
1808  if( newcontribution > 0.0 )
1809  (*activityposhuge)++;
1810  else
1811  (*activityneghuge)++;
1812  }
1813  /* "normal case": just add the contribution to the activity */
1814  else
1815  delta = newcontribution;
1816  }
1817  }
1818  /* old bound was -infinity */
1819  else
1820  {
1821  assert(oldbound < 0.0);
1822  assert((*activityneginf) >= 1);
1823 
1824  /* we only have to do something ig the new bound is not again -infinity */
1825  if( finitenewbound || newbound > 0.0 )
1826  {
1827  /* decrease the counter for negative infinite contributions */
1828  (*activityneginf)--;
1829 
1830  /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1831  if( !finitenewbound && newbound > 0.0 )
1832  (*activityposinf)++;
1833  else if( hugevalnewcont )
1834  {
1835  /* if the contribution of this variable is too large, increase the counter for huge values */
1836  if( newcontribution > 0.0 )
1837  (*activityposhuge)++;
1838  else
1839  (*activityneghuge)++;
1840  }
1841  /* "normal case": just add the contribution to the activity */
1842  else
1843  delta = newcontribution;
1844  }
1845  }
1846  }
1847  else if( SCIPisHugeValue(scip, REALABS(oldcontribution)) )
1848  {
1849  /* old contribution was too large and positive */
1850  if( oldcontribution > 0.0 )
1851  {
1852  assert((*activityposhuge) >= 1);
1853 
1854  /* decrease the counter for huge positive contributions; it might be increased again later,
1855  * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
1856  */
1857  (*activityposhuge)--;
1858 
1859  if( !finitenewbound )
1860  {
1861  /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1862  if( newbound > 0.0 )
1863  (*activityposinf)++;
1864  /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1865  else
1866  (*activityneginf)++;
1867  }
1868  else if( hugevalnewcont )
1869  {
1870  /* if the contribution of this variable is too large and positive, increase the corresponding counter */
1871  if( newcontribution > 0.0 )
1872  (*activityposhuge)++;
1873  /* if the contribution of this variable is too large and negative, increase the corresponding counter */
1874  else
1875  (*activityneghuge)++;
1876  }
1877  /* "normal case": just add the contribution to the activity */
1878  else
1879  delta = newcontribution;
1880  }
1881  /* old contribution was too large and negative */
1882  else
1883  {
1884  assert(oldcontribution < 0.0);
1885  assert((*activityneghuge) >= 1);
1886 
1887  /* decrease the counter for huge negative contributions; it might be increased again later,
1888  * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
1889  */
1890  (*activityneghuge)--;
1891 
1892  if( !finitenewbound )
1893  {
1894  /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1895  if( newbound > 0.0 )
1896  (*activityposinf)++;
1897  /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1898  else
1899  (*activityneginf)++;
1900  }
1901  else if( hugevalnewcont )
1902  {
1903  /* if the contribution of this variable is too large and positive, increase the corresponding counter */
1904  if( newcontribution > 0.0 )
1905  (*activityposhuge)++;
1906  /* if the contribution of this variable is too large and negative, increase the corresponding counter */
1907  else
1908  (*activityneghuge)++;
1909  }
1910  /* "normal case": just add the contribution to the activity */
1911  else
1912  delta = newcontribution;
1913  }
1914  }
1915  /* old bound was finite and not too large */
1916  else
1917  {
1918  if( !finitenewbound )
1919  {
1920  /* if the new bound is +infinity, the old contribution has to be subtracted
1921  * and the counter for positive infinite contributions has to be increased
1922  */
1923  if( newbound > 0.0 )
1924  {
1925  (*activityposinf)++;
1926  delta = -oldcontribution;
1927  }
1928  /* if the new bound is -infinity, the old contribution has to be subtracted
1929  * and the counter for negative infinite contributions has to be increased
1930  */
1931  else
1932  {
1933  assert(newbound < 0.0 );
1934 
1935  (*activityneginf)++;
1936  delta = -oldcontribution;
1937  }
1938  }
1939  /* if the contribution of this variable is too large, increase the counter for huge values */
1940  else if( hugevalnewcont )
1941  {
1942  if( newcontribution > 0.0 )
1943  {
1944  (*activityposhuge)++;
1945  delta = -oldcontribution;
1946  }
1947  else
1948  {
1949  (*activityneghuge)++;
1950  delta = -oldcontribution;
1951  }
1952  }
1953  /* "normal case": just update the activity */
1954  else
1955  delta = newcontribution - oldcontribution;
1956  }
1957 
1958  /* update the activity, if the current value is valid and there was a change in the finite part */
1959  if( validact && (delta != 0.0) )
1960  {
1961  /* if the absolute value of the activity is increased, this is regarded as reliable,
1962  * otherwise, we check whether we can still trust the updated value
1963  */
1964  (*activity) = (*activity) + delta;
1965  assert(!SCIPisInfinity(scip, -(*activity)) && !SCIPisInfinity(scip, *activity));
1966 
1967  if( REALABS((*lastactivity)) < REALABS(*activity) )
1968  {
1969  (*lastactivity) = (*activity);
1970  }
1971  else
1972  {
1973  if( checkreliability && SCIPisUpdateUnreliable(scip, (*activity), (*lastactivity)) )
1974  {
1975  SCIPdebugMsg(scip, "%s activity of linear constraint unreliable after update: %16.9g\n",
1976  (global ? "global " : ""), (*activity));
1977 
1978  /* mark the activity that was just changed and is not reliable anymore to be invalid */
1979  if( global )
1980  {
1981  if( (boundtype == SCIP_BOUNDTYPE_LOWER) == (val > 0.0) )
1982  consdata->validglbminact = FALSE;
1983  else
1984  consdata->validglbmaxact = FALSE;
1985  }
1986  else
1987  {
1988  if( (boundtype == SCIP_BOUNDTYPE_LOWER) == (val > 0.0) )
1989  consdata->validminact = FALSE;
1990  else
1991  consdata->validmaxact = FALSE;
1992  }
1993  }
1994  }
1995  }
1996 }
1997 
1998 /** updates minimum and maximum activity for a change in lower bound */
1999 static
2001  SCIP* scip, /**< SCIP data structure */
2002  SCIP_CONSDATA* consdata, /**< linear constraint data */
2003  SCIP_VAR* var, /**< variable that has been changed */
2004  SCIP_Real oldlb, /**< old lower bound of variable */
2005  SCIP_Real newlb, /**< new lower bound of variable */
2006  SCIP_Real val, /**< coefficient of constraint entry */
2007  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2008  )
2009 {
2010  assert(scip != NULL);
2011  assert(consdata != NULL);
2012  assert(var != NULL);
2013 
2014  if( consdata->validactivities )
2015  {
2016  consdataUpdateActivities(scip, consdata, var, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, FALSE, checkreliability);
2017 
2018  assert(!SCIPisInfinity(scip, -consdata->minactivity) && !SCIPisInfinity(scip, consdata->minactivity));
2019  assert(!SCIPisInfinity(scip, -consdata->maxactivity) && !SCIPisInfinity(scip, consdata->maxactivity));
2020  }
2021 }
2022 
2023 /** updates minimum and maximum activity for a change in upper bound */
2024 static
2026  SCIP* scip, /**< SCIP data structure */
2027  SCIP_CONSDATA* consdata, /**< linear constraint data */
2028  SCIP_VAR* var, /**< variable that has been changed */
2029  SCIP_Real oldub, /**< old upper bound of variable */
2030  SCIP_Real newub, /**< new upper bound of variable */
2031  SCIP_Real val, /**< coefficient of constraint entry */
2032  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2033  )
2034 {
2035  assert(scip != NULL);
2036  assert(consdata != NULL);
2037  assert(var != NULL);
2038 
2039  if( consdata->validactivities )
2040  {
2041  consdataUpdateActivities(scip, consdata, var, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, FALSE, checkreliability);
2042 
2043  assert(!SCIPisInfinity(scip, -consdata->minactivity) && !SCIPisInfinity(scip, consdata->minactivity));
2044  assert(!SCIPisInfinity(scip, -consdata->maxactivity) && !SCIPisInfinity(scip, consdata->maxactivity));
2045  }
2046 }
2047 
2048 /** updates minimum and maximum global activity for a change in the global lower bound */
2049 static
2051  SCIP* scip, /**< SCIP data structure */
2052  SCIP_CONSDATA* consdata, /**< linear constraint data */
2053  SCIP_Real oldlb, /**< old lower bound of variable */
2054  SCIP_Real newlb, /**< new lower bound of variable */
2055  SCIP_Real val, /**< coefficient of constraint entry */
2056  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2057  )
2058 {
2059  assert(scip != NULL);
2060  assert(consdata != NULL);
2061 
2062  if( consdata->validactivities )
2063  {
2064  consdataUpdateActivities(scip, consdata, NULL, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, TRUE, checkreliability);
2065 
2066  assert(!SCIPisInfinity(scip, -consdata->glbminactivity) && !SCIPisInfinity(scip, consdata->glbminactivity));
2067  assert(!SCIPisInfinity(scip, -consdata->glbmaxactivity) && !SCIPisInfinity(scip, consdata->glbmaxactivity));
2068  }
2070 
2071 /** updates minimum and maximum global activity for a change in global upper bound */
2072 static
2074  SCIP* scip, /**< SCIP data structure */
2075  SCIP_CONSDATA* consdata, /**< linear constraint data */
2076  SCIP_Real oldub, /**< old upper bound of variable */
2077  SCIP_Real newub, /**< new upper bound of variable */
2078  SCIP_Real val, /**< coefficient of constraint entry */
2079  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2080  )
2081 {
2082  assert(scip != NULL);
2083  assert(consdata != NULL);
2084 
2085  if( consdata->validactivities )
2086  {
2087  consdataUpdateActivities(scip, consdata, NULL, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, TRUE, checkreliability);
2088 
2089  assert(!SCIPisInfinity(scip, -consdata->glbminactivity) && !SCIPisInfinity(scip, consdata->glbminactivity));
2090  assert(!SCIPisInfinity(scip, -consdata->glbmaxactivity) && !SCIPisInfinity(scip, consdata->glbmaxactivity));
2091  }
2093 
2094 /** updates minimum and maximum activity and maximum absolute value for coefficient addition */
2095 static
2097  SCIP* scip, /**< SCIP data structure */
2098  SCIP_CONSDATA* consdata, /**< linear constraint data */
2099  SCIP_VAR* var, /**< variable of constraint entry */
2100  SCIP_Real val, /**< coefficient of constraint entry */
2101  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2102  )
2103 {
2104  assert(scip != NULL);
2105  assert(consdata != NULL);
2106  assert(var != NULL);
2107 
2108  /* update maximum absolute value */
2109  if( consdata->validmaxabsval )
2110  {
2111  SCIP_Real absval;
2112 
2113  assert(consdata->maxabsval < SCIP_INVALID);
2114 
2115  absval = REALABS(val);
2116  consdata->maxabsval = MAX(consdata->maxabsval, absval);
2117  }
2118 
2119  if( consdata->validminabsval )
2120  {
2121  SCIP_Real absval;
2122 
2123  assert(consdata->minabsval < SCIP_INVALID);
2124 
2125  absval = REALABS(val);
2126  consdata->minabsval = MIN(consdata->minabsval, absval);
2127  }
2128 
2129  /* update minimal and maximal activity */
2130  if( consdata->validactivities )
2131  {
2132  assert(consdata->minactivity < SCIP_INVALID);
2133  assert(consdata->maxactivity < SCIP_INVALID);
2134  assert(consdata->glbminactivity < SCIP_INVALID);
2135  assert(consdata->glbmaxactivity < SCIP_INVALID);
2136 
2137  consdataUpdateActivitiesLb(scip, consdata, var, 0.0, SCIPvarGetLbLocal(var), val, checkreliability);
2138  consdataUpdateActivitiesUb(scip, consdata, var, 0.0, SCIPvarGetUbLocal(var), val, checkreliability);
2139  consdataUpdateActivitiesGlbLb(scip, consdata, 0.0, SCIPvarGetLbGlobal(var), val, checkreliability);
2140  consdataUpdateActivitiesGlbUb(scip, consdata, 0.0, SCIPvarGetUbGlobal(var), val, checkreliability);
2141  }
2142 }
2143 
2144 /** updates minimum and maximum activity for coefficient deletion, invalidates maximum absolute value if necessary */
2145 static
2147  SCIP* scip, /**< SCIP data structure */
2148  SCIP_CONSDATA* consdata, /**< linear constraint data */
2149  SCIP_VAR* var, /**< variable of constraint entry */
2150  SCIP_Real val, /**< coefficient of constraint entry */
2151  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2152  )
2153 {
2154  assert(scip != NULL);
2155  assert(consdata != NULL);
2156  assert(var != NULL);
2157 
2158  /* invalidate maximum absolute value, if this coefficient was the maximum */
2159  if( consdata->validmaxabsval )
2160  {
2161  SCIP_Real absval;
2162 
2163  absval = REALABS(val);
2164 
2165  if( SCIPisEQ(scip, absval, consdata->maxabsval) )
2166  {
2167  consdata->validmaxabsval = FALSE;
2168  consdata->maxabsval = SCIP_INVALID;
2169  }
2170  }
2171 
2172  /* invalidate minimum absolute value, if this coefficient was the minimum */
2173  if( consdata->validminabsval )
2174  {
2175  SCIP_Real absval;
2176 
2177  absval = REALABS(val);
2178 
2179  if( SCIPisEQ(scip, absval, consdata->minabsval) )
2180  {
2181  consdata->validminabsval = FALSE;
2182  consdata->minabsval = SCIP_INVALID;
2183  }
2184  }
2185 
2186  /* update minimal and maximal activity */
2187  if( consdata->validactivities )
2188  {
2189  assert(consdata->minactivity < SCIP_INVALID);
2190  assert(consdata->maxactivity < SCIP_INVALID);
2191  assert(consdata->glbminactivity < SCIP_INVALID);
2192  assert(consdata->glbmaxactivity < SCIP_INVALID);
2193 
2194  consdataUpdateActivitiesLb(scip, consdata, var, SCIPvarGetLbLocal(var), 0.0, val, checkreliability);
2195  consdataUpdateActivitiesUb(scip, consdata, var, SCIPvarGetUbLocal(var), 0.0, val, checkreliability);
2196  consdataUpdateActivitiesGlbLb(scip, consdata, SCIPvarGetLbGlobal(var), 0.0, val, checkreliability);
2197  consdataUpdateActivitiesGlbUb(scip, consdata, SCIPvarGetUbGlobal(var), 0.0, val, checkreliability);
2198  }
2199 }
2200 
2201 /** updates minimum and maximum activity for coefficient change, invalidates maximum absolute value if necessary */
2202 static
2204  SCIP* scip, /**< SCIP data structure */
2205  SCIP_CONSDATA* consdata, /**< linear constraint data */
2206  SCIP_VAR* var, /**< variable of constraint entry */
2207  SCIP_Real oldval, /**< old coefficient of constraint entry */
2208  SCIP_Real newval, /**< new coefficient of constraint entry */
2209  SCIP_Bool checkreliability /**< should the reliability of the recalculated activity be checked? */
2210  )
2211 {
2212  assert(scip != NULL);
2213  assert(consdata != NULL);
2214  assert(var != NULL);
2215 
2216  /* old zero coefficients should be handled by consdataUpdateAddCoef() */
2217  assert(!SCIPisZero(scip, oldval));
2218 
2219  /* new zero coefficients should be handled by consdataUpdateDelCoef() */
2220  assert(!SCIPisZero(scip, newval));
2221 
2222  /* update maximum absolute value */
2223  if( consdata->validmaxabsval )
2224  {
2225  SCIP_Real absval;
2226 
2227  absval = REALABS(newval);
2228 
2229  if( SCIPisGE(scip, absval, consdata->maxabsval) )
2230  {
2231  consdata->maxabsval = absval;
2232  }
2233  else
2234  {
2235  absval = REALABS(oldval);
2236 
2237  /* invalidate maximum absolute value */
2238  if( SCIPisEQ(scip, absval, consdata->maxabsval) )
2239  {
2240  consdata->validmaxabsval = FALSE;
2241  consdata->maxabsval = SCIP_INVALID;
2242  }
2243  }
2244  }
2245 
2246  /* update minimum absolute value */
2247  if( consdata->validminabsval )
2248  {
2249  SCIP_Real absval;
2250 
2251  absval = REALABS(newval);
2252 
2253  if( SCIPisLE(scip, absval, consdata->minabsval) )
2254  {
2255  consdata->minabsval = absval;
2256  }
2257  else
2258  {
2259  absval = REALABS(oldval);
2260 
2261  /* invalidate minimum absolute value */
2262  if( SCIPisEQ(scip, absval, consdata->minabsval) )
2263  {
2264  consdata->validminabsval = FALSE;
2265  consdata->minabsval = SCIP_INVALID;
2266  }
2267  }
2268  }
2269 
2270  /* update maximum activity delta */
2271  if( !SCIPisInfinity(scip, consdata->maxactdelta ) )
2272  {
2273  SCIP_Real domain;
2274  SCIP_Real delta;
2275 
2276  assert(!SCIPisInfinity(scip, SCIPvarGetLbLocal(var)));
2277  assert(!SCIPisInfinity(scip, SCIPvarGetUbLocal(var)));
2278 
2279  domain = SCIPvarGetUbLocal(var) - SCIPvarGetLbLocal(var);
2280  delta = REALABS(newval) * domain;
2281 
2282  if( delta > consdata->maxactdelta )
2283  {
2284  consdata->maxactdelta = delta;
2285  consdata->maxactdeltavar = var;
2286  }
2287  else
2288  {
2289  /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
2290  if( consdata->maxactdeltavar == var )
2291  consdata->maxactdelta = SCIP_INVALID;
2292  }
2293  }
2294 
2295  /* @todo do something more clever here, e.g. if oldval * newval >= 0, do the update directly */
2296  consdataUpdateDelCoef(scip, consdata, var, oldval, checkreliability);
2297  consdataUpdateAddCoef(scip, consdata, var, newval, checkreliability);
2298 }
2299 
2300 /** returns the maximum absolute value of all coefficients in the constraint */
2301 static
2303  SCIP_CONSDATA* consdata /**< linear constraint data */
2304  )
2305 {
2306  assert(consdata != NULL);
2307 
2308  if( !consdata->validmaxabsval )
2309  consdataCalcMaxAbsval(consdata);
2310  assert(consdata->validmaxabsval);
2311  assert(consdata->maxabsval < SCIP_INVALID);
2312 
2313  return consdata->maxabsval;
2314 }
2315 
2316 /** returns the minimum absolute value of all coefficients in the constraint */
2317 static
2319  SCIP_CONSDATA* consdata /**< linear constraint data */
2320  )
2322  assert(consdata != NULL);
2323 
2324  if( !consdata->validminabsval )
2325  consdataCalcMinAbsval(consdata);
2326  assert(consdata->validminabsval);
2327  assert(consdata->minabsval < SCIP_INVALID);
2328 
2329  return consdata->minabsval;
2330 }
2331 
2332 /** calculates minimum and maximum local and global activity for constraint from scratch;
2333  * additionally recalculates maximum absolute value of coefficients
2334  */
2335 static
2337  SCIP* scip, /**< SCIP data structure */
2338  SCIP_CONSDATA* consdata /**< linear constraint data */
2339  )
2340 {
2341  int i;
2342 
2343  assert(scip != NULL);
2344  assert(consdata != NULL);
2345  assert(!consdata->validactivities);
2346  assert(consdata->minactivity >= SCIP_INVALID || consdata->validminact);
2347  assert(consdata->maxactivity >= SCIP_INVALID || consdata->validmaxact);
2348  assert(consdata->glbminactivity >= SCIP_INVALID || consdata->validglbminact);
2349  assert(consdata->glbmaxactivity >= SCIP_INVALID || consdata->validglbmaxact);
2350 
2351  consdata->validmaxabsval = TRUE;
2352  consdata->validminabsval = TRUE;
2353  consdata->validactivities = TRUE;
2354  consdata->validminact = TRUE;
2355  consdata->validmaxact = TRUE;
2356  consdata->validglbminact = TRUE;
2357  consdata->validglbmaxact = TRUE;
2358  consdata->maxabsval = 0.0;
2359  consdata->minabsval = (consdata->nvars == 0 ? 0.0 : REALABS(consdata->vals[0]));
2360  consdata->minactivity = 0.0;
2361  consdata->maxactivity = 0.0;
2362  consdata->lastminactivity = 0.0;
2363  consdata->lastmaxactivity = 0.0;
2364  consdata->minactivityneginf = 0;
2365  consdata->minactivityposinf = 0;
2366  consdata->maxactivityneginf = 0;
2367  consdata->maxactivityposinf = 0;
2368  consdata->minactivityneghuge = 0;
2369  consdata->minactivityposhuge = 0;
2370  consdata->maxactivityneghuge = 0;
2371  consdata->maxactivityposhuge = 0;
2372  consdata->glbminactivity = 0.0;
2373  consdata->glbmaxactivity = 0.0;
2374  consdata->lastglbminactivity = 0.0;
2375  consdata->lastglbmaxactivity = 0.0;
2376  consdata->glbminactivityneginf = 0;
2377  consdata->glbminactivityposinf = 0;
2378  consdata->glbmaxactivityneginf = 0;
2379  consdata->glbmaxactivityposinf = 0;
2380  consdata->glbminactivityneghuge = 0;
2381  consdata->glbminactivityposhuge = 0;
2382  consdata->glbmaxactivityneghuge = 0;
2383  consdata->glbmaxactivityposhuge = 0;
2384 
2385  for( i = 0; i < consdata->nvars; ++i )
2386  consdataUpdateAddCoef(scip, consdata, consdata->vars[i], consdata->vals[i], FALSE);
2387 
2388  consdata->lastminactivity = consdata->minactivity;
2389  consdata->lastmaxactivity = consdata->maxactivity;
2390  consdata->lastglbminactivity = consdata->glbminactivity;
2391  consdata->lastglbmaxactivity = consdata->glbmaxactivity;
2392 }
2393 
2394 /** gets minimal activity for constraint and given values of counters for infinite and huge contributions
2395  * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
2396  */
2397 static
2398 void getMinActivity(
2399  SCIP* scip, /**< SCIP data structure */
2400  SCIP_CONSDATA* consdata, /**< linear constraint */
2401  int posinf, /**< number of coefficients contributing pos. infinite value */
2402  int neginf, /**< number of coefficients contributing neg. infinite value */
2403  int poshuge, /**< number of coefficients contributing huge pos. value */
2404  int neghuge, /**< number of coefficients contributing huge neg. value */
2405  SCIP_Real delta, /**< value to subtract from stored minactivity
2406  * (contribution of the variable set to zero when getting residual activity) */
2407  SCIP_Bool global, /**< should the global or local minimal activity be returned? */
2408  SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
2409  SCIP_Real* minactivity, /**< pointer to store the minimal activity */
2410  SCIP_Bool* isrelax, /**< pointer to store whether the activity is a relaxation,
2411  * i.e. is <= the exact minactivity (in case of huge contributing values) */
2412  SCIP_Bool* issettoinfinity /**< pointer to store whether minactivity was set to infinity or calculated */
2413  )
2414 {
2415  assert(scip != NULL);
2416  assert(consdata != NULL);
2417  assert(posinf >= 0);
2418  assert(neginf >= 0);
2419  assert(poshuge >= 0);
2420  assert(neghuge >= 0);
2421  assert(minactivity != NULL);
2422  assert(isrelax != NULL);
2423  assert(issettoinfinity != NULL);
2424 
2425  /* if we have pos. infinite contributions, the minactivity is +infty */
2426  if( posinf > 0 )
2427  {
2428  *minactivity = SCIPinfinity(scip);
2429  *issettoinfinity = TRUE;
2430  *isrelax = FALSE;
2431  }
2432  /* if we have neg. (and no pos.) infinite contributions, the minactivity is -infty */
2433  else if( neginf > 0 )
2434  {
2435  *minactivity = -SCIPinfinity(scip);
2436  *issettoinfinity = TRUE;
2437  *isrelax = FALSE;
2438  }
2439  /* if we have neg. huge contributions, we only know that -infty is a relaxation of the minactivity */
2440  else if( neghuge > 0 )
2441  {
2442  *minactivity = -SCIPinfinity(scip);
2443  *issettoinfinity = TRUE;
2444  *isrelax = TRUE;
2445  }
2446  /* we do not need a good relaxation and we have positive huge contributions, so we just return -infty as activity */
2447  else if( !goodrelax && poshuge > 0 )
2448  {
2449  *minactivity = -SCIPinfinity(scip);
2450  *issettoinfinity = TRUE;
2451  *isrelax = TRUE;
2452  }
2453  else
2454  {
2455  SCIP_Real tmpactivity;
2456 
2457  /* recompute minactivity if it is not valid */
2458  if( global )
2459  {
2460  if( !consdata->validglbminact )
2461  consdataRecomputeGlbMinactivity(scip, consdata);
2462  assert(consdata->validglbminact);
2463 
2464  tmpactivity = consdata->glbminactivity;
2465  }
2466  else
2467  {
2468  if( !consdata->validminact )
2469  consdataRecomputeMinactivity(scip, consdata);
2470  assert(consdata->validminact);
2471 
2472  tmpactivity = consdata->minactivity;
2473  }
2474 
2475  /* we have no infinite and no neg. huge contributions, but pos. huge contributions;
2476  * a feasible relaxation of the minactivity is the number of positive huge contributions
2477  * times the minimum value counting as "huge" plus finite (and non-huge) part of minactivity - delta
2478  */
2479  if( poshuge > 0 )
2480  {
2481  *minactivity = 1.0 * poshuge * SCIPgetHugeValue(scip) + (tmpactivity - delta);
2482  *issettoinfinity = FALSE;
2483  *isrelax = TRUE;
2484  }
2485  /* all counters are zero, so the minactivity is just stored and we subtract the delta */
2486  else
2487  {
2488  *minactivity = tmpactivity - delta;
2489  *issettoinfinity = FALSE;
2490  *isrelax = FALSE;
2491  }
2492  }
2493 }
2494 
2495 /** gets maximal activity for constraint and given values of counters for infinite and huge contributions
2496  * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
2497  */
2498 static
2499 void getMaxActivity(
2500  SCIP* scip, /**< SCIP data structure */
2501  SCIP_CONSDATA* consdata, /**< linear constraint */
2502  int posinf, /**< number of coefficients contributing pos. infinite value */
2503  int neginf, /**< number of coefficients contributing neg. infinite value */
2504  int poshuge, /**< number of coefficients contributing huge pos. value */
2505  int neghuge, /**< number of coefficients contributing huge neg. value */
2506  SCIP_Real delta, /**< value to subtract from stored maxactivity
2507  * (contribution of the variable set to zero when getting residual activity) */
2508  SCIP_Bool global, /**< should the global or local maximal activity be returned? */
2509  SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
2510  SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
2511  SCIP_Bool* isrelax, /**< pointer to store whether the activity is a relaxation,
2512  * i.e. is >= the exact maxactivity (in case of huge contributing values) */
2513  SCIP_Bool* issettoinfinity /**< pointer to store whether maxactivity was set to infinity or calculated */
2514  )
2515 {
2516  assert(scip != NULL);
2517  assert(consdata != NULL);
2518  assert(posinf >= 0);
2519  assert(neginf >= 0);
2520  assert(poshuge >= 0);
2521  assert(neghuge >= 0);
2522  assert(maxactivity != NULL);
2523  assert(isrelax != NULL);
2524  assert(issettoinfinity != NULL);
2525 
2526  /* if we have neg. infinite contributions, the maxactivity is -infty */
2527  if( neginf > 0 )
2528  {
2529  *maxactivity = -SCIPinfinity(scip);
2530  *issettoinfinity = TRUE;
2531  *isrelax = FALSE;
2532  }
2533  /* if we have pos. (and no neg.) infinite contributions, the maxactivity is +infty */
2534  else if( posinf > 0 )
2535  {
2536  *maxactivity = SCIPinfinity(scip);
2537  *issettoinfinity = TRUE;
2538  *isrelax = FALSE;
2539  }
2540  /* if we have pos. huge contributions, we only know that +infty is a relaxation of the maxactivity */
2541  else if( poshuge > 0 )
2542  {
2543  *maxactivity = SCIPinfinity(scip);
2544  *issettoinfinity = TRUE;
2545  *isrelax = TRUE;
2546  }
2547  /* we do not need a good relaxation and we have positve huge contributions, so we just return +infty as activity */
2548  else if( !goodrelax && neghuge > 0 )
2549  {
2550  *maxactivity = SCIPinfinity(scip);
2551  *issettoinfinity = TRUE;
2552  *isrelax = TRUE;
2553  }
2554  else
2555  {
2556  SCIP_Real tmpactivity;
2557 
2558  /* recompute maxactivity if it is not valid */
2559  if( global )
2560  {
2561  if( !consdata->validglbmaxact )
2562  consdataRecomputeGlbMaxactivity(scip, consdata);
2563  assert(consdata->validglbmaxact);
2564 
2565  tmpactivity = consdata->glbmaxactivity;
2566  }
2567  else
2568  {
2569  if( !consdata->validmaxact )
2570  consdataRecomputeMaxactivity(scip, consdata);
2571  assert(consdata->validmaxact);
2572 
2573  tmpactivity = consdata->maxactivity;
2574  }
2575 
2576  /* we have no infinite, and no pos. huge contributions, but neg. huge contributions;
2577  * a feasible relaxation of the maxactivity is minus the number of negative huge contributions
2578  * times the minimum value counting as "huge" plus the finite (and non-huge) part of maxactivity minus delta
2579  */
2580  if( neghuge > 0 )
2581  {
2582  *maxactivity = -1.0 * neghuge * SCIPgetHugeValue(scip) + tmpactivity - delta;
2583  *issettoinfinity = FALSE;
2584  *isrelax = TRUE;
2585  }
2586  /* all counters are zero, so the maxactivity is just stored and we subtract the delta */
2587  else
2588  {
2589  *maxactivity = tmpactivity - delta;
2590  *issettoinfinity = FALSE;
2591  *isrelax = FALSE;
2592  }
2593  }
2594 }
2595 
2596 /** gets activity bounds for constraint */
2597 static
2599  SCIP* scip, /**< SCIP data structure */
2600  SCIP_CONSDATA* consdata, /**< linear constraint */
2601  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2602  * relaxed activities ignored, anyway? */
2603  SCIP_Real* minactivity, /**< pointer to store the minimal activity */
2604  SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
2605  SCIP_Bool* minisrelax, /**< pointer to store whether the returned minactivity is just a relaxation,
2606  * i.e. <= the exact minactivity (in case of huge contributions),
2607  * or equal to the exact minimal activity */
2608  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned maxactivity is just a relaxation,
2609  * i.e. >= the exact maxactivity (in case of huge contributions),
2610  * or equal to the exact maximal activity */
2611  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minactivity was set to infinity or calculated */
2612  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxactivity was set to infinity or calculated */
2613 
2614  )
2615 {
2616  assert(scip != NULL);
2617  assert(consdata != NULL);
2618  assert(minactivity != NULL);
2619  assert(maxactivity != NULL);
2620  assert(isminsettoinfinity != NULL);
2621  assert(ismaxsettoinfinity != NULL);
2622 
2623  if( !consdata->validactivities )
2624  {
2625  consdataCalcActivities(scip, consdata);
2626  assert(consdata->validminact);
2627  assert(consdata->validmaxact);
2628  }
2629  assert(consdata->minactivity < SCIP_INVALID);
2630  assert(consdata->maxactivity < SCIP_INVALID);
2631  assert(consdata->minactivityneginf >= 0);
2632  assert(consdata->minactivityposinf >= 0);
2633  assert(consdata->maxactivityneginf >= 0);
2634  assert(consdata->maxactivityposinf >= 0);
2635 
2636  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2637  consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2638  minactivity, minisrelax, isminsettoinfinity);
2639 
2640  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2641  consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2642  maxactivity, maxisrelax, ismaxsettoinfinity);
2643 }
2644 
2645 /** calculates activity bounds for constraint after setting variable to zero */
2646 static
2648  SCIP* scip, /**< SCIP data structure */
2649  SCIP_CONSDATA* consdata, /**< linear constraint */
2650  SCIP_VAR* cancelvar, /**< variable to calculate activity residual for */
2651  SCIP_Real* resactivity, /**< pointer to store the residual activity */
2652  SCIP_Bool isminresact, /**< should minimal or maximal residual activity be calculated? */
2653  SCIP_Bool useglobalbounds /**< should global or local bounds be used? */
2654  )
2655 {
2656  SCIP_VAR* var;
2657  SCIP_Real val;
2658  SCIP_Real lb;
2659  SCIP_Real ub;
2660  int v;
2661 
2662  assert(scip != NULL);
2663  assert(consdata != NULL);
2664  assert(cancelvar != NULL);
2665  assert(resactivity != NULL);
2667  *resactivity = 0.0;
2668 
2669  for( v = 0; v < consdata->nvars; ++v )
2670  {
2671  var = consdata->vars[v];
2672  assert(var != NULL);
2673  if( var == cancelvar )
2674  continue;
2675 
2676  val = consdata->vals[v];
2677 
2678  if( useglobalbounds )
2679  {
2680  lb = SCIPvarGetLbGlobal(var);
2681  ub = SCIPvarGetUbGlobal(var);
2682  }
2683  else
2684  {
2685  lb = SCIPvarGetLbLocal(var);
2686  ub = SCIPvarGetUbLocal(var);
2687  }
2688 
2689  assert(!SCIPisZero(scip, val));
2690  assert(SCIPisLE(scip, lb, ub));
2691 
2692  if( val > 0.0 )
2693  {
2694  if( isminresact )
2695  {
2696  assert(!SCIPisInfinity(scip, -lb));
2697  assert(!SCIPisHugeValue(scip, REALABS(val*lb)));
2698  *resactivity += val*lb;
2699  }
2700  else
2701  {
2702  assert(!SCIPisInfinity(scip, ub));
2703  assert(!SCIPisHugeValue(scip, REALABS(val*ub)));
2704  *resactivity += val*ub;
2705  }
2706  }
2707  else
2708  {
2709  if( isminresact)
2710  {
2711  assert(!SCIPisInfinity(scip, ub));
2712  assert(!SCIPisHugeValue(scip, REALABS(val*ub)));
2713  *resactivity += val*ub;
2714  }
2715  else
2716  {
2717  assert(!SCIPisInfinity(scip, -lb));
2718  assert(!SCIPisHugeValue(scip, REALABS(val*lb)));
2719  *resactivity += val*lb;
2720  }
2721  }
2722  }
2723  assert(!SCIPisInfinity(scip, *resactivity) && !SCIPisInfinity(scip, -(*resactivity)));
2724 }
2725 
2726 /** gets activity bounds for constraint after setting variable to zero */
2727 static
2729  SCIP* scip, /**< SCIP data structure */
2730  SCIP_CONSDATA* consdata, /**< linear constraint */
2731  SCIP_VAR* var, /**< variable to calculate activity residual for */
2732  SCIP_Real val, /**< coefficient value of variable in linear constraint */
2733  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2734  * relaxed acticities ignored, anyway? */
2735  SCIP_Real* minresactivity, /**< pointer to store the minimal residual activity */
2736  SCIP_Real* maxresactivity, /**< pointer to store the maximal residual activity */
2737  SCIP_Bool* minisrelax, /**< pointer to store whether the returned residual minactivity is just a
2738  * relaxation, i.e. <= the exact residual minactivity (in case of huge
2739  * contributions), or equal to the exact residual minactivity */
2740  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned residual maxactivity is just a
2741  * relaxation, i.e. <= the exact residual maxactivity (in case of huge
2742  * contributions), or equal to the exact residual minactivity */
2743  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2744  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
2745  )
2746 {
2747  SCIP_Real minactbound;
2748  SCIP_Real maxactbound;
2749  SCIP_Real absval;
2750 
2751  assert(scip != NULL);
2752  assert(consdata != NULL);
2753  assert(var != NULL);
2754  assert(minresactivity != NULL);
2755  assert(maxresactivity != NULL);
2756  assert(minisrelax != NULL);
2757  assert(maxisrelax != NULL);
2758  assert(isminsettoinfinity != NULL);
2759  assert(ismaxsettoinfinity != NULL);
2760 
2761  /* get activity bounds of linear constraint */
2762  if( !consdata->validactivities )
2763  {
2764  consdataCalcActivities(scip, consdata);
2765  assert(consdata->validminact);
2766  assert(consdata->validmaxact);
2767  }
2768  assert(consdata->minactivity < SCIP_INVALID);
2769  assert(consdata->maxactivity < SCIP_INVALID);
2770  assert(consdata->minactivityneginf >= 0);
2771  assert(consdata->minactivityposinf >= 0);
2772  assert(consdata->maxactivityneginf >= 0);
2773  assert(consdata->maxactivityposinf >= 0);
2774  assert(consdata->minactivityneghuge >= 0);
2775  assert(consdata->minactivityposhuge >= 0);
2776  assert(consdata->maxactivityneghuge >= 0);
2777  assert(consdata->maxactivityposhuge >= 0);
2778 
2779  if( val > 0.0 )
2780  {
2781  minactbound = SCIPvarGetLbLocal(var);
2782  maxactbound = SCIPvarGetUbLocal(var);
2783  absval = val;
2784  }
2785  else
2786  {
2787  minactbound = -SCIPvarGetUbLocal(var);
2788  maxactbound = -SCIPvarGetLbLocal(var);
2789  absval = -val;
2790  }
2791 
2792  /* get/compute minactivity by calling getMinActivity() with updated counters for infinite and huge values
2793  * and contribution of variable set to zero that has to be subtracted from finite part of activity
2794  */
2795  if( SCIPisInfinity(scip, minactbound) )
2796  {
2797  assert(consdata->minactivityposinf >= 1);
2798 
2799  getMinActivity(scip, consdata, consdata->minactivityposinf - 1, consdata->minactivityneginf,
2800  consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2801  minresactivity, minisrelax, isminsettoinfinity);
2802  }
2803  else if( SCIPisInfinity(scip, -minactbound) )
2804  {
2805  assert(consdata->minactivityneginf >= 1);
2806 
2807  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf - 1,
2808  consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2809  minresactivity, minisrelax, isminsettoinfinity);
2810  }
2811  else if( SCIPisHugeValue(scip, minactbound * absval) )
2812  {
2813  assert(consdata->minactivityposhuge >= 1);
2814 
2815  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2816  consdata->minactivityposhuge - 1, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2817  minresactivity, minisrelax, isminsettoinfinity);
2818  }
2819  else if( SCIPisHugeValue(scip, -minactbound * absval) )
2820  {
2821  assert(consdata->minactivityneghuge >= 1);
2822 
2823  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2824  consdata->minactivityposhuge, consdata->minactivityneghuge - 1, 0.0, FALSE, goodrelax,
2825  minresactivity, minisrelax, isminsettoinfinity);
2826  }
2827  else
2828  {
2829  getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2830  consdata->minactivityposhuge, consdata->minactivityneghuge, absval * minactbound, FALSE, goodrelax,
2831  minresactivity, minisrelax, isminsettoinfinity);
2832  }
2833 
2834  /* get/compute maxactivity by calling getMaxActivity() with updated counters for infinite and huge values
2835  * and contribution of variable set to zero that has to be subtracted from finite part of activity
2836  */
2837  if( SCIPisInfinity(scip, -maxactbound) )
2838  {
2839  assert(consdata->maxactivityneginf >= 1);
2840 
2841  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf - 1,
2842  consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2843  maxresactivity, maxisrelax, ismaxsettoinfinity);
2844  }
2845  else if( SCIPisInfinity(scip, maxactbound) )
2846  {
2847  assert(consdata->maxactivityposinf >= 1);
2848 
2849  getMaxActivity(scip, consdata, consdata->maxactivityposinf - 1, consdata->maxactivityneginf,
2850  consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2851  maxresactivity, maxisrelax, ismaxsettoinfinity);
2852  }
2853  else if( SCIPisHugeValue(scip, absval * maxactbound) )
2854  {
2855  assert(consdata->maxactivityposhuge >= 1);
2856 
2857  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2858  consdata->maxactivityposhuge - 1, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2859  maxresactivity, maxisrelax, ismaxsettoinfinity);
2860  }
2861  else if( SCIPisHugeValue(scip, -absval * maxactbound) )
2862  {
2863  assert(consdata->maxactivityneghuge >= 1);
2864 
2865  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2866  consdata->maxactivityposhuge, consdata->maxactivityneghuge - 1, 0.0, FALSE, goodrelax,
2867  maxresactivity, maxisrelax, ismaxsettoinfinity);
2868  }
2869  else
2870  {
2871  getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2872  consdata->maxactivityposhuge, consdata->maxactivityneghuge, absval * maxactbound, FALSE, goodrelax,
2873  maxresactivity, maxisrelax, ismaxsettoinfinity);
2874  }
2875 }
2876 
2877 /** gets global activity bounds for constraint */
2878 static
2880  SCIP* scip, /**< SCIP data structure */
2881  SCIP_CONSDATA* consdata, /**< linear constraint */
2882  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2883  * relaxed acticities ignored, anyway? */
2884  SCIP_Real* glbminactivity, /**< pointer to store the minimal activity, or NULL, if not needed */
2885  SCIP_Real* glbmaxactivity, /**< pointer to store the maximal activity, or NULL, if not needed */
2886  SCIP_Bool* minisrelax, /**< pointer to store whether the returned minactivity is just a relaxation,
2887  * i.e. <= the exact minactivity (in case of huge contributions),
2888  * or equal to the exact minimal activity */
2889  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned maxactivity is just a relaxation,
2890  * i.e. >= the exact maxactivity (in case of huge contributions),
2891  * or equal to the exact maximal activity */
2892  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2893  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
2894  )
2895 {
2896  assert(scip != NULL);
2897  assert(consdata != NULL);
2898  assert((glbminactivity != NULL && minisrelax != NULL && isminsettoinfinity != NULL)
2899  || (glbmaxactivity != NULL && maxisrelax != NULL && ismaxsettoinfinity != NULL));
2900 
2901  if( !consdata->validactivities )
2902  {
2903  consdataCalcActivities(scip, consdata);
2904  assert(consdata->validglbminact);
2905  assert(consdata->validglbmaxact);
2906  }
2907  assert(consdata->glbminactivity < SCIP_INVALID);
2908  assert(consdata->glbmaxactivity < SCIP_INVALID);
2909  assert(consdata->glbminactivityneginf >= 0);
2910  assert(consdata->glbminactivityposinf >= 0);
2911  assert(consdata->glbmaxactivityneginf >= 0);
2912  assert(consdata->glbmaxactivityposinf >= 0);
2913  assert(consdata->glbminactivityneghuge >= 0);
2914  assert(consdata->glbminactivityposhuge >= 0);
2915  assert(consdata->glbmaxactivityneghuge >= 0);
2916  assert(consdata->glbmaxactivityposhuge >= 0);
2917 
2918  if( glbminactivity != NULL )
2919  {
2920  assert(isminsettoinfinity != NULL);
2921  assert(minisrelax != NULL);
2922 
2923  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
2924  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
2925  glbminactivity, minisrelax, isminsettoinfinity);
2926  }
2927 
2928  if( glbmaxactivity != NULL )
2929  {
2930  assert(ismaxsettoinfinity != NULL);
2931  assert(maxisrelax != NULL);
2932 
2933  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
2934  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
2935  glbmaxactivity, maxisrelax, ismaxsettoinfinity);
2936  }
2937 }
2938 
2939 /** gets global activity bounds for constraint after setting variable to zero */
2940 static
2942  SCIP* scip, /**< SCIP data structure */
2943  SCIP_CONSDATA* consdata, /**< linear constraint */
2944  SCIP_VAR* var, /**< variable to calculate activity residual for */
2945  SCIP_Real val, /**< coefficient value of variable in linear constraint */
2946  SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2947  * relaxed acticities ignored, anyway? */
2948  SCIP_Real* minresactivity, /**< pointer to store the minimal residual activity, or NULL, if not needed */
2949  SCIP_Real* maxresactivity, /**< pointer to store the maximal residual activity, or NULL, if not needed */
2950  SCIP_Bool* minisrelax, /**< pointer to store whether the returned residual minactivity is just a
2951  * relaxation, i.e. <= the exact residual minactivity (in case of huge
2952  * contributions), or equal to the exact residual minactivity */
2953  SCIP_Bool* maxisrelax, /**< pointer to store whether the returned residual maxactivity is just a
2954  * relaxation, i.e. <= the exact residual maxactivity (in case of huge
2955  * contributions), or equal to the exact residual minactivity */
2956  SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2957  SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
2958  )
2959 {
2960  SCIP_Real minactbound;
2961  SCIP_Real maxactbound;
2962  SCIP_Real absval;
2963 
2964  assert(scip != NULL);
2965  assert(consdata != NULL);
2966  assert(var != NULL);
2967  assert((minresactivity != NULL && minisrelax != NULL && isminsettoinfinity != NULL )
2968  || (maxresactivity != NULL && maxisrelax != NULL && ismaxsettoinfinity != NULL));
2969 
2970  /* get activity bounds of linear constraint */
2971  if( !consdata->validactivities )
2972  consdataCalcActivities(scip, consdata);
2973 
2974  assert(consdata->glbminactivity < SCIP_INVALID);
2975  assert(consdata->glbmaxactivity < SCIP_INVALID);
2976  assert(consdata->glbminactivityneginf >= 0);
2977  assert(consdata->glbminactivityposinf >= 0);
2978  assert(consdata->glbmaxactivityneginf >= 0);
2979  assert(consdata->glbmaxactivityposinf >= 0);
2980 
2981  if( val > 0.0 )
2982  {
2983  minactbound = SCIPvarGetLbGlobal(var);
2984  maxactbound = SCIPvarGetUbGlobal(var);
2985  absval = val;
2986  }
2987  else
2988  {
2989  minactbound = -SCIPvarGetUbGlobal(var);
2990  maxactbound = -SCIPvarGetLbGlobal(var);
2991  absval = -val;
2992  }
2993 
2994  if( minresactivity != NULL )
2995  {
2996  assert(isminsettoinfinity != NULL);
2997  assert(minisrelax != NULL);
2998 
2999  /* get/compute minactivity by calling getMinActivity() with updated counters for infinite and huge values
3000  * and contribution of variable set to zero that has to be subtracted from finite part of activity
3001  */
3002  if( SCIPisInfinity(scip, minactbound) )
3003  {
3004  assert(consdata->glbminactivityposinf >= 1);
3005 
3006  getMinActivity(scip, consdata, consdata->glbminactivityposinf - 1, consdata->glbminactivityneginf,
3007  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
3008  minresactivity, minisrelax, isminsettoinfinity);
3009  }
3010  else if( SCIPisInfinity(scip, -minactbound) )
3011  {
3012  assert(consdata->glbminactivityneginf >= 1);
3013 
3014  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf - 1,
3015  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
3016  minresactivity, minisrelax, isminsettoinfinity);
3017  }
3018  else if( SCIPisHugeValue(scip, minactbound * absval) )
3019  {
3020  assert(consdata->glbminactivityposhuge >= 1);
3021 
3022  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
3023  consdata->glbminactivityposhuge - 1, consdata->glbminactivityneghuge, 0.0, TRUE, goodrelax,
3024  minresactivity, minisrelax, isminsettoinfinity);
3025  }
3026  else if( SCIPisHugeValue(scip, -minactbound * absval) )
3027  {
3028  assert(consdata->glbminactivityneghuge >= 1);
3029 
3030  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
3031  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge - 1, 0.0, TRUE, goodrelax,
3032  minresactivity, minisrelax, isminsettoinfinity);
3033  }
3034  else
3035  {
3036  getMinActivity(scip, consdata, consdata->glbminactivityposinf, consdata->glbminactivityneginf,
3037  consdata->glbminactivityposhuge, consdata->glbminactivityneghuge, absval * minactbound, TRUE,
3038  goodrelax, minresactivity, minisrelax, isminsettoinfinity);
3039  }
3040  }
3041 
3042  if( maxresactivity != NULL )
3043  {
3044  assert(ismaxsettoinfinity != NULL);
3045  assert(maxisrelax != NULL);
3046 
3047  /* get/compute maxactivity by calling getMaxActivity() with updated counters for infinite and huge values
3048  * and contribution of variable set to zero that has to be subtracted from finite part of activity
3049  */
3050  if( SCIPisInfinity(scip, -maxactbound) )
3051  {
3052  assert(consdata->glbmaxactivityneginf >= 1);
3053 
3054  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf - 1,
3055  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
3056  maxresactivity, maxisrelax, ismaxsettoinfinity);
3057  }
3058  else if( SCIPisInfinity(scip, maxactbound) )
3059  {
3060  assert(consdata->glbmaxactivityposinf >= 1);
3061 
3062  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf - 1, consdata->glbmaxactivityneginf,
3063  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
3064  maxresactivity, maxisrelax, ismaxsettoinfinity);
3065  }
3066  else if( SCIPisHugeValue(scip, absval * maxactbound) )
3067  {
3068  assert(consdata->glbmaxactivityposhuge >= 1);
3069 
3070  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
3071  consdata->glbmaxactivityposhuge - 1, consdata->glbmaxactivityneghuge, 0.0, TRUE, goodrelax,
3072  maxresactivity, maxisrelax, ismaxsettoinfinity);
3073  }
3074  else if( SCIPisHugeValue(scip, -absval * maxactbound) )
3075  {
3076  assert(consdata->glbmaxactivityneghuge >= 1);
3077 
3078  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
3079  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge - 1, 0.0, TRUE, goodrelax,
3080  maxresactivity, maxisrelax, ismaxsettoinfinity);
3081  }
3082  else
3083  {
3084  getMaxActivity(scip, consdata, consdata->glbmaxactivityposinf, consdata->glbmaxactivityneginf,
3085  consdata->glbmaxactivityposhuge, consdata->glbmaxactivityneghuge, absval * maxactbound, TRUE,
3086  goodrelax, maxresactivity, maxisrelax, ismaxsettoinfinity);
3087  }
3088  }
3089 }
3090 
3091 /** calculates the activity of the linear constraint for given solution */
3092 static
3094  SCIP* scip, /**< SCIP data structure */
3095  SCIP_CONSDATA* consdata, /**< linear constraint data */
3096  SCIP_SOL* sol /**< solution to get activity for, NULL to current solution */
3097  )
3098 {
3099  SCIP_Real activity;
3100 
3101  assert(scip != NULL);
3102  assert(consdata != NULL);
3103 
3104  if( sol == NULL && !SCIPhasCurrentNodeLP(scip) )
3105  activity = consdataComputePseudoActivity(scip, consdata);
3106  else
3107  {
3108  SCIP_Real solval;
3109  int nposinf;
3110  int nneginf;
3111  SCIP_Bool negsign;
3112  int v;
3113 
3114  activity = 0.0;
3115  nposinf = 0;
3116  nneginf = 0;
3117 
3118  for( v = 0; v < consdata->nvars; ++v )
3119  {
3120  solval = SCIPgetSolVal(scip, sol, consdata->vars[v]);
3121 
3122  if( consdata->vals[v] < 0 )
3123  negsign = TRUE;
3124  else
3125  negsign = FALSE;
3126 
3127  if( (SCIPisInfinity(scip, solval) && !negsign) || (SCIPisInfinity(scip, -solval) && negsign) )
3128  ++nposinf;
3129  else if( (SCIPisInfinity(scip, solval) && negsign) || (SCIPisInfinity(scip, -solval) && !negsign) )
3130  ++nneginf;
3131  else
3132  activity += consdata->vals[v] * solval;
3133  }
3134  assert(nneginf >= 0 && nposinf >= 0);
3135 
3136  SCIPdebugMsg(scip, "activity of linear constraint: %.15g, %d positive infinity values, %d negative infinity values \n", activity, nposinf, nneginf);
3137 
3138  /* check for amount of infinity values and correct the activity */
3139  if( nposinf > 0 && nneginf > 0 )
3140  activity = (consdata->rhs + consdata->lhs) / 2;
3141  else if( nposinf > 0 )
3142  activity = SCIPinfinity(scip);
3143  else if( nneginf > 0 )
3144  activity = -SCIPinfinity(scip);
3145 
3146  SCIPdebugMsg(scip, "corrected activity of linear constraint: %.15g\n", activity);
3147  }
3148 
3149  if( activity == SCIP_INVALID ) /*lint !e777*/
3150  return activity;
3151  else if( activity < 0 )
3152  activity = MAX(activity, -SCIPinfinity(scip)); /*lint !e666*/
3153  else
3154  activity = MIN(activity, SCIPinfinity(scip)); /*lint !e666*/
3155 
3156  return activity;
3157 }
3158 
3159 /** calculates the feasibility of the linear constraint for given solution */
3160 static
3162  SCIP* scip, /**< SCIP data structure */
3163  SCIP_CONSDATA* consdata, /**< linear constraint data */
3164  SCIP_SOL* sol /**< solution to get feasibility for, NULL to current solution */
3165  )
3166 {
3167  SCIP_Real activity;
3168 
3169  assert(scip != NULL);
3170  assert(consdata != NULL);
3171 
3172  activity = consdataGetActivity(scip, consdata, sol);
3173 
3174  if( activity == SCIP_INVALID ) /*lint !e777*/
3175  return -SCIPinfinity(scip);
3176 
3177  return MIN(consdata->rhs - activity, activity - consdata->lhs);
3178 }
3179 
3180 /** updates bit signatures after adding a single coefficient */
3181 static
3183  SCIP_CONSDATA* consdata, /**< linear constraint data */
3184  int pos /**< position of coefficient to update signatures for */
3185  )
3186 {
3187  uint64_t varsignature;
3188  SCIP_Real lb;
3189  SCIP_Real ub;
3190  SCIP_Real val;
3191 
3192  assert(consdata != NULL);
3193  assert(consdata->validsignature);
3194 
3195  varsignature = SCIPhashSignature64(SCIPvarGetIndex(consdata->vars[pos]));
3196  lb = SCIPvarGetLbGlobal(consdata->vars[pos]);
3197  ub = SCIPvarGetUbGlobal(consdata->vars[pos]);
3198  val = consdata->vals[pos];
3199  if( (val > 0.0 && ub > 0.0) || (val < 0.0 && lb < 0.0) )
3200  consdata->possignature |= varsignature;
3201  if( (val > 0.0 && lb < 0.0) || (val < 0.0 && ub > 0.0) )
3202  consdata->negsignature |= varsignature;
3203 }
3204 
3205 /** calculates the bit signatures of the given constraint data */
3206 static
3208  SCIP_CONSDATA* consdata /**< linear constraint data */
3209  )
3210 {
3211  assert(consdata != NULL);
3212 
3213  if( !consdata->validsignature )
3214  {
3215  int i;
3216 
3217  consdata->validsignature = TRUE;
3218  consdata->possignature = 0;
3219  consdata->negsignature = 0;
3220  for( i = 0; i < consdata->nvars; ++i )
3221  consdataUpdateSignatures(consdata, i);
3222  }
3223 }
3224 
3225 /** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
3226 static
3227 SCIP_DECL_SORTINDCOMP(consdataCompVar)
3228 { /*lint --e{715}*/
3229  SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
3230  SCIP_VAR* var1;
3231  SCIP_VAR* var2;
3232 
3233  assert(consdata != NULL);
3234  assert(0 <= ind1 && ind1 < consdata->nvars);
3235  assert(0 <= ind2 && ind2 < consdata->nvars);
3236 
3237  var1 = consdata->vars[ind1];
3238  var2 = consdata->vars[ind2];
3239 
3240  /* exactly one variable is binary */
3241  if( SCIPvarIsBinary(var1) != SCIPvarIsBinary(var2) )
3242  {
3243  return (SCIPvarIsBinary(var1) ? -1 : +1);
3244  }
3245  /* both variables are binary */
3246  else if( SCIPvarIsBinary(var1) )
3247  {
3248  return SCIPvarCompare(var1, var2);
3249  }
3250  else
3251  {
3252  SCIP_VARTYPE vartype1 = SCIPvarGetType(var1);
3253  SCIP_VARTYPE vartype2 = SCIPvarGetType(var2);
3254 
3255  if( vartype1 < vartype2 )
3256  return -1;
3257  else if( vartype1 > vartype2 )
3258  return +1;
3259  else
3260  return SCIPvarCompare(var1, var2);
3261  }
3262 }
3263 
3264 /** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
3265 static
3266 SCIP_DECL_SORTINDCOMP(consdataCompVarProp)
3267 { /*lint --e{715}*/
3268  SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
3269  SCIP_VAR* var1;
3270  SCIP_VAR* var2;
3271 
3272  assert(consdata != NULL);
3273  assert(0 <= ind1 && ind1 < consdata->nvars);
3274  assert(0 <= ind2 && ind2 < consdata->nvars);
3275 
3276  var1 = consdata->vars[ind1];
3277  var2 = consdata->vars[ind2];
3278 
3279  /* exactly one variable is binary */
3280  if( SCIPvarIsBinary(var1) != SCIPvarIsBinary(var2) )
3281  {
3282  return (SCIPvarIsBinary(var1) ? -1 : +1);
3283  }
3284  /* both variables are binary */
3285  else if( SCIPvarIsBinary(var1) )
3286  {
3287  SCIP_Real abscoef1 = REALABS(consdata->vals[ind1]);
3288  SCIP_Real abscoef2 = REALABS(consdata->vals[ind2]);
3289 
3290  if( EPSGT(abscoef1, abscoef2, 1e-9) )
3291  return -1;
3292  else if( EPSGT(abscoef2, abscoef1, 1e-9) )
3293  return +1;
3294  else
3295  return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
3296  }
3297  else
3298  {
3299  SCIP_VARTYPE vartype1 = SCIPvarGetType(var1);
3300  SCIP_VARTYPE vartype2 = SCIPvarGetType(var2);
3301 
3302  if( vartype1 < vartype2 )
3303  {
3304  return -1;
3305  }
3306  else if( vartype1 > vartype2 )
3307  {
3308  return +1;
3309  }
3310  else
3311  {
3312  /* both variables are continuous */
3313  if( !SCIPvarIsIntegral(var1) )
3314  {
3315  assert(!SCIPvarIsIntegral(var2));
3316  return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
3317  }
3318  else
3319  {
3320  SCIP_Real abscont1 = REALABS(consdata->vals[ind1] * (SCIPvarGetUbGlobal(var1) - SCIPvarGetLbGlobal(var1)));
3321  SCIP_Real abscont2 = REALABS(consdata->vals[ind2] * (SCIPvarGetUbGlobal(var2) - SCIPvarGetLbGlobal(var2)));
3322 
3323  if( EPSGT(abscont1, abscont2, 1e-9) )
3324  return -1;
3325  else if( EPSGT(abscont2, abscont1, 1e-9) )
3326  return +1;
3327  else
3328  return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
3329  }
3330  }
3331  }
3332 }
3333 
3334 /** permutes the constraint's variables according to a given permutation. */
3335 static
3336 void permSortConsdata(
3337  SCIP_CONSDATA* consdata, /**< the constraint data */
3338  int* perm, /**< the target permutation */
3339  int nvars /**< the number of variables */
3340  )
3341 { /*lint --e{715}*/
3342  SCIP_VAR* varv;
3343  SCIP_EVENTDATA* eventdatav;
3344  SCIP_Real valv;
3345  int v;
3346  int i;
3347  int nexti;
3348 
3349  assert(perm != NULL);
3350  assert(consdata != NULL);
3351 
3352  /* permute the variables in the linear constraint according to the target permutation */
3353  eventdatav = NULL;
3354  for( v = 0; v < nvars; ++v )
3355  {
3356  if( perm[v] != v )
3357  {
3358  varv = consdata->vars[v];
3359  valv = consdata->vals[v];
3360  if( consdata->eventdata != NULL )
3361  eventdatav = consdata->eventdata[v];
3362  i = v;
3363  do
3364  {
3365  assert(0 <= perm[i] && perm[i] < nvars);
3366  assert(perm[i] != i);
3367  consdata->vars[i] = consdata->vars[perm[i]];
3368  consdata->vals[i] = consdata->vals[perm[i]];
3369  if( consdata->eventdata != NULL )
3370  {
3371  consdata->eventdata[i] = consdata->eventdata[perm[i]];
3372  consdata->eventdata[i]->varpos = i;
3373  }
3374  nexti = perm[i];
3375  perm[i] = i;
3376  i = nexti;
3377  }
3378  while( perm[i] != v );
3379  consdata->vars[i] = varv;
3380  consdata->vals[i] = valv;
3381  if( consdata->eventdata != NULL )
3382  {
3383  consdata->eventdata[i] = eventdatav;
3384  consdata->eventdata[i]->varpos = i;
3385  }
3386  perm[i] = i;
3387  }
3388  }
3389 #ifdef SCIP_DEBUG
3390  /* check sorting */
3391  for( v = 0; v < nvars; ++v )
3392  {
3393  assert(perm[v] == v);
3394  assert(consdata->eventdata == NULL || consdata->eventdata[v]->varpos == v);
3395  }
3396 #endif
3397 }
3398 
3399 /** sorts linear constraint's variables depending on the stage of the solving process:
3400  * - during PRESOLVING
3401  * sorts variables by binaries, integers, implicit integers, and continuous variables,
3402  * and the variables of the same type by non-decreasing variable index
3403  *
3404  * - during SOLVING
3405  * sorts variables of the remaining problem by binaries, integers, implicit integers, and continuous variables,
3406  * and binary and integer variables by their global max activity delta (within each group),
3407  * ties within a group are broken by problem index of the variable.
3408  *
3409  * This fastens the propagation time of the constraint handler.
3410  */
3411 static
3413  SCIP* scip, /**< SCIP data structure */
3414  SCIP_CONSDATA* consdata /**< linear constraint data */
3415  )
3416 {
3417  assert(scip != NULL);
3418  assert(consdata != NULL);
3419 
3420  /* check if there are variables for sorting */
3421  if( consdata->nvars <= 1 )
3422  {
3423  consdata->indexsorted = TRUE;
3424  consdata->coefsorted = TRUE;
3425  consdata->nbinvars = (consdata->nvars == 1 ? (int)SCIPvarIsBinary(consdata->vars[0]) : 0);
3426  }
3427  else if( (!consdata->indexsorted && SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE)
3428  || (!consdata->coefsorted && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE) )
3429  {
3430  int* perm;
3431  int v;
3432 
3433  /* get temporary memory to store the sorted permutation */
3434  SCIP_CALL( SCIPallocBufferArray(scip, &perm, consdata->nvars) );
3435 
3436  /* call sorting method */
3437  if( SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE )
3438  SCIPsort(perm, consdataCompVar, (void*)consdata, consdata->nvars);
3439  else
3440  SCIPsort(perm, consdataCompVarProp, (void*)consdata, consdata->nvars);
3441 
3442  permSortConsdata(consdata, perm, consdata->nvars);
3443 
3444  /* free temporary memory */
3445  SCIPfreeBufferArray(scip, &perm);
3446 
3447  if( SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE )
3448  {
3449  consdata->indexsorted = FALSE;
3450  consdata->coefsorted = TRUE;
3451 
3452  /* count binary variables in the sorted vars array */
3453  consdata->nbinvars = 0;
3454  for( v = 0; v < consdata->nvars; ++v )
3455  {
3456  if( SCIPvarIsBinary(consdata->vars[v]) )
3457  ++consdata->nbinvars;
3458  else
3459  break;
3460  }
3461  }
3462  else
3463  {
3464  consdata->indexsorted = TRUE;
3465  consdata->coefsorted = FALSE;
3466  }
3467  }
3468 
3469  return SCIP_OKAY;
3470 }
3471 
3472 
3473 /*
3474  * local linear constraint handler methods
3475  */
3476 
3477 /** sets left hand side of linear constraint */
3478 static
3480  SCIP* scip, /**< SCIP data structure */
3481  SCIP_CONS* cons, /**< linear constraint */
3482  SCIP_Real lhs /**< new left hand side */
3483  )
3484 {
3485  SCIP_CONSDATA* consdata;
3486  SCIP_Bool locked;
3487  int i;
3488 
3489  assert(scip != NULL);
3490  assert(cons != NULL);
3491  assert(!SCIPisInfinity(scip, lhs));
3492 
3493  /* adjust value to not be smaller than -inf */
3494  if ( SCIPisInfinity(scip, -lhs) )
3495  lhs = -SCIPinfinity(scip);
3496 
3497  consdata = SCIPconsGetData(cons);
3498  assert(consdata != NULL);
3499  assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
3500  assert(!SCIPisInfinity(scip, consdata->lhs));
3501 
3502  /* check whether the side is not changed */
3503  if( SCIPisEQ(scip, consdata->lhs, lhs) )
3504  return SCIP_OKAY;
3505 
3506  /* ensure that rhs >= lhs is satisfied without numerical tolerance */
3507  if( SCIPisEQ(scip, lhs, consdata->rhs) )
3508  {
3509  consdata->rhs = lhs;
3510  assert(consdata->row == NULL);
3511  }
3512 
3513  locked = FALSE;
3514  for( i = 0; i < NLOCKTYPES && !locked; i++ )
3515  locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
3516 
3517  /* if necessary, update the rounding locks of variables */
3518  if( locked )
3519  {
3520  if( SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, -lhs) )
3521  {
3522  SCIP_VAR** vars;
3523  SCIP_Real* vals;
3524  int v;
3525 
3526  /* the left hand side switched from -infinity to a non-infinite value -> install rounding locks */
3527  vars = consdata->vars;
3528  vals = consdata->vals;
3529 
3530  for( v = 0; v < consdata->nvars; ++v )
3531  {
3532  assert(vars[v] != NULL);
3533  assert(!SCIPisZero(scip, vals[v]));
3534 
3535  if( SCIPisPositive(scip, vals[v]) )
3536  {
3537  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3538  }
3539  else
3540  {
3541  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3542  }
3543  }
3544  }
3545  else if( !SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, -lhs) )
3546  {
3547  SCIP_VAR** vars;
3548  SCIP_Real* vals;
3549  int v;
3550 
3551  /* the left hand side switched from a non-infinite value to -infinity -> remove rounding locks */
3552  vars = consdata->vars;
3553  vals = consdata->vals;
3554 
3555  for( v = 0; v < consdata->nvars; ++v )
3556  {
3557  assert(vars[v] != NULL);
3558  assert(!SCIPisZero(scip, vals[v]));
3559 
3560  if( SCIPisPositive(scip, vals[v]) )
3561  {
3562  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3563  }
3564  else
3565  {
3566  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3567  }
3568  }
3569  }
3570  }
3571 
3572  /* check whether the left hand side is increased, if and only if that's the case we maybe can propagate, tighten and add more cliques */
3573  if( !SCIPisInfinity(scip, -lhs) && SCIPisGT(scip, lhs, consdata->lhs) )
3574  {
3575  consdata->boundstightened = 0;
3576  consdata->presolved = FALSE;
3577  consdata->cliquesadded = FALSE;
3578  consdata->implsadded = FALSE;
3579 
3580  /* mark the constraint for propagation */
3581  if( SCIPconsIsTransformed(cons) )
3582  {
3583  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3584  }
3585  }
3586 
3587  /* set new left hand side and update constraint data */
3588  consdata->lhs = lhs;
3589  consdata->changed = TRUE;
3590  consdata->normalized = FALSE;
3591  consdata->upgradetried = FALSE;
3592  consdata->rangedrowpropagated = 0;
3593 
3594  /* update the lhs of the LP row */
3595  if( consdata->row != NULL )
3596  {
3597  SCIP_CALL( SCIPchgRowLhs(scip, consdata->row, lhs) );
3598  }
3599 
3600  return SCIP_OKAY;
3601 }
3602 
3603 /** sets right hand side of linear constraint */
3604 static
3606  SCIP* scip, /**< SCIP data structure */
3607  SCIP_CONS* cons, /**< linear constraint */
3608  SCIP_Real rhs /**< new right hand side */
3609  )
3610 {
3611  SCIP_CONSDATA* consdata;
3612  SCIP_Bool locked;
3613  int i;
3614 
3615  assert(scip != NULL);
3616  assert(cons != NULL);
3617  assert(!SCIPisInfinity(scip, -rhs));
3618 
3619  /* adjust value to not be larger than inf */
3620  if ( SCIPisInfinity(scip, rhs) )
3621  rhs = SCIPinfinity(scip);
3622 
3623  consdata = SCIPconsGetData(cons);
3624  assert(consdata != NULL);
3625  assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
3626  assert(!SCIPisInfinity(scip, -consdata->rhs));
3627 
3628  /* check whether the side is not changed */
3629  if( SCIPisEQ(scip, consdata->rhs, rhs) )
3630  return SCIP_OKAY;
3631 
3632  /* ensure that rhs >= lhs is satisfied without numerical tolerance */
3633  if( SCIPisEQ(scip, rhs, consdata->lhs) )
3634  {
3635  consdata->lhs = rhs;
3636  assert(consdata->row == NULL);
3637  }
3638 
3639  locked = FALSE;
3640  for( i = 0; i < NLOCKTYPES && !locked; i++ )
3641  locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
3642 
3643  /* if necessary, update the rounding locks of variables */
3644  if( locked )
3645  {
3646  assert(SCIPconsIsTransformed(cons));
3647 
3648  if( SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, rhs) )
3649  {
3650  SCIP_VAR** vars;
3651  SCIP_Real* vals;
3652  int v;
3653 
3654  /* the right hand side switched from infinity to a non-infinite value -> install rounding locks */
3655  vars = consdata->vars;
3656  vals = consdata->vals;
3657 
3658  for( v = 0; v < consdata->nvars; ++v )
3659  {
3660  assert(vars[v] != NULL);
3661  assert(!SCIPisZero(scip, vals[v]));
3662 
3663  if( SCIPisPositive(scip, vals[v]) )
3664  {
3665  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3666  }
3667  else
3668  {
3669  SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3670  }
3671  }
3672  }
3673  else if( !SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, rhs) )
3674  {
3675  SCIP_VAR** vars;
3676  SCIP_Real* vals;
3677  int v;
3678 
3679  /* the right hand side switched from a non-infinite value to infinity -> remove rounding locks */
3680  vars = consdata->vars;
3681  vals = consdata->vals;
3682 
3683  for( v = 0; v < consdata->nvars; ++v )
3684  {
3685  assert(vars[v] != NULL);
3686  assert(!SCIPisZero(scip, vals[v]));
3687 
3688  if( SCIPisPositive(scip, vals[v]) )
3689  {
3690  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3691  }
3692  else
3693  {
3694  SCIP_CALL( SCIPunlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3695  }
3696  }
3697  }
3698  }
3699 
3700  /* check whether the right hand side is decreased, if and only if that's the case we maybe can propagate, tighten and add more cliques */
3701  if( !SCIPisInfinity(scip, rhs) && SCIPisLT(scip, rhs, consdata->rhs) )
3702  {
3703  consdata->boundstightened = 0;
3704  consdata->presolved = FALSE;
3705  consdata->cliquesadded = FALSE;
3706  consdata->implsadded = FALSE;
3707 
3708  /* mark the constraint for propagation */
3709  if( SCIPconsIsTransformed(cons) )
3710  {
3711  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3712  }
3713  }
3714 
3715  /* set new right hand side and update constraint data */
3716  consdata->rhs = rhs;
3717  consdata->changed = TRUE;
3718  consdata->normalized = FALSE;
3719  consdata->upgradetried = FALSE;
3720  consdata->rangedrowpropagated = 0;
3721 
3722  /* update the rhs of the LP row */
3723  if( consdata->row != NULL )
3724  {
3725  SCIP_CALL( SCIPchgRowRhs(scip, consdata->row, rhs) );
3726  }
3727 
3728  return SCIP_OKAY;
3729 }
3730 
3731 /** adds coefficient in linear constraint */
3732 static
3734  SCIP* scip, /**< SCIP data structure */
3735  SCIP_CONS* cons, /**< linear constraint */
3736  SCIP_VAR* var, /**< variable of constraint entry */
3737  SCIP_Real val /**< coefficient of constraint entry */
3738  )
3739 {
3740  SCIP_CONSDATA* consdata;
3741  SCIP_Bool transformed;
3742 
3743  assert(scip != NULL);
3744  assert(cons != NULL);
3745  assert(var != NULL);
3746 
3747  /* relaxation-only variables must not be used in checked or enforced constraints */
3748  assert(!SCIPvarIsRelaxationOnly(var) || (!SCIPconsIsChecked(cons) && !SCIPconsIsEnforced(cons)));
3749 
3750  /* ignore coefficient if it is nearly zero */
3751  if( SCIPisZero(scip, val) )
3752  return SCIP_OKAY;
3753 
3754  consdata = SCIPconsGetData(cons);
3755  assert(consdata != NULL);
3756 
3757  /* are we in the transformed problem? */
3758  transformed = SCIPconsIsTransformed(cons);
3759 
3760  /* always use transformed variables in transformed constraints */
3761  if( transformed )
3762  {
3763  SCIP_CALL( SCIPgetTransformedVar(scip, var, &var) );
3764  }
3765  assert(var != NULL);
3766  assert(transformed == SCIPvarIsTransformed(var));
3767 
3768  SCIP_CALL( consdataEnsureVarsSize(scip, consdata, consdata->nvars+1) );
3769  consdata->vars[consdata->nvars] = var;
3770  consdata->vals[consdata->nvars] = val;
3771  consdata->nvars++;
3772 
3773  /* capture variable */
3774  SCIP_CALL( SCIPcaptureVar(scip, var) );
3775 
3776  /* if we are in transformed problem, the variable needs an additional event data */
3777  if( transformed )
3778  {
3779  if( consdata->eventdata != NULL )
3780  {
3781  SCIP_CONSHDLR* conshdlr;
3782  SCIP_CONSHDLRDATA* conshdlrdata;
3783 
3784  /* check for event handler */
3785  conshdlr = SCIPconsGetHdlr(cons);
3786  conshdlrdata = SCIPconshdlrGetData(conshdlr);
3787  assert(conshdlrdata != NULL);
3788  assert(conshdlrdata->eventhdlr != NULL);
3789 
3790  /* initialize eventdata array */
3791  consdata->eventdata[consdata->nvars-1] = NULL;
3792 
3793  /* catch bound change events of variable */
3794  SCIP_CALL( consCatchEvent(scip, cons, conshdlrdata->eventhdlr, consdata->nvars-1) );
3795  }
3796 
3797  /* update minimum and maximum activities */
3798  consdataUpdateAddCoef(scip, consdata, var, val, FALSE);
3799 
3800  /* update maximum activity delta */
3801  if( !SCIPisInfinity(scip, consdata->maxactdelta ) )
3802  {
3803  SCIP_Real lb;
3804  SCIP_Real ub;
3805 
3806  lb = SCIPvarGetLbLocal(var);
3807  ub = SCIPvarGetUbLocal(var);
3808 
3809  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
3810  {
3811  consdata->maxactdelta = SCIPinfinity(scip);
3812  consdata->maxactdeltavar = var;
3813  }
3814  else
3815  {
3816  SCIP_Real domain = ub - lb;
3817  SCIP_Real delta = REALABS(val) * domain;
3818 
3819  if( delta > consdata->maxactdelta )
3820  {
3821  consdata->maxactdelta = delta;
3822  consdata->maxactdeltavar = var;
3823  }
3824  }
3825  }
3826  }
3827 
3828  /* install rounding locks for new variable */
3829  SCIP_CALL( lockRounding(scip, cons, var, val) );
3830 
3831  /* mark the constraint for propagation */
3832  if( transformed )
3833  {
3834  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3835  }
3836 
3837  consdata->boundstightened = 0;
3838  consdata->presolved = FALSE;
3839  consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(var);
3840 
3841  if( consdata->validsignature )
3842  consdataUpdateSignatures(consdata, consdata->nvars-1);
3843 
3844  consdata->changed = TRUE;
3845  consdata->normalized = FALSE;
3846  consdata->upgradetried = FALSE;
3847  consdata->cliquesadded = FALSE;
3848  consdata->implsadded = FALSE;
3849  consdata->rangedrowpropagated = 0;
3850 
3851  if( consdata->nvars == 1 )
3852  {
3853  consdata->indexsorted = TRUE;
3854  consdata->coefsorted = TRUE;
3855  consdata->merged = TRUE;
3856  }
3857  else
3858  {
3859  consdata->merged = FALSE;
3860 
3861  if( SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE )
3862  {
3863  consdata->indexsorted = consdata->indexsorted && (consdataCompVar((void*)consdata, consdata->nvars-2, consdata->nvars-1) <= 0);
3864  consdata->coefsorted = FALSE;
3865  }
3866  else
3867  {
3868  consdata->indexsorted = FALSE;
3869  consdata->coefsorted = consdata->coefsorted && (consdataCompVarProp((void*)consdata, consdata->nvars-2, consdata->nvars-1) <= 0);
3870  }
3871  }
3872 
3873  /* update hascontvar and hasnonbinvar flags */
3874  if( consdata->hasnonbinvalid && !consdata->hascontvar )
3875  {
3876  SCIP_VARTYPE vartype = SCIPvarGetType(var);
3877 
3878  if( vartype != SCIP_VARTYPE_BINARY )
3879  {
3880  consdata->hasnonbinvar = TRUE;
3881 
3882  if( vartype == SCIP_VARTYPE_CONTINUOUS )
3883  consdata->hascontvar = TRUE;
3884  }
3885  }
3886 
3887  /* add the new coefficient to the LP row */
3888  if( consdata->row != NULL )
3889  {
3890  SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, var, val) );
3891  }
3892 
3893  return SCIP_OKAY;
3894 }
3895 
3896 /** deletes coefficient at given position from linear constraint data */
3897 static
3899  SCIP* scip, /**< SCIP data structure */
3900  SCIP_CONS* cons, /**< linear constraint */
3901  int pos /**< position of coefficient to delete */
3902  )
3903 {
3904  SCIP_CONSDATA* consdata;
3905  SCIP_VAR* var;
3906  SCIP_Real val;
3907 
3908  assert(scip != NULL);
3909  assert(cons != NULL);
3910 
3911  consdata = SCIPconsGetData(cons);
3912  assert(consdata != NULL);
3913  assert(0 <= pos && pos < consdata->nvars);
3914 
3915  var = consdata->vars[pos];
3916  val = consdata->vals[pos];
3917  assert(var != NULL);
3918 
3919  /* remove rounding locks for deleted variable */
3920  SCIP_CALL( unlockRounding(scip, cons, var, val) );
3921 
3922  /* if we are in transformed problem, delete the event data of the variable */
3923  if( SCIPconsIsTransformed(cons) )
3924  {
3925  SCIP_CONSHDLR* conshdlr;
3926  SCIP_CONSHDLRDATA* conshdlrdata;
3927 
3928  /* check for event handler */
3929  conshdlr = SCIPconsGetHdlr(cons);
3930  conshdlrdata = SCIPconshdlrGetData(conshdlr);
3931  assert(conshdlrdata != NULL);
3932  assert(conshdlrdata->eventhdlr != NULL);
3933 
3934  /* drop bound change events of variable */
3935  if( consdata->eventdata != NULL )
3936  {
3937  SCIP_CALL( consDropEvent(scip, cons, conshdlrdata->eventhdlr, pos) );
3938  assert(consdata->eventdata[pos] == NULL);
3939  }
3940  }
3941 
3942  /* move the last variable to the free slot */
3943  if( pos != consdata->nvars - 1 )
3944  {
3945  consdata->vars[pos] = consdata->vars[consdata->nvars-1];
3946  consdata->vals[pos] = consdata->vals[consdata->nvars-1];
3947 
3948  if( consdata->eventdata != NULL )
3949  {
3950  consdata->eventdata[pos] = consdata->eventdata[consdata->nvars-1];
3951  assert(consdata->eventdata[pos] != NULL);
3952  consdata->eventdata[pos]->varpos = pos;
3953  }
3954 
3955  consdata->indexsorted = consdata->indexsorted && (pos + 2 >= consdata->nvars);
3956  consdata->coefsorted = consdata->coefsorted && (pos + 2 >= consdata->nvars);
3957  }
3958  consdata->nvars--;
3959 
3960  /* if at most one variable is left, the activities should be recalculated (to correspond exactly to the bounds
3961  * of the remaining variable, or give exactly 0.0)
3962  */
3963  if( consdata->nvars <= 1 )
3964  consdataInvalidateActivities(consdata);
3965  else
3966  {
3967  if( SCIPconsIsTransformed(cons) )
3968  {
3969  /* if we are in transformed problem, update minimum and maximum activities */
3970  consdataUpdateDelCoef(scip, consdata, var, val, TRUE);
3971 
3972  /* if the variable defining the maximal activity delta was removed from the constraint, the maximal activity
3973  * delta needs to be recalculated on the next real propagation
3974  */
3975  if( consdata->maxactdeltavar == var )
3976  {
3977  consdata->maxactdelta = SCIP_INVALID;
3978  consdata->maxactdeltavar = NULL;
3979  }
3980  }
3981  }
3982 
3983  /* mark the constraint for propagation */
3984  if( SCIPconsIsTransformed(cons) )
3985  {
3986  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
3987  }
3988 
3989  consdata->boundstightened = 0;
3990  consdata->presolved = FALSE;
3991  consdata->validsignature = FALSE;
3992  consdata->changed = TRUE;
3993  consdata->normalized = FALSE;
3994  consdata->upgradetried = FALSE;
3995  consdata->cliquesadded = FALSE;
3996  consdata->implsadded = FALSE;
3997  consdata->rangedrowpropagated = 0;
3998 
3999  /* check if hasnonbinvar flag might be incorrect now */
4000  if( consdata->hasnonbinvar && SCIPvarGetType(var) != SCIP_VARTYPE_BINARY )
4001  {
4002  consdata->hasnonbinvalid = FALSE;
4003  }
4004 
4005  /* delete coefficient from the LP row */
4006  if( consdata->row != NULL )
4007  {
4008  SCIP_CALL( SCIPaddVarToRow(scip, consdata->row, var, -val) );
4009  }
4010 
4011  /* release variable */
4012  SCIP_CALL( SCIPreleaseVar(scip, &var) );
4013 
4014  return SCIP_OKAY;
4015 }
4016 
4017 /** changes coefficient value at given position of linear constraint data */
4018 static
4020  SCIP* scip, /**< SCIP data structure */
4021  SCIP_CONS* cons, /**< linear constraint */
4022  int pos, /**< position of coefficient to delete */
4023  SCIP_Real newval /**< new value of coefficient */
4024  )
4025 {
4026  SCIP_CONSDATA* consdata;
4027  SCIP_VAR* var;
4028  SCIP_Real val;
4029  SCIP_Bool locked;
4030  int i;
4031 
4032  assert(scip != NULL);
4033  assert(cons != NULL);
4034  assert(!SCIPisZero(scip, newval));
4035 
4036  consdata = SCIPconsGetData(cons);
4037  assert(consdata != NULL);
4038  assert(0 <= pos && pos < consdata->nvars);
4039  assert(!SCIPisZero(scip, newval));
4040 
4041  var = consdata->vars[pos];
4042  val = consdata->vals[pos];
4043  assert(var != NULL);
4044  assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(var));
4045 
4046  locked = FALSE;
4047  for( i = 0; i < NLOCKTYPES && !locked; i++ )
4048  locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
4049 
4050  /* if necessary, update the rounding locks of the variable */
4051  if( locked && newval * val < 0.0 )
4052  {
4053  assert(SCIPconsIsTransformed(cons));
4054 
4055  /* remove rounding locks for variable with old coefficient */
4056  SCIP_CALL( unlockRounding(scip, cons, var, val) );
4057 
4058  /* install rounding locks for variable with new coefficient */
4059  SCIP_CALL( lockRounding(scip, cons, var, newval) );
4060  }
4061 
4062  /* change the value */
4063  consdata->vals[pos] = newval;
4064 
4065  if( consdata->coefsorted )
4066  {
4067  if( pos > 0 )
4068  consdata->coefsorted = (consdataCompVarProp((void*)consdata, pos - 1, pos) <= 0);
4069  if( consdata->coefsorted && pos < consdata->nvars - 1 )
4070  consdata->coefsorted = (consdataCompVarProp((void*)consdata, pos, pos + 1) <= 0);
4071  }
4072 
4073  /* update minimum and maximum activities */
4074  if( SCIPconsIsTransformed(cons) )
4075  consdataUpdateChgCoef(scip, consdata, var, val, newval, TRUE);
4076 
4077  /* mark the constraint for propagation */
4078  if( SCIPconsIsTransformed(cons) )
4079  {
4080  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
4081  }
4082 
4083  consdata->boundstightened = 0;
4084  consdata->presolved = FALSE;
4085  consdata->validsignature = consdata->validsignature && (newval * val > 0.0);
4086  consdata->changed = TRUE;
4087  consdata->normalized = FALSE;
4088  consdata->upgradetried = FALSE;
4089  consdata->cliquesadded = FALSE;
4090  consdata->implsadded = FALSE;
4091  consdata->rangedrowpropagated = 0;
4092 
4093  return SCIP_OKAY;
4094 }
4095 
4096 /** scales a linear constraint with a constant scalar */
4097 static
4099  SCIP* scip, /**< SCIP data structure */
4100  SCIP_CONS* cons, /**< linear constraint to scale */
4101  SCIP_Real scalar /**< value to scale constraint with */
4102  )
4103 {
4104  SCIP_CONSDATA* consdata;
4105  SCIP_Real newval;
4106  SCIP_Real absscalar;
4107  int i;
4108 
4109  assert(scip != NULL);
4110  assert(cons != NULL);
4111 
4112  consdata = SCIPconsGetData(cons);
4113  assert(consdata != NULL);
4114  assert(consdata->row == NULL);
4115  assert(!SCIPisEQ(scip, scalar, 1.0));
4116 
4117  if( (!SCIPisInfinity(scip, -consdata->lhs) && SCIPisInfinity(scip, -consdata->lhs * scalar))
4118  || (!SCIPisInfinity(scip, consdata->rhs) && SCIPisInfinity(scip, consdata->rhs * scalar)) )
4119  {
4120  SCIPwarningMessage(scip, "skipped scaling for linear constraint <%s> to avoid numerical troubles (scalar: %.15g)\n",
4121  SCIPconsGetName(cons), scalar);
4122 
4123  return SCIP_OKAY;
4124  }
4125 
4126  /* scale the coefficients */
4127  for( i = consdata->nvars - 1; i >= 0; --i )
4128  {
4129  newval = scalar * consdata->vals[i];
4130 
4131  /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasFloor, we add an additional 0.5 before
4132  * flooring down our new value
4133  */
4134  if( SCIPisScalingIntegral(scip, consdata->vals[i], scalar) )
4135  newval = SCIPfeasFloor(scip, newval + 0.5);
4136 
4137  if( SCIPisZero(scip, newval) )
4138  {
4139  SCIPwarningMessage(scip, "coefficient %.15g of variable <%s> in linear constraint <%s> scaled to zero (scalar: %.15g)\n",
4140  consdata->vals[i], SCIPvarGetName(consdata->vars[i]), SCIPconsGetName(cons), scalar);
4141  SCIP_CALL( delCoefPos(scip, cons, i) );
4142  }
4143  else
4144  consdata->vals[i] = newval;
4145  }
4146 
4147  /* scale the sides */
4148  if( scalar < 0.0 )
4149  {
4150  SCIP_Real lhs;
4151 
4152  lhs = consdata->lhs;
4153  consdata->lhs = -consdata->rhs;
4154  consdata->rhs = -lhs;
4155  }
4156  absscalar = REALABS(scalar);
4157  if( !SCIPisInfinity(scip, -consdata->lhs) )
4158  {
4159  newval = absscalar * consdata->lhs;
4160 
4161  /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasFloor, we add an additional 0.5 before
4162  * flooring down our new value
4163  */
4164  if( SCIPisScalingIntegral(scip, consdata->lhs, absscalar) )
4165  consdata->lhs = SCIPfeasFloor(scip, newval + 0.5);
4166  else
4167  consdata->lhs = newval;
4168  }
4169  if( !SCIPisInfinity(scip, consdata->rhs) )
4170  {
4171  newval = absscalar * consdata->rhs;
4172 
4173  /* because SCIPisScalingIntegral uses another integrality check as SCIPfeasCeil, we subtract 0.5 before ceiling up
4174  * our new value
4175  */
4176  if( SCIPisScalingIntegral(scip, consdata->rhs, absscalar) )
4177  consdata->rhs = SCIPfeasCeil(scip, newval - 0.5);
4178  else
4179  consdata->rhs = newval;
4180  }
4181 
4182  consdataInvalidateActivities(consdata);
4183  consdata->cliquesadded = FALSE;
4184  consdata->implsadded = FALSE;
4185 
4186  return SCIP_OKAY;
4187 }
4188 
4189 /** perform deletion of variables in all constraints of the constraint handler */
4190 static
4192  SCIP* scip, /**< SCIP data structure */
4193  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
4194  SCIP_CONS** conss, /**< array of constraints */
4195  int nconss /**< number of constraints */
4196  )
4197 {
4198  SCIP_CONSDATA* consdata;
4199  int i;
4200  int v;
4201 
4202  assert(scip != NULL);
4203  assert(conshdlr != NULL);
4204  assert(conss != NULL);
4205  assert(nconss >= 0);
4206  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
4207 
4208  /* iterate over all constraints */
4209  for( i = 0; i < nconss; i++ )
4210  {
4211  consdata = SCIPconsGetData(conss[i]);
4212 
4213  /* constraint is marked, that some of its variables were deleted */
4214  if( consdata->varsdeleted )
4215  {
4216  /* iterate over all variables of the constraint and delete them from the constraint */
4217  for( v = consdata->nvars - 1; v >= 0; --v )
4218  {
4219  if( SCIPvarIsDeleted(consdata->vars[v]) )
4220  {
4221  SCIP_CALL( delCoefPos(scip, conss[i], v) );
4222  }
4223  }
4224  consdata->varsdeleted = FALSE;
4225  }
4226  }
4227 
4228  return SCIP_OKAY;
4229 }
4230 
4231 
4232 /** normalizes a linear constraint with the following rules:
4233  * - if all coefficients have them same absolute value, change them to (-)1.0
4234  * - multiplication with +1 or -1:
4235  * Apply the following rules in the given order, until the sign of the factor is determined. Later rules only apply,
4236  * if the current rule doesn't determine the sign):
4237  * 1. the right hand side must not be negative
4238  * 2. the right hand side must not be infinite
4239  * 3. the absolute value of the right hand side must be greater than that of the left hand side
4240  * 4. the number of positive coefficients must not be smaller than the number of negative coefficients
4241  * 5. multiply with +1
4242  * - rationals to integrals
4243  * Try to identify a rational representation of the fractional coefficients, and multiply all coefficients
4244  * by the smallest common multiple of all denominators to get integral coefficients.
4245  * Forbid large denominators due to numerical stability.
4246  * - division by greatest common divisor
4247  * If all coefficients are integral, divide them by the greatest common divisor.
4248  */
4249 static
4251  SCIP* scip, /**< SCIP data structure */
4252  SCIP_CONS* cons, /**< linear constraint to normalize */
4253  SCIP_Bool* infeasible /**< pointer to store whether infeasibility was detected */
4254  )
4255 {
4256  SCIP_CONSDATA* consdata;
4257  SCIP_Real* vals;
4258  SCIP_Longint scm;
4259  SCIP_Longint nominator;
4260  SCIP_Longint denominator;
4261  SCIP_Longint gcd;
4262  SCIP_Longint maxmult;
4263  SCIP_Real epsilon;
4264  SCIP_Real feastol;
4265  SCIP_Real maxabsval;
4266  SCIP_Real minabsval;
4267  SCIP_Bool success;
4268  SCIP_Bool onlyintegral;
4269  int nvars;
4270  int mult;
4271  int nposcoeffs;
4272  int nnegcoeffs;
4273  int i;
4274  int v;
4275 
4276  assert(scip != NULL);
4277  assert(cons != NULL);
4278  assert(infeasible != NULL);
4279 
4280  *infeasible = FALSE;
4281 
4282  /* we must not change a modifiable constraint in any way */
4283  if( SCIPconsIsModifiable(cons) )
4284  return SCIP_OKAY;
4285 
4286  /* get constraint data */
4287  consdata = SCIPconsGetData(cons);
4288  assert(consdata != NULL);
4289 
4290  /* check, if the constraint is already normalized */
4291  if( consdata->normalized )
4292  return SCIP_OKAY;
4293 
4294  /* get coefficient arrays */
4295  vals = consdata->vals;
4296  nvars = consdata->nvars;
4297  assert(nvars == 0 || vals != NULL);
4298 
4299  if( nvars == 0 )
4300  {
4301  consdata->normalized = TRUE;
4302  return SCIP_OKAY;
4303  }
4304 
4305  assert(vals != NULL);
4306 
4307  /* get maximal and minimal absolute coefficient */
4308  maxabsval = consdataGetMaxAbsval(consdata);
4309  minabsval = consdataGetMinAbsval(consdata);
4310 
4311  /* return if scaling by maxval will eliminate coefficients */
4312  if( SCIPisZero(scip, minabsval/maxabsval) )
4313  return SCIP_OKAY;
4314 
4315  /* check if all coefficients are in absolute value equal, and not 1.0 */
4316  if( !SCIPisEQ(scip, maxabsval, 1.0) )
4317  {
4318  SCIP_Bool abscoefsequ;
4319 
4320  abscoefsequ = TRUE;
4321 
4322  for( v = nvars - 1; v >= 0; --v )
4323  {
4324  if( !SCIPisEQ(scip, REALABS(vals[v]), maxabsval) )
4325  {
4326  abscoefsequ = FALSE;
4327  break;
4328  }
4329  }
4330 
4331  /* all coefficients are in absolute value equal, so change them to (-)1.0 */
4332  if( abscoefsequ )
4333  {
4334  SCIPdebugMsg(scip, "divide linear constraint with %g, because all coefficients are in absolute value the same\n", maxabsval);
4335  SCIPdebugPrintCons(scip, cons, NULL);
4336  SCIP_CALL( scaleCons(scip, cons, 1/maxabsval) );
4337 
4338  if( consdata->validmaxabsval )
4339  {
4340  if( !SCIPisEQ(scip, consdata->maxabsval, 1.0) )
4341  consdata->maxabsval = 1.0;
4342  if( !SCIPisEQ(scip, consdata->minabsval, 1.0) )
4343  consdata->minabsval = 1.0;
4344 
4345  maxabsval = 1.0;
4346  }
4347  else
4348  {
4349  /* get maximal absolute coefficient */
4350  maxabsval = consdataGetMaxAbsval(consdata);
4351  }
4352 
4353  /* get new consdata information, because scaleCons() might have deleted variables */
4354  vals = consdata->vals;
4355  nvars = consdata->nvars;
4356 
4357  assert(nvars == 0 || vals != NULL);
4358  }
4359  }
4360 
4361  /* nvars might have changed */
4362  if( nvars == 0 )
4363  {
4364  consdata->normalized = TRUE;
4365  return SCIP_OKAY;
4366  }
4367 
4368  assert(vals != NULL);
4369 
4370  /* calculate the maximal multiplier for common divisor calculation:
4371  * |p/q - val| < epsilon and q < feastol/epsilon => |p - q*val| < feastol
4372  * which means, a value of feastol/epsilon should be used as maximal multiplier;
4373  * additionally, we don't want to scale the constraint if this would lead to too
4374  * large coefficients
4375  */
4376  epsilon = SCIPepsilon(scip) * 0.9; /* slightly decrease epsilon to be safe in rational conversion below */
4377  feastol = SCIPfeastol(scip);
4378  maxmult = (SCIP_Longint)(feastol/epsilon + feastol);
4379 
4380  if( !consdata->hasnonbinvalid )
4381  consdataCheckNonbinvar(consdata);
4382 
4383  /* if all variables are of integral type we will allow a greater multiplier */
4384  if( !consdata->hascontvar )
4385  maxmult = MIN(maxmult, (SCIP_Longint) (MAXSCALEDCOEFINTEGER / MAX(maxabsval, 1.0))); /*lint !e835*/
4386  else
4387  maxmult = MIN(maxmult, (SCIP_Longint) (MAXSCALEDCOEF / MAX(maxabsval, 1.0))); /*lint !e835*/
4388 
4389  /*
4390  * multiplication with +1 or -1
4391  */
4392  mult = 0;
4393 
4394  /* 1. the right hand side must not be negative */
4395  if( SCIPisPositive(scip, consdata->lhs) )
4396  mult = +1;
4397  else if( SCIPisNegative(scip, consdata->rhs) )
4398  mult = -1;
4399 
4400  if( mult == 0 )
4401  {
4402  /* 2. the right hand side must not be infinite */
4403  if( SCIPisInfinity(scip, -consdata->lhs) )
4404  mult = +1;
4405  else if( SCIPisInfinity(scip, consdata->rhs) )
4406  mult = -1;
4407  }
4408 
4409  if( mult == 0 )
4410  {
4411  /* 3. the absolute value of the right hand side must be greater than that of the left hand side */
4412  if( SCIPisGT(scip, REALABS(consdata->rhs), REALABS(consdata->lhs)) )
4413  mult = +1;
4414  else if( SCIPisLT(scip, REALABS(consdata->rhs), REALABS(consdata->lhs)) )
4415  mult = -1;
4416  }
4417 
4418  if( mult == 0 )
4419  {
4420  /* 4. the number of positive coefficients must not be smaller than the number of negative coefficients */
4421  nposcoeffs = 0;
4422  nnegcoeffs = 0;
4423  for( i = 0; i < nvars; ++i )
4424  {
4425  if( vals[i] > 0.0 )
4426  nposcoeffs++;
4427  else
4428  nnegcoeffs++;
4429  }
4430  if( nposcoeffs > nnegcoeffs )
4431  mult = +1;
4432  else if( nposcoeffs < nnegcoeffs )
4433  mult = -1;
4434  }
4435 
4436  if( mult == 0 )
4437  {
4438  /* 5. multiply with +1 */
4439  mult = +1;
4440  }
4441 
4442  assert(mult == +1 || mult == -1);
4443  if( mult == -1 )
4444  {
4445  /* scale the constraint with -1 */
4446  SCIPdebugMsg(scip, "multiply linear constraint with -1.0\n");
4447  SCIPdebugPrintCons(scip, cons, NULL);
4448  SCIP_CALL( scaleCons(scip, cons, -1.0) );
4449 
4450  /* scalecons() can delete variables, but scaling with -1 should not do that */
4451  assert(nvars == consdata->nvars);
4452  }
4453 
4454  /*
4455  * rationals to integrals
4456  *
4457  * @todo try scaling only on behalf of non-continuous variables
4458  */
4459  success = TRUE;
4460  scm = 1;
4461  for( i = 0; i < nvars && success && scm <= maxmult; ++i )
4462  {
4463  if( !SCIPisIntegral(scip, vals[i]) )
4464  {
4465  /* epsilon has been slightly decreased above - to be on the safe side */
4466  success = SCIPrealToRational(vals[i], -epsilon, epsilon , maxmult, &nominator, &denominator);
4467  if( success )
4468  scm = SCIPcalcSmaComMul(scm, denominator);
4469  }
4470  }
4471  assert(scm >= 1);
4472 
4473  /* it might be that we have really big coefficients, but all are integral, in that case we want to divide them by
4474  * their greatest common divisor
4475  */
4476  onlyintegral = TRUE;
4477  if( scm == 1 )
4478  {
4479  for( i = nvars - 1; i >= 0; --i )
4480  {
4481  if( !SCIPisIntegral(scip, vals[i]) )
4482  {
4483  onlyintegral = FALSE;
4484  break;
4485  }
4486  }
4487  }
4488 
4489  success = success && (scm <= maxmult || (scm == 1 && onlyintegral));
4490  if( success && scm != 1 )
4491  {
4492  /* scale the constraint with the smallest common multiple of all denominators */
4493  SCIPdebugMsg(scip, "scale linear constraint with %" SCIP_LONGINT_FORMAT " to make coefficients integral\n", scm);
4494  SCIPdebugPrintCons(scip, cons, NULL);
4495  SCIP_CALL( scaleCons(scip, cons, (SCIP_Real)scm) );
4496 
4497  if( consdata->validmaxabsval )
4498  {
4499  consdata->maxabsval *= REALABS((SCIP_Real)scm);
4500  if( !SCIPisIntegral(scip, consdata->maxabsval) )
4501  {
4502  consdata->validmaxabsval = FALSE;
4503  consdata->maxabsval = SCIP_INVALID;
4504  consdataCalcMaxAbsval(consdata);
4505  }
4506  }
4507 
4508  if( consdata->validminabsval )
4509  {
4510  consdata->minabsval *= REALABS((SCIP_Real)scm);
4511  if( !SCIPisIntegral(scip, consdata->minabsval) )
4512  {
4513  consdata->validminabsval = FALSE;
4514  consdata->minabsval = SCIP_INVALID;
4515  consdataCalcMinAbsval(consdata);
4516  }
4517  }
4518 
4519  /* get new consdata information, because scalecons() might have deleted variables */
4520  vals = consdata->vals;
4521  nvars = consdata->nvars;
4522  assert(nvars == 0 || vals != NULL);
4523  }
4524 
4525  /*
4526  * division by greatest common divisor
4527  */
4528  if( success && nvars >= 1 )
4529  {
4530  /* all coefficients are integral: divide them by their greatest common divisor */
4531  assert(SCIPisIntegral(scip, vals[0]));
4532 
4533  gcd = (SCIP_Longint)(REALABS(vals[0]) + feastol);
4534  for( i = 1; i < nvars && gcd > 1; ++i )
4535  {
4536  assert(SCIPisIntegral(scip, vals[i]));
4537  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[i]) + feastol));
4538  }
4539 
4540  if( gcd > 1 )
4541  {
4542  /* since the lhs/rhs is not respected for gcd calculation it can happen that we detect infeasibility */
4543  if( !consdata->hascontvar && onlyintegral )
4544  {
4545  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) && !SCIPisFeasIntegral(scip, consdata->rhs / gcd) )
4546  {
4547  *infeasible = TRUE;
4548 
4549  SCIPdebugMsg(scip, "detected infeasibility of constraint after scaling with gcd=%" SCIP_LONGINT_FORMAT ":\n", gcd);
4550  SCIPdebugPrintCons(scip, cons, NULL);
4551 
4552  return SCIP_OKAY;
4553  }
4554  }
4555 
4556  /* divide the constraint by the greatest common divisor of the coefficients */
4557  SCIPdebugMsg(scip, "divide linear constraint by greatest common divisor %" SCIP_LONGINT_FORMAT "\n", gcd);
4558  SCIPdebugPrintCons(scip, cons, NULL);
4559  SCIP_CALL( scaleCons(scip, cons, 1.0/(SCIP_Real)gcd) );
4560 
4561  if( consdata->validmaxabsval )
4562  {
4563  consdata->maxabsval /= REALABS((SCIP_Real)gcd);
4564  }
4565  if( consdata->validminabsval )
4566  {
4567  consdata->minabsval /= REALABS((SCIP_Real)gcd);
4568  }
4569  }
4570  }
4571 
4572  /* mark constraint to be normalized */
4573  consdata->normalized = TRUE;
4574 
4575  SCIPdebugMsg(scip, "normalized constraint:\n");
4576  SCIPdebugPrintCons(scip, cons, NULL);
4577 
4578  return SCIP_OKAY;
4579 }
4580 
4581 /** replaces multiple occurrences of a variable by a single coefficient */
4582 static
4584  SCIP* scip, /**< SCIP data structure */
4585  SCIP_CONS* cons /**< linear constraint */
4586  )
4587 {
4588  SCIP_CONSDATA* consdata;
4589  SCIP_VAR* var;
4590  SCIP_Real valsum;
4591  int v;
4592 
4593  assert(scip != NULL);
4594  assert(cons != NULL);
4595 
4596  consdata = SCIPconsGetData(cons);
4597  assert(consdata != NULL);
4598 
4599  if( consdata->merged )
4600  return SCIP_OKAY;
4601 
4602  /* sort the constraint */
4603  SCIP_CALL( consdataSort(scip, consdata) );
4604 
4605  /* go backwards through the constraint looking for multiple occurrences of the same variable;
4606  * backward direction is necessary, since delCoefPos() modifies the given position and
4607  * the subsequent ones
4608  */
4609  v = consdata->nvars-1;
4610  while( v >= 1 )
4611  {
4612  var = consdata->vars[v];
4613  if( consdata->vars[v-1] == var )
4614  {
4615  valsum = consdata->vals[v];
4616  do
4617  {
4618  SCIP_CALL( delCoefPos(scip, cons, v) );
4619  --v;
4620  valsum += consdata->vals[v];
4621  }
4622  while( v >= 1 && consdata->vars[v-1] == var );
4623 
4624  /* modify the last existing occurrence of the variable */
4625  assert(consdata->vars[v] == var);
4626  if( SCIPisZero(scip, valsum) )
4627  {
4628  SCIP_CALL( delCoefPos(scip, cons, v) );
4629 
4630  /* if the variable defining the maximal activity delta was removed from the constraint, the maximal activity
4631  * delta needs to be recalculated on the next real propagation
4632  */
4633  if( consdata->maxactdeltavar == var )
4634  {
4635  consdata->maxactdelta = SCIP_INVALID;
4636  consdata->maxactdeltavar = NULL;
4637  }
4638  }
4639  else
4640  {
4641  SCIP_CALL( chgCoefPos(scip, cons, v, valsum) );
4642  }
4643  }
4644  --v;
4645  }
4646 
4647  consdata->merged = TRUE;
4648 
4649  return SCIP_OKAY;
4650 }
4651 
4652 /** replaces all fixed and aggregated variables by their non-fixed counterparts */
4653 static
4655  SCIP* scip, /**< SCIP data structure */
4656  SCIP_CONS* cons, /**< linear constraint */
4657  SCIP_Bool* infeasible /**< pointer to store if infeasibility is detected; or NULL if this
4658  * information is not needed; in this case, we apply all fixings
4659  * instead of stopping after the first infeasible one */
4660  )
4661 {
4662  SCIP_CONSDATA* consdata;
4663  SCIP_VAR* var;
4664  SCIP_VAR** aggrvars;
4665  SCIP_Real val;
4666  SCIP_Real* aggrscalars;
4667  SCIP_Real fixedval;
4668  SCIP_Real aggrconst;
4669  int v;
4670  int naggrvars;
4671  int i;
4672 
4673  assert(scip != NULL);
4674  assert(cons != NULL);
4675 
4676  if( infeasible != NULL )
4677  *infeasible = FALSE;
4678 
4679  consdata = SCIPconsGetData(cons);
4680  assert(consdata != NULL);
4681 
4682  if( consdata->eventdata == NULL )
4683  {
4684  SCIP_CONSHDLR* conshdlr;
4685  SCIP_CONSHDLRDATA* conshdlrdata;
4686 
4687  conshdlr = SCIPconsGetHdlr(cons);
4688  assert(conshdlr != NULL);
4689 
4690  conshdlrdata = SCIPconshdlrGetData(conshdlr);
4691  assert(conshdlrdata != NULL);
4692 
4693  /* catch bound change events of variables */
4694  SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
4695  assert(consdata->eventdata != NULL);
4696  }
4697 
4698  if( !consdata->removedfixings )
4699  {
4700  SCIP_Real lhssubtrahend;
4701  SCIP_Real rhssubtrahend;
4702 
4703  /* if an unmodifiable row has been added to the LP, then we cannot apply fixing anymore (cannot change a row)
4704  * this should not happen, as applyFixings is called in addRelaxation() before creating and adding a row
4705  */
4706  assert(consdata->row == NULL || !SCIProwIsInLP(consdata->row) || SCIProwIsModifiable(consdata->row));
4707 
4708  lhssubtrahend = 0.0;
4709  rhssubtrahend = 0.0;
4710 
4711  SCIPdebugMsg(scip, "applying fixings:\n");
4712  SCIPdebugPrintCons(scip, cons, NULL);
4713 
4714  v = 0;
4715  while( v < consdata->nvars )
4716  {
4717  var = consdata->vars[v];
4718  val = consdata->vals[v];
4719  assert(SCIPvarIsTransformed(var));
4720 
4721  switch( SCIPvarGetStatus(var) )
4722  {
4724  SCIPerrorMessage("original variable in transformed linear constraint\n");
4725  return SCIP_INVALIDDATA;
4726 
4727  case SCIP_VARSTATUS_LOOSE:
4728  case SCIP_VARSTATUS_COLUMN:
4729  ++v;
4730  break;
4731 
4732  case SCIP_VARSTATUS_FIXED:
4733  assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)));
4734  fixedval = SCIPvarGetLbGlobal(var);
4735  if( !SCIPisInfinity(scip, -consdata->lhs) )
4736  {
4737  if( SCIPisInfinity(scip, ABS(fixedval)) )
4738  {
4739  if( val * fixedval > 0.0 )
4740  {
4741  SCIP_CALL( chgLhs(scip, cons, -SCIPinfinity(scip)) );
4742  }
4743  else
4744  {
4745  if( infeasible != NULL )
4746  {
4747  /* if lhs gets infinity it means that the problem is infeasible */
4748  *infeasible = TRUE;
4749  return SCIP_OKAY;
4750  }
4751  else
4752  {
4753  SCIP_CALL( chgLhs(scip, cons, SCIPinfinity(scip)) );
4754  }
4755  }
4756  }
4757  else
4758  lhssubtrahend += val * fixedval;
4759  }
4760  if( !SCIPisInfinity(scip, consdata->rhs) )
4761  {
4762  if( SCIPisInfinity(scip, ABS(fixedval)) )
4763  {
4764  if( val * fixedval > 0.0 )
4765  {
4766  if( infeasible != NULL )
4767  {
4768  /* if rhs gets -infinity it means that the problem is infeasible */
4769  *infeasible = TRUE;
4770  return SCIP_OKAY;
4771  }
4772  else
4773  {
4774  SCIP_CALL( chgRhs(scip, cons, -SCIPinfinity(scip)) );
4775  }
4776  }
4777  else
4778  {
4779  SCIP_CALL( chgRhs(scip, cons, SCIPinfinity(scip)) );
4780  }
4781  }
4782  else
4783  rhssubtrahend += val * fixedval;
4784  }
4785  SCIP_CALL( delCoefPos(scip, cons, v) );
4786  break;
4787 
4789  {
4790  SCIP_VAR* activevar = SCIPvarGetAggrVar(var);
4791  SCIP_Real activescalar = val * SCIPvarGetAggrScalar(var);
4792  SCIP_Real activeconstant = val * SCIPvarGetAggrConstant(var);
4793 
4794  assert(activevar != NULL);
4795  SCIP_CALL( SCIPgetProbvarSum(scip, &activevar, &activescalar, &activeconstant) );
4796  assert(activevar != NULL);
4797 
4798  if( !SCIPisZero(scip, activescalar) )
4799  {
4800  SCIP_CALL( addCoef(scip, cons, activevar, activescalar) );
4801  }
4802 
4803  if( !SCIPisZero(scip, activeconstant) )
4804  {
4805  if( !SCIPisInfinity(scip, -consdata->lhs) )
4806  lhssubtrahend += activeconstant;
4807  if( !SCIPisInfinity(scip, consdata->rhs) )
4808  rhssubtrahend += activeconstant;
4809  }
4810 
4811  SCIP_CALL( delCoefPos(scip, cons, v) );
4812  break;
4813  }
4816  naggrvars = SCIPvarGetMultaggrNVars(var);
4817  aggrvars = SCIPvarGetMultaggrVars(var);
4818  aggrscalars = SCIPvarGetMultaggrScalars(var);
4819  for( i = 0; i < naggrvars; ++i )
4820  {
4821  SCIP_CALL( addCoef(scip, cons, aggrvars[i], val * aggrscalars[i]) );
4822  }
4823  aggrconst = SCIPvarGetMultaggrConstant(var);
4824 
4825  if( !SCIPisInfinity(scip, -consdata->lhs) )
4826  lhssubtrahend += val * aggrconst;
4827  if( !SCIPisInfinity(scip, consdata->rhs) )
4828  rhssubtrahend += val * aggrconst;
4829 
4830  SCIP_CALL( delCoefPos(scip, cons, v) );
4831  break;
4832 
4834  SCIP_CALL( addCoef(scip, cons, SCIPvarGetNegationVar(var), -val) );
4835  aggrconst = SCIPvarGetNegationConstant(var);
4836 
4837  if( !SCIPisInfinity(scip, -consdata->lhs) )
4838  lhssubtrahend += val * aggrconst;
4839  if( !SCIPisInfinity(scip, consdata->rhs) )
4840  rhssubtrahend += val * aggrconst;
4841 
4842  SCIP_CALL( delCoefPos(scip, cons, v) );
4843  break;
4844 
4845  default:
4846  SCIPerrorMessage("unknown variable status\n");
4847  SCIPABORT();
4848  return SCIP_INVALIDDATA; /*lint !e527*/
4849  }
4850  }
4851 
4852  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->lhs) )
4853  {
4854  /* for large numbers that are relatively equal, substraction can lead to cancellation,
4855  * causing wrong fixings of other variables --> better use a real zero here;
4856  * for small numbers, polishing the difference might lead to wrong results -->
4857  * better use the exact difference in this case
4858  */
4859  if( SCIPisEQ(scip, lhssubtrahend, consdata->lhs) && SCIPisFeasGE(scip, REALABS(lhssubtrahend), 1.0) )
4860  {
4861  SCIP_CALL( chgLhs(scip, cons, 0.0) );
4862  }
4863  else
4864  {
4865  SCIP_CALL( chgLhs(scip, cons, consdata->lhs - lhssubtrahend) );
4866  }
4867  }
4868  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, -consdata->rhs))
4869  {
4870  /* for large numbers that are relatively equal, substraction can lead to cancellation,
4871  * causing wrong fixings of other variables --> better use a real zero here;
4872  * for small numbers, polishing the difference might lead to wrong results -->
4873  * better use the exact difference in this case
4874  */
4875  if( SCIPisEQ(scip, rhssubtrahend, consdata->rhs ) && SCIPisFeasGE(scip, REALABS(rhssubtrahend), 1.0) )
4876  {
4877  SCIP_CALL( chgRhs(scip, cons, 0.0) );
4878  }
4879  else
4880  {
4881  SCIP_CALL( chgRhs(scip, cons, consdata->rhs - rhssubtrahend) );
4882  }
4883  }
4884  consdata->removedfixings = TRUE;
4885 
4886  SCIPdebugMsg(scip, "after fixings:\n");
4887  SCIPdebugPrintCons(scip, cons, NULL);
4888 
4889  /* if aggregated variables have been replaced, multiple entries of the same variable are possible and we have
4890  * to clean up the constraint
4891  */
4892  SCIP_CALL( mergeMultiples(scip, cons) );
4893 
4894  SCIPdebugMsg(scip, "after merging:\n");
4895  SCIPdebugPrintCons(scip, cons, NULL);
4896  }
4897  assert(consdata->removedfixings);
4898 
4899 #ifndef NDEBUG
4900  /* check, if all fixings are applied */
4901  for( v = 0; v < consdata->nvars; ++v )
4902  assert(SCIPvarIsActive(consdata->vars[v]));
4903 #endif
4904 
4905  return SCIP_OKAY;
4906 }
4907 
4908 /** for each variable in the linear constraint, except the inferred variable, adds one bound to the conflict analysis'
4909  * candidate store (bound depends on sign of coefficient and whether the left or right hand side was the reason for the
4910  * inference variable's bound change); the conflict analysis can be initialized with the linear constraint being the
4911  * conflict detecting constraint by using NULL as inferred variable
4912  */
4913 static
4915  SCIP* scip, /**< SCIP data structure */
4916  SCIP_CONS* cons, /**< constraint that inferred the bound change */
4917  SCIP_VAR* infervar, /**< variable that was deduced, or NULL */
4918  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
4919  int inferpos, /**< position of the inferred variable in the vars array */
4920  SCIP_Bool reasonisrhs /**< is the right hand side responsible for the bound change? */
4921  )
4922 {
4923  SCIP_CONSDATA* consdata;
4924  SCIP_VAR** vars;
4925  SCIP_Real* vals;
4926  int nvars;
4927  int i;
4928 
4929  assert(scip != NULL);
4930  assert(cons != NULL);
4931 
4932  consdata = SCIPconsGetData(cons);
4934  assert(consdata != NULL);
4935 
4936  vars = consdata->vars;
4937  vals = consdata->vals;
4938  nvars = consdata->nvars;
4939 
4940  assert(vars != NULL || nvars == 0);
4941  assert(vals != NULL || nvars == 0);
4942 
4943  assert(-1 <= inferpos && inferpos < nvars);
4944  assert((infervar == NULL) == (inferpos == -1));
4945  assert(inferpos == -1 || vars[inferpos] == infervar); /*lint !e613*/
4946 
4947  /* for each variable, add the bound to the conflict queue, that is responsible for the minimal or maximal
4948  * residual value, depending on whether the left or right hand side is responsible for the bound change:
4949  * - if the right hand side is the reason, the minimal residual activity is responsible
4950  * - if the left hand side is the reason, the maximal residual activity is responsible
4951  */
4952 
4953  /* if the variable is integral we only need to add reason bounds until the propagation could be applied */
4954  if( infervar == NULL || SCIPvarIsIntegral(infervar) )
4955  {
4956  SCIP_Real minresactivity;
4957  SCIP_Real maxresactivity;
4958  SCIP_Bool minisrelax;
4959  SCIP_Bool maxisrelax;
4960  SCIP_Bool isminsettoinfinity;
4961  SCIP_Bool ismaxsettoinfinity;
4962 
4963  minresactivity = -SCIPinfinity(scip);
4964  maxresactivity = SCIPinfinity(scip);
4965 
4966  /* calculate the minimal and maximal global activity of all other variables involved in the constraint */
4967  if( infervar != NULL )
4968  {
4969  assert(vals != NULL); /* for flexelint */
4970  if( reasonisrhs )
4971  consdataGetGlbActivityResiduals(scip, consdata, infervar, vals[inferpos], FALSE, &minresactivity, NULL,
4972  &minisrelax, NULL, &isminsettoinfinity, NULL);
4973  else
4974  consdataGetGlbActivityResiduals(scip, consdata, infervar, vals[inferpos], FALSE, NULL, &maxresactivity,
4975  NULL, &maxisrelax, NULL, &ismaxsettoinfinity);
4976  }
4977  else
4978  {
4979  if( reasonisrhs )
4980  consdataGetGlbActivityBounds(scip, consdata, FALSE, &minresactivity, NULL,
4981  &minisrelax, NULL, &isminsettoinfinity, NULL);
4982  else
4983  consdataGetGlbActivityBounds(scip, consdata, FALSE, NULL, &maxresactivity,
4984  NULL, &maxisrelax, NULL, &ismaxsettoinfinity);
4985  }
4986 
4987  /* we can only do something clever, if the residual activity is finite and not relaxed */
4988  if( (reasonisrhs && !isminsettoinfinity && !minisrelax) || (!reasonisrhs && !ismaxsettoinfinity && !maxisrelax) ) /*lint !e644*/
4989  {
4990  SCIP_Real rescap;
4991  SCIP_Bool resactisinf;
4992 
4993  resactisinf = FALSE;
4994 
4995  /* calculate the residual capacity that would be left, if the variable would be set to one more / one less
4996  * than its inferred bound
4997  */
4998  if( infervar != NULL )
4999  {
5000  assert(vals != NULL); /* for flexelint */
5001 
5002  if( reasonisrhs )
5003  {
5004  if( SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastglbminactivity) )
5005  {
5006  consdataGetReliableResidualActivity(scip, consdata, infervar, &minresactivity, TRUE, TRUE);
5007  if( SCIPisInfinity(scip, -minresactivity) )
5008  resactisinf = TRUE;
5009  }
5010  rescap = consdata->rhs - minresactivity;
5011  }
5012  else
5013  {
5014  if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastglbmaxactivity) )
5015  {
5016  consdataGetReliableResidualActivity(scip, consdata, infervar, &maxresactivity, FALSE, TRUE);
5017  if( SCIPisInfinity(scip, maxresactivity) )
5018  resactisinf = TRUE;
5019  }
5020  rescap = consdata->lhs - maxresactivity;
5021  }
5022 
5023  if( reasonisrhs == (vals[inferpos] > 0.0) )
5024  rescap -= vals[inferpos] * (SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) + 1.0);
5025  else
5026  rescap -= vals[inferpos] * (SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) - 1.0);
5027  }
5028  else
5029  rescap = (reasonisrhs ? consdata->rhs - minresactivity : consdata->lhs - maxresactivity);
5030 
5031  if( !resactisinf )
5032  {
5033  /* now add bounds as reasons until the residual capacity is exceeded */
5034  for( i = 0; i < nvars; ++i )
5035  {
5036  assert( vars != NULL && vals != NULL ); /* for lint */
5037 
5038  /* zero coefficients and the infered variable can be ignored */
5039  if( vars[i] == infervar || SCIPisZero(scip, vals[i]) )
5040  continue;
5041 
5042  /* check if the residual capacity is exceeded */
5043  if( (reasonisrhs && SCIPisFeasNegative(scip, rescap))
5044  || (!reasonisrhs && SCIPisFeasPositive(scip, rescap)) )
5045  break;
5046 
5047  /* update the residual capacity due to the local bound of this variable */
5048  if( reasonisrhs == (vals[i] > 0.0) )
5049  {
5050  /* rhs is reason and coeff is positive, or lhs is reason and coeff is negative -> lower bound */
5051  SCIP_CALL( SCIPaddConflictLb(scip, vars[i], bdchgidx) );
5052  rescap -= vals[i] * (SCIPgetVarLbAtIndex(scip, vars[i], bdchgidx, FALSE) - SCIPvarGetLbGlobal(vars[i]));
5053  }
5054  else
5055  {
5056  /* lhs is reason and coeff is positive, or rhs is reason and coeff is negative -> upper bound */
5057  SCIP_CALL( SCIPaddConflictUb(scip, vars[i], bdchgidx) );
5058  rescap -= vals[i] * (SCIPgetVarUbAtIndex(scip, vars[i], bdchgidx, FALSE) - SCIPvarGetUbGlobal(vars[i]));
5059  }
5060  }
5061  return SCIP_OKAY;
5062  }
5063  }
5064  }
5065 
5066  /* for a bound change on a continuous variable, all locally changed bounds are responsible */
5067  for( i = 0; i < nvars; ++i )
5068  {
5069  assert(vars != NULL); /* for flexelint */
5070  assert(vals != NULL); /* for flexelint */
5071 
5072  /* zero coefficients and the infered variable can be ignored */
5073  if( vars[i] == infervar || SCIPisZero(scip, vals[i]) )
5074  continue;
5075 
5076  if( reasonisrhs == (vals[i] > 0.0) )
5077  {
5078  /* rhs is reason and coeff is positive, or lhs is reason and coeff is negative -> lower bound is responsible */
5079  SCIP_CALL( SCIPaddConflictLb(scip, vars[i], bdchgidx) );
5080  }
5081  else
5082  {
5083  /* lhs is reason and coeff is positive, or rhs is reason and coeff is negative -> upper bound is responsible */
5084  SCIP_CALL( SCIPaddConflictUb(scip, vars[i], bdchgidx) );
5085  }
5086  }
5087 
5088  return SCIP_OKAY;
5089 }
5090 
5091 /** for each variable in the linear ranged row constraint, except the inferred variable, adds the bounds of all fixed
5092  * variables to the conflict analysis' candidate store; the conflict analysis can be initialized
5093  * with the linear constraint being the conflict detecting constraint by using NULL as inferred variable
5094  */
5095 static
5097  SCIP* scip, /**< SCIP data structure */
5098  SCIP_CONS* cons, /**< constraint that inferred the bound change */
5099  SCIP_VAR* infervar, /**< variable that was deduced, or NULL */
5100  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
5101  int inferpos /**< position of the inferred variable in the vars array, or -1 */
5102  )
5103 {
5104  SCIP_CONSDATA* consdata;
5105  SCIP_VAR** vars;
5106  int nvars;
5107  int v;
5108 
5109  assert(scip != NULL);
5110  assert(cons != NULL);
5111 
5112  consdata = SCIPconsGetData(cons);
5113  assert(consdata != NULL);
5114  vars = consdata->vars;
5115  nvars = consdata->nvars;
5116  assert(vars != NULL || nvars == 0);
5117  assert(-1 <= inferpos && inferpos < nvars);
5118  assert((infervar == NULL) == (inferpos == -1));
5119  assert(inferpos == -1 || vars != NULL);
5120  assert(inferpos == -1 || vars[inferpos] == infervar); /*lint !e613*/
5121 
5122  /* collect all fixed variables */
5123  for( v = nvars - 1; v >= 0; --v )
5124  {
5125  assert(vars != NULL); /* for flexelint */
5126 
5127  /* need to add old bounds before propagation of inferrence variable */
5128  if( vars[v] == infervar )
5129  {
5130  assert(vars[v] != NULL);
5131 
5132  if( !SCIPisEQ(scip, SCIPgetVarLbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPvarGetLbGlobal(vars[v])) )
5133  {
5134  /* @todo get boundchange index before this last boundchange and correct the index */
5135  SCIP_CALL( SCIPaddConflictLb(scip, vars[v], bdchgidx) );
5136  }
5137 
5138  if( !SCIPisEQ(scip, SCIPgetVarUbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPvarGetUbGlobal(vars[v])) )
5139  {
5140  /* @todo get boundchange index before this last boundchange and correct the index */
5141  SCIP_CALL( SCIPaddConflictUb(scip, vars[v], bdchgidx) );
5142  }
5143 
5144  continue;
5145  }
5146 
5147  /* check for fixed variables */
5148  if( SCIPisEQ(scip, SCIPgetVarLbAtIndex(scip, vars[v], bdchgidx, FALSE), SCIPgetVarUbAtIndex(scip, vars[v], bdchgidx, FALSE)) )
5149  {
5150  /* add all bounds of fixed variables which lead to the boundchange of the given inference variable */
5151  SCIP_CALL( SCIPaddConflictLb(scip, vars[v], bdchgidx) );
5152  SCIP_CALL( SCIPaddConflictUb(scip, vars[v], bdchgidx) );
5153  }
5154  }
5155 
5156  return SCIP_OKAY;
5157 }
5158 
5159 /** add reasoning variables to conflict candidate queue which led to the conflict */
5160 static
5162  SCIP* scip, /**< SCIP data structure */
5163  SCIP_VAR** vars, /**< variables reasoning the infeasibility */
5164  int nvars, /**< number of variables reasoning the infeasibility */
5165  SCIP_VAR* var, /**< variable which was tried to fix/tighten, or NULL */
5166  SCIP_Real bound /**< bound of variable which was tried to apply, or SCIP_INVALID */
5167  )
5168 {
5169  int v;
5170 
5171  assert(scip != NULL);
5172 
5173  /* collect all variables for which the local bounds differ from their global bounds */
5174  for( v = nvars - 1; v >= 0; --v )
5175  {
5176  assert(vars != NULL);
5177 
5178  /* check for local bound changes variables */
5179  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(vars[v]), SCIPvarGetLbGlobal(vars[v])) )
5180  {
5181  /* add conflict bound */
5182  SCIP_CALL( SCIPaddConflictLb(scip, vars[v], 0) );
5183  }
5184 
5185  if( !SCIPisEQ(scip, SCIPvarGetUbLocal(vars[v]), SCIPvarGetUbGlobal(vars[v])) )
5186  {
5187  SCIP_CALL( SCIPaddConflictUb(scip, vars[v], 0) );
5188  }
5189  }
5190 
5191  if( var != NULL )
5192  {
5193  if( bound < SCIPvarGetLbLocal(var) )
5194  {
5195  SCIP_CALL( SCIPaddConflictLb(scip, var, 0) );
5196  }
5197 
5198  if( bound > SCIPvarGetUbLocal(var) )
5199  {
5200  SCIP_CALL( SCIPaddConflictUb(scip, var, 0) );
5201  }
5202  }
5203 
5204  return SCIP_OKAY;
5205 }
5206 
5207 /** resolves a propagation on the given variable by supplying the variables needed for applying the corresponding
5208  * propagation rule (see propagateCons()):
5209  * (1) activity residuals of all other variables tighten bounds of single variable
5210  */
5211 static
5213  SCIP* scip, /**< SCIP data structure */
5214  SCIP_CONS* cons, /**< constraint that inferred the bound change */
5215  SCIP_VAR* infervar, /**< variable that was deduced */
5216  INFERINFO inferinfo, /**< inference information */
5217  SCIP_BOUNDTYPE boundtype, /**< the type of the changed bound (lower or upper bound) */
5218  SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
5219  SCIP_RESULT* result /**< pointer to store the result of the propagation conflict resolving call */
5220  )
5221 {
5222  SCIP_CONSDATA* consdata;
5223  SCIP_VAR** vars;
5224 #ifndef NDEBUG
5225  SCIP_Real* vals;
5226 #endif
5227  int nvars;
5228  int inferpos;
5229 
5230  assert(scip != NULL);
5231  assert(cons != NULL);
5232  assert(result != NULL);
5233 
5234  consdata = SCIPconsGetData(cons);
5235  assert(consdata != NULL);
5236  vars = consdata->vars;
5237  nvars = consdata->nvars;
5238 #ifndef NDEBUG
5239  vals = consdata->vals;
5240  assert(vars != NULL);
5241  assert(vals != NULL);
5242 #endif
5243 
5244  /* get the position of the inferred variable in the vars array */
5245  inferpos = inferInfoGetPos(inferinfo);
5246  if( inferpos >= nvars || vars[inferpos] != infervar )
5247  {
5248  /* find inference variable in constraint */
5249  /**@todo use a binary search here; the variables can be sorted by variable index */
5250  for( inferpos = 0; inferpos < nvars && vars[inferpos] != infervar; ++inferpos )
5251  {}
5252  }
5253  assert(inferpos < nvars);
5254  assert(vars[inferpos] == infervar);
5255  assert(!SCIPisZero(scip, vals[inferpos]));
5256 
5257  switch( inferInfoGetProprule(inferinfo) )
5258  {
5259  case PROPRULE_1_RHS:
5260  /* the bound of the variable was tightened, because the minimal or maximal residual activity of the linear
5261  * constraint (only taking the other variables into account) didn't leave enough space for a larger
5262  * domain in order to not exceed the right hand side of the inequality
5263  */
5264  assert((vals[inferpos] > 0.0) == (boundtype == SCIP_BOUNDTYPE_UPPER));
5265  SCIP_CALL( addConflictBounds(scip, cons, infervar, bdchgidx, inferpos, TRUE) );
5266  *result = SCIP_SUCCESS;
5267  break;
5268 
5269  case PROPRULE_1_LHS:
5270  /* the bound of the variable was tightened, because the minimal or maximal residual activity of the linear
5271  * constraint (only taking the other variables into account) didn't leave enough space for a larger
5272  * domain in order to not fall below the left hand side of the inequality
5273  */
5274  assert((vals[inferpos] > 0.0) == (boundtype == SCIP_BOUNDTYPE_LOWER));
5275  SCIP_CALL( addConflictBounds(scip, cons, infervar, bdchgidx, inferpos, FALSE) );
5276  *result = SCIP_SUCCESS;
5277  break;
5278 
5279  case PROPRULE_1_RANGEDROW:
5280  /* the bound of the variable was tightened, because some variables were already fixed and the leftover only allow
5281  * the given inference variable to their bounds in this given ranged row
5282  */
5283 
5284  /* check that we really have a ranged row here */
5285  assert(!SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->rhs));
5286  SCIP_CALL( addConflictFixedVars(scip, cons, infervar, bdchgidx, inferpos) );
5287  *result = SCIP_SUCCESS;
5288  break;
5289 
5290  case PROPRULE_INVALID:
5291  default:
5292  SCIPerrorMessage("invalid inference information %d in linear constraint <%s> at position %d for %s bound of variable <%s>\n",
5293  inferInfoGetProprule(inferinfo), SCIPconsGetName(cons), inferInfoGetPos(inferinfo),
5294  boundtype == SCIP_BOUNDTYPE_LOWER ? "lower" : "upper", SCIPvarGetName(infervar));
5295  SCIP_CALL( SCIPprintCons(scip, cons, NULL) );
5296  SCIPinfoMessage(scip, NULL, ";\n");
5297  return SCIP_INVALIDDATA;
5298  }
5299 
5300  return SCIP_OKAY;
5301 }
5302 
5303 /** analyzes conflicting bounds on given constraint, and adds conflict constraint to problem */
5304 static
5306  SCIP* scip, /**< SCIP data structure */
5307  SCIP_CONS* cons, /**< conflict detecting constraint */
5308  SCIP_Bool reasonisrhs /**< is the right hand side responsible for the conflict? */
5309  )
5310 {
5311  /* conflict analysis can only be applied in solving stage and if it is turned on */
5313  return SCIP_OKAY;
5314 
5315  /* initialize conflict analysis */
5317 
5318  /* add the conflicting bound for each variable of infeasible constraint to conflict candidate queue */
5319  SCIP_CALL( addConflictBounds(scip, cons, NULL, NULL, -1, reasonisrhs) );
5320 
5321  /* analyze the conflict */
5322  SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
5323 
5324  return SCIP_OKAY;
5325 }
5326 
5327 /** check if there is any hope of tightening some bounds */
5328 static
5330  SCIP_CONS* cons /**< linear constraint */
5331  )
5332 {
5333  SCIP_CONSDATA* consdata;
5334  int infcountmin;
5335  int infcountmax;
5336 
5337  consdata = SCIPconsGetData(cons);
5338  assert(consdata != NULL);
5339 
5340  infcountmin = consdata->minactivityneginf
5341  + consdata->minactivityposinf
5342  + consdata->minactivityneghuge
5343  + consdata->minactivityposhuge;
5344  infcountmax = consdata->maxactivityneginf
5345  + consdata->maxactivityposinf
5346  + consdata->maxactivityneghuge
5347  + consdata->maxactivityposhuge;
5349  if( infcountmin > 1 && infcountmax > 1 )
5350  return FALSE;
5351 
5352  return TRUE;
5353 }
5354 
5355 /** tighten upper bound */
5356 static
5358  SCIP* scip, /**< SCIP data structure */
5359  SCIP_CONS* cons, /**< linear constraint */
5360  int pos, /**< variable position */
5361  PROPRULE proprule, /**< propagation rule that deduced the value */
5362  SCIP_Real newub, /**< new upper bound */
5363  SCIP_Real oldub, /**< old upper bound */
5364  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
5365  int* nchgbds, /**< pointer to count the total number of tightened bounds */
5366  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
5367  )
5368 {
5369  SCIP_CONSDATA* consdata;
5370  SCIP_VAR* var;
5371  SCIP_Real lb;
5372  SCIP_Bool infeasible;
5373  SCIP_Bool tightened;
5374 
5375  assert(cons != NULL);
5376  assert(!SCIPisInfinity(scip, newub));
5377 
5378  consdata = SCIPconsGetData(cons);
5379  assert(consdata != NULL);
5380  var = consdata->vars[pos];
5381  assert(var != NULL);
5382 
5383  lb = SCIPvarGetLbLocal(var);
5384  newub = SCIPadjustedVarUb(scip, var, newub);
5385 
5386  if( force || SCIPisUbBetter(scip, newub, lb, oldub) )
5387  {
5388  SCIP_VARTYPE vartype;
5389 
5390  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, activity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newub=%.15g\n",
5391  SCIPconsGetName(cons), SCIPvarGetName(var), lb, oldub, consdata->vals[pos], consdata->minactivity, consdata->maxactivity, consdata->lhs, consdata->rhs, newub);
5392 
5393  vartype = SCIPvarGetType(var);
5394 
5395  /* tighten upper bound */
5396  SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(proprule, pos), force, &infeasible, &tightened) );
5397 
5398  if( infeasible )
5399  {
5400  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5401  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5402 
5403  /* analyze conflict */
5404  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
5405 
5406  *cutoff = TRUE;
5407  }
5408  else if( tightened )
5409  {
5410  assert(SCIPisFeasLE(scip, SCIPvarGetUbLocal(var), oldub));
5411  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
5412  SCIPconsGetName(cons), SCIPvarGetName(var), lb, SCIPvarGetUbLocal(var));
5413 
5414  (*nchgbds)++;
5415 
5416  /* if variable type was changed we might be able to upgrade the constraint */
5417  if( vartype != SCIPvarGetType(var) )
5418  consdata->upgradetried = FALSE;
5419  }
5420  }
5421  return SCIP_OKAY;
5422 }
5423 
5424 /** tighten lower bound */
5425 static
5427  SCIP* scip, /**< SCIP data structure */
5428  SCIP_CONS* cons, /**< linear constraint */
5429  int pos, /**< variable position */
5430  PROPRULE proprule, /**< propagation rule that deduced the value */
5431  SCIP_Real newlb, /**< new lower bound */
5432  SCIP_Real oldlb, /**< old lower bound */
5433  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
5434  int* nchgbds, /**< pointer to count the total number of tightened bounds */
5435  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
5436  )
5437 {
5438  SCIP_CONSDATA* consdata;
5439  SCIP_VAR* var;
5440  SCIP_Real ub;
5441  SCIP_Bool infeasible;
5442  SCIP_Bool tightened;
5443 
5444  assert(cons != NULL);
5445  assert(!SCIPisInfinity(scip, newlb));
5446 
5447  consdata = SCIPconsGetData(cons);
5448  assert(consdata != NULL);
5449  var = consdata->vars[pos];
5450  assert(var != NULL);
5451 
5452  ub = SCIPvarGetUbLocal(var);
5453  newlb = SCIPadjustedVarLb(scip, var, newlb);
5454 
5455  if( force || SCIPisLbBetter(scip, newlb, oldlb, ub) )
5456  {
5457  SCIP_VARTYPE vartype;
5458 
5459  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, activity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
5460  SCIPconsGetName(cons), SCIPvarGetName(var), oldlb, ub, consdata->vals[pos], consdata->minactivity, consdata->maxactivity, consdata->lhs, consdata->rhs, newlb);
5461 
5462  vartype = SCIPvarGetType(var);
5463 
5464  /* tighten lower bound */
5465  SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(proprule, pos), force, &infeasible, &tightened) );
5466 
5467  if( infeasible )
5468  {
5469  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5470  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5471 
5472  /* analyze conflict */
5473  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
5474 
5475  *cutoff = TRUE;
5476  }
5477  else if( tightened )
5478  {
5479  assert(SCIPisFeasGE(scip, SCIPvarGetLbLocal(var), oldlb));
5480  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
5481  SCIPconsGetName(cons), SCIPvarGetName(var), SCIPvarGetLbLocal(var), ub);
5482 
5483  (*nchgbds)++;
5484 
5485  /* if variable type was changed we might be able to upgrade the constraint */
5486  if( vartype != SCIPvarGetType(var) )
5487  consdata->upgradetried = FALSE;
5488  }
5489  }
5490  return SCIP_OKAY;
5491 }
5492 
5493 /** tightens bounds of a single variable due to activity bounds (easy case) */
5494 static
5496  SCIP* scip, /**< SCIP data structure */
5497  SCIP_CONS* cons, /**< linear constraint */
5498  int pos, /**< position of the variable in the vars array */
5499  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
5500  int* nchgbds, /**< pointer to count the total number of tightened bounds */
5501  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
5502  )
5503 {
5504  SCIP_CONSDATA* consdata;
5505  SCIP_VAR* var;
5506  SCIP_Real val;
5507  SCIP_Real lb;
5508  SCIP_Real ub;
5509  SCIP_Real lhs;
5510  SCIP_Real rhs;
5511 
5512  assert(scip != NULL);
5513  assert(cons != NULL);
5514  assert(cutoff != NULL);
5515  assert(nchgbds != NULL);
5516 
5517  /* we cannot tighten variables' bounds, if the constraint may be not complete */
5518  if( SCIPconsIsModifiable(cons) )
5519  return SCIP_OKAY;
5520 
5521  consdata = SCIPconsGetData(cons);
5522  assert(consdata != NULL);
5523  assert(0 <= pos && pos < consdata->nvars);
5524 
5525  *cutoff = FALSE;
5526 
5527  var = consdata->vars[pos];
5528  assert(var != NULL);
5529 
5530  /* we cannot tighten bounds of multi-aggregated variables */
5532  return SCIP_OKAY;
5533 
5534  val = consdata->vals[pos];
5535  lhs = consdata->lhs;
5536  rhs = consdata->rhs;
5537  assert(!SCIPisZero(scip, val));
5538  assert(!SCIPisInfinity(scip, lhs));
5539  assert(!SCIPisInfinity(scip, -rhs));
5540 
5541  lb = SCIPvarGetLbLocal(var);
5542  ub = SCIPvarGetUbLocal(var);
5543  assert(SCIPisLE(scip, lb, ub));
5544 
5545  /* recompute activities if needed */
5546  if( !consdata->validactivities )
5547  consdataCalcActivities(scip, consdata);
5548  assert(consdata->validactivities);
5549  if( !consdata->validminact )
5550  consdataRecomputeMinactivity(scip, consdata);
5551  assert(consdata->validminact);
5552 
5553  if( val > 0.0 )
5554  {
5555  /* check, if we can tighten the variable's upper bound */
5556  if( !SCIPisInfinity(scip, rhs) )
5557  {
5558  SCIP_Real slack;
5559  SCIP_Real alpha;
5560 
5561  /* min activity should be valid at this point (if this is not true, then some decisions might be wrong!) */
5562  assert(consdata->validminact);
5563 
5564  /* if the minactivity is larger than the right hand side by feasibility epsilon, the constraint is infeasible */
5565  if( SCIPisFeasLT(scip, rhs, consdata->minactivity) )
5566  {
5567  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, minactivity=%.15g > rhs=%.15g\n",
5568  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->minactivity, rhs);
5569 
5570  *cutoff = TRUE;
5571  return SCIP_OKAY;
5572  }
5573 
5574  slack = rhs - consdata->minactivity;
5575 
5576  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5577  * it to zero
5578  */
5579  if( !SCIPisPositive(scip, slack) )
5580  slack = 0.0;
5581 
5582  alpha = val * (ub - lb);
5583  assert(!SCIPisNegative(scip, alpha));
5584 
5585  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5586  {
5587  SCIP_Real newub;
5588 
5589  /* compute new upper bound */
5590  newub = lb + (slack / val);
5591 
5592  SCIP_CALL( tightenVarUb(scip, cons, pos, PROPRULE_1_RHS, newub, ub, cutoff, nchgbds, force) );
5593 
5594  if( *cutoff )
5595  {
5596  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5597  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5598 
5599  return SCIP_OKAY;
5600  }
5601 
5602  /* collect the new upper bound which is needed for the lower bound computation */
5603  ub = SCIPvarGetUbLocal(var);
5604  }
5605  }
5606 
5607  /* check, if we can tighten the variable's lower bound */
5608  if( !SCIPisInfinity(scip, -lhs) )
5609  {
5610  SCIP_Real slack;
5611  SCIP_Real alpha;
5612 
5613  /* make sure the max activity is reliable */
5614  if( !consdata->validmaxact )
5615  {
5616  consdataRecomputeMaxactivity(scip, consdata);
5617  }
5618  assert(consdata->validmaxact);
5619 
5620  /* if the maxactivity is smaller than the left hand side by feasibility epsilon, the constraint is infeasible */
5621  if( SCIPisFeasLT(scip, consdata->maxactivity, lhs) )
5622  {
5623  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, maxactivity=%.15g < lhs=%.15g\n",
5624  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->maxactivity, lhs);
5625  *cutoff = TRUE;
5626  return SCIP_OKAY;
5627  }
5628 
5629  slack = consdata->maxactivity - lhs;
5630 
5631  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5632  * it to zero
5633  */
5634  if( !SCIPisPositive(scip, slack) )
5635  slack = 0.0;
5636 
5637  alpha = val * (ub - lb);
5638  assert(!SCIPisNegative(scip, alpha));
5639 
5640  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5641  {
5642  SCIP_Real newlb;
5643 
5644  /* compute new lower bound */
5645  newlb = ub - (slack / val);
5646 
5647  SCIP_CALL( tightenVarLb(scip, cons, pos, PROPRULE_1_LHS, newlb, lb, cutoff, nchgbds, force) );
5648 
5649  if( *cutoff )
5650  {
5651  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5652  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5653 
5654  return SCIP_OKAY;
5655  }
5656  }
5657  }
5658  }
5659  else
5660  {
5661  /* check, if we can tighten the variable's lower bound */
5662  if( !SCIPisInfinity(scip, rhs) )
5663  {
5664  SCIP_Real slack;
5665  SCIP_Real alpha;
5666 
5667  /* min activity should be valid at this point (if this is not true, then some decisions might be wrong!) */
5668  assert(consdata->validminact);
5669 
5670  /* if the minactivity is larger than the right hand side by feasibility epsilon, the constraint is infeasible */
5671  if( SCIPisFeasLT(scip, rhs, consdata->minactivity) )
5672  {
5673  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, minactivity=%.15g > rhs=%.15g\n",
5674  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->minactivity, rhs);
5675 
5676  *cutoff = TRUE;
5677  return SCIP_OKAY;
5678  }
5679 
5680  slack = rhs - consdata->minactivity;
5681 
5682  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5683  * it to zero
5684  */
5685  if( !SCIPisPositive(scip, slack) )
5686  slack = 0.0;
5687 
5688  alpha = val * (lb - ub);
5689  assert(!SCIPisNegative(scip, alpha));
5690 
5691  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5692  {
5693  SCIP_Real newlb;
5694 
5695  /* compute new lower bound */
5696  newlb = ub + slack / val;
5697 
5698  SCIP_CALL( tightenVarLb(scip, cons, pos, PROPRULE_1_RHS, newlb, lb, cutoff, nchgbds, force) );
5699 
5700  if( *cutoff )
5701  {
5702  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5703  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
5704 
5705  return SCIP_OKAY;
5706  }
5707  /* collect the new lower bound which is needed for the upper bound computation */
5708  lb = SCIPvarGetLbLocal(var);
5709  }
5710  }
5711 
5712  /* check, if we can tighten the variable's upper bound */
5713  if( !SCIPisInfinity(scip, -lhs) )
5714  {
5715  SCIP_Real slack;
5716  SCIP_Real alpha;
5717 
5718  /* make sure the max activity is reliable */
5719  if( !consdata->validmaxact )
5720  {
5721  consdataRecomputeMaxactivity(scip, consdata);
5722  }
5723  assert(consdata->validmaxact);
5724 
5725  /* if the maxactivity is smaller than the left hand side by feasibility epsilon, the constraint is infeasible */
5726  if( SCIPisFeasLT(scip, consdata->maxactivity, lhs) )
5727  {
5728  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, maxactivity=%.15g < lhs=%.15g\n",
5729  SCIPconsGetName(cons), SCIPvarGetName(var), consdata->maxactivity, lhs);
5730 
5731  *cutoff = TRUE;
5732  return SCIP_OKAY;
5733  }
5734 
5735  slack = consdata->maxactivity - lhs;
5736 
5737  /* if the slack is zero in tolerances (or negative, but not enough to make the constraint infeasible), we set
5738  * it to zero
5739  */
5740  if( !SCIPisPositive(scip, slack) )
5741  slack = 0.0;
5742 
5743  alpha = val * (lb - ub);
5744  assert(!SCIPisNegative(scip, alpha));
5745 
5746  if( SCIPisSumGT(scip, alpha, slack) || (force && SCIPisGT(scip, alpha, slack)) )
5747  {
5748  SCIP_Real newub;
5749 
5750  /* compute new upper bound */
5751  newub = lb - (slack / val);
5752 
5753  SCIP_CALL( tightenVarUb(scip, cons, pos, PROPRULE_1_LHS, newub, ub, cutoff, nchgbds, force) );
5754 
5755  if( *cutoff )
5756  {
5757  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
5758  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
5759 
5760  return SCIP_OKAY;
5761  }
5762  }
5763  }
5764  }
5765 
5766  return SCIP_OKAY;
5767 }
5768 
5769 /** analyzes conflicting bounds on given ranged row constraint, and adds conflict constraint to problem */
5770 static
5772  SCIP* scip, /**< SCIP data structure */
5773  SCIP_CONS* cons, /**< conflict detecting constraint */
5774  SCIP_VAR** vars, /**< variables reasoning the infeasibility */
5775  int nvars, /**< number of variables reasoning the infeasibility */
5776  SCIP_VAR* var, /**< variable which was tried to fix/tighten, or NULL */
5777  SCIP_Real bound /**< bound of variable which was tried to apply, or SCIP_INVALID */
5778  )
5779 {
5780 #ifndef NDEBUG
5781  SCIP_CONSDATA* consdata;
5782 
5783  assert(scip != NULL);
5784  assert(cons != NULL);
5785 
5786  consdata = SCIPconsGetData(cons);
5787  assert(consdata != NULL);
5788  assert(!SCIPisInfinity(scip, -consdata->lhs) && !SCIPisInfinity(scip, consdata->rhs));
5789 #endif
5791  /* conflict analysis can only be applied in solving stage and if it is turned on */
5793  return SCIP_OKAY;
5794 
5795  /* initialize conflict analysis */
5797 
5798  /* add the conflicting fixed variables of this ranged row constraint to conflict candidate queue */
5799  SCIP_CALL( addConflictFixedVars(scip, cons, NULL, NULL, -1) );
5800 
5801  /* add reasoning variables to conflict candidate queue which led to the conflict */
5802  SCIP_CALL( addConflictReasonVars(scip, vars, nvars, var, bound) );
5803 
5804  /* analyze the conflict */
5805  SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
5806 
5807  return SCIP_OKAY;
5808 }
5809 
5810 /** propagate ranged rows
5811  *
5812  * Check ranged rows for possible solutions, possibly detect infeasibility, fix variables due to having only one possible
5813  * solution, tighten bounds if having only two possible solutions or add constraints which propagate a subset of
5814  * variables better.
5815  *
5816  * Example:
5817  * c1: 12 x1 + 9 x2 - x3 = 0 with x1, x2 free and 1 <= x3 <= 2
5818  *
5819  * x3 needs to be a multiple of 3, so the instance is infeasible.
5820  *
5821  * Example:
5822  * c1: 12 x1 + 9 x2 - x3 = 1 with x1, x2 free and 1 <= x3 <= 2
5823  *
5824  * The only possible value for x3 is 2, so the variable will be fixed.
5825  *
5826  * @todo add holes if possible
5827  */
5828 static
5830  SCIP* scip, /**< SCIP data structure */
5831  SCIP_CONS* cons, /**< linear constraint */
5832  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
5833  int* nfixedvars, /**< pointer to count number of fixed variables */
5834  int* nchgbds, /**< pointer to count the number of bound changes */
5835  int* naddconss /**< pointer to count number of added constraints */
5836  )
5837 {
5838  SCIP_CONSHDLRDATA* conshdlrdata;
5839  SCIP_CONSHDLR* conshdlr;
5840  SCIP_CONSDATA* consdata;
5841  SCIP_VAR** infcheckvars;
5842  SCIP_Real* infcheckvals;
5843  SCIP_Real minactinfvars;
5844  SCIP_Real maxactinfvars;
5845  SCIP_Real lb;
5846  SCIP_Real ub;
5847  SCIP_Real feastol;
5848  SCIP_Real fixedact;
5849  SCIP_Real lhs;
5850  SCIP_Real rhs;
5851  SCIP_Real absminbincoef;
5852  SCIP_Longint gcd;
5853  SCIP_Longint gcdtmp;
5854  SCIP_Bool minactinfvarsinvalid;
5855  SCIP_Bool maxactinfvarsinvalid;
5856  SCIP_Bool possiblegcd;
5857  SCIP_Bool gcdisone;
5858  SCIP_Bool addartconss;
5859  int ninfcheckvars;
5860  int nunfixedvars;
5861  int nfixedconsvars;
5862  int ncontvars;
5863  int pos;
5864  int v;
5865 
5866  assert(scip != NULL);
5867  assert(cons != NULL);
5868  assert(cutoff != NULL);
5869  assert(nfixedvars != NULL);
5870  assert(nchgbds != NULL);
5871  assert(naddconss != NULL);
5872 
5873  /* modifiable constraint can be changed so we do not have all necessary information */
5874  if( SCIPconsIsModifiable(cons) )
5875  return SCIP_OKAY;
5876 
5877  consdata = SCIPconsGetData(cons);
5878  assert(consdata != NULL);
5879 
5880  /* we already did full ranged row propagation */
5881  if( consdata->rangedrowpropagated == 2 )
5882  return SCIP_OKAY;
5883 
5884  /* at least three variables are needed */
5885  if( consdata->nvars < 3 )
5886  return SCIP_OKAY;
5887 
5888  /* do nothing on normal inequalities */
5889  if( SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, consdata->rhs) )
5890  return SCIP_OKAY;
5891 
5892  /* get constraint handler data */
5893  conshdlr = SCIPconsGetHdlr(cons);
5894  assert(conshdlr != NULL);
5895  conshdlrdata = SCIPconshdlrGetData(conshdlr);
5896  assert(conshdlrdata != NULL);
5897 
5898  addartconss = conshdlrdata->rangedrowartcons && SCIPgetDepth(scip) < 1 && !SCIPinProbing(scip) && !SCIPinRepropagation(scip);
5899 
5900  /* we may add artificial constraints */
5901  if( addartconss )
5902  consdata->rangedrowpropagated = 2;
5903  /* we are not allowed to add artificial constraints during propagation; if nothing changed on this constraint since
5904  * the last rangedrowpropagation, we can stop; otherwise, we mark this constraint to be rangedrowpropagated without
5905  * artificial constraints
5906  */
5907  else
5908  {
5909  if( consdata->rangedrowpropagated > 0 )
5910  return SCIP_OKAY;
5911 
5912  consdata->rangedrowpropagated = 1;
5913  }
5914  fixedact = 0;
5915  nfixedconsvars = 0;
5916  /* calculate fixed activity and number of fixed variables */
5917  for( v = consdata->nvars - 1; v >= 0; --v )
5918  {
5919  /* all zero coefficients should be eliminated */
5920  assert(!SCIPisZero(scip, consdata->vals[v]));
5921 
5922  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5923  {
5924  fixedact += SCIPvarGetLbLocal(consdata->vars[v]) * consdata->vals[v];
5925  ++nfixedconsvars;
5926  }
5927  }
5928 
5929  /* do not work with huge fixed activities */
5930  if( SCIPisHugeValue(scip, REALABS(fixedact)) )
5931  return SCIP_OKAY;
5932 
5933  /* compute lhs and rhs for unfixed variables only and get number of unfixed variables */
5934  assert(!SCIPisInfinity(scip, -fixedact) && !SCIPisInfinity(scip, fixedact));
5935  lhs = consdata->lhs - fixedact;
5936  rhs = consdata->rhs - fixedact;
5937  nunfixedvars = consdata->nvars - nfixedconsvars;
5938 
5939  /* allocate temporary memory for variables and coefficients which may lead to infeasibility */
5940  SCIP_CALL( SCIPallocBufferArray(scip, &infcheckvars, nunfixedvars) );
5941  SCIP_CALL( SCIPallocBufferArray(scip, &infcheckvals, nunfixedvars) );
5942 
5943  absminbincoef = SCIP_REAL_MAX;
5944  ncontvars = 0;
5945  gcdisone = TRUE;
5946  possiblegcd = TRUE;
5947 
5948  /* we now partition all unfixed variables in two groups:
5949  *
5950  * the first one contains all integral variable with integral
5951  * coefficient so that all variables in this group will have a gcd greater than 1, this group will be implicitly
5952  * given
5953  *
5954  * the second group will contain all left unfixed variables and will be saved as infcheckvars with corresponding
5955  * coefficients as infcheckvals, the order of these variables should be the same as in the consdata object
5956  */
5957 
5958  /* find first integral variables with integral coefficient greater than 1, thereby collecting all other unfixed
5959  * variables
5960  */
5961  ninfcheckvars = 0;
5962  v = -1;
5963  pos = -1;
5964  do
5965  {
5966  ++v;
5967 
5968  /* partition the variables, do not change the order of collection, because it might be used later on */
5969  while( v < consdata->nvars && (SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS ||
5970  !SCIPisIntegral(scip, consdata->vals[v]) || SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0)) )
5971  {
5972  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
5973  {
5974  if( SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS )
5975  {
5976  ++ncontvars;
5977  }
5978  else if( SCIPvarIsBinary(consdata->vars[v]) )
5979  {
5980  SCIP_Real absval;
5981 
5982  absval = REALABS(consdata->vals[v]);
5983 
5984  if( absminbincoef > absval )
5985  absminbincoef = absval;
5986  }
5987 
5988  gcdisone = gcdisone && SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0);
5989  possiblegcd = FALSE;
5990  infcheckvars[ninfcheckvars] = consdata->vars[v];
5991  infcheckvals[ninfcheckvars] = consdata->vals[v];
5992  ++ninfcheckvars;
5993 
5994  if( pos == -1 )
5995  pos = v;
5996  }
5997  ++v;
5998  }
5999  }
6000  while( v < consdata->nvars && SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) );
6001 
6002  /* if the first group of variables is empty, we stop */
6003  /* @todo try to propagate/split up a constraint of the form:
6004  * x_1 + ... + x_m + a_1*y_1 + ... + a_n*y_n = k + c,
6005  * with k \in Z, c \in (d,d + 1], d \in Z, (a_1*y_1 + ... + a_n*y_n) \in (c-1 + d,d + 1]
6006  */
6007  if( v == consdata->nvars )
6008  goto TERMINATE;
6009 
6010  /* we need at least two non-continuous variables */
6011  if( ncontvars + 2 > nunfixedvars )
6012  goto TERMINATE;
6013 
6014  assert(!SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])));
6015  assert(SCIPisIntegral(scip, consdata->vals[v]) && SCIPvarGetType(consdata->vars[v]) != SCIP_VARTYPE_CONTINUOUS && REALABS(consdata->vals[v]) > 1.5);
6016 
6017  feastol = SCIPfeastol(scip);
6018 
6019  gcd = (SCIP_Longint)(REALABS(consdata->vals[v]) + feastol);
6020  assert(gcd >= 2);
6021 
6022  /* go on to partition the variables, do not change the order of collection, because it might be used later on;
6023  * calculate gcd over the first part of variables */
6024  for( ; v < consdata->nvars; ++v )
6025  {
6026  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6027  continue;
6028 
6029  if( SCIPvarIsBinary(consdata->vars[v]) )
6030  {
6031  SCIP_Real absval;
6032 
6033  absval = REALABS(consdata->vals[v]);
6034 
6035  if( absminbincoef > absval )
6036  absminbincoef = absval;
6037  }
6038 
6039  if( !SCIPisIntegral(scip, consdata->vals[v]) || SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS ||
6040  SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0) )
6041  {
6042  if( SCIPvarGetType(consdata->vars[v]) == SCIP_VARTYPE_CONTINUOUS )
6043  ++ncontvars;
6044 
6045  gcdisone = gcdisone && SCIPisEQ(scip, REALABS(consdata->vals[v]), 1.0);
6046  possiblegcd = FALSE;
6047  infcheckvars[ninfcheckvars] = consdata->vars[v];
6048  infcheckvals[ninfcheckvars] = consdata->vals[v];
6049 
6050  ++ninfcheckvars;
6051 
6052  if( pos == -1 )
6053  pos = v;
6054  }
6055  else
6056  {
6057  assert(REALABS(consdata->vals[v]) > 1.5);
6058 
6059  gcdtmp = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(consdata->vals[v]) + feastol));
6060  assert(gcdtmp >= 1);
6061 
6062  if( gcdtmp == 1 )
6063  {
6064  infcheckvars[ninfcheckvars] = consdata->vars[v];
6065  infcheckvals[ninfcheckvars] = consdata->vals[v];
6066 
6067  ++ninfcheckvars;
6068 
6069  if( pos == -1 )
6070  pos = v;
6071  }
6072  else
6073  gcd = gcdtmp;
6074  }
6075  }
6076  assert(gcd >= 2);
6077 
6078  /* it should not happen that all variables are of integral type and have a gcd >= 2, this should be done by
6079  * normalizeCons() */
6080  if( ninfcheckvars == 0 )
6081  goto TERMINATE;
6082 
6083  assert(pos >= 0);
6084 
6085  minactinfvarsinvalid = FALSE;
6086  maxactinfvarsinvalid = FALSE;
6087  maxactinfvars = 0.0;
6088  minactinfvars = 0.0;
6089 
6090  /* calculate activities over all infcheckvars */
6091  for( v = ninfcheckvars - 1; v >= 0; --v )
6092  {
6093  lb = SCIPvarGetLbLocal(infcheckvars[v]);
6094  ub = SCIPvarGetUbLocal(infcheckvars[v]);
6095 
6096  if( SCIPisInfinity(scip, -lb) )
6097  {
6098  if( infcheckvals[v] < 0.0 )
6099  maxactinfvarsinvalid = TRUE;
6100  else
6101  minactinfvarsinvalid = TRUE;
6102  }
6103  else
6104  {
6105  if( infcheckvals[v] < 0.0 )
6106  maxactinfvars += infcheckvals[v] * lb;
6107  else
6108  minactinfvars += infcheckvals[v] * lb;
6109  }
6110 
6111  if( SCIPisInfinity(scip, ub) )
6112  {
6113  if( infcheckvals[v] > 0.0 )
6114  maxactinfvarsinvalid = TRUE;
6115  else
6116  minactinfvarsinvalid = TRUE;
6117  }
6118  else
6119  {
6120  if( infcheckvals[v] > 0.0 )
6121  maxactinfvars += infcheckvals[v] * ub;
6122  else
6123  minactinfvars += infcheckvals[v] * ub;
6124  }
6125 
6126  /* better abort on to big values */
6127  if( SCIPisHugeValue(scip, -minactinfvars) )
6128  minactinfvarsinvalid = TRUE;
6129  if( SCIPisHugeValue(scip, maxactinfvars) )
6130  maxactinfvarsinvalid = TRUE;
6131 
6132  if( minactinfvarsinvalid || maxactinfvarsinvalid )
6133  goto TERMINATE;
6134  }
6135  assert(!minactinfvarsinvalid && !maxactinfvarsinvalid);
6136 
6137  SCIPdebugMsg(scip, "minactinfvarsinvalid = %u, minactinfvars = %g, maxactinfvarsinvalid = %u, maxactinfvars = %g, gcd = %lld, ninfcheckvars = %d, ncontvars = %d\n",
6138  minactinfvarsinvalid, minactinfvars, maxactinfvarsinvalid, maxactinfvars, gcd, ninfcheckvars, ncontvars);
6139 
6140  /* @todo maybe we took the wrong variables as infcheckvars we could try to exchange integer variables */
6141  /* @todo if minactinfvarsinvalid or maxactinfvarsinvalid are true, try to exchange both partitions to maybe get valid
6142  * activities */
6143  /* @todo calculate minactivity and maxactivity for all non-intcheckvars, and use this for better bounding,
6144  * !!!note!!!
6145  * that therefore the conflict variables in addConflictFixedVars() need to be extended by all variables which
6146  * are not at their global bound
6147  */
6148 
6149  /* check if between left hand side and right hand side exist a feasible point, if not the constraint leads to
6150  * infeasibility */
6151  if( !SCIPisIntegral(scip, (lhs - maxactinfvars) / gcd) &&
6152  SCIPisGT(scip, SCIPceil(scip, (lhs - maxactinfvars) / gcd) * gcd, rhs - minactinfvars) )
6153  {
6154  SCIPdebugMsg(scip, "no feasible value exist, constraint <%s> lead to infeasibility", SCIPconsGetName(cons));
6155  SCIPdebugPrintCons(scip, cons, NULL);
6156 
6157  /* start conflict analysis */
6158  /* @todo improve conflict analysis by adding relaxed bounds */
6159  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6160 
6161  *cutoff = TRUE;
6162  }
6163  else if( ncontvars == 0 )
6164  {
6165  SCIP_Longint gcdinfvars = -1;
6166 
6167  /* check for gcd over all infcheckvars */
6168  if( possiblegcd )
6169  {
6170  v = ninfcheckvars - 1;
6171  gcdinfvars = (SCIP_Longint)(REALABS(infcheckvals[v]) + feastol);
6172  assert(gcdinfvars >= 2);
6173 
6174  for( ; v >= 0 && gcdinfvars >= 2; --v )
6175  {
6176  gcdinfvars = SCIPcalcGreComDiv(gcdinfvars, (SCIP_Longint)(REALABS(infcheckvals[v]) + feastol));
6177  }
6178  }
6179  else if( gcdisone )
6180  gcdinfvars = 1;
6181 
6182  SCIPdebugMsg(scip, "gcdinfvars =%lld, possiblegcd = %u\n", gcdinfvars, possiblegcd);
6183 
6184  /* compute solutions for this ranged row, if all variables are of integral type with integral coefficients */
6185  if( gcdinfvars >= 1 )
6186  {
6187  SCIP_Real value;
6188  SCIP_Real value2;
6189  SCIP_Real minvalue = SCIP_INVALID;
6190  SCIP_Real maxvalue = SCIP_INVALID;
6191  int nsols = 0;
6192 
6193  value = SCIPceil(scip, minactinfvars - SCIPfeastol(scip));
6194 
6195  /* check how many possible solutions exist */
6196  while( SCIPisLE(scip, value, maxactinfvars) )
6197  {
6198  value2 = value + gcd * (SCIPceil(scip, (lhs - value) / gcd));
6199 
6200  /* value2 might violate lhs due to numerics, in this case take the next divisible number */
6201  if( !SCIPisGE(scip, value2, lhs) )
6202  {
6203  value2 += gcd;
6204  }
6205 
6206  if( SCIPisLE(scip, value2, rhs) )
6207  {
6208  ++nsols;
6209 
6210  /* early termination if we found more than two solutions */
6211  if( nsols == 3 )
6212  break;
6213 
6214  if( minvalue == SCIP_INVALID ) /*lint !e777*/
6215  minvalue = value;
6216 
6217  maxvalue = value;
6218  }
6219  value += gcdinfvars;
6220  }
6221  assert(nsols < 2 || minvalue <= maxvalue);
6222 
6223  /* determine last possible solution for better bounding */
6224  if( nsols == 3 )
6225  {
6226 #ifndef NDEBUG
6227  SCIP_Real secondsolval = maxvalue;
6228 #endif
6229  value = SCIPfloor(scip, maxactinfvars + SCIPfeastol(scip));
6230 
6231  /* check how many possible solutions exist */
6232  while( SCIPisGE(scip, value, minactinfvars) )
6233  {
6234  value2 = value + gcd * (SCIPfloor(scip, (rhs - value) / gcd));
6235 
6236  /* value2 might violate rhs due to numerics, in this case take the next divisible number */
6237  if( !SCIPisLE(scip, value2, rhs) )
6238  {
6239  value2 -= gcd;
6240  }
6241 
6242  if( SCIPisGE(scip, value2, lhs) )
6243  {
6244  maxvalue = value;
6245  assert(maxvalue > minvalue);
6246  break;
6247  }
6248  value -= gcdinfvars;
6249  }
6250  assert(maxvalue > secondsolval);
6251  }
6252 
6253  SCIPdebugMsg(scip, "here nsols %s %d, minsolvalue = %g, maxsolvalue = %g, ninfcheckvars = %d, nunfixedvars = %d\n",
6254  nsols > 2 ? ">=" : "=", nsols, minvalue, maxvalue, ninfcheckvars, nunfixedvars);
6255 
6256  /* no possible solution found */
6257  if( nsols == 0 )
6258  {
6259  SCIPdebugMsg(scip, "gcdinfvars = %lld, gcd = %lld, correctedlhs = %g, correctedrhs = %g\n",
6260  gcdinfvars, gcd, lhs, rhs);
6261  SCIPdebugMsg(scip, "no solution found; constraint <%s> lead to infeasibility\n", SCIPconsGetName(cons));
6262  SCIPdebugPrintCons(scip, cons, NULL);
6263 
6264  /* start conflict analysis */
6265  /* @todo improve conflict analysis by adding relaxed bounds */
6266  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6267 
6268  *cutoff = TRUE;
6269  }
6270  /* if only one solution exist we can extract a new constraint or fix variables */
6271  else if( nsols == 1 )
6272  {
6273  assert(minvalue == maxvalue); /*lint !e777*/
6274 
6275  /* we can fix the only variable in our second set of variables */
6276  if( ninfcheckvars == 1 )
6277  {
6278  SCIP_Bool fixed;
6279 
6280  assert(SCIPisEQ(scip, (SCIP_Real)gcdinfvars, REALABS(infcheckvals[0])));
6281 
6282  SCIPdebugMsg(scip, "fixing single variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
6283  SCIPvarGetName(infcheckvars[0]), SCIPvarGetLbLocal(infcheckvars[0]),
6284  SCIPvarGetUbLocal(infcheckvars[0]), maxvalue/infcheckvals[0]);
6285 
6286  /* fix variable to only possible value */
6287  SCIP_CALL( SCIPinferVarFixCons(scip, infcheckvars[0], maxvalue/infcheckvals[0], cons,
6288  getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &fixed) );
6289 
6290  if( *cutoff )
6291  {
6292  /* start conflict analysis */
6293  /* @todo improve conflict analysis by adding relaxed bounds */
6294  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6295  }
6296 
6297  if( fixed )
6298  ++(*nfixedvars);
6299  }
6300  else
6301  {
6302  /* check for exactly one unfixed variable which is not part of the infcheckvars */
6303  if( ninfcheckvars == nunfixedvars - 1 )
6304  {
6305  SCIP_Real bound;
6306  SCIP_Bool foundvar = FALSE;
6307  SCIP_Bool fixed;
6308  int w = 0;
6309 
6310  assert(ninfcheckvars > 0);
6311 
6312  /* find variable which is not an infcheckvar and fix it */
6313  for( v = 0; v < consdata->nvars - 1; ++v )
6314  {
6315  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6316  {
6317  if( w >= ninfcheckvars || consdata->vars[v] != infcheckvars[w] )
6318  {
6319 #ifndef NDEBUG
6320  int v2 = v + 1;
6321  int w2 = w;
6322 
6323  assert((nfixedconsvars == 0) ? (consdata->nvars - v - 1 == ninfcheckvars - w) : TRUE);
6324 
6325  for( ; v2 < consdata->nvars && w2 < ninfcheckvars; ++v2 )
6326  {
6327  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v2]), SCIPvarGetUbLocal(consdata->vars[v2])) )
6328  continue;
6329 
6330  assert(consdata->vars[v2] == infcheckvars[w2]);
6331  ++w2;
6332  }
6333  assert(w2 == ninfcheckvars);
6334 #endif
6335  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6336 
6337  foundvar = TRUE;
6338 
6339  if( consdata->vals[v] < 0 )
6340  {
6341  bound = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6342  }
6343  else
6344  {
6345  bound = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6346  }
6347 
6348  SCIPdebugMsg(scip, "fixing variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
6349  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]),
6350  SCIPvarGetUbLocal(consdata->vars[v]), bound);
6351 
6352  /* fix variable to only possible value */
6353  SCIP_CALL( SCIPinferVarFixCons(scip, consdata->vars[v], bound, cons,
6354  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &fixed) );
6355 
6356  if( *cutoff )
6357  {
6358  /* start conflict analysis */
6359  /* @todo improve conflict analysis by adding relaxed bounds */
6360  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6361  consdata->vars[v], bound) );
6362  }
6363 
6364  if( fixed )
6365  ++(*nfixedvars);
6366 
6367  break;
6368  }
6369 
6370  ++w;
6371  }
6372  }
6373 
6374  /* maybe last variable was the not infcheckvar */
6375  if( !foundvar )
6376  {
6377  assert(v == consdata->nvars - 1);
6378  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6379 
6380  if( consdata->vals[v] < 0 )
6381  {
6382  bound = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6383  }
6384  else
6385  {
6386  bound = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6387  }
6388 
6389  SCIPdebugMsg(scip, "fixing variable <%s> with bounds [%.15g,%.15g] to %.15g\n",
6390  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]),
6391  SCIPvarGetUbLocal(consdata->vars[v]), bound);
6392 
6393  /* fix variable to only possible value */
6394  SCIP_CALL( SCIPinferVarFixCons(scip, consdata->vars[v], bound, cons,
6395  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &fixed) );
6396 
6397  if( *cutoff )
6398  {
6399  /* start conflict analysis */
6400  /* @todo improve conflict analysis by adding relaxed bounds */
6401  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6402  consdata->vars[v], bound) );
6403  }
6404 
6405  if( fixed )
6406  ++(*nfixedvars);
6407  }
6408  }
6409  else if( addartconss && (SCIPisGT(scip, minvalue, minactinfvars) || SCIPisLT(scip, maxvalue, maxactinfvars)) )
6410  {
6411  /* aggregation possible if we have two variables, but this will be done later on */
6412  SCIP_CONS* newcons;
6413  char name[SCIP_MAXSTRLEN];
6414 
6415  /* create, add, and release new artificial constraint */
6416  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6417  ++conshdlrdata->naddconss;
6418 
6419  SCIPdebugMsg(scip, "adding artificial constraint %s\n", name);
6420 
6421  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals,
6422  maxvalue, maxvalue, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6423  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6424 
6425  SCIPdebugPrintCons(scip, newcons, NULL);
6426 
6427  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6428 
6429  ++(*naddconss);
6430  }
6431  }
6432  }
6433  /* at least two solutions */
6434  else
6435  {
6436  /* @todo if we found more then one solution, we may reduced domains due to dualpresolving? */
6437 
6438  /* only one variable in the second set, so we can bound this variables */
6439  if( ninfcheckvars == 1 )
6440  {
6441  SCIP_Bool tightened;
6442  SCIP_Real newlb;
6443  SCIP_Real newub;
6444 
6445  assert(SCIPisEQ(scip, (SCIP_Real)gcdinfvars, REALABS(infcheckvals[0])));
6446 
6447  if( infcheckvals[0] < 0 )
6448  {
6449  newlb = maxvalue/infcheckvals[0];
6450  newub = minvalue/infcheckvals[0];
6451  }
6452  else
6453  {
6454  newlb = minvalue/infcheckvals[0];
6455  newub = maxvalue/infcheckvals[0];
6456  }
6457  assert(newlb < newub);
6458 
6459  if( newlb > SCIPvarGetLbLocal(infcheckvars[0]) )
6460  {
6461  /* update lower bound of variable */
6462  SCIPdebugMsg(scip, "tightening lower bound of variable <%s> from %g to %g\n",
6463  SCIPvarGetName(infcheckvars[0]), SCIPvarGetLbLocal(infcheckvars[0]), newlb);
6464 
6465  /* tighten variable lower bound to minimal possible value */
6466  SCIP_CALL( SCIPinferVarLbCons(scip, infcheckvars[0], newlb, cons,
6467  getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &tightened) );
6468 
6469  if( *cutoff )
6470  {
6471  /* start conflict analysis */
6472  /* @todo improve conflict analysis by adding relaxed bounds */
6473  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6474  }
6475 
6476  if( tightened )
6477  ++(*nchgbds);
6478  }
6479 
6480  if( newub < SCIPvarGetUbLocal(infcheckvars[0]) )
6481  {
6482  /* update upper bound of variable */
6483  SCIPdebugMsg(scip, "tightening upper bound of variable <%s> from %g to %g\n",
6484  SCIPvarGetName(infcheckvars[0]), SCIPvarGetUbLocal(infcheckvars[0]), newub);
6485 
6486  /* tighten variable upper bound to maximal possible value */
6487  SCIP_CALL( SCIPinferVarUbCons(scip, infcheckvars[0], newub, cons,
6488  getInferInt(PROPRULE_1_RANGEDROW, pos), TRUE, cutoff, &tightened) );
6489 
6490  if( *cutoff )
6491  {
6492  /* start conflict analysis */
6493  /* @todo improve conflict analysis by adding relaxed bounds */
6494  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, NULL, SCIP_INVALID) );
6495  }
6496 
6497  if( tightened )
6498  ++(*nchgbds);
6499  }
6500  }
6501  /* check if we have only one not infcheckvars, if so we can tighten this variable */
6502  else if( ninfcheckvars == nunfixedvars - 1 )
6503  {
6504  SCIP_Bool foundvar = FALSE;
6505  SCIP_Bool tightened;
6506  SCIP_Real newlb;
6507  SCIP_Real newub;
6508  int w = 0;
6509 
6510  assert(ninfcheckvars > 0);
6511  assert(minvalue < maxvalue);
6512 
6513  /* find variable which is not an infcheckvar and fix it */
6514  for( v = 0; v < consdata->nvars - 1; ++v )
6515  {
6516  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6517  {
6518  if( w >= ninfcheckvars || consdata->vars[v] != infcheckvars[w] )
6519  {
6520 #ifndef NDEBUG
6521  int v2 = v + 1;
6522  int w2 = w;
6523 
6524  assert((nfixedconsvars == 0) ? (consdata->nvars - v - 1 == ninfcheckvars - w) : TRUE);
6525 
6526  for( ; v2 < consdata->nvars && w2 < ninfcheckvars; ++v2 )
6527  {
6528  if( SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v2]), SCIPvarGetUbLocal(consdata->vars[v2])) )
6529  continue;
6530 
6531  assert(consdata->vars[v2] == infcheckvars[w2]);
6532  ++w2;
6533  }
6534  assert(w2 == ninfcheckvars);
6535 #endif
6536 
6537  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6538  foundvar = TRUE;
6539 
6540  if( consdata->vals[v] < 0 )
6541  {
6542  newlb = SCIPfloor(scip, (rhs - minvalue) / consdata->vals[v]);
6543  newub = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6544  }
6545  else
6546  {
6547  newlb = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6548  newub = SCIPceil(scip, (rhs - minvalue) / consdata->vals[v]);
6549  }
6550  assert(SCIPisLE(scip, newlb, newub));
6551 
6552  if( newlb > SCIPvarGetLbLocal(consdata->vars[v]) )
6553  {
6554  /* update lower bound of variable */
6555  SCIPdebugMsg(scip, "tightening lower bound of variable <%s> from %g to %g\n",
6556  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]), newlb);
6557 
6558  /* tighten variable lower bound to minimal possible value */
6559  SCIP_CALL( SCIPinferVarLbCons(scip, consdata->vars[v], newlb, cons,
6560  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6561 
6562  if( *cutoff )
6563  {
6564  /* start conflict analysis */
6565  /* @todo improve conflict analysis by adding relaxed bounds */
6566  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6567  consdata->vars[v], newlb) );
6568  }
6569 
6570  if( tightened )
6571  ++(*nchgbds);
6572  }
6573 
6574  if( newub < SCIPvarGetUbLocal(consdata->vars[v]) )
6575  {
6576  /* update upper bound of variable */
6577  SCIPdebugMsg(scip, "tightening upper bound of variable <%s> from %g to %g\n",
6578  SCIPvarGetName(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v]), newub);
6579 
6580  /* tighten variable upper bound to maximal possible value */
6581  SCIP_CALL( SCIPinferVarUbCons(scip, consdata->vars[v], newub, cons,
6582  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6583 
6584  if( *cutoff )
6585  {
6586  /* start conflict analysis */
6587  /* @todo improve conflict analysis by adding relaxed bounds */
6588  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars,
6589  consdata->vars[v], newub) );
6590  }
6591 
6592  if( tightened )
6593  ++(*nchgbds);
6594  }
6595 
6596  break;
6597  }
6598 
6599  ++w;
6600  }
6601  }
6602 
6603  /* maybe last variable was the not infcheckvar */
6604  if( !foundvar )
6605  {
6606  assert(v == consdata->nvars - 1);
6607  assert(SCIPisEQ(scip, (SCIP_Real)gcd, REALABS(consdata->vals[v])));
6608 
6609  if( consdata->vals[v] < 0 )
6610  {
6611  newlb = SCIPfloor(scip, (rhs - minvalue) / consdata->vals[v]);
6612  newub = SCIPfloor(scip, (lhs - maxvalue) / consdata->vals[v]);
6613  }
6614  else
6615  {
6616  newlb = SCIPceil(scip, (lhs - maxvalue) / consdata->vals[v]);
6617  newub = SCIPceil(scip, (rhs - minvalue) / consdata->vals[v]);
6618  }
6619  assert(SCIPisLE(scip, newlb, newub));
6620 
6621  if( newlb > SCIPvarGetLbLocal(consdata->vars[v]) )
6622  {
6623  /* update lower bound of variable */
6624  SCIPdebugMsg(scip, "tightening lower bound of variable <%s> from %g to %g\n",
6625  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v]), newlb);
6626 
6627  /* tighten variable lower bound to minimal possible value */
6628  SCIP_CALL( SCIPinferVarLbCons(scip, consdata->vars[v], newlb, cons,
6629  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6630 
6631  if( *cutoff )
6632  {
6633  /* start conflict analysis */
6634  /* @todo improve conflict analysis by adding relaxed bounds */
6635  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, consdata->vars[v], newlb) );
6636  }
6637 
6638  if( tightened )
6639  ++(*nchgbds);
6640  }
6641 
6642  if( newub < SCIPvarGetUbLocal(consdata->vars[v]) )
6643  {
6644  /* update upper bound of variable */
6645  SCIPdebugMsg(scip, "tightening upper bound of variable <%s> from %g to %g\n",
6646  SCIPvarGetName(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v]), newub);
6647 
6648  /* tighten variable upper bound to maximal possible value */
6649  SCIP_CALL( SCIPinferVarUbCons(scip, consdata->vars[v], newub, cons,
6650  getInferInt(PROPRULE_1_RANGEDROW, v), TRUE, cutoff, &tightened) );
6651 
6652  if( *cutoff )
6653  {
6654  /* start conflict analysis */
6655  /* @todo improve conflict analysis by adding relaxed bounds */
6656  SCIP_CALL( analyzeConflictRangedRow(scip, cons, infcheckvars, ninfcheckvars, consdata->vars[v], newub) );
6657  }
6658 
6659  if( tightened )
6660  ++(*nchgbds);
6661  }
6662  }
6663  }
6664  /* at least two solutions and more than one variable, so we add a new constraint which bounds the feasible
6665  * region for our infcheckvars, if possible
6666  */
6667  else if( addartconss && (SCIPisGT(scip, minvalue, minactinfvars) || SCIPisLT(scip, maxvalue, maxactinfvars)) )
6668  {
6669  SCIP_CONS* newcons;
6670  char name[SCIP_MAXSTRLEN];
6671  SCIP_Real newlhs;
6672  SCIP_Real newrhs;
6673 
6674  assert(maxvalue > minvalue);
6675 
6676  if( SCIPisGT(scip, minvalue, minactinfvars) )
6677  newlhs = minvalue;
6678  else
6679  newlhs = -SCIPinfinity(scip);
6680 
6681  if( SCIPisLT(scip, maxvalue, maxactinfvars) )
6682  newrhs = maxvalue;
6683  else
6684  newrhs = SCIPinfinity(scip);
6685 
6686  if( !SCIPisInfinity(scip, -newlhs) || !SCIPisInfinity(scip, newrhs) )
6687  {
6688  /* create, add, and release new artificial constraint */
6689  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons1_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6690  ++conshdlrdata->naddconss;
6691 
6692  SCIPdebugMsg(scip, "adding artificial constraint %s\n", name);
6693 
6694  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals, newlhs, newrhs,
6695  TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6696  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6697 
6698  SCIPdebugPrintCons(scip, newcons, NULL);
6699  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6700 
6701  ++(*naddconss);
6702  }
6703  /* @todo maybe add constraint for all variables which are not infcheckvars, lhs should be minvalue, rhs
6704  * should be maxvalue */
6705  }
6706  }
6707  }
6708  }
6709  else if( addartconss && ncontvars < ninfcheckvars )
6710  {
6711  SCIP_Real maxact = 0.0;
6712  SCIP_Real minact = 0.0;
6713  int w = 0;
6714 
6715  /* compute activities of non-infcheckvars */
6716  for( v = 0; v < consdata->nvars; ++v )
6717  {
6718  if( w < ninfcheckvars && consdata->vars[v] == infcheckvars[w] )
6719  {
6720  ++w;
6721  continue;
6722  }
6723 
6724  if( !SCIPisEQ(scip, SCIPvarGetLbLocal(consdata->vars[v]), SCIPvarGetUbLocal(consdata->vars[v])) )
6725  {
6726  if( SCIPvarIsBinary(consdata->vars[v]) )
6727  {
6728  if( consdata->vals[v] > 0.0 )
6729  maxact += consdata->vals[v];
6730  else
6731  minact += consdata->vals[v];
6732  }
6733  else
6734  {
6735  SCIP_Real tmpval;
6736 
6737  assert(SCIPvarIsIntegral(consdata->vars[v]));
6738 
6739  if( consdata->vals[v] > 0.0 )
6740  {
6741  tmpval = consdata->vals[v] * SCIPvarGetLbLocal(consdata->vars[v]);
6742 
6743  if( SCIPisHugeValue(scip, -tmpval) )
6744  break;
6745 
6746  minact += tmpval;
6747 
6748  tmpval = consdata->vals[v] * SCIPvarGetUbLocal(consdata->vars[v]);
6749 
6750  if( SCIPisHugeValue(scip, tmpval) )
6751  break;
6752 
6753  maxact += tmpval;
6754  }
6755  else
6756  {
6757  tmpval = consdata->vals[v] * SCIPvarGetUbLocal(consdata->vars[v]);
6758 
6759  if( SCIPisHugeValue(scip, -tmpval) )
6760  break;
6761 
6762  minact += tmpval;
6763 
6764  tmpval = consdata->vals[v] * SCIPvarGetLbLocal(consdata->vars[v]);
6765 
6766  if( SCIPisHugeValue(scip, tmpval) )
6767  break;
6768 
6769  maxact += tmpval;
6770  }
6771  }
6772  }
6773  }
6774  if( v == consdata->nvars && !SCIPisHugeValue(scip, -minact) && !SCIPisHugeValue(scip, maxact) )
6775  {
6776  SCIP_CONS* newcons;
6777  char name[SCIP_MAXSTRLEN];
6778  SCIP_Real newlhs;
6779  SCIP_Real newrhs;
6780 
6781  assert(maxact > minact);
6782  assert(w == ninfcheckvars);
6783 
6784  newlhs = lhs - maxact;
6785  newrhs = rhs - minact;
6786  assert(newlhs < newrhs);
6787 
6788  /* create, add, and release new artificial constraint */
6789  (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_artcons2_%d", SCIPconsGetName(cons), conshdlrdata->naddconss);
6790  ++conshdlrdata->naddconss;
6791 
6792  SCIPdebugMsg(scip, "adding artificial constraint %s\n", name);
6793 
6794  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, ninfcheckvars, infcheckvars, infcheckvals, newlhs, newrhs,
6795  TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, FALSE, FALSE, TRUE, FALSE) );
6796  SCIP_CALL( SCIPaddConsLocal(scip, newcons, NULL) );
6797 
6798  SCIPdebugPrintCons(scip, newcons, NULL);
6799  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
6800 
6801  ++(*naddconss);
6802  }
6803  }
6804 
6805  TERMINATE:
6806  SCIPfreeBufferArray(scip, &infcheckvals);
6807  SCIPfreeBufferArray(scip, &infcheckvars);
6808 
6809  return SCIP_OKAY;
6810 }
6811 
6812 /** tightens bounds of a single variable due to activity bounds */
6813 static
6815  SCIP* scip, /**< SCIP data structure */
6816  SCIP_CONS* cons, /**< linear constraint */
6817  int pos, /**< position of the variable in the vars array */
6818  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
6819  int* nchgbds, /**< pointer to count the total number of tightened bounds */
6820  SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
6821  )
6822 {
6823  SCIP_CONSDATA* consdata;
6824  SCIP_VAR* var;
6825  SCIP_Real val;
6826  SCIP_Real lb;
6827  SCIP_Real ub;
6828  SCIP_Real minresactivity;
6829  SCIP_Real maxresactivity;
6830  SCIP_Real lhs;
6831  SCIP_Real rhs;
6832  SCIP_Bool infeasible;
6833  SCIP_Bool tightened;
6834  SCIP_Bool minisrelax;
6835  SCIP_Bool maxisrelax;
6836  SCIP_Bool isminsettoinfinity;
6837  SCIP_Bool ismaxsettoinfinity;
6838 
6839  assert(scip != NULL);
6840  assert(cons != NULL);
6841  assert(cutoff != NULL);
6842  assert(nchgbds != NULL);
6843 
6844  /* we cannot tighten variables' bounds, if the constraint may be not complete */
6845  if( SCIPconsIsModifiable(cons) )
6846  return SCIP_OKAY;
6847 
6848  consdata = SCIPconsGetData(cons);
6849  assert(consdata != NULL);
6850  assert(0 <= pos && pos < consdata->nvars);
6851 
6852  *cutoff = FALSE;
6853 
6854  var = consdata->vars[pos];
6855 
6856  /* we cannot tighten bounds of multi-aggregated variables */
6858  return SCIP_OKAY;
6859 
6860  val = consdata->vals[pos];
6861  lhs = consdata->lhs;
6862  rhs = consdata->rhs;
6863  consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
6864  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
6865  assert(var != NULL);
6866  assert(!SCIPisZero(scip, val));
6867  assert(!SCIPisInfinity(scip, lhs));
6868  assert(!SCIPisInfinity(scip, -rhs));
6869 
6870  lb = SCIPvarGetLbLocal(var);
6871  ub = SCIPvarGetUbLocal(var);
6872  assert(SCIPisLE(scip, lb, ub));
6873 
6874  if( val > 0.0 )
6875  {
6876  /* check, if we can tighten the variable's bounds */
6877  if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && !minisrelax )
6878  {
6879  SCIP_Real newub;
6880 
6881  newub = (rhs - minresactivity)/val;
6882 
6883  if( !SCIPisInfinity(scip, newub) &&
6884  ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
6885  {
6886  SCIP_Bool activityunreliable;
6887  activityunreliable = SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity);
6888 
6889  /* check minresactivities for reliability */
6890  if( activityunreliable )
6891  {
6892  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
6893  newub = (rhs - minresactivity)/val;
6894  activityunreliable = SCIPisInfinity(scip, -minresactivity) ||
6895  (!SCIPisUbBetter(scip, newub, lb, ub) && (!SCIPisFeasLT(scip, newub, ub) || !SCIPvarIsIntegral(var))
6896  && (!force || !SCIPisLT(scip, newub, ub)));
6897  }
6898 
6899  if( !activityunreliable )
6900  {
6901  /* tighten upper bound */
6902  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newub=%.15g\n",
6903  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newub);
6904  SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_RHS, pos), force,
6905  &infeasible, &tightened) );
6906  if( infeasible )
6907  {
6908  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
6909  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
6910 
6911  /* analyze conflict */
6912  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
6913 
6914  *cutoff = TRUE;
6915  return SCIP_OKAY;
6916  }
6917  if( tightened )
6918  {
6919  ub = SCIPvarGetUbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6920  assert(SCIPisFeasLE(scip, ub, newub));
6921  (*nchgbds)++;
6922 
6923  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6924  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6925  }
6926  }
6927  }
6928  }
6929 
6930  if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && !maxisrelax )
6931  {
6932  SCIP_Real newlb;
6933 
6934  newlb = (lhs - maxresactivity)/val;
6935  if( !SCIPisInfinity(scip, -newlb) &&
6936  ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
6937  {
6938  /* check maxresactivities for reliability */
6939  if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
6940  {
6941  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
6942  newlb = (lhs - maxresactivity)/val;
6943 
6944  if( SCIPisInfinity(scip, maxresactivity) || (!SCIPisLbBetter(scip, newlb, lb, ub)
6945  && (!SCIPisFeasGT(scip, newlb, lb) || !SCIPvarIsIntegral(var))
6946  && (!force || !SCIPisGT(scip, newlb, lb))) )
6947  return SCIP_OKAY;
6948  }
6949 
6950  /* tighten lower bound */
6951  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
6952  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newlb);
6953  SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_LHS, pos), force,
6954  &infeasible, &tightened) );
6955  if( infeasible )
6956  {
6957  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
6958  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
6959 
6960  /* analyze conflict */
6961  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
6962 
6963  *cutoff = TRUE;
6964  return SCIP_OKAY;
6965  }
6966  if( tightened )
6967  {
6968  lb = SCIPvarGetLbLocal(var); /* get bound again: it may be additionally modified due to integrality */
6969  assert(SCIPisFeasGE(scip, lb, newlb));
6970  (*nchgbds)++;
6971  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
6972  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
6973  }
6974  }
6975  }
6976  }
6977  else
6978  {
6979  /* check, if we can tighten the variable's bounds */
6980  if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && !minisrelax )
6981  {
6982  SCIP_Real newlb;
6983 
6984  newlb = (rhs - minresactivity)/val;
6985  if( !SCIPisInfinity(scip, -newlb) &&
6986  ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
6987  {
6988  SCIP_Bool activityunreliable;
6989  activityunreliable = SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity);
6990  /* check minresactivities for reliability */
6991  if( activityunreliable )
6992  {
6993  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
6994  newlb = (rhs - minresactivity)/val;
6995 
6996  activityunreliable = SCIPisInfinity(scip, -minresactivity)
6997  || (!SCIPisLbBetter(scip, newlb, lb, ub) && (!SCIPisFeasGT(scip, newlb, lb) || !SCIPvarIsIntegral(var))
6998  && (!force || !SCIPisGT(scip, newlb, lb)));
6999  }
7000 
7001  if( !activityunreliable )
7002  {
7003  /* tighten lower bound */
7004  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
7005  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newlb);
7006  SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_RHS, pos), force,
7007  &infeasible, &tightened) );
7008  if( infeasible )
7009  {
7010  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
7011  SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
7012 
7013  /* analyze conflict */
7014  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
7015 
7016  *cutoff = TRUE;
7017  return SCIP_OKAY;
7018  }
7019  if( tightened )
7020  {
7021  lb = SCIPvarGetLbLocal(var); /* get bound again: it may be additionally modified due to integrality */
7022  assert(SCIPisFeasGE(scip, lb, newlb));
7023  (*nchgbds)++;
7024  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
7025  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
7026  }
7027  }
7028  }
7029  }
7030 
7031  if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && !maxisrelax )
7032  {
7033  SCIP_Real newub;
7034 
7035  newub = (lhs - maxresactivity)/val;
7036  if( !SCIPisInfinity(scip, newub) &&
7037  ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
7038  {
7039  /* check maxresactivities for reliability */
7040  if( SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
7041  {
7042  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
7043  newub = (lhs - maxresactivity)/val;
7044 
7045  if( SCIPisInfinity(scip, maxresactivity) || (!SCIPisUbBetter(scip, newub, lb, ub)
7046  && (!SCIPisFeasLT(scip, newub, ub) && !SCIPvarIsIntegral(var))
7047  && (!force || !SCIPisLT(scip, newub, ub))) )
7048  return SCIP_OKAY;
7049  }
7050 
7051  /* tighten upper bound */
7052  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g], newub=%.15g\n",
7053  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, val, minresactivity, maxresactivity, lhs, rhs, newub);
7054  SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_LHS, pos), force,
7055  &infeasible, &tightened) );
7056  if( infeasible )
7057  {
7058  SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
7059  SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
7060 
7061  /* analyze conflict */
7062  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
7063 
7064  *cutoff = TRUE;
7065  return SCIP_OKAY;
7066  }
7067  if( tightened )
7068  {
7069  ub = SCIPvarGetUbLocal(var); /* get bound again: it may be additionally modified due to integrality */
7070  assert(SCIPisFeasLE(scip, ub, newub));
7071  (*nchgbds)++;
7072  SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
7073  SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
7074  }
7075  }
7076  }
7077  }
7078 
7079  return SCIP_OKAY;
7080 }
7081 
7082 #define MAXTIGHTENROUNDS 10
7083 
7084 /** tightens bounds of variables in constraint due to activity bounds */
7085 static
7087  SCIP* scip, /**< SCIP data structure */
7088  SCIP_CONS* cons, /**< linear constraint */
7089  SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
7090  SCIP_Bool sortvars, /**< should variables be used in sorted order? */
7091  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
7092  int* nchgbds /**< pointer to count the total number of tightened bounds */
7093  )
7094 {
7095  SCIP_CONSDATA* consdata;
7096  unsigned int tightenmode;
7097  int nvars;
7098  int nrounds;
7099  int lastchange;
7100  int oldnchgbds;
7101 #ifndef SCIP_DEBUG
7102  int oldnchgbdstotal;
7103 #endif
7104  int v;
7105  SCIP_Bool force;
7106  SCIP_Bool easycase;
7107 
7108  assert(scip != NULL);
7109  assert(cons != NULL);
7110  assert(nchgbds != NULL);
7111  assert(cutoff != NULL);
7112 
7113  *cutoff = FALSE;
7114 
7115  /* we cannot tighten variables' bounds, if the constraint may be not complete */
7116  if( SCIPconsIsModifiable(cons) )
7117  return SCIP_OKAY;
7118 
7119  /* if a constraint was created after presolve, then it may hold fixed variables
7120  * if there are even multi-aggregated variables, then we cannot do bound tightening on these
7121  * thus, ensure here again that variable fixings have been applied
7122  */
7123  SCIP_CALL( applyFixings(scip, cons, cutoff) );
7124  if( *cutoff )
7125  return SCIP_OKAY;
7126 
7127  /* check if constraint has any chances of tightening bounds */
7128  if( !canTightenBounds(cons) )
7129  return SCIP_OKAY;
7130 
7131  consdata = SCIPconsGetData(cons);
7132  assert(consdata != NULL);
7133 
7134  nvars = consdata->nvars;
7135  force = (nvars == 1) && !SCIPconsIsModifiable(cons);
7136 
7137  /* we are at the root node or during presolving */
7138  if( SCIPgetDepth(scip) < 1 )
7139  tightenmode = 2;
7140  else
7141  tightenmode = 1;
7142 
7143  /* stop if we already tightened the constraint and the tightening is not forced */
7144  if( !force && (consdata->boundstightened >= tightenmode) ) /*lint !e574*/
7145  return SCIP_OKAY;
7146 
7147  /* ensure that the variables are properly sorted */
7148  if( sortvars && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE && !consdata->coefsorted )
7149  {
7150  SCIP_CALL( consdataSort(scip, consdata) );
7151  assert(consdata->coefsorted);
7152  }
7153 
7154  /* update maximal activity delta if necessary */
7155  if( consdata->maxactdelta == SCIP_INVALID ) /*lint !e777*/
7156  consdataRecomputeMaxActivityDelta(scip, consdata);
7157 
7158  assert(consdata->maxactdelta != SCIP_INVALID); /*lint !e777*/
7159  assert(!SCIPisFeasNegative(scip, consdata->maxactdelta));
7160  checkMaxActivityDelta(scip, consdata);
7161 
7162  /* this may happen if all variables are fixed */
7163  if( SCIPisFeasZero(scip, consdata->maxactdelta) )
7164  return SCIP_OKAY;
7165 
7166  if( !SCIPisInfinity(scip, consdata->maxactdelta) )
7167  {
7168  SCIP_Real slack;
7169  SCIP_Real surplus;
7170  SCIP_Real minactivity;
7171  SCIP_Real maxactivity;
7172  SCIP_Bool minisrelax;
7173  SCIP_Bool maxisrelax;
7174  SCIP_Bool isminsettoinfinity;
7175  SCIP_Bool ismaxsettoinfinity;
7176 
7177  /* use maximal activity delta to skip propagation (cannot deduce anything) */
7178  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minisrelax, &maxisrelax,
7179  &isminsettoinfinity, &ismaxsettoinfinity);
7180  assert(!SCIPisInfinity(scip, minactivity));
7181  assert(!SCIPisInfinity(scip, -maxactivity));
7182 
7183  slack = (SCIPisInfinity(scip, consdata->rhs) || isminsettoinfinity) ? SCIPinfinity(scip) : (consdata->rhs - minactivity);
7184  surplus = (SCIPisInfinity(scip, -consdata->lhs) || ismaxsettoinfinity) ? SCIPinfinity(scip) : (maxactivity - consdata->lhs);
7185 
7186  /* check if the constraint will propagate */
7187  if( SCIPisLE(scip, consdata->maxactdelta, MIN(slack, surplus)) )
7188  return SCIP_OKAY;
7189  }
7190 
7191  /* check if we can use fast implementation for easy and numerically well behaved cases */
7192  easycase = SCIPisLT(scip, consdata->maxactdelta, maxeasyactivitydelta);
7193 
7194  /* as long as the bounds might be tightened again, try to tighten them; abort after a maximal number of rounds */
7195  lastchange = -1;
7196  oldnchgbds = 0;
7197 
7198 #ifndef SCIP_DEBUG
7199  oldnchgbdstotal = *nchgbds;
7200 #endif
7201 
7202  for( nrounds = 0; (force || consdata->boundstightened < tightenmode) && nrounds < MAXTIGHTENROUNDS; ++nrounds ) /*lint !e574*/
7203  {
7204  /* ensure that the variables are properly sorted
7205  *
7206  * note: it might happen that integer variables become binary during bound tightening at the root node
7207  */
7208  if( sortvars && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE && !consdata->coefsorted )
7209  {
7210  SCIP_CALL( consdataSort(scip, consdata) );
7211  assert(consdata->coefsorted);
7212  }
7213 
7214  /* mark the constraint to have the variables' bounds tightened */
7215  consdata->boundstightened = (unsigned int)tightenmode;
7216 
7217  /* try to tighten the bounds of each variable in the constraint. During solving process, the binary variable
7218  * sorting enables skipping variables
7219  */
7220  v = 0;
7221  while( v < nvars && v != lastchange && !(*cutoff) )
7222  {
7223  oldnchgbds = *nchgbds;
7224 
7225  if( easycase )
7226  {
7227  SCIP_CALL( tightenVarBoundsEasy(scip, cons, v, cutoff, nchgbds, force) );
7228  }
7229  else
7230  {
7231  SCIP_CALL( tightenVarBounds(scip, cons, v, cutoff, nchgbds, force) );
7232  }
7233 
7234  /* if there was no progress, skip the rest of the binary variables */
7235  if( *nchgbds > oldnchgbds )
7236  {
7237  lastchange = v;
7238  ++v;
7239  }
7240  else if( consdata->coefsorted && v < consdata->nbinvars - 1
7241  && !SCIPisFeasEQ(scip, SCIPvarGetUbLocal(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v])) )
7242  v = consdata->nbinvars;
7243  else
7244  ++v;
7245  }
7246 
7247 #ifndef SCIP_DEBUG
7248  SCIPdebugMessage("linear constraint <%s> found %d bound changes in round %d\n", SCIPconsGetName(cons),
7249  *nchgbds - oldnchgbdstotal, nrounds);
7250  oldnchgbdstotal += oldnchgbds;
7251 #endif
7252  }
7253 
7254 #ifndef NDEBUG
7255  if( force && SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
7256  assert(*cutoff || SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->vars[0]), SCIPvarGetUbLocal(consdata->vars[0])));
7257 #endif
7258 
7259  return SCIP_OKAY;
7260 }
7261 
7262 /** checks linear constraint for feasibility of given solution or current solution */
7263 static
7265  SCIP* scip, /**< SCIP data structure */
7266  SCIP_CONS* cons, /**< linear constraint */
7267  SCIP_SOL* sol, /**< solution to be checked, or NULL for current solution */
7268  SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
7269  SCIP_Bool checkrelmaxabs, /**< Should the violation for a constraint with side 0.0 be checked relative
7270  * to 1.0 (FALSE) or to the maximum absolute value in the activity (TRUE)? */
7271  SCIP_Bool* violated /**< pointer to store whether the constraint is violated */
7272  )
7273 {
7274  SCIP_CONSDATA* consdata;
7275  SCIP_Real activity;
7276  SCIP_Real absviol;
7277  SCIP_Real relviol;
7278  SCIP_Real lhsviol;
7279  SCIP_Real rhsviol;
7280 
7281  assert(scip != NULL);
7282  assert(cons != NULL);
7283  assert(violated != NULL);
7284 
7285  SCIPdebugMsg(scip, "checking linear constraint <%s>\n", SCIPconsGetName(cons));
7286  SCIPdebugPrintCons(scip, cons, NULL);
7287 
7288  consdata = SCIPconsGetData(cons);
7289  assert(consdata != NULL);
7290 
7291  *violated = FALSE;
7292 
7293  if( consdata->row != NULL )
7294  {
7295  if( !checklprows && SCIProwIsInLP(consdata->row) )
7296  return SCIP_OKAY;
7297  else if( sol == NULL && !SCIPhasCurrentNodeLP(scip) )
7298  activity = consdataComputePseudoActivity(scip, consdata);
7299  else
7300  activity = SCIPgetRowSolActivity(scip, consdata->row, sol);
7301  }
7302  else
7303  activity = consdataGetActivity(scip, consdata, sol);
7304 
7305  SCIPdebugMsg(scip, " consdata activity=%.15g (lhs=%.15g, rhs=%.15g, row=%p, checklprows=%u, rowinlp=%u, sol=%p, hascurrentnodelp=%u)\n",
7306  activity, consdata->lhs, consdata->rhs, (void*)consdata->row, checklprows,
7307  consdata->row == NULL ? 0 : SCIProwIsInLP(consdata->row), (void*)sol,
7308  consdata->row == NULL ? FALSE : SCIPhasCurrentNodeLP(scip));
7309 
7310  /* calculate absolute and relative bound violations */
7311  lhsviol = consdata->lhs - activity;
7312  rhsviol = activity - consdata->rhs;
7313 
7314  absviol = 0.0;
7315  relviol = 0.0;
7316  if( (lhsviol > 0) && (lhsviol > rhsviol) )
7317  {
7318  absviol = lhsviol;
7319  relviol = SCIPrelDiff(consdata->lhs, activity);
7320  }
7321  else if( rhsviol > 0 )
7322  {
7323  absviol = rhsviol;
7324  relviol = SCIPrelDiff(activity, consdata->rhs);
7325  }
7326 
7327  /* the activity of pseudo solutions may be invalid if it comprises positive and negative infinity contributions; we
7328  * return infeasible for safety
7329  */
7330  if( activity == SCIP_INVALID ) /*lint !e777*/
7331  {
7332  assert(sol == NULL);
7333  *violated = TRUE;
7334 
7335  /* set violation of invalid pseudo solutions */
7336  absviol = SCIP_INVALID;
7337  relviol = SCIP_INVALID;
7338 
7339  /* reset constraint age since we are in enforcement */
7340  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7341  }
7342  /* check with relative tolerances (the default) */
7343  else if( !consdata->checkabsolute && (SCIPisFeasLT(scip, activity, consdata->lhs) || SCIPisFeasGT(scip, activity, consdata->rhs)) )
7344  {
7345  /* the "normal" check: one of the two sides is violated */
7346  if( !checkrelmaxabs )
7347  {
7348  *violated = TRUE;
7349 
7350  /* only reset constraint age if we are in enforcement */
7351  if( sol == NULL )
7352  {
7353  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7354  }
7355  }
7356  /* the (much) more complicated check: we try to disregard random noise and violations of a 0.0 side which are
7357  * small compared to the absolute values occurring in the activity
7358  */
7359  else
7360  {
7361  SCIP_Real maxabs;
7362  SCIP_Real coef;
7363  SCIP_Real absval;
7364  SCIP_Real solval;
7365  int v;
7366 
7367  maxabs = 1.0;
7368 
7369  /* compute maximum absolute value */
7370  for( v = 0; v < consdata->nvars; ++v )
7371  {
7372  if( consdata->vals != NULL )
7373  {
7374  coef = consdata->vals[v];
7375  }
7376  else
7377  coef = 1.0;
7378 
7379  solval = SCIPgetSolVal(scip, sol, consdata->vars[v]);
7380  absval = REALABS( coef * solval );
7381  maxabs = MAX( maxabs, absval );
7382  }
7383 
7384  /* regard left hand side, first */
7385  if( SCIPisFeasLT(scip, activity, consdata->lhs) )
7386  {
7387  /* check whether violation is random noise */
7388  if( (consdata->lhs - activity) <= (1e-15 * maxabs) )
7389  {
7390  SCIPdebugMsg(scip, " lhs violated due to random noise: violation=%16.9g, maxabs=%16.9g\n",
7391  consdata->lhs - activity, maxabs);
7392  SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
7393 
7394  /* only increase constraint age if we are in enforcement */
7395  if( sol == NULL )
7396  {
7397  SCIP_CALL( SCIPincConsAge(scip, cons) );
7398  }
7399  }
7400  /* lhs is violated and lhs is 0.0: use relative tolerance w.r.t. largest absolute value */
7401  else if( SCIPisZero(scip, consdata->lhs) )
7402  {
7403  if( (consdata->lhs - activity) <= (SCIPfeastol(scip) * maxabs) )
7404  {
7405  SCIPdebugMsg(scip, " lhs violated absolutely (violation=%16.9g), but feasible when using relative tolerance w.r.t. maximum absolute value (%16.9g)\n",
7406  consdata->lhs - activity, maxabs);
7407  SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
7408 
7409  /* only increase constraint age if we are in enforcement */
7410  if( sol == NULL )
7411  {
7412  SCIP_CALL( SCIPincConsAge(scip, cons) );
7413  }
7414  }
7415  else
7416  {
7417  *violated = TRUE;
7418 
7419  /* only reset constraint age if we are in enforcement */
7420  if( sol == NULL )
7421  {
7422  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7423  }
7424  }
7425  }
7426  else
7427  {
7428  *violated = TRUE;
7429 
7430  /* only reset constraint age if we are in enforcement */
7431  if( sol == NULL )
7432  {
7433  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7434  }
7435  }
7436  }
7437 
7438  /* now regard right hand side */
7439  if( SCIPisFeasGT(scip, activity, consdata->rhs) )
7440  {
7441  /* check whether violation is random noise */
7442  if( (activity - consdata->rhs) <= (1e-15 * maxabs) )
7443  {
7444  SCIPdebugMsg(scip, " rhs violated due to random noise: violation=%16.9g, maxabs=%16.9g\n",
7445  activity - consdata->rhs, maxabs);
7446  SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
7447 
7448  /* only increase constraint age if we are in enforcement */
7449  if( sol == NULL )
7450  {
7451  SCIP_CALL( SCIPincConsAge(scip, cons) );
7452  }
7453  }
7454  /* rhs is violated and rhs is 0.0, use relative tolerance w.r.t. largest absolute value */
7455  else if( SCIPisZero(scip, consdata->rhs) )
7456  {
7457  if( (activity - consdata->rhs) <= (SCIPfeastol(scip) * maxabs) )
7458  {
7459  SCIPdebugMsg(scip, " rhs violated absolutely (violation=%16.9g), but feasible when using relative tolerance w.r.t. maximum absolute value (%16.9g)\n",
7460  activity - consdata->rhs, maxabs);
7461  SCIPdebug( SCIP_CALL( consPrintConsSol(scip, cons, sol, NULL) ) );
7462 
7463  /* only increase constraint age if we are in enforcement */
7464  if( sol == NULL )
7465  {
7466  SCIP_CALL( SCIPincConsAge(scip, cons) );
7467  }
7468  }
7469  else
7470  {
7471  *violated = TRUE;
7472 
7473  /* only reset constraint age if we are in enforcement */
7474  if( sol == NULL )
7475  {
7476  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7477  }
7478  }
7479  }
7480  else
7481  {
7482  *violated = TRUE;
7483 
7484  /* only reset constraint age if we are in enforcement */
7485  if( sol == NULL )
7486  {
7487  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7488  }
7489  }
7490  }
7491  }
7492  }
7493  /* check with absolute tolerances */
7494  else if( consdata->checkabsolute &&
7495  ((!SCIPisInfinity(scip, -consdata->lhs) && SCIPisGT(scip, consdata->lhs-activity, SCIPfeastol(scip))) ||
7496  (!SCIPisInfinity(scip, consdata->rhs) && SCIPisGT(scip, activity-consdata->rhs, SCIPfeastol(scip)))) )
7497  {
7498  *violated = TRUE;
7499 
7500  /* only reset constraint age if we are in enforcement */
7501  if( sol == NULL )
7502  {
7503  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7504  }
7505  }
7506  else
7507  {
7508  /* only increase constraint age if we are in enforcement */
7509  if( sol == NULL )
7510  {
7511  SCIP_CALL( SCIPincConsAge(scip, cons) );
7512  }
7513  }
7514 
7515  /* update absolute and relative violation of the solution */
7516  if( sol != NULL )
7517  SCIPupdateSolLPConsViolation(scip, sol, absviol, relviol);
7518 
7519  return SCIP_OKAY;
7520 }
7521 
7522 /** creates an LP row in a linear constraint data */
7523 static
7525  SCIP* scip, /**< SCIP data structure */
7526  SCIP_CONS* cons /**< linear constraint */
7527  )
7528 {
7529  SCIP_CONSDATA* consdata;
7530 
7531  assert(scip != NULL);
7532  assert(cons != NULL);
7533 
7534  consdata = SCIPconsGetData(cons);
7535  assert(consdata != NULL);
7536  assert(consdata->row == NULL);
7537 
7538  SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row, cons, SCIPconsGetName(cons), consdata->lhs, consdata->rhs,
7540 
7541  SCIP_CALL( SCIPaddVarsToRow(scip, consdata->row, consdata->nvars, consdata->vars, consdata->vals) );
7542 
7543  return SCIP_OKAY;
7544 }
7545 
7546 /** adds linear constraint as cut to the LP */
7547 static
7549  SCIP* scip, /**< SCIP data structure */
7550  SCIP_CONS* cons, /**< linear constraint */
7551  SCIP_Bool* cutoff /**< pointer to store whether a cutoff was found */
7552  )
7553 {
7554  SCIP_CONSDATA* consdata;
7555 
7556  assert(scip != NULL);
7557  assert(cons != NULL);
7558 
7559  consdata = SCIPconsGetData(cons);
7560  assert(consdata != NULL);
7561 
7562  if( consdata->row == NULL )
7563  {
7564  if( !SCIPconsIsModifiable(cons) )
7565  {
7566  /* 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
7567  * removing this here will make test cons/linear/fixedvar.c fail (as of 2018-12-03)
7568  */
7569  SCIP_CALL( applyFixings(scip, cons, cutoff) );
7570  if( *cutoff )
7571  return SCIP_OKAY;
7572  }
7573 
7574  /* convert consdata object into LP row */
7575  SCIP_CALL( createRow(scip, cons) );
7576  }
7577  assert(consdata->row != NULL);
7578 
7579  if( consdata->nvars == 0 )
7580  {
7581  SCIPdebugMsg(scip, "Empty linear constraint enters LP: <%s>\n", SCIPconsGetName(cons));
7582  }
7583 
7584  /* insert LP row as cut */
7585  if( !SCIProwIsInLP(consdata->row) )
7586  {
7587  SCIPdebugMsg(scip, "adding relaxation of linear constraint <%s>: ", SCIPconsGetName(cons));
7588  SCIPdebug( SCIP_CALL( SCIPprintRow(scip, consdata->row, NULL)) );
7589  /* if presolving is turned off, the row might be trivial */
7590  if ( ! SCIPisInfinity(scip, -consdata->lhs) || ! SCIPisInfinity(scip, consdata->rhs) )
7591  {
7592  SCIP_CALL( SCIPaddRow(scip, consdata->row, FALSE, cutoff) );
7593  }
7594 #ifndef NDEBUG
7595  else
7596  {
7597  int pr;
7598  int cr;
7599  SCIP_CALL( SCIPgetIntParam(scip, "presolving/maxrounds", &pr) );
7600  SCIP_CALL( SCIPgetIntParam(scip, "constraints/linear/maxprerounds", &cr) );
7601  assert( pr == 0 || cr == 0 );
7602  }
7603 #endif
7604  }
7605 
7606  return SCIP_OKAY;
7607 }
7608 
7609 /** adds linear constraint as row to the NLP, if not added yet */
7610 static
7612  SCIP* scip, /**< SCIP data structure */
7613  SCIP_CONS* cons /**< linear constraint */
7614  )
7615 {
7616  SCIP_CONSDATA* consdata;
7617 
7618  assert(SCIPisNLPConstructed(scip));
7619 
7620  /* skip deactivated, redundant, or local linear constraints (the NLP does not allow for local rows at the moment) */
7621  if( !SCIPconsIsActive(cons) || !SCIPconsIsChecked(cons) || SCIPconsIsLocal(cons) )
7622  return SCIP_OKAY;
7623 
7624  consdata = SCIPconsGetData(cons);
7625  assert(consdata != NULL);
7626 
7627  if( consdata->nlrow == NULL )
7628  {
7629  assert(consdata->lhs <= consdata->rhs);
7631  SCIP_CALL( SCIPcreateNlRow(scip, &consdata->nlrow, SCIPconsGetName(cons),
7632  0.0, consdata->nvars, consdata->vars, consdata->vals, NULL, consdata->lhs, consdata->rhs, SCIP_EXPRCURV_LINEAR) );
7633 
7634  assert(consdata->nlrow != NULL);
7635  }
7636 
7637  if( !SCIPnlrowIsInNLP(consdata->nlrow) )
7638  {
7639  SCIP_CALL( SCIPaddNlRow(scip, consdata->nlrow) );
7640  }
7641 
7642  return SCIP_OKAY;
7643 }
7644 
7645 /** separates linear constraint: adds linear constraint as cut, if violated by given solution */
7646 static
7648  SCIP* scip, /**< SCIP data structure */
7649  SCIP_CONS* cons, /**< linear constraint */
7650  SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
7651  SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
7652  SCIP_Bool separatecards, /**< should knapsack cardinality cuts be generated? */
7653  SCIP_Bool separateall, /**< should all constraints be subject to cardinality cut generation instead of only
7654  * the ones with non-zero dual value? */
7655  int* ncuts, /**< pointer to add up the number of found cuts */
7656  SCIP_Bool* cutoff /**< pointer to store whether a cutoff was found */
7657  )
7658 {
7659  SCIP_CONSDATA* consdata;
7660  SCIP_Bool violated;
7661  int oldncuts;
7662 
7663  assert(scip != NULL);
7664  assert(conshdlrdata != NULL);
7665  assert(cons != NULL);
7666  assert(cutoff != NULL);
7667 
7668  consdata = SCIPconsGetData(cons);
7669  assert(ncuts != NULL);
7670  assert(consdata != NULL);
7671 
7672  oldncuts = *ncuts;
7673  *cutoff = FALSE;
7674 
7675  SCIP_CALL( checkCons(scip, cons, sol, (sol != NULL), conshdlrdata->checkrelmaxabs, &violated) );
7676 
7677  if( violated )
7678  {
7679  /* insert LP row as cut */
7680  SCIP_CALL( addRelaxation(scip, cons, cutoff) );
7681  (*ncuts)++;
7682  }
7683  else if( !SCIPconsIsModifiable(cons) && separatecards )
7684  {
7685  /* relax linear constraint into knapsack constraint and separate lifted cardinality cuts */
7686  if( !separateall && sol == NULL )
7687  {
7688  /* we only want to call the knapsack cardinality cut separator for rows that have a non-zero dual solution */
7689  if( consdata->row != NULL && SCIProwIsInLP(consdata->row) )
7690  {
7691  SCIP_Real dualsol;
7692 
7693  dualsol = SCIProwGetDualsol(consdata->row);
7694  if( SCIPisFeasNegative(scip, dualsol) )
7695  {
7696  if( !SCIPisInfinity(scip, consdata->rhs) )
7697  {
7698  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7699  consdata->vals, +1.0, consdata->rhs, sol, cutoff, ncuts) );
7700  }
7701  }
7702  else if( SCIPisFeasPositive(scip, dualsol) )
7703  {
7704  if( !SCIPisInfinity(scip, -consdata->lhs) )
7705  {
7706  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7707  consdata->vals, -1.0, -consdata->lhs, sol, cutoff, ncuts) );
7708  }
7709  }
7710  }
7711  }
7712  else
7713  {
7714  if( !SCIPisInfinity(scip, consdata->rhs) )
7715  {
7716  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7717  consdata->vals, +1.0, consdata->rhs, sol, cutoff, ncuts) );
7718  }
7719  if( !SCIPisInfinity(scip, -consdata->lhs) )
7720  {
7721  SCIP_CALL( SCIPseparateRelaxedKnapsack(scip, cons, NULL, consdata->nvars, consdata->vars,
7722  consdata->vals, -1.0, -consdata->lhs, sol, cutoff, ncuts) );
7723  }
7724  }
7725  }
7726 
7727  if( *ncuts > oldncuts )
7728  {
7729  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7730  }
7731 
7732  return SCIP_OKAY;
7733 }
7734 
7735 /** propagation method for linear constraints */
7736 static
7738  SCIP* scip, /**< SCIP data structure */
7739  SCIP_CONS* cons, /**< linear constraint */
7740  SCIP_Bool tightenbounds, /**< should the variable's bounds be tightened? */
7741  SCIP_Bool rangedrowpropagation,/**< should ranged row propagation be performed? */
7742  SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
7743  SCIP_Bool sortvars, /**< should variable sorting for faster propagation be used? */
7744  SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
7745  int* nchgbds /**< pointer to count the total number of tightened bounds */
7746  )
7747 {
7748  SCIP_CONSDATA* consdata;
7749  SCIP_Real minactivity;
7750  SCIP_Real maxactivity;
7751  SCIP_Bool minactisrelax;
7752  SCIP_Bool maxactisrelax;
7753  SCIP_Bool isminsettoinfinity;
7754  SCIP_Bool ismaxsettoinfinity;
7755 
7756  assert(scip != NULL);
7757  assert(cons != NULL);
7758  assert(cutoff != NULL);
7759  assert(nchgbds != NULL);
7760 
7761  /*SCIPdebugMsg(scip, "propagating linear constraint <%s>\n", SCIPconsGetName(cons));*/
7762 
7763  consdata = SCIPconsGetData(cons);
7764  assert(consdata != NULL);
7765 
7766  if( consdata->eventdata == NULL )
7767  {
7768  SCIP_CONSHDLR* conshdlr;
7769  SCIP_CONSHDLRDATA* conshdlrdata;
7770 
7771  conshdlr = SCIPconsGetHdlr(cons);
7772  assert(conshdlr != NULL);
7773 
7774  conshdlrdata = SCIPconshdlrGetData(conshdlr);
7775  assert(conshdlrdata != NULL);
7776 
7777  /* catch bound change events of variables */
7778  SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
7779  assert(consdata->eventdata != NULL);
7780  }
7781 
7782  *cutoff = FALSE;
7783 
7784  /* we can only infer activity bounds of the linear constraint, if it is not modifiable */
7785  if( !SCIPconsIsModifiable(cons) )
7786  {
7787  /* increase age of constraint; age is reset to zero, if a conflict or a propagation was found */
7788  if( !SCIPinRepropagation(scip) )
7789  {
7790  SCIP_CALL( SCIPincConsAge(scip, cons) );
7791  }
7792 
7793  /* tighten the variable's bounds */
7794  if( tightenbounds )
7795  {
7796  int oldnchgbds;
7797 
7798  oldnchgbds = *nchgbds;
7799 
7800  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
7801 
7802  if( *nchgbds > oldnchgbds )
7803  {
7804  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7805  }
7806  }
7807 
7808  /* propagate ranged rows */
7809  if( rangedrowpropagation && tightenbounds && !(*cutoff) )
7810  {
7811  int nfixedvars;
7812  int naddconss;
7813  SCIPdebug( int oldnchgbds = *nchgbds; )
7814 
7815  nfixedvars = 0;
7816  naddconss = 0;
7817 
7818  SCIP_CALL( rangedRowPropagation(scip, cons, cutoff, &nfixedvars, nchgbds, &naddconss) );
7819 
7820  if( *cutoff )
7821  {
7822  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible\n", SCIPconsGetName(cons));
7823  }
7824  else
7825  {
7826  SCIPdebug( SCIPdebugMsg(scip, "linear constraint <%s> found %d bound changes and %d fixings\n", SCIPconsGetName(cons), *nchgbds - oldnchgbds, nfixedvars); )
7827  }
7828 
7829  if( nfixedvars > 0 )
7830  *nchgbds += 2*nfixedvars;
7831  } /*lint !e438*/
7832 
7833  /* check constraint for infeasibility and redundancy */
7834  if( !(*cutoff) )
7835  {
7836  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
7837  &isminsettoinfinity, &ismaxsettoinfinity);
7838 
7839  if( SCIPisFeasGT(scip, minactivity, consdata->rhs) )
7840  {
7841  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible (rhs): activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7842  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7843 
7844  /* analyze conflict */
7845  SCIP_CALL( analyzeConflict(scip, cons, TRUE) );
7846 
7847  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7848  *cutoff = TRUE;
7849  }
7850  else if( SCIPisFeasLT(scip, maxactivity, consdata->lhs) )
7851  {
7852  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible (lhs): activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7853  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7854 
7855  /* analyze conflict */
7856  SCIP_CALL( analyzeConflict(scip, cons, FALSE) );
7857 
7858  SCIP_CALL( SCIPresetConsAge(scip, cons) );
7859  *cutoff = TRUE;
7860  }
7861  else if( SCIPisGE(scip, minactivity, consdata->lhs) && SCIPisLE(scip, maxactivity, consdata->rhs) )
7862  {
7863  SCIPdebugMsg(scip, "linear constraint <%s> is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
7864  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
7865 
7866  /* remove the constraint locally unless it has become empty, in which case it is removed globally */
7867  if( consdata->nvars > 0 )
7868  SCIP_CALL( SCIPdelConsLocal(scip, cons) );
7869  else
7870  SCIP_CALL( SCIPdelCons(scip, cons) );
7871  }
7872  }
7873  }
7874 
7875  return SCIP_OKAY;
7876 }
7877 
7878 
7879 /*
7880  * Presolving methods
7881  */
7882 
7883 /** converts all variables with fixed domain into FIXED variables */
7884 static
7886  SCIP* scip, /**< SCIP data structure */
7887  SCIP_CONS* cons, /**< linear constraint */
7888  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
7889  int* nfixedvars /**< pointer to count the total number of fixed variables */
7890  )
7891 {
7892  SCIP_CONSDATA* consdata;
7893  SCIP_VAR* var;
7894  SCIP_VARSTATUS varstatus;
7895  SCIP_Real lb;
7896  SCIP_Real ub;
7897  SCIP_Bool fixed;
7898  SCIP_Bool infeasible;
7899  int v;
7900 
7901  assert(scip != NULL);
7902  assert(cons != NULL);
7903  assert(cutoff != NULL);
7904  assert(nfixedvars != NULL);
7905 
7906  consdata = SCIPconsGetData(cons);
7907  assert(consdata != NULL);
7908 
7909  for( v = 0; v < consdata->nvars; ++v )
7910  {
7911  assert(consdata->vars != NULL);
7912  var = consdata->vars[v];
7913  varstatus = SCIPvarGetStatus(var);
7914 
7915  if( varstatus != SCIP_VARSTATUS_FIXED )
7916  {
7917  lb = SCIPvarGetLbGlobal(var);
7918  ub = SCIPvarGetUbGlobal(var);
7919  if( SCIPisEQ(scip, lb, ub) )
7920  {
7921  SCIP_Real fixval;
7922 
7923  fixval = SCIPselectSimpleValue(lb, ub, MAXDNOM);
7924  SCIPdebugMsg(scip, "converting variable <%s> with fixed bounds [%.15g,%.15g] into fixed variable fixed at %.15g\n",
7925  SCIPvarGetName(var), lb, ub, fixval);
7926  SCIP_CALL( SCIPfixVar(scip, var, fixval, &infeasible, &fixed) );
7927  if( infeasible )
7928  {
7929  SCIPdebugMsg(scip, " -> infeasible fixing\n");
7930  *cutoff = TRUE;
7931  return SCIP_OKAY;
7932  }
7933  if( fixed )
7934  (*nfixedvars)++;
7935  }
7936  }
7937  }
7938 
7939  SCIP_CALL( applyFixings(scip, cons, &infeasible) );
7940 
7941  if( infeasible )
7942  {
7943  SCIPdebugMsg(scip, " -> infeasible fixing\n");
7944  *cutoff = TRUE;
7945  return SCIP_OKAY;
7946  }
7947 
7948  assert(consdata->removedfixings);
7949 
7950  return SCIP_OKAY;
7951 }
7952 
7953 #define MAX_CLIQUE_NONZEROS_PER_CONS 1000000
7954 
7955 /** extracts cliques of the constraint and adds them to SCIP
7956  *
7957  * The following clique extraction mechanism are implemeneted
7958  *
7959  * 1. collect binary variables and sort them in non increasing order, then
7960  *
7961  * a) if the constraint has a finite right hand side and the negative infinity counters for the minactivity are zero
7962  * then add the variables as a clique for which all successive pairs of coefficients fullfill the following
7963  * condition
7964  *
7965  * minactivity + vals[i] + vals[i+1] > rhs
7966  *
7967  * and also add the binary to binary implication also for non-successive variables for which the same argument
7968  * holds
7969  *
7970  * minactivity + vals[i] + vals[j] > rhs
7971  *
7972  * 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
7973  * binary to binary implications x1 = 1 => x4 = 0 and x2 = 1 => x4 = 0
7974  *
7975  * b) if the constraint has a finite left hand side and the positive infinity counters for the maxactivity are zero
7976  * then add the variables as a clique for which all successive pairs of coefficients fullfill the follwoing
7977  * condition
7978  *
7979  * maxactivity + vals[i] + vals[i-1] < lhs
7980  *
7981  * and also add the binary to binary implication also for non-successive variables for which the same argument
7982  * holds
7983  *
7984  * maxactivity + vals[i] + vals[j] < lhs
7985  *
7986  * e.g. you could multiply the above example by -1
7987  *
7988  * c) the constraint has a finite right hand side and a finite minactivity then add the variables as a negated
7989  * clique(clique on the negated variables) for which all successive pairs of coefficients fullfill the following
7990  * condition
7991  *
7992  * minactivity - vals[i] - vals[i-1] > rhs
7993  *
7994  * and also add the binary to binary implication also for non-successive variables for which the
7995  * same argument holds
7996  *
7997  * minactivity - vals[i] - vals[j] > rhs
7998  *
7999  * e.g. -4 x1 -3 x2 - 2 x3 + 2 x4 <= -4 would lead to the (negated) clique (~x1, ~x2) and the binary to binary
8000  * implication x1 = 0 => x3 = 1
8001  *
8002  * d) the constraint has a finite left hand side and a finite maxactivity then add the variables as a negated
8003  * clique(clique on the negated variables) for which all successive pairs of coefficients fullfill the following
8004  * condition
8005  *
8006  * maxactivity - vals[i] - vals[i+1] < lhs
8007  *
8008  * and also add the binary to binary implication also for non-successive variables for which the same argument
8009  * holds
8010  *
8011  * maxactivity - vals[i] - vals[j] < lhs
8012  *
8013  * e.g. you could multiply the above example by -1
8014  *
8015  * 2. if the linear constraint represents a set-packing or set-partitioning constraint, the whole constraint is added
8016  * as clique, (this part is done at the end of the method)
8017  *
8018  */
8019 static
8021  SCIP* scip, /**< SCIP data structure */
8022  SCIP_CONS* cons, /**< linear constraint */
8023  SCIP_Real maxeasyactivitydelta,/**< maximum activity delta to run easy propagation on linear constraint */
8024  SCIP_Bool sortvars, /**< should variables be used in sorted order? */
8025  int* nfixedvars, /**< pointer to count number of fixed variables */
8026  int* nchgbds, /**< pointer to count the total number of tightened bounds */
8027  SCIP_Bool* cutoff /**< pointer to store TRUE, if a cutoff was found */
8028  )
8029 {
8030  SCIP_VAR** vars;
8031  SCIP_Real* vals;
8032  SCIP_CONSDATA* consdata;
8033  SCIP_Bool lhsclique;
8034  SCIP_Bool rhsclique;
8035  SCIP_Bool finitelhs;
8036  SCIP_Bool finiterhs;
8037  SCIP_Bool finiteminact;
8038  SCIP_Bool finitemaxact;
8039  SCIP_Bool finitenegminact;
8040  SCIP_Bool finitenegmaxact;
8041  SCIP_Bool finiteposminact;
8042  SCIP_Bool finiteposmaxact;
8043  SCIP_Bool infeasible;
8044  SCIP_Bool stopped;
8045  int cliquenonzerosadded;
8046  int v;
8047  int i;
8048  int nposcoefs;
8049  int nnegcoefs;
8050  int nvars;
8051 
8052  assert(scip != NULL);
8053  assert(cons != NULL);
8054  assert(nfixedvars != NULL);
8055  assert(nchgbds != NULL);
8056  assert(cutoff != NULL);
8057  assert(!SCIPconsIsDeleted(cons));
8058 
8059  consdata = SCIPconsGetData(cons);
8060  assert(consdata != NULL);
8061 
8062  if( consdata->nvars < 2 )
8063  return SCIP_OKAY;
8064 
8065  /* add implications if posibble
8066  *
8067  * for now we only add binary to non-binary implications, and this is only done for the binary variable with the
8068  * maximal absolute contribution and also only if this variable would force all other variables to their bound
8069  * corresponding to the global minimal activity of the constraint
8070  */
8071  if( !consdata->implsadded )
8072  {
8073  /* sort variables by variable type */
8074  SCIP_CALL( consdataSort(scip, consdata) );
8075 
8076  /* @todo we might extract implications/cliques if SCIPvarIsBinary() variables exist and we have integer variables
8077  * up front, might change sorting correspondingly
8078  */
8079  /* fast abort if no binaries exist */
8080  if( !SCIPvarIsBinary(consdata->vars[0]) )
8081  {
8082 #ifndef NDEBUG
8083  for( i = 1; i < consdata->nvars; i++ )
8084  assert(!SCIPvarIsBinary(consdata->vars[i]));
8085 #endif
8086  return SCIP_OKAY;
8087  }
8088  nvars = consdata->nvars;
8089  vars = consdata->vars;
8090  vals = consdata->vals;
8091 
8092  /* recompute activities if needed */
8093  if( !consdata->validactivities )
8094  consdataCalcActivities(scip, consdata);
8095  assert(consdata->validactivities);
8096 
8097  finitelhs = !SCIPisInfinity(scip, -consdata->lhs);
8098  finiterhs = !SCIPisInfinity(scip, consdata->rhs);
8099  finitenegminact = (consdata->glbminactivityneginf == 0 && consdata->glbminactivityneghuge == 0);
8100  finitenegmaxact = (consdata->glbmaxactivityneginf == 0 && consdata->maxactivityneghuge == 0);
8101  finiteposminact = (consdata->glbminactivityposinf == 0 && consdata->glbminactivityposhuge == 0);
8102  finiteposmaxact = (consdata->glbmaxactivityposinf == 0 && consdata->glbmaxactivityposhuge == 0);
8103  finiteminact = (finitenegminact && finiteposminact);
8104  finitemaxact = (finitenegmaxact && finiteposmaxact);
8105 
8106  if( (finiterhs || finitelhs) && (finitenegminact || finiteposminact || finitenegmaxact || finiteposmaxact) )
8107  {
8108  SCIP_Real maxabscontrib = -1.0;
8109  SCIP_Bool posval = FALSE;
8110  SCIP_Bool allbinary = TRUE;
8111  int oldnchgbds = *nchgbds;
8112  int nbdchgs = 0;
8113  int nimpls = 0;
8114  int position = -1;
8115 
8116  /* we need a valid minimal/maximal activity to add cliques */
8117  if( (finitenegminact || finiteposminact) && !consdata->validglbminact )
8118  {
8119  consdataRecomputeGlbMinactivity(scip, consdata);
8120  assert(consdata->validglbminact);
8121  }
8122 
8123  if( (finitenegmaxact || finiteposmaxact) && !consdata->validglbmaxact )
8124  {
8125  consdataRecomputeGlbMaxactivity(scip, consdata);
8126  assert(consdata->validglbmaxact);
8127  }
8128  assert(consdata->validglbminact || consdata->validglbmaxact);
8129 
8130  /* @todo extend this to local/constraint probing */
8131 
8132  /* determine maximal contribution to the activity */
8133  for( v = nvars - 1; v >= 0; --v )
8134  {
8135  if( SCIPvarIsBinary(vars[v]) )
8136  {
8137  if( vals[v] > 0 )
8138  {
8139  SCIP_Real value = vals[v] * SCIPvarGetUbGlobal(vars[v]);
8140 
8141  if( value > maxabscontrib )
8142  {
8143  maxabscontrib = value;
8144  position = v;
8145  posval = TRUE;
8146  }
8147  }
8148  else
8149  {
8150  SCIP_Real value = vals[v] * SCIPvarGetLbGlobal(vars[v]);
8151 
8152  value = REALABS(value);
8153 
8154  if( value > maxabscontrib )
8155  {
8156  maxabscontrib = value;
8157  position = v;
8158  posval = FALSE;
8159  }
8160  }
8161  }
8162  else
8163  allbinary = FALSE;
8164  }
8165  assert(0 <= position && position < nvars);
8166 
8167  if( !SCIPisEQ(scip, maxabscontrib, 1.0) && !allbinary )
8168  {
8169  /* if the right hand side and the minimal activity are finite and changing the variable with the biggest
8170  * influence to their bound forces all other variables to be at their minimal contribution, we can add these
8171  * implications
8172  */
8173  if( finiterhs && finiteminact && SCIPisEQ(scip, consdata->glbminactivity, consdata->rhs - maxabscontrib) )
8174  {
8175  for( v = nvars - 1; v >= 0; --v )
8176  {
8177  /* binary to binary implications will be collected when extrating cliques */
8178  if( !SCIPvarIsBinary(vars[v]) )
8179  {
8180  if( v != position )
8181  {
8182  if( vals[v] > 0 )
8183  {
8184  /* add implications */
8185  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_UPPER, SCIPvarGetLbGlobal(vars[v]), &infeasible, &nbdchgs) );
8186  ++nimpls;
8187  *nchgbds += nbdchgs;
8188  }
8189  else
8190  {
8191  /* add implications */
8192  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_LOWER, SCIPvarGetUbGlobal(vars[v]), &infeasible, &nbdchgs) );
8193  ++nimpls;
8194  *nchgbds += nbdchgs;
8195  }
8196 
8197  if( infeasible )
8198  {
8199  *cutoff = TRUE;
8200  break;
8201  }
8202  }
8203  }
8204  /* stop when reaching a 'real' binary variable because the variables are sorted after their type */
8205  else if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_BINARY )
8206  break;
8207  }
8208  }
8209 
8210  /* if the left hand side and the maximal activity are finite and changing the variable with the biggest
8211  * influence to their bound forces all other variables to be at their minimal contribution, we can add these
8212  * implications
8213  */
8214  if( finitelhs && finitemaxact && SCIPisEQ(scip, consdata->glbmaxactivity, consdata->lhs - maxabscontrib) )
8215  {
8216  for( v = nvars - 1; v >= 0; --v )
8217  {
8218  /* binary to binary implications will be collected when extrating cliques */
8219  if( !SCIPvarIsBinary(vars[v]) )
8220  {
8221  if( v != position )
8222  {
8223  if( vals[v] > 0 )
8224  {
8225  /* add implications */
8226  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_LOWER, SCIPvarGetUbGlobal(vars[v]), &infeasible, &nbdchgs) );
8227  ++nimpls;
8228  *nchgbds += nbdchgs;
8229  }
8230  else
8231  {
8232  /* add implications */
8233  SCIP_CALL( SCIPaddVarImplication(scip, vars[position], posval, vars[v], SCIP_BOUNDTYPE_UPPER, SCIPvarGetLbGlobal(vars[v]), &infeasible, &nbdchgs) );
8234  ++nimpls;
8235  *nchgbds += nbdchgs;
8236  }
8237 
8238  if( infeasible )
8239  {
8240  *cutoff = TRUE;
8241  break;
8242  }
8243  }
8244  }
8245  /* stop when reaching a 'real' binary variable because the variables are sorted after their type */
8246  else if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_BINARY )
8247  break;
8248  }
8249  }
8250 
8251  /* did we find some implications */
8252  if( nimpls > 0 )
8253  {
8254  SCIPdebugMsg(scip, "extracted %d implications from constraint %s which led to %d bound changes, %scutoff detetcted\n", nimpls, SCIPconsGetName(cons), *nchgbds - oldnchgbds, *cutoff ? "" : "no ");
8255 
8256  if( *cutoff )
8257  return SCIP_OKAY;
8258 
8259  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8260  if( *nchgbds - oldnchgbds > 0 )
8261  {
8262  /* check for fixed variables */
8263  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8264  if( *cutoff )
8265  return SCIP_OKAY;
8266 
8267  /* tighten variable's bounds */
8268  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8269  if( *cutoff )
8270  return SCIP_OKAY;
8271 
8272  /* check for fixed variables */
8273  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8274  if( *cutoff )
8275  return SCIP_OKAY;
8276  }
8277  }
8278  }
8279  }
8280 
8281  consdata->implsadded = TRUE;
8282  }
8283 
8284  /* check if we already added the cliques of this constraint */
8285  if( consdata->cliquesadded )
8286  return SCIP_OKAY;
8287 
8288  consdata->cliquesadded = TRUE;
8289  cliquenonzerosadded = 0;
8290  stopped = FALSE;
8291 
8292  /* sort variables by variable type */
8293  SCIP_CALL( consdataSort(scip, consdata) );
8294 
8295  nvars = consdata->nvars;
8296  vars = consdata->vars;
8297  vals = consdata->vals;
8298 
8299  /**@todo extract more cliques, implications and variable bounds from linear constraints */
8300 
8301  /* recompute activities if needed */
8302  if( !consdata->validactivities )
8303  consdataCalcActivities(scip, consdata);
8304  assert(consdata->validactivities);
8305 
8306  finitelhs = !SCIPisInfinity(scip, -consdata->lhs);
8307  finiterhs = !SCIPisInfinity(scip, consdata->rhs);
8308  finitenegminact = (consdata->glbminactivityneginf == 0 && consdata->glbminactivityneghuge == 0);
8309  finitenegmaxact = (consdata->glbmaxactivityneginf == 0 && consdata->maxactivityneghuge == 0);
8310  finiteposminact = (consdata->glbminactivityposinf == 0 && consdata->glbminactivityposhuge == 0);
8311  finiteposmaxact = (consdata->glbmaxactivityposinf == 0 && consdata->glbmaxactivityposhuge == 0);
8312  finiteminact = (finitenegminact && finiteposminact);
8313  finitemaxact = (finitenegmaxact && finiteposmaxact);
8314 
8315  /* 1. we wheck whether some variables do not fit together into this constraint and add the corresponding clique
8316  * information
8317  */
8318  if( (finiterhs || finitelhs) && (finitenegminact || finiteposminact || finitenegmaxact || finiteposmaxact) )
8319  {
8320  SCIP_VAR** binvars;
8321  SCIP_Real* binvarvals;
8322  int nposbinvars = 0;
8323  int nnegbinvars = 0;
8324  int allonebinary = 0;
8325 
8326  SCIP_CALL( SCIPallocBufferArray(scip, &binvars, nvars) );
8327  SCIP_CALL( SCIPallocBufferArray(scip, &binvarvals, nvars) );
8328 
8329  /* collect binary variables */
8330  for( i = 0; i < nvars; ++i )
8331  {
8332  if( SCIPvarIsBinary(vars[i]) )
8333  {
8334  assert(!SCIPisZero(scip, vals[i]));
8335 
8336  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8337  ++allonebinary;
8338 
8339  binvars[nposbinvars + nnegbinvars] = vars[i];
8340  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8341 
8342  if( SCIPisPositive(scip, vals[i]) )
8343  ++nposbinvars;
8344  else
8345  ++nnegbinvars;
8346 
8347  assert(nposbinvars + nnegbinvars <= nvars);
8348  }
8349  /* stop searching for binary variables, because the constraint data is sorted */
8350  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8351  break;
8352  }
8353  assert(nposbinvars + nnegbinvars <= nvars);
8354 
8355  /* setppc constraints will be handled later; we need at least two binary variables with same sign to extract
8356  * cliques
8357  */
8358  if( allonebinary < nvars && (nposbinvars >= 2 || nnegbinvars >= 2) )
8359  {
8360  SCIP_Real threshold;
8361  int oldnchgbds = *nchgbds;
8362  int nbdchgs;
8363  int jstart;
8364  int j;
8365 
8366  /* we need a valid minimal/maximal activity to add cliques */
8367  if( (finitenegminact || finiteposminact) && !consdata->validglbminact )
8368  {
8369  consdataRecomputeGlbMinactivity(scip, consdata);
8370  assert(consdata->validglbminact);
8371  }
8372 
8373  if( (finitenegmaxact || finiteposmaxact) && !consdata->validglbmaxact )
8374  {
8375  consdataRecomputeGlbMaxactivity(scip, consdata);
8376  assert(consdata->validglbmaxact);
8377  }
8378  assert(consdata->validglbminact || consdata->validglbmaxact);
8379 
8380  /* sort coefficients non-increasing to be faster in the clique search */
8381  SCIPsortDownRealPtr(binvarvals, (void**) binvars, nposbinvars + nnegbinvars);
8382 
8383  /* case a) */
8384  if( finiterhs && finitenegminact && nposbinvars >= 2 )
8385  {
8386  /* compute value that needs to be exceeded */
8387  threshold = consdata->rhs - consdata->glbminactivity;
8388 
8389  j = 1;
8390 #ifdef SCIP_DISABLED_CODE /* assertion should only hold when constraints were fully propagated and boundstightened */
8391  /* check that it is possible to choose binvar[i], otherwise it should have been fixed to zero */
8392  assert(SCIPisFeasLE(scip, binvarvals[0], threshold));
8393 #endif
8394  /* check if at least two variables are in a clique */
8395  if( SCIPisFeasGT(scip, binvarvals[0] + binvarvals[j], threshold) )
8396  {
8397  ++j;
8398  /* check for extending the clique */
8399  while( j < nposbinvars )
8400  {
8401  if( !SCIPisFeasGT(scip, binvarvals[j-1] + binvarvals[j], threshold) )
8402  break;
8403  ++j;
8404  }
8405  assert(j >= 2);
8406 
8407  /* add clique with at least two variables */
8408  SCIP_CALL( SCIPaddClique(scip, binvars, NULL, j, FALSE, &infeasible, &nbdchgs) );
8409 
8410  if( infeasible )
8411  *cutoff = TRUE;
8412 
8413  *nchgbds += nbdchgs;
8414 
8415  cliquenonzerosadded += j;
8416  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8417  stopped = TRUE;
8418 
8419  /* exchange the last variable in the clique if possible and add all new ones */
8420  if( !stopped && !(*cutoff) && j < nposbinvars )
8421  {
8422  SCIP_VAR** clqvars;
8423  int lastfit = j - 2;
8424  assert(lastfit >= 0);
8425 
8426  /* copy all 'main'-clique variables */
8427  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, binvars, j) );
8428 
8429  /* iterate up to the end with j and up to the front with lastfit, and check for different cliques */
8430  while( lastfit >= 0 && j < nposbinvars )
8431  {
8432  /* check if two variables are in a clique */
8433  if( SCIPisFeasGT(scip, binvarvals[lastfit] + binvarvals[j], threshold) )
8434  {
8435  clqvars[lastfit + 1] = binvars[j];
8436 
8437  /* add clique with at least two variables */
8438  SCIP_CALL( SCIPaddClique(scip, clqvars, NULL, lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8439 
8440  if( infeasible )
8441  {
8442  *cutoff = TRUE;
8443  break;
8444  }
8445 
8446  *nchgbds += nbdchgs;
8447 
8448  cliquenonzerosadded += (lastfit + 2);
8449  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8450  {
8451  stopped = TRUE;
8452  break;
8453  }
8454 
8455  ++j;
8456  }
8457  else
8458  --lastfit;
8459  }
8460 
8461  SCIPfreeBufferArray(scip, &clqvars);
8462  }
8463  }
8464  }
8465 
8466  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8467  if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8468  {
8469  /* check for fixed variables */
8470  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8471 
8472  if( !*cutoff )
8473  {
8474  /* tighten variable's bounds */
8475  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8476 
8477  if( !*cutoff )
8478  {
8479  /* check for fixed variables */
8480  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8481 
8482  if( !*cutoff )
8483  {
8484  /* sort variables by variable type */
8485  SCIP_CALL( consdataSort(scip, consdata) );
8486 
8487  /* recompute activities if needed */
8488  if( !consdata->validactivities )
8489  consdataCalcActivities(scip, consdata);
8490  assert(consdata->validactivities);
8491 
8492  nvars = consdata->nvars;
8493  vars = consdata->vars;
8494  vals = consdata->vals;
8495  nposbinvars = 0;
8496  nnegbinvars = 0;
8497  allonebinary = 0;
8498 
8499  /* update binary variables */
8500  for( i = 0; i < nvars; ++i )
8501  {
8502  if( SCIPvarIsBinary(vars[i]) )
8503  {
8504  assert(!SCIPisZero(scip, vals[i]));
8505 
8506  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8507  ++allonebinary;
8508 
8509  binvars[nposbinvars + nnegbinvars] = vars[i];
8510  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8511 
8512  if( SCIPisPositive(scip, vals[i]) )
8513  ++nposbinvars;
8514  else
8515  ++nnegbinvars;
8516 
8517  assert(nposbinvars + nnegbinvars <= nvars);
8518  }
8519  /* stop searching for binary variables, because the constraint data is sorted */
8520  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8521  break;
8522  }
8523  assert(nposbinvars + nnegbinvars <= nvars);
8524  }
8525  }
8526  }
8527 
8528  oldnchgbds = *nchgbds;
8529  }
8530 
8531  /* case b) */
8532  if( !stopped && !(*cutoff) && finitelhs && finiteposmaxact && nnegbinvars >= 2 )
8533  {
8534  /* compute value that needs to be deceeded */
8535  threshold = consdata->lhs - consdata->glbmaxactivity;
8536 
8537  i = nposbinvars + nnegbinvars - 1;
8538  j = i - 1;
8539 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8540  /* check that it is possible to choose binvar[i], otherwise it should have been fixed to zero */
8541  assert(SCIPisFeasGE(scip, binvarvals[i], threshold));
8542 #endif
8543  /* check if two variables are in a clique */
8544  if( SCIPisFeasLT(scip, binvarvals[i] + binvarvals[j], threshold) )
8545  {
8546  --j;
8547  /* check for extending the clique */
8548  while( j >= nposbinvars )
8549  {
8550  if( !SCIPisFeasLT(scip, binvarvals[j+1] + binvarvals[j], threshold) )
8551  break;
8552  --j;
8553  }
8554  jstart = j;
8555 
8556  assert(i - j >= 2);
8557  /* add clique with at least two variables */
8558  SCIP_CALL( SCIPaddClique(scip, &(binvars[j+1]), NULL, i - j, FALSE, &infeasible, &nbdchgs) );
8559 
8560  if( infeasible )
8561  *cutoff = TRUE;
8562 
8563  *nchgbds += nbdchgs;
8564 
8565  cliquenonzerosadded += (i - j);
8566  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8567  stopped = TRUE;
8568 
8569  /* exchange the last variable in the clique if possible and add all new ones */
8570  if( !stopped && !(*cutoff) && jstart >= nposbinvars )
8571  {
8572  SCIP_VAR** clqvars;
8573  int lastfit = jstart + 1;
8574  assert(lastfit < i);
8575 
8576  /* copy all 'main'-clique variables */
8577  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[lastfit]), i - j) );
8578  ++lastfit;
8579 
8580  /* iterate up to the front with j and up to the end with lastfit, and check for different cliques */
8581  while( lastfit <= i && j >= nposbinvars )
8582  {
8583  /* check if two variables are in a clique */
8584  if( SCIPisFeasLT(scip, binvarvals[lastfit] + binvarvals[j], threshold) )
8585  {
8586  assert(lastfit - jstart - 2 >= 0 && lastfit - jstart - 2 < i);
8587  clqvars[lastfit - jstart - 2] = binvars[j];
8588 
8589  assert(i - lastfit + 2 >= 2);
8590  /* add clique with at least two variables */
8591  SCIP_CALL( SCIPaddClique(scip, &(clqvars[lastfit - jstart - 2]), NULL, i - lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8592 
8593  if( infeasible )
8594  {
8595  *cutoff = TRUE;
8596  break;
8597  }
8598 
8599  *nchgbds += nbdchgs;
8600 
8601  cliquenonzerosadded += (i - lastfit + 2);
8602  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8603  {
8604  stopped = TRUE;
8605  break;
8606  }
8607 
8608  --j;
8609  }
8610  else
8611  ++lastfit;
8612  }
8613 
8614  SCIPfreeBufferArray(scip, &clqvars);
8615  }
8616  }
8617  }
8618 
8619  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8620  if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8621  {
8622  /* check for fixed variables */
8623  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8624 
8625  if( !*cutoff )
8626  {
8627  /* tighten variable's bounds */
8628  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8629 
8630  if( !*cutoff )
8631  {
8632  /* check for fixed variables */
8633  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8634 
8635  if( !*cutoff )
8636  {
8637  /* sort variables by variable type */
8638  SCIP_CALL( consdataSort(scip, consdata) );
8639 
8640  /* recompute activities if needed */
8641  if( !consdata->validactivities )
8642  consdataCalcActivities(scip, consdata);
8643  assert(consdata->validactivities);
8644 
8645  nvars = consdata->nvars;
8646  vars = consdata->vars;
8647  vals = consdata->vals;
8648  nposbinvars = 0;
8649  nnegbinvars = 0;
8650  allonebinary = 0;
8651 
8652  /* update binary variables */
8653  for( i = 0; i < nvars; ++i )
8654  {
8655  if( SCIPvarIsBinary(vars[i]) )
8656  {
8657  assert(!SCIPisZero(scip, vals[i]));
8658 
8659  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8660  ++allonebinary;
8661 
8662  binvars[nposbinvars + nnegbinvars] = vars[i];
8663  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8664 
8665  if( SCIPisPositive(scip, vals[i]) )
8666  ++nposbinvars;
8667  else
8668  ++nnegbinvars;
8669 
8670  assert(nposbinvars + nnegbinvars <= nvars);
8671  }
8672  /* stop searching for binary variables, because the constraint data is sorted */
8673  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8674  break;
8675  }
8676  assert(nposbinvars + nnegbinvars <= nvars);
8677  }
8678  }
8679  }
8680 
8681  oldnchgbds = *nchgbds;
8682  }
8683 
8684  /* case c) */
8685  if( !(*cutoff) && finiterhs && finiteminact && nnegbinvars >= 2 )
8686  {
8687  SCIP_Bool* values;
8688 
8689  /* initialize clique values array for adding a negated clique */
8690  SCIP_CALL( SCIPallocBufferArray(scip, &values, nnegbinvars) );
8691  BMSclearMemoryArray(values, nnegbinvars);
8692 
8693  /* compute value that needs to be exceeded */
8694  threshold = consdata->rhs - consdata->glbminactivity;
8695 
8696  i = nposbinvars + nnegbinvars - 1;
8697  j = i - 1;
8698 
8699 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8700  /* check if the variable should not have already been fixed to one */
8701  assert(!SCIPisFeasGT(scip, binvarvals[i], threshold));
8702 #endif
8703 
8704  if( SCIPisFeasGT(scip, -binvarvals[i] - binvarvals[j], threshold) )
8705  {
8706  --j;
8707  /* check for extending the clique */
8708  while( j >= nposbinvars )
8709  {
8710  if( !SCIPisFeasGT(scip, -binvarvals[j+1] - binvarvals[j], threshold) )
8711  break;
8712  --j;
8713  }
8714  jstart = j;
8715 
8716  assert(i - j >= 2);
8717  /* add negated clique with at least two variables */
8718  SCIP_CALL( SCIPaddClique(scip, &(binvars[j+1]), values, i - j, FALSE, &infeasible, &nbdchgs) );
8719 
8720  if( infeasible )
8721  *cutoff = TRUE;
8722 
8723  *nchgbds += nbdchgs;
8724 
8725  cliquenonzerosadded += (i - j);
8726  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8727  stopped = TRUE;
8728 
8729  /* exchange the last variable in the clique if possible and add all new ones */
8730  if( !stopped && !(*cutoff) && jstart >= nposbinvars )
8731  {
8732  SCIP_VAR** clqvars;
8733  int lastfit = j + 1;
8734  assert(lastfit < i);
8735 
8736  /* copy all 'main'-clique variables */
8737  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, &(binvars[lastfit]), i - j) );
8738  ++lastfit;
8739 
8740  /* iterate up to the front with j and up to the end with lastfit, and check for different cliques */
8741  while( lastfit <= i && j >= nposbinvars )
8742  {
8743  /* check if two variables are in a negated clique */
8744  if( SCIPisFeasGT(scip, -binvarvals[lastfit] - binvarvals[j], threshold) )
8745  {
8746  assert(lastfit - jstart - 2 >= 0 && lastfit - jstart - 2 < i);
8747  clqvars[lastfit - jstart - 2] = binvars[j];
8748 
8749  assert(i - lastfit + 2 >= 2);
8750  /* add clique with at least two variables */
8751  SCIP_CALL( SCIPaddClique(scip, &(clqvars[lastfit - jstart - 2]), values, i - lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8752 
8753  if( infeasible )
8754  {
8755  *cutoff = TRUE;
8756  break;
8757  }
8758 
8759  *nchgbds += nbdchgs;
8760 
8761  cliquenonzerosadded += (i - lastfit + 2);
8762  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8763  {
8764  stopped = TRUE;
8765  break;
8766  }
8767 
8768  --j;
8769  }
8770  else
8771  ++lastfit;
8772  }
8773 
8774  SCIPfreeBufferArray(scip, &clqvars);
8775  }
8776  }
8777 
8778  SCIPfreeBufferArray(scip, &values);
8779  }
8780 
8781  /* did we find some boundchanges, then we need to remove fixings and tighten the bounds further */
8782  if( !stopped && !*cutoff && *nchgbds - oldnchgbds > 0 )
8783  {
8784  /* check for fixed variables */
8785  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8786 
8787  if( !*cutoff )
8788  {
8789  /* tighten variable's bounds */
8790  SCIP_CALL( tightenBounds(scip, cons, maxeasyactivitydelta, sortvars, cutoff, nchgbds) );
8791 
8792  if( !*cutoff )
8793  {
8794  /* check for fixed variables */
8795  SCIP_CALL( fixVariables(scip, cons, cutoff, nfixedvars) );
8796 
8797  if( !*cutoff )
8798  {
8799  /* sort variables by variable type */
8800  SCIP_CALL( consdataSort(scip, consdata) );
8801 
8802  /* recompute activities if needed */
8803  if( !consdata->validactivities )
8804  consdataCalcActivities(scip, consdata);
8805  assert(consdata->validactivities);
8806 
8807  nvars = consdata->nvars;
8808  vars = consdata->vars;
8809  vals = consdata->vals;
8810  nposbinvars = 0;
8811  nnegbinvars = 0;
8812  allonebinary = 0;
8813 
8814  /* update binary variables */
8815  for( i = 0; i < nvars; ++i )
8816  {
8817  if( SCIPvarIsBinary(vars[i]) )
8818  {
8819  assert(!SCIPisZero(scip, vals[i]));
8820 
8821  if( SCIPisEQ(scip, REALABS(vals[i]), 1.0) )
8822  ++allonebinary;
8823 
8824  binvars[nposbinvars + nnegbinvars] = vars[i];
8825  binvarvals[nposbinvars + nnegbinvars] = vals[i];
8826 
8827  if( SCIPisPositive(scip, vals[i]) )
8828  ++nposbinvars;
8829  else
8830  ++nnegbinvars;
8831 
8832  assert(nposbinvars + nnegbinvars <= nvars);
8833  }
8834  /* stop searching for binary variables, because the constraint data is sorted */
8835  else if( SCIPvarGetType(vars[i]) == SCIP_VARTYPE_CONTINUOUS )
8836  break;
8837  }
8838  assert(nposbinvars + nnegbinvars <= nvars);
8839  }
8840  }
8841  }
8842  }
8843 
8844  /* case d) */
8845  if( !stopped && !(*cutoff) && finitelhs && finitemaxact && nposbinvars >= 2 )
8846  {
8847  SCIP_Bool* values;
8848 
8849  /* initialize clique values array for adding a negated clique */
8850  SCIP_CALL( SCIPallocBufferArray(scip, &values, nposbinvars) );
8851  BMSclearMemoryArray(values, nposbinvars);
8852 
8853  /* compute value that needs to be exceeded */
8854  threshold = consdata->lhs - consdata->glbmaxactivity;
8855 
8856  j = 1;
8857 
8858 #if 0 /* assertion should only holds when constraints were fully propagated and boundstightened */
8859  /* check if the variable should not have already been fixed to one */
8860  assert(!SCIPisFeasLT(scip, -binvarvals[0], threshold));
8861 #endif
8862 
8863  if( SCIPisFeasLT(scip, -binvarvals[0] - binvarvals[j], threshold) )
8864  {
8865  ++j;
8866  /* check for extending the clique */
8867  while( j < nposbinvars )
8868  {
8869  if( !SCIPisFeasLT(scip, -binvarvals[j-1] - binvarvals[j], threshold) )
8870  break;
8871  ++j;
8872  }
8873  assert(j >= 2);
8874 
8875  /* add negated clique with at least two variables */
8876  SCIP_CALL( SCIPaddClique(scip, binvars, values, j, FALSE, &infeasible, &nbdchgs) );
8877 
8878  if( infeasible )
8879  *cutoff = TRUE;
8880 
8881  *nchgbds += nbdchgs;
8882 
8883  cliquenonzerosadded += j;
8884  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8885  stopped = TRUE;
8886 
8887  /* exchange the last variable in the clique if possible and add all new ones */
8888  if( !stopped && !(*cutoff) && j < nposbinvars )
8889  {
8890  SCIP_VAR** clqvars;
8891  int lastfit = j - 2;
8892  assert(lastfit >= 0);
8893 
8894  /* copy all 'main'-clique variables */
8895  SCIP_CALL( SCIPduplicateBufferArray(scip, &clqvars, binvars, j) );
8896 
8897  /* iterate up to the end with j and up to the front with lastfit, and check for different cliques */
8898  while( lastfit >= 0 && j < nposbinvars )
8899  {
8900  /* check if two variables are in a negated clique */
8901  if( SCIPisFeasLT(scip, -binvarvals[lastfit] - binvarvals[j], threshold) )
8902  {
8903  clqvars[lastfit + 1] = binvars[j];
8904 
8905  /* add clique with at least two variables */
8906  SCIP_CALL( SCIPaddClique(scip, clqvars, values, lastfit + 2, FALSE, &infeasible, &nbdchgs) );
8907 
8908  if( infeasible )
8909  {
8910  *cutoff = TRUE;
8911  break;
8912  }
8913 
8914  *nchgbds += nbdchgs;
8915 
8916  cliquenonzerosadded += lastfit + 2;
8917  if( cliquenonzerosadded >= MAX_CLIQUE_NONZEROS_PER_CONS )
8918  break;
8919 
8920  ++j;
8921  }
8922  else
8923  --lastfit;
8924  }
8925 
8926  SCIPfreeBufferArray(scip, &clqvars);
8927  }
8928  }
8929 
8930  SCIPfreeBufferArray(scip, &values);
8931  }
8932  }
8933 
8934  SCIPfreeBufferArray(scip, &binvarvals);
8935  SCIPfreeBufferArray(scip, &binvars);
8936 
8937  if( *cutoff )
8938  return SCIP_OKAY;
8939  }
8940 
8941  /* 2. we only check if the constraint is a set packing / partitioning constraint */
8942 
8943  /* check if all variables are binary, if the coefficients are +1 or -1, and if the right hand side is equal
8944  * to 1 - number of negative coefficients, or if the left hand side is equal to number of positive coefficients - 1
8945  */
8946  nposcoefs = 0;
8947  nnegcoefs = 0;
8948  for( i = 0; i < nvars; ++i )
8949  {
8950  if( !SCIPvarIsBinary(vars[i]) )
8951  return SCIP_OKAY;
8952  else if( SCIPisEQ(scip, vals[i], +1.0) )
8953  nposcoefs++;
8954  else if( SCIPisEQ(scip, vals[i], -1.0) )
8955  nnegcoefs++;
8956  else
8957  return SCIP_OKAY;
8958  }
8959 
8960  lhsclique = SCIPisEQ(scip, consdata->lhs, (SCIP_Real)nposcoefs - 1.0);
8961  rhsclique = SCIPisEQ(scip, consdata->rhs, 1.0 - (SCIP_Real)nnegcoefs);
8962 
8963  if( lhsclique || rhsclique )
8964  {
8965  SCIP_Bool* values;
8966  int nbdchgs;
8967 
8968  SCIPdebugMsg(scip, "linear constraint <%s>: adding clique with %d vars (%d pos, %d neg)\n",
8969  SCIPconsGetName(cons), nvars, nposcoefs, nnegcoefs);
8970  SCIP_CALL( SCIPallocBufferArray(scip, &values, nvars) );
8971 
8972  for( i = 0; i < nvars; ++i )
8973  values[i] = (rhsclique == (vals[i] > 0.0));
8974 
8975  SCIP_CALL( SCIPaddClique(scip, vars, values, nvars, SCIPisEQ(scip, consdata->lhs, consdata->rhs), &infeasible, &nbdchgs) );
8976 
8977  if( infeasible )
8978  *cutoff = TRUE;
8979 
8980  *nchgbds += nbdchgs;
8981  SCIPfreeBufferArray(scip, &values);
8982  }
8983 
8984  return SCIP_OKAY;
8985 }
8986 
8987 /** tightens left and right hand side of constraint due to integrality */
8988 static
8990  SCIP* scip, /**< SCIP data structure */
8991  SCIP_CONS* cons, /**< linear constraint */
8992  int* nchgsides, /**< pointer to count number of side changes */
8993  SCIP_Bool* infeasible /**< pointer to store whether infeasibility was detected */
8994  )
8995 {
8996  SCIP_CONSDATA* consdata;
8997  SCIP_Real newlhs;
8998  SCIP_Real newrhs;
8999  SCIP_Bool chglhs;
9000  SCIP_Bool chgrhs;
9001  SCIP_Bool integral;
9002  int i;
9003 
9004  assert(scip != NULL);
9005  assert(cons != NULL);
9006  assert(nchgsides != NULL);
9007  assert(infeasible != NULL);
9009  consdata = SCIPconsGetData(cons);
9010  assert(consdata != NULL);
9011 
9012  *infeasible = FALSE;
9013 
9014  chglhs = FALSE;
9015  chgrhs = FALSE;
9016  newlhs = -SCIPinfinity(scip);
9017  newrhs = SCIPinfinity(scip);
9018 
9019  if( !SCIPisIntegral(scip, consdata->lhs) || !SCIPisIntegral(scip, consdata->rhs) )
9020  {
9021  integral = TRUE;
9022  for( i = 0; i < consdata->nvars && integral; ++i )
9023  {
9024  integral = SCIPisIntegral(scip, consdata->vals[i])
9025  && (SCIPvarGetType(consdata->vars[i]) != SCIP_VARTYPE_CONTINUOUS);
9026  }
9027  if( integral )
9028  {
9029  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisIntegral(scip, consdata->lhs) )
9030  {
9031  newlhs = SCIPfeasCeil(scip, consdata->lhs);
9032  chglhs = TRUE;
9033  }
9034  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisIntegral(scip, consdata->rhs) )
9035  {
9036  newrhs = SCIPfeasFloor(scip, consdata->rhs);
9037  chgrhs = TRUE;
9038  }
9039 
9040  /* check whether rounding would lead to an unsatisfiable constraint */
9041  if( SCIPisGT(scip, newlhs, newrhs) )
9042  {
9043  SCIPdebugMsg(scip, "rounding sides=[%.15g,%.15g] of linear constraint <%s> with integral coefficients and variables only "
9044  "is infeasible\n", consdata->lhs, consdata->rhs, SCIPconsGetName(cons));
9045 
9046  *infeasible = TRUE;
9047  return SCIP_OKAY;
9048  }
9049 
9050  SCIPdebugMsg(scip, "linear constraint <%s>: make sides integral: sides=[%.15g,%.15g]\n",
9051  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
9052 
9053  if( chglhs )
9054  {
9055  assert(!SCIPisInfinity(scip, -newlhs));
9056 
9057  SCIP_CALL( chgLhs(scip, cons, newlhs) );
9058  if( !consdata->upgraded )
9059  (*nchgsides)++;
9060  }
9061  if( chgrhs )
9062  {
9063  assert(!SCIPisInfinity(scip, newrhs));
9064 
9065  SCIP_CALL( chgRhs(scip, cons, newrhs) );
9066  if( !consdata->upgraded )
9067  (*nchgsides)++;
9068  }
9069  SCIPdebugMsg(scip, "linear constraint <%s>: new integral sides: sides=[%.15g,%.15g]\n",
9070  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
9071  }
9072  }
9073 
9074  return SCIP_OKAY;
9075 }
9076 
9077 /** tightens coefficients of binary, integer, and implicit integer variables due to activity bounds in presolving:
9078  * given an inequality lhs <= a*x + ai*xi <= rhs, with a non-continuous variable li <= xi <= ui
9079  * let minact := min{a*x + ai*xi}, maxact := max{a*x + ai*xi}
9080  * (i) ai >= 0:
9081  * if minact + ai >= lhs and maxact - ai <= rhs: (**)
9082  * - a deviation from the lower/upper bound of xi would make the left/right hand side redundant
9083  * - ai, lhs and rhs can be changed to have the same redundancy effect and the same results for
9084  * xi fixed to its bounds, but with a reduced ai and tightened sides to tighten the LP relaxation
9085  * - change coefficients:
9086  * ai' := max(lhs - minact, maxact - rhs)
9087  * lhs' := lhs - (ai - ai')*li
9088  * rhs' := rhs - (ai - ai')*ui
9089  * (ii) ai < 0:
9090  * if minact - ai >= lhs and maxact + ai <= rhs: (***)
9091  * - a deviation from the upper/lower bound of xi would make the left/right hand side redundant
9092  * - ai, lhs and rhs can be changed to have the same redundancy effect and the same results for
9093  * xi fixed to its bounds, but with a reduced ai and tightened sides to tighten the LP relaxation
9094  * - change coefficients:
9095  * ai' := min(rhs - maxact, minact - lhs)
9096  * lhs' := lhs - (ai - ai')*ui
9097  * rhs' := rhs - (ai - ai')*li
9098  *
9099  * We further try to remove redundant variable from the constraint;
9100  * Variables which fulfill conditions (**) or (***) are called surely non-redundant variables.
9101  * A deviation of only one from their bound makes the lhs/rhs feasible (i.e., redundant), even if all other
9102  * variables are set to their "worst" bound. If all variables which are not surely non-redundant cannot make
9103  * the lhs/rhs redundant, even if they are set to their "best" bound, they can be removed from the constraint.
9104  * 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
9105  * suffices to fulfill the inequality, whereas the x_i do not contribute to feasibility and can be removed.
9106  *
9107  * @todo use also some tightening procedures for (knapsack) constraints with non-integer coefficients, see
9108  * cons_knapsack.c the following methods detectRedundantVars() and tightenWeights()
9109  */
9110 static
9112  SCIP* scip, /**< SCIP data structure */
9113  SCIP_CONS* cons, /**< linear constraint */
9114  int* nchgcoefs, /**< pointer to count total number of changed coefficients */
9115  int* nchgsides /**< pointer to count number of side changes */
9116  )
9117 {
9118  SCIP_CONSDATA* consdata;
9119  SCIP_VAR* var;
9120  SCIP_Real minactivity; /* minimal value w.r.t. the variable's local bounds for the constraint's
9121  * activity, ignoring the coefficients contributing with infinite value */
9122  SCIP_Real maxactivity; /* maximal value w.r.t. the variable's local bounds for the constraint's
9123  * activity, ignoring the coefficients contributing with infinite value */
9124  SCIP_Bool minactisrelax; /* do huge finite values contribute to the minactivity? */
9125  SCIP_Bool maxactisrelax; /* do huge finite values contribute to the maxactivity? */
9126  SCIP_Bool isminsettoinfinity;
9127  SCIP_Bool ismaxsettoinfinity;
9128  SCIP_Real minleftactivity; /* minimal activity without surely non-redundant variables. */
9129  SCIP_Real maxleftactivity; /* maximal activity without surely non-redundant variables. */
9130  SCIP_Real aggrlhs; /* lhs without minimal activity of surely non-redundant variables. */
9131  SCIP_Real aggrrhs; /* rhs without maximal activity of surely non-redundant variables. */
9132  SCIP_Real lval; /* candidate for new value arising from considering the left hand side */
9133  SCIP_Real rval; /* candidate for new value arising from considering the left hand side */
9134  SCIP_Real val;
9135  SCIP_Real newval;
9136  SCIP_Real newlhs;
9137  SCIP_Real newrhs;
9138  SCIP_Real lb;
9139  SCIP_Real ub;
9140  int i;
9141 
9142  assert(scip != NULL);
9143  assert(cons != NULL);
9144  assert(nchgcoefs != NULL);
9145  assert(nchgsides != NULL);
9146 
9147  consdata = SCIPconsGetData(cons);
9148  assert(consdata != NULL);
9149 
9150  /* @todo Is this still needed with automatic recomputation of activities? */
9151  /* if the maximal coefficient is too large, recompute the activities */
9152  if( (consdata->validmaxabsval && consdata->maxabsval > MAXVALRECOMP)
9153  || (consdata->validminabsval && consdata->minabsval < MINVALRECOMP) )
9154  {
9155  consdataRecomputeMinactivity(scip, consdata);
9156  consdataRecomputeMaxactivity(scip, consdata);
9157  }
9158 
9159  /* get the minimal and maximal activity of the constraint */
9160  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9161  &isminsettoinfinity, &ismaxsettoinfinity);
9162 
9163  minleftactivity = 0.0;
9164  maxleftactivity = 0.0;
9165 
9166  /* try to tighten each coefficient */
9167  i = 0;
9168  while( i < consdata->nvars )
9169  {
9170  var = consdata->vars[i];
9171 
9172  /* get coefficient and variable's bounds */
9173  lb = SCIPvarGetLbLocal(var);
9174  ub = SCIPvarGetUbLocal(var);
9175  val = consdata->vals[i];
9176  assert(!SCIPisZero(scip, val));
9177 
9178  /* check sign of coefficient */
9179  if( val >= 0.0 )
9180  {
9181  /* check, if a deviation from lower/upper bound would make lhs/rhs redundant */
9183  SCIPisGE(scip, minactivity + val, consdata->lhs) && SCIPisLE(scip, maxactivity - val, consdata->rhs) )
9184  {
9185  /* change coefficients:
9186  * ai' := max(lhs - minact, maxact - rhs)
9187  * lhs' := lhs - (ai - ai')*li
9188  * rhs' := rhs - (ai - ai')*ui
9189  */
9190 
9191  lval = consdata->lhs - minactivity;
9192  rval = maxactivity - consdata->rhs;
9193 
9194  /* Try to avoid cancellation, if there are only two variables */
9195  if( consdata->nvars == 2 )
9196  {
9197  SCIP_Real otherval;
9198  otherval = consdata->vals[1-i];
9199 
9200  if( !SCIPisInfinity(scip, -consdata->lhs) && !isminsettoinfinity )
9201  {
9202  lval = consdata->lhs - val*lb;
9203  lval -= otherval > 0.0 ? otherval * SCIPvarGetLbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetUbLocal(consdata->vars[1-i]);
9204  }
9205 
9206  if( !SCIPisInfinity(scip, consdata->rhs) && !ismaxsettoinfinity )
9207  {
9208  rval = val*ub - consdata->rhs;
9209  rval += otherval > 0.0 ? otherval * SCIPvarGetUbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetLbLocal(consdata->vars[1-i]);
9210  }
9211  }
9212 
9213  newval = MAX(lval, rval);
9214  assert(SCIPisSumRelLE(scip, newval, val));
9215 
9216  /* Try to avoid cancellation in computation of lhs/rhs */
9217  newlhs = consdata->lhs - val * lb;
9218  newlhs += newval * lb;
9219  newrhs = consdata->rhs - val * ub;
9220  newrhs += newval * ub;
9221 
9222  if( !SCIPisSumRelEQ(scip, newval, val) )
9223  {
9224  SCIPdebugMsg(scip, "linear constraint <%s>: change coefficient %+.15g<%s> to %+.15g<%s>, act=[%.15g,%.15g], side=[%.15g,%.15g]\n",
9225  SCIPconsGetName(cons), val, SCIPvarGetName(var), newval, SCIPvarGetName(var),
9226  minactivity, maxactivity, consdata->lhs, consdata->rhs);
9227 
9228  /* update the coefficient and the activity bounds */
9229  if( SCIPisZero(scip, newval) )
9230  {
9231  SCIP_CALL( delCoefPos(scip, cons, i) );
9232  i--;
9233  }
9234  else
9235  {
9236  SCIP_CALL( chgCoefPos(scip, cons, i, newval) );
9237  }
9238  (*nchgcoefs)++;
9239 
9240  /* get the new minimal and maximal activity of the constraint */
9241  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9242  &isminsettoinfinity, &ismaxsettoinfinity);
9243 
9244  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisEQ(scip, newlhs, consdata->lhs) )
9245  {
9246  SCIPdebugMsg(scip, "linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
9247 
9248  SCIP_CALL( chgLhs(scip, cons, newlhs) );
9249  (*nchgsides)++;
9250  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
9251  }
9252 
9253  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisEQ(scip, newrhs, consdata->rhs) )
9254  {
9255  SCIPdebugMsg(scip, "linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
9256 
9257  SCIP_CALL( chgRhs(scip, cons, newrhs) );
9258  (*nchgsides)++;
9259  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
9260  }
9261  }
9262  }
9263  else
9264  {
9265  if( !SCIPisInfinity(scip, -minleftactivity) )
9266  {
9267  assert(!SCIPisInfinity(scip, val));
9268  assert(!SCIPisInfinity(scip, lb));
9269  if( SCIPisInfinity(scip, -lb) )
9270  minleftactivity = -SCIPinfinity(scip);
9271  else
9272  minleftactivity += val * lb;
9273  }
9274 
9275  if( !SCIPisInfinity(scip, maxleftactivity) )
9276  {
9277  assert(!SCIPisInfinity(scip, val));
9278  assert(!SCIPisInfinity(scip, -ub));
9279  if( SCIPisInfinity(scip,ub) )
9280  maxleftactivity = SCIPinfinity(scip);
9281  else
9282  maxleftactivity += val * ub;
9283  }
9284  }
9285  }
9286  else
9287  {
9288  /* check, if a deviation from lower/upper bound would make lhs/rhs redundant */
9290  SCIPisGE(scip, minactivity - val, consdata->lhs) && SCIPisLE(scip, maxactivity + val, consdata->rhs) )
9291  {
9292  /* change coefficients:
9293  * ai' := min(rhs - maxact, minact - lhs)
9294  * lhs' := lhs - (ai - ai')*ui
9295  * rhs' := rhs - (ai - ai')*li
9296  */
9297 
9298  lval = minactivity - consdata->lhs;
9299  rval = consdata->rhs - maxactivity;
9300 
9301  /* Try to avoid cancellation, if there are only two variables */
9302  if( consdata->nvars == 2 )
9303  {
9304  SCIP_Real otherval;
9305  otherval = consdata->vals[1-i];
9306 
9307  if( !SCIPisInfinity(scip, -consdata->lhs) && !isminsettoinfinity )
9308  {
9309  lval = val*ub - consdata->lhs;
9310  lval += otherval > 0.0 ? otherval * SCIPvarGetLbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetUbLocal(consdata->vars[1-i]);
9311  }
9312 
9313  if( !SCIPisInfinity(scip, consdata->rhs) && !ismaxsettoinfinity )
9314  {
9315  rval = consdata->rhs - val*lb;
9316  rval -= otherval > 0.0 ? otherval * SCIPvarGetUbLocal(consdata->vars[1-i]) : otherval * SCIPvarGetLbLocal(consdata->vars[1-i]);
9317  }
9318  }
9319 
9320  newval = MIN(lval, rval);
9321  assert(SCIPisSumRelGE(scip, newval, val));
9322 
9323  /* Try to avoid cancellation in computation of lhs/rhs */
9324  newlhs = consdata->lhs - val * ub;
9325  newlhs += newval * ub;
9326  newrhs = consdata->rhs - val * lb;
9327  newrhs += newval * lb;
9328 
9329  if( !SCIPisSumRelEQ(scip, newval, val) )
9330  {
9331  SCIPdebugMsg(scip, "linear constraint <%s>: change coefficient %+.15g<%s> to %+.15g<%s>, act=[%.15g,%.15g], side=[%.15g,%.15g]\n",
9332  SCIPconsGetName(cons), val, SCIPvarGetName(var), newval, SCIPvarGetName(var),
9333  minactivity, maxactivity, consdata->lhs, consdata->rhs);
9334 
9335  /* update the coefficient and the activity bounds */
9336  if( SCIPisZero(scip, newval) )
9337  {
9338  SCIP_CALL( delCoefPos(scip, cons, i) );
9339  i--;
9340  }
9341  else
9342  {
9343  SCIP_CALL( chgCoefPos(scip, cons, i, newval) );
9344  }
9345  (*nchgcoefs)++;
9346 
9347  /* get the new minimal and maximal activity of the constraint */
9348  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9349  &isminsettoinfinity, &ismaxsettoinfinity);
9350 
9351  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisEQ(scip, newlhs, consdata->lhs) )
9352  {
9353  SCIPdebugMsg(scip, "linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
9354 
9355  SCIP_CALL( chgLhs(scip, cons, newlhs) );
9356  (*nchgsides)++;
9357  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
9358  }
9359 
9360  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisEQ(scip, newrhs, consdata->rhs) )
9361  {
9362  SCIPdebugMsg(scip, "linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
9363 
9364  SCIP_CALL( chgRhs(scip, cons, newrhs) );
9365  (*nchgsides)++;
9366  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
9367  }
9368  }
9369  }
9370  else
9371  {
9372  if( !SCIPisInfinity(scip, -minleftactivity) )
9373  {
9374  assert(!SCIPisInfinity(scip, -val));
9375  assert(!SCIPisInfinity(scip, -ub));
9376  if( SCIPisInfinity(scip, ub) )
9377  minleftactivity = -SCIPinfinity(scip);
9378  else
9379  minleftactivity += val * ub;
9380  }
9381 
9382  if( !SCIPisInfinity(scip, maxleftactivity) )
9383  {
9384  assert(!SCIPisInfinity(scip, -val));
9385  assert(!SCIPisInfinity(scip, lb));
9386  if( SCIPisInfinity(scip, -lb) )
9387  maxleftactivity = SCIPinfinity(scip);
9388  else
9389  maxleftactivity += val * lb;
9390  }
9391  }
9392  }
9393  ++i;
9394  }
9395 
9396  SCIPdebugMsg(scip, "minleftactivity = %.15g, rhs = %.15g\n",
9397  minleftactivity, consdata->rhs);
9398  SCIPdebugMsg(scip, "maxleftactivity = %.15g, lhs = %.15g\n",
9399  maxleftactivity, consdata->lhs);
9400 
9401  /* minleft == \infty ==> minactivity == \infty */
9402  assert(!SCIPisInfinity(scip, -minleftactivity) || SCIPisInfinity(scip, -minactivity));
9403  assert(!SCIPisInfinity(scip, maxleftactivity) || SCIPisInfinity(scip, maxactivity));
9404 
9405  /* if the lhs is finite, we will check in the following whether the not non-redundant variables can make lhs feasible;
9406  * this is not valid, if the minactivity is -\infty (aggrlhs would be minus infinity in the following computation)
9407  * or if huge values contributed to the minactivity, because the minactivity is then just a relaxation
9408  * (<= the exact minactivity), and we might falsely claim variables to be redundant in the following
9409  */
9410  assert(!SCIPisInfinity(scip, minactivity));
9411  if( !SCIPisInfinity(scip, -consdata->lhs) && (SCIPisInfinity(scip, -minactivity) || minactisrelax) )
9412  return SCIP_OKAY;
9413 
9414  /* if the rhs is finite, we will check in the following whether the not non-redundant variables can make rhs feasible;
9415  * this is not valid, if the maxactivity is \infty (aggrrhs would be infinity in the following computation)
9416  * or if huge values contributed to the maxactivity, because the maxactivity is then just a relaxation
9417  * (>= the exact maxactivity), and we might falsely claim variables to be redundant in the following
9418  */
9419  assert(!SCIPisInfinity(scip, -maxactivity));
9420  if( !SCIPisInfinity(scip, consdata->rhs) && (SCIPisInfinity(scip, maxactivity) || maxactisrelax) )
9421  return SCIP_OKAY;
9422 
9423  /* correct lhs and rhs by min/max activity of surely non-redundant variables
9424  * surely non-redundant variables are all those where a deviation from the bound makes the lhs/rhs redundant
9425  */
9426  aggrlhs = consdata->lhs - minactivity + minleftactivity;
9427  aggrrhs = consdata->rhs - maxactivity + maxleftactivity;
9428 
9429  /* check if the constraint contains variables which are redundant. The reasoning is the following:
9430  * Each non-redundant variable can make the lhs/rhs feasible with a deviation of only one in the bound.
9431  * If _all_ variables which are not non-redundant together cannot make lhs/rhs feasible,
9432  * they can be removed from the constraint.
9433  * aggrrhs may contain some near-infinity value, but only if rhs is infinity.
9434  */
9435  if( (SCIPisInfinity(scip, -consdata->lhs) || SCIPisLT(scip, maxleftactivity, aggrlhs))
9436  && (SCIPisInfinity(scip, consdata->rhs) || SCIPisGT(scip, minleftactivity, aggrrhs)) )
9437  {
9438  SCIP_Real minleftactivitypart;
9439  SCIP_Real maxleftactivitypart;
9440 
9441  assert(!SCIPisInfinity(scip, -consdata->lhs) || !SCIPisInfinity(scip, consdata->rhs));
9442 
9443  /* try to remove redundant variables from constraint */
9444  i = 0;
9445  while( i < consdata->nvars )
9446  {
9447  var = consdata->vars[i];
9448  minleftactivitypart = 0.0;
9449  maxleftactivitypart = 0.0;
9450  lb = SCIPvarGetLbLocal(var);
9451  ub = SCIPvarGetUbLocal(var);
9452 
9453  /* get coefficient and variable's bounds */
9454  val = consdata->vals[i];
9455  assert(!SCIPisZero(scip, val));
9456 
9457  /* check sign of coefficient */
9458  if( val >= 0.0 )
9459  {
9460  /* negation of condition above in case of positive val */
9462  SCIPisLT(scip, minactivity + val, consdata->lhs) || SCIPisGT(scip, maxactivity - val, consdata->rhs) )
9463  {
9464  SCIPdebugMsg(scip, "minactivity = %g\tval = %g\tlhs = %g\n", minactivity, val, consdata->lhs);
9465  SCIPdebugMsg(scip, "maxactivity = %g\tval = %g\trhs = %g\n", maxactivity, val, consdata->rhs);
9466  SCIPdebugMsg(scip, "linear constraint <%s>: remove variable <%s> with coefficient <%g> from constraint since it is redundant\n",
9467  SCIPconsGetName(cons), SCIPvarGetName(consdata->vars[i]), val);
9468 
9469  minleftactivitypart = val * lb;
9470  maxleftactivitypart = val * ub;
9471 
9472  SCIP_CALL( delCoefPos(scip, cons, i) );
9473  i--;
9474 
9475  /* get the new minimal and maximal activity of the constraint */
9476  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9477  &isminsettoinfinity, &ismaxsettoinfinity);
9478 
9479  /* we return above if the condition does not hold and deleting a variable cannot increase the number of
9480  * huge contributions
9481  */
9482  assert(!minactisrelax || SCIPisInfinity(scip, -consdata->lhs));
9483  assert(!maxactisrelax || SCIPisInfinity(scip, consdata->rhs));
9484  }
9485  }
9486  else
9487  {
9488  /* negation of condition above in case of negative val */
9490  SCIPisLT(scip, minactivity - val, consdata->lhs) || SCIPisGT(scip, maxactivity + val, consdata->rhs) )
9491  {
9492  SCIPdebugMsg(scip, "linear constraint <%s>: remove variable <%s> with coefficient <%g> from constraint since it is redundant\n",
9493  SCIPconsGetName(cons), SCIPvarGetName(consdata->vars[i]), val);
9494 
9495  minleftactivitypart = val * ub;
9496  maxleftactivitypart = val * lb;
9497 
9498  SCIP_CALL( delCoefPos(scip, cons, i) );
9499  i--;
9500 
9501  /* get the new minimal and maximal activity of the constraint */
9502  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
9503  &isminsettoinfinity, &ismaxsettoinfinity);
9504 
9505  /* we return above if the condition does not hold and deleting a variable cannot increase the number of
9506  * huge contributions
9507  */
9508  assert(!minactisrelax || SCIPisInfinity(scip, -consdata->lhs));
9509  assert(!maxactisrelax || SCIPisInfinity(scip, consdata->rhs));
9510  }
9511  }
9512 
9513  /* the following update step is needed in every iteration cause otherwise it is possible that the surely none-
9514  * redundant variables could get deleted,
9515  * e.g. y_1 + 16y_2 >= 25, y1 with bounds [9,12], y2 with bounds [0,2], minactivity would be 9, it follows that
9516  * y_2 is surely not redundant and y_1 is redundant so we would first delete y1 and without updating the sides
9517  * we would also delete y2 and as a result we would have gotten infeasibility */
9518  /* adjust lhs and right hand side */
9519  newlhs = consdata->lhs - minleftactivitypart;
9520  newrhs = consdata->rhs - maxleftactivitypart;
9521 
9522  if( !SCIPisInfinity(scip, -consdata->lhs) && !SCIPisFeasEQ(scip, newlhs, consdata->lhs) )
9523  {
9524  SCIPdebugMsg(scip, "linear constraint <%s>: change lhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->lhs, newlhs);
9525  SCIP_CALL( chgLhs(scip, cons, newlhs) );
9526  ++(*nchgsides);
9527  assert(SCIPisEQ(scip, consdata->lhs, newlhs));
9528  }
9529  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisFeasEQ(scip, newrhs, consdata->rhs) )
9530  {
9531  SCIPdebugMsg(scip, "linear constraint <%s>: change rhs %.15g to %.15g\n", SCIPconsGetName(cons), consdata->rhs, newrhs);
9532  SCIP_CALL( chgRhs(scip, cons, newrhs) );
9533  ++(*nchgsides);
9534  assert(SCIPisEQ(scip, consdata->rhs, newrhs));
9535  }
9536  ++i;
9537  }
9538  }
9539 
9540  return SCIP_OKAY;
9541 }
9542 
9543 /** processes equality with only one variable by fixing the variable and deleting the constraint */
9544 static
9546  SCIP* scip, /**< SCIP data structure */
9547  SCIP_CONS* cons, /**< linear constraint */
9548  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
9549  int* nfixedvars, /**< pointer to count number of fixed variables */
9550  int* ndelconss /**< pointer to count number of deleted constraints */
9551  )
9552 {
9553  SCIP_CONSDATA* consdata;
9554  SCIP_VAR* var;
9555  SCIP_Real val;
9556  SCIP_Real fixval;
9557  SCIP_Bool infeasible;
9558  SCIP_Bool fixed;
9559 
9560  assert(scip != NULL);
9561  assert(cons != NULL);
9562  assert(cutoff != NULL);
9563  assert(nfixedvars != NULL);
9564  assert(ndelconss != NULL);
9565 
9566  consdata = SCIPconsGetData(cons);
9567  assert(consdata != NULL);
9568  assert(consdata->nvars == 1);
9569  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9570 
9571  /* calculate the value to fix the variable to */
9572  var = consdata->vars[0];
9573  val = consdata->vals[0];
9574  assert(!SCIPisZero(scip, val));
9575  fixval = SCIPselectSimpleValue(consdata->lhs/val - 0.9 * SCIPepsilon(scip),
9576  consdata->rhs/val + 0.9 * SCIPepsilon(scip), MAXDNOM);
9577  SCIPdebugMsg(scip, "linear equality <%s>: fix <%s> == %.15g\n",
9578  SCIPconsGetName(cons), SCIPvarGetName(var), fixval);
9579 
9580  /* fix variable */
9581  SCIP_CALL( SCIPfixVar(scip, var, fixval, &infeasible, &fixed) );
9582  if( infeasible )
9583  {
9584  SCIPdebugMsg(scip, " -> infeasible fixing\n");
9585  *cutoff = TRUE;
9586  return SCIP_OKAY;
9587  }
9588  if( fixed )
9589  (*nfixedvars)++;
9590 
9591  /* disable constraint */
9592  SCIP_CALL( SCIPdelCons(scip, cons) );
9593  if( !consdata->upgraded )
9594  (*ndelconss)++;
9595 
9596  return SCIP_OKAY;
9597 }
9598 
9599 /** processes equality with exactly two variables by aggregating one of the variables and deleting the constraint */
9600 static
9602  SCIP* scip, /**< SCIP data structure */
9603  SCIP_CONS* cons, /**< linear constraint */
9604  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
9605  int* naggrvars, /**< pointer to count number of aggregated variables */
9606  int* ndelconss /**< pointer to count number of deleted constraints */
9607  )
9608 {
9609  SCIP_CONSDATA* consdata;
9610  SCIP_Bool infeasible;
9611  SCIP_Bool redundant;
9612  SCIP_Bool aggregated;
9613 
9614  assert(scip != NULL);
9615  assert(cons != NULL);
9616  assert(cutoff != NULL);
9617  assert(naggrvars != NULL);
9618  assert(ndelconss != NULL);
9619 
9620  consdata = SCIPconsGetData(cons);
9621  assert(consdata != NULL);
9622  assert(consdata->nvars == 2);
9623  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9624 
9625  SCIPdebugMsg(scip, "linear constraint <%s>: aggregate %.15g<%s> + %.15g<%s> == %.15g\n",
9626  SCIPconsGetName(cons), consdata->vals[0], SCIPvarGetName(consdata->vars[0]),
9627  consdata->vals[1], SCIPvarGetName(consdata->vars[1]), consdata->rhs);
9628 
9629  /* aggregate the equality */
9630  SCIP_CALL( SCIPaggregateVars(scip, consdata->vars[0], consdata->vars[1], consdata->vals[0], consdata->vals[1],
9631  consdata->rhs, &infeasible, &redundant, &aggregated) );
9632 
9633  /* check for infeasibility of aggregation */
9634  if( infeasible )
9635  {
9636  SCIPdebugMsg(scip, " -> infeasible aggregation\n");
9637  *cutoff = TRUE;
9638  return SCIP_OKAY;
9639  }
9640 
9641  /* count the aggregation */
9642  if( aggregated )
9643  (*naggrvars)++;
9644 
9645  /* delete the constraint, if it is redundant */
9646  if( redundant )
9647  {
9648  SCIP_CALL( SCIPdelCons(scip, cons) );
9649 
9650  if( !consdata->upgraded )
9651  (*ndelconss)++;
9652  }
9653 
9654  return SCIP_OKAY;
9655 }
9656 
9657 /** calculates the new lhs and rhs of the constraint after the given variable is aggregated out */
9658 static
9660  SCIP* scip, /**< SCIP data structure */
9661  SCIP_CONSDATA* consdata, /**< linear constraint data */
9662  SCIP_VAR* slackvar, /**< variable to be aggregated out */
9663  SCIP_Real slackcoef, /**< coefficient of variable in constraint */
9664  SCIP_Real* newlhs, /**< pointer to store new lhs of constraint */
9665  SCIP_Real* newrhs /**< pointer to store new rhs of constraint */
9666  )
9667 {
9668  SCIP_Real slackvarlb;
9669  SCIP_Real slackvarub;
9670 
9671  assert(scip != NULL);
9672  assert(consdata != NULL);
9673  assert(newlhs != NULL);
9674  assert(newrhs != NULL);
9675  assert(!SCIPisInfinity(scip, -consdata->lhs));
9676  assert(!SCIPisInfinity(scip, consdata->rhs));
9677 
9678  slackvarlb = SCIPvarGetLbGlobal(slackvar);
9679  slackvarub = SCIPvarGetUbGlobal(slackvar);
9680  if( slackcoef > 0.0 )
9681  {
9682  if( SCIPisInfinity(scip, -slackvarlb) )
9683  *newrhs = SCIPinfinity(scip);
9684  else
9685  *newrhs = consdata->rhs - slackcoef * slackvarlb;
9686  if( SCIPisInfinity(scip, slackvarub) )
9687  *newlhs = -SCIPinfinity(scip);
9688  else
9689  *newlhs = consdata->lhs - slackcoef * slackvarub;
9690  }
9691  else
9692  {
9693  if( SCIPisInfinity(scip, -slackvarlb) )
9694  *newlhs = -SCIPinfinity(scip);
9695  else
9696  *newlhs = consdata->rhs - slackcoef * slackvarlb;
9697  if( SCIPisInfinity(scip, slackvarub) )
9698  *newrhs = SCIPinfinity(scip);
9699  else
9700  *newrhs = consdata->lhs - slackcoef * slackvarub;
9701  }
9702  assert(SCIPisLE(scip, *newlhs, *newrhs));
9703 }
9704 
9705 /** processes equality with more than two variables by multi-aggregating one of the variables and converting the equality
9706  * into an inequality; if multi-aggregation is not possible, tries to identify one continuous or integer variable that
9707  * is implicitly integral by this constraint
9708  *
9709  * @todo Check whether a more clever way of avoiding aggregation of variables containing implicitly integer variables
9710  * can help.
9711  */
9712 static
9714  SCIP* scip, /**< SCIP data structure */
9715  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
9716  SCIP_CONS* cons, /**< linear constraint */
9717  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
9718  int* naggrvars, /**< pointer to count number of aggregated variables */
9719  int* ndelconss /**< pointer to count number of deleted constraints */
9720  )
9721 {
9722  SCIP_CONSDATA* consdata;
9723  SCIP_VAR** vars;
9724  SCIP_Real* vals;
9725  SCIP_VARTYPE bestslacktype;
9726  SCIP_VARTYPE slacktype;
9727  SCIP_Real lhs;
9728  SCIP_Real rhs;
9729  SCIP_Real bestslackdomrng;
9730  SCIP_Real minabsval;
9731  SCIP_Real maxabsval;
9732  SCIP_Bool bestremovescons;
9733  SCIP_Bool coefszeroone;
9734  SCIP_Bool coefsintegral;
9735  SCIP_Bool varsintegral;
9736  SCIP_Bool infeasible;
9737  SCIP_Bool samevar;
9738  int supinf; /* counter for infinite contributions to the supremum of a possible
9739  * multi-aggregation
9740  */
9741  int infinf; /* counter for infinite contributions to the infimum of a possible
9742  * multi-aggregation
9743  */
9744  int maxnlocksstay;
9745  int maxnlocksremove;
9746  int bestslackpos;
9747  int bestnlocks;
9748  int ncontvars;
9749  int contvarpos;
9750  int nintvars;
9751  int nimplvars;
9752  int intvarpos;
9753  int v;
9754 
9755  assert(scip != NULL);
9756  assert(cons != NULL);
9757  assert(cutoff != NULL);
9758  assert(naggrvars != NULL);
9759 
9760  consdata = SCIPconsGetData(cons);
9761  assert(consdata != NULL);
9762  assert(consdata->nvars > 2);
9763  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
9764 
9765  SCIPdebugMsg(scip, "linear constraint <%s>: try to multi-aggregate equality\n", SCIPconsGetName(cons));
9766 
9767  /* We do not want to increase the total number of non-zeros due to the multi-aggregation.
9768  * Therefore, we have to restrict the number of locks of a variable that is aggregated out.
9769  * maxnlocksstay: maximal sum of lock numbers if the constraint does not become redundant after the aggregation
9770  * maxnlocksremove: maximal sum of lock numbers if the constraint can be deleted after the aggregation
9771  */
9772  lhs = consdata->lhs;
9773  rhs = consdata->rhs;
9774  maxnlocksstay = 0;
9775  if( consdata->nvars == 3 )
9776  {
9777  /* If the constraint becomes redundant, 3 non-zeros are removed, and we get 1 additional non-zero for each
9778  * constraint the variable appears in. Thus, the variable must appear in at most 3 other constraints.
9779  */
9780  maxnlocksremove = 3;
9781  }
9782  else if( consdata->nvars == 4 )
9783  {
9784  /* If the constraint becomes redundant, 4 non-zeros are removed, and we get 2 additional non-zeros for each
9785  * constraint the variable appears in. Thus, the variable must appear in at most 2 other constraints.
9786  */
9787  maxnlocksremove = 2;
9788  }
9789  else
9790  {
9791  /* If the constraint is redundant but has more than 4 variables, we can only accept one other constraint. */
9792  maxnlocksremove = 1;
9793  }
9794 
9795  /* the locks on this constraint can be ignored */
9796  if( SCIPconsIsChecked(cons) )
9797  {
9798  if( !SCIPisInfinity(scip, -lhs) )
9799  {
9800  maxnlocksstay++;
9801  maxnlocksremove++;
9802  }
9803  if( !SCIPisInfinity(scip, rhs) )
9804  {
9805  maxnlocksstay++;
9806  maxnlocksremove++;
9807  }
9808  }
9809 
9810  /* look for a slack variable s to convert a*x + s == b into lhs <= a*x <= rhs */
9811  vars = consdata->vars;
9812  vals = consdata->vals;
9813  bestslackpos = -1;
9814  bestslacktype = SCIP_VARTYPE_BINARY;
9815  bestnlocks = INT_MAX;
9816  bestremovescons = FALSE;
9817  bestslackdomrng = 0.0;
9818  coefszeroone = TRUE;
9819  coefsintegral = TRUE;
9820  varsintegral = TRUE;
9821  ncontvars = 0;
9822  contvarpos = -1;
9823  nintvars = 0;
9824  nimplvars = 0;
9825  intvarpos = -1;
9826  minabsval = SCIPinfinity(scip);
9827  maxabsval = -1.0;
9828  for( v = 0; v < consdata->nvars; ++v )
9829  {
9830  SCIP_VAR* var;
9831  SCIP_Real val;
9832  SCIP_Real absval;
9833  SCIP_Real varlb;
9834  SCIP_Real varub;
9835  SCIP_Bool iscont;
9836  int nlocks;
9837 
9838  assert(vars != NULL);
9839  assert(vals != NULL);
9840 
9841  var = vars[v];
9842  assert(!SCIPconsIsChecked(cons) || SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) >= 1); /* because variable is locked in this equality */
9843  assert(!SCIPconsIsChecked(cons) || SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) >= 1);
9844  varlb = SCIPvarGetLbGlobal(var);
9845  varub = SCIPvarGetUbGlobal(var);
9846 
9847  val = vals[v];
9848  absval = REALABS(val);
9849  assert(SCIPisPositive(scip, absval));
9850 
9851  /* calculate minimal and maximal absolute value */
9852  if( absval < minabsval )
9853  minabsval = absval;
9854  if( absval > maxabsval )
9855  maxabsval = absval;
9856 
9857  /* do not try to multi aggregate, when numerical bad */
9858  if( maxabsval / minabsval > conshdlrdata->maxmultaggrquot )
9859  return SCIP_OKAY;
9860 
9861  slacktype = SCIPvarGetType(var);
9862  coefszeroone = coefszeroone && SCIPisEQ(scip, absval, 1.0);
9863  coefsintegral = coefsintegral && SCIPisIntegral(scip, val);
9864  varsintegral = varsintegral && (slacktype != SCIP_VARTYPE_CONTINUOUS);
9865  iscont = (slacktype == SCIP_VARTYPE_CONTINUOUS || slacktype == SCIP_VARTYPE_IMPLINT);
9866 
9867  /* update candidates for continuous -> implint and integer -> implint conversion */
9868  if( slacktype == SCIP_VARTYPE_CONTINUOUS )
9869  {
9870  ncontvars++;
9871  contvarpos = v;
9872  }
9873  else if( slacktype == SCIP_VARTYPE_IMPLINT )
9874  {
9875  ++nimplvars;
9876  }
9877  else if( slacktype == SCIP_VARTYPE_INTEGER )
9878  {
9879  nintvars++;
9880  intvarpos = v;
9881  }
9882 
9883  /* check, if variable is already fixed or aggregated */
9884  if( !SCIPvarIsActive(var) )
9885  continue;
9886 
9887  /* check, if variable is used in too many other constraints, even if this constraint could be deleted */
9889 
9890  if( nlocks > maxnlocksremove )
9891  continue;
9892 
9893  /* check, if variable can be used as a slack variable */
9894  if( (iscont || (coefsintegral && varsintegral && SCIPisEQ(scip, absval, 1.0))) &&
9895  !SCIPdoNotMultaggrVar(scip, var) )
9896  {
9897  SCIP_Bool better;
9898  SCIP_Bool equal;
9899  SCIP_Real slackdomrng;
9900 
9901  if( SCIPisInfinity(scip, varub) || SCIPisInfinity(scip, -varlb) )
9902  slackdomrng = SCIPinfinity(scip);
9903  /* we do not want to perform multi-aggregation due to numerics, if the bounds are huge */
9904  else if( SCIPisHugeValue(scip, varub) || SCIPisHugeValue(scip, -varlb) )
9905  return SCIP_OKAY;
9906  else
9907  {
9908  slackdomrng = (varub - varlb)*absval;
9909  assert(!SCIPisInfinity(scip, slackdomrng));
9910  }
9911  equal = FALSE;
9912  better = (slacktype > bestslacktype) || (bestslackpos == -1);
9913  if( !better && slacktype == bestslacktype )
9914  {
9915  better = (nlocks < bestnlocks);
9916  if( nlocks == bestnlocks && !bestremovescons )
9917  {
9918  better = SCIPisGT(scip, slackdomrng, bestslackdomrng);
9919  equal = !better && SCIPisGE(scip, slackdomrng, bestslackdomrng);
9920  }
9921  }
9922 
9923  if( better || equal )
9924  {
9925  SCIP_Real minresactivity;
9926  SCIP_Real maxresactivity;
9927  SCIP_Real newlhs;
9928  SCIP_Real newrhs;
9929  SCIP_Bool removescons;
9930  SCIP_Bool minisrelax;
9931  SCIP_Bool maxisrelax;
9932  SCIP_Bool isminsettoinfinity;
9933  SCIP_Bool ismaxsettoinfinity;
9934 
9935  /* check if the constraint becomes redundant after multi-aggregation */
9936  consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
9937  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
9938 
9939  /* do not perform the multi-aggregation due to numerics, if we have huge contributions in the residual
9940  * activity
9941  */
9942  if( minisrelax || maxisrelax )
9943  continue;
9944 
9945  getNewSidesAfterAggregation(scip, consdata, var, val, &newlhs, &newrhs);
9946  removescons = (SCIPisFeasLE(scip, newlhs, minresactivity) && SCIPisFeasLE(scip, maxresactivity, newrhs));
9947 
9948  /* check resactivities for reliability */
9949  if( removescons )
9950  {
9951  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
9952  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
9953 
9954  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity)
9955  && SCIPisFeasLE(scip, newlhs, minresactivity))
9956  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
9957 
9958  removescons = (SCIPisFeasLE(scip, newlhs, minresactivity) && SCIPisFeasLE(scip, maxresactivity, newrhs));
9959  }
9960 
9961  /* if parameter multaggrremove is set to TRUE, only aggregate when this removes constraint */
9962  if( conshdlrdata->multaggrremove && !removescons )
9963  continue;
9964 
9965  /* prefer variables that make the constraints redundant */
9966  if( bestremovescons && !removescons )
9967  continue;
9968 
9969  /* if the constraint does not become redundant, only accept the variable if it does not appear in
9970  * other constraints
9971  */
9972  if( !removescons && nlocks > maxnlocksstay )
9973  continue;
9974 
9975  better = better || (!bestremovescons && removescons);
9976  if( better )
9977  {
9978  bestslackpos = v;
9979  bestslacktype = slacktype;
9980  bestnlocks = nlocks;
9981  bestslackdomrng = slackdomrng;
9982  bestremovescons = removescons;
9983  }
9984  }
9985  }
9986  }
9987 
9988  /* if all coefficients and variables are integral, the right hand side must also be integral */
9989  if( coefsintegral && varsintegral && !SCIPisFeasIntegral(scip, consdata->rhs) )
9990  {
9991  SCIPdebugMsg(scip, "linear equality <%s> is integer infeasible\n", SCIPconsGetName(cons));
9992  SCIPdebugPrintCons(scip, cons, NULL);
9993  *cutoff = TRUE;
9994  return SCIP_OKAY;
9995  }
9996 
9997  supinf = 0;
9998  infinf = 0;
9999  samevar = FALSE;
10000 
10001  /* check whether the the infimum and the supremum of the multi-aggregation can be get infinite */
10002  for( v = 0; v < consdata->nvars; ++v )
10003  {
10004  if( v != bestslackpos )
10005  {
10006  if( SCIPisPositive(scip, consdata->vals[v]) )
10007  {
10008  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
10009  {
10010  ++supinf;
10011  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
10012  {
10013  ++infinf;
10014  samevar = TRUE;
10015  }
10016  }
10017  else if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
10018  ++infinf;
10019  }
10020  else if( SCIPisNegative(scip, consdata->vals[v]) )
10021  {
10022  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[v])) )
10023  {
10024  ++supinf;
10025  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
10026  {
10027  ++infinf;
10028  samevar = TRUE;
10029  }
10030  }
10031  else if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[v])) )
10032  ++infinf;
10033  }
10034  }
10035  }
10036  assert(!samevar || (supinf > 0 && infinf > 0));
10037 
10038  /* If the infimum and the supremum of a multi-aggregation are both infinite, then the multi-aggregation might not be resolvable.
10039  * E.g., consider the equality z = x-y. If x and y are both fixed to +infinity, the value for z is not determined */
10040  if( (samevar && (supinf > 1 || infinf > 1)) || (!samevar && supinf > 0 && infinf > 0) )
10041  {
10042  SCIPdebugMsg(scip, "do not perform multi-aggregation: infimum and supremum are both infinite\n");
10043  return SCIP_OKAY;
10044  }
10045 
10046  /* if the slack variable is of integer type, and the constraint itself may take fractional values,
10047  * we cannot aggregate the variable, because the integrality condition would get lost
10048  * Similarly, if there are implicitly integral variables we cannot aggregate, since we might
10049  * loose the integrality condition for this variable.
10050  */
10051  if( bestslackpos >= 0
10052  && (bestslacktype == SCIP_VARTYPE_CONTINUOUS || bestslacktype == SCIP_VARTYPE_IMPLINT
10053  || (coefsintegral && varsintegral && nimplvars == 0)) )
10054  {
10055  SCIP_VAR* slackvar;
10056  SCIP_Real* scalars;
10057  SCIP_Real slackcoef;
10058  SCIP_Real aggrconst;
10059  SCIP_Real newlhs;
10060  SCIP_Real newrhs;
10061  SCIP_Bool aggregated;
10062 
10063  /* we found a slack variable that only occurs in at most one other constraint:
10064  * a_1*x_1 + ... + a_k*x_k + a'*s == rhs -> s == rhs - a_1/a'*x_1 - ... - a_k/a'*x_k
10065  */
10066  assert(bestslackpos < consdata->nvars);
10067 
10068  /* do not multi aggregate binary variables */
10069  if( SCIPvarIsBinary(vars[bestslackpos]) )
10070  return SCIP_OKAY;
10071 
10072  /* convert equality into inequality by deleting the slack variable:
10073  * x + a*s == b, l <= s <= u -> b - a*u <= x <= b - a*l
10074  */
10075  slackvar = vars[bestslackpos];
10076  slackcoef = vals[bestslackpos];
10077  assert(!SCIPisZero(scip, slackcoef));
10078  aggrconst = consdata->rhs/slackcoef;
10079 
10080  getNewSidesAfterAggregation(scip, consdata, slackvar, slackcoef, &newlhs, &newrhs);
10081  assert(SCIPisLE(scip, newlhs, newrhs));
10082  SCIP_CALL( chgLhs(scip, cons, newlhs) );
10083  SCIP_CALL( chgRhs(scip, cons, newrhs) );
10084  SCIP_CALL( delCoefPos(scip, cons, bestslackpos) );
10085 
10086  /* allocate temporary memory */
10087  SCIP_CALL( SCIPallocBufferArray(scip, &scalars, consdata->nvars) );
10088 
10089  /* set up the multi-aggregation */
10090  SCIPdebugMsg(scip, "linear constraint <%s>: multi-aggregate <%s> ==", SCIPconsGetName(cons), SCIPvarGetName(slackvar));
10091  for( v = 0; v < consdata->nvars; ++v )
10092  {
10093  scalars[v] = -consdata->vals[v]/slackcoef;
10094  SCIPdebugMsgPrint(scip, " %+.15g<%s>", scalars[v], SCIPvarGetName(vars[v]));
10095  }
10096  SCIPdebugMsgPrint(scip, " %+.15g, bounds of <%s>: [%.15g,%.15g], nlocks=%d, maxnlocks=%d, removescons=%u\n",
10097  aggrconst, SCIPvarGetName(slackvar), SCIPvarGetLbGlobal(slackvar), SCIPvarGetUbGlobal(slackvar),
10098  bestnlocks, bestremovescons ? maxnlocksremove : maxnlocksstay, bestremovescons);
10099 
10100  /* perform the multi-aggregation */
10101  SCIP_CALL( SCIPmultiaggregateVar(scip, slackvar, consdata->nvars, vars, scalars, aggrconst,
10102  &infeasible, &aggregated) );
10103  assert(aggregated);
10104 
10105  /* free temporary memory */
10106  SCIPfreeBufferArray(scip, &scalars);
10107 
10108  /* check for infeasible aggregation */
10109  if( infeasible )
10110  {
10111  SCIPdebugMsg(scip, "linear constraint <%s>: infeasible multi-aggregation\n", SCIPconsGetName(cons));
10112  *cutoff = TRUE;
10113  return SCIP_OKAY;
10114  }
10115 
10116  (*naggrvars)++;
10117 
10118  /* delete the constraint if it became redundant */
10119  if( bestremovescons )
10120  {
10121  SCIPdebugMsg(scip, "linear constraint <%s>: redundant after multi-aggregation\n", SCIPconsGetName(cons));
10122  SCIP_CALL( SCIPdelCons(scip, cons) );
10123 
10124  if( !consdata->upgraded )
10125  (*ndelconss)++;
10126  }
10127  }
10128  else if( ncontvars == 1 )
10129  {
10130  SCIP_VAR* var;
10131 
10132  assert(0 <= contvarpos && contvarpos < consdata->nvars);
10133  var = vars[contvarpos];
10134  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
10135 
10136  if( coefsintegral && SCIPisFeasIntegral(scip, consdata->rhs) )
10137  {
10138  /* upgrade continuous variable to an implicit one, if the absolute value of the coefficient is one */
10139  if( SCIPisEQ(scip, REALABS(vals[contvarpos]), 1.0) )
10140  {
10141  /* convert the continuous variable with coefficient 1.0 into an implicit integer variable */
10142  SCIPdebugMsg(scip, "linear constraint <%s>: converting continuous variable <%s> to implicit integer variable\n",
10143  SCIPconsGetName(cons), SCIPvarGetName(var));
10144  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
10145  if( infeasible )
10146  {
10147  SCIPdebugMsg(scip, "infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
10148  *cutoff = TRUE;
10149 
10150  return SCIP_OKAY;
10151  }
10152  }
10153  /* aggregate continuous variable to an implicit one, if the absolute value of the coefficient is unequal to one */
10154  /* @todo check if the aggregation coefficient should be in some range(, which is not too big) */
10155  else if( !SCIPdoNotAggr(scip) )
10156  {
10157  SCIP_VAR* newvar;
10158  SCIP_Real absval;
10159  char newvarname[SCIP_MAXSTRLEN];
10160  SCIP_Bool redundant;
10161  SCIP_Bool aggregated;
10162 
10163  absval = REALABS(vals[contvarpos]);
10164 
10165  (void) SCIPsnprintf(newvarname, SCIP_MAXSTRLEN, "%s_impl", SCIPvarGetName(var));
10166 
10167  /* create new implicit variable for aggregation */
10168  SCIP_CALL( SCIPcreateVar(scip, &newvar, newvarname, -SCIPinfinity(scip), SCIPinfinity(scip), 0.0,
10170 
10171  /* add new variable to problem */
10172  SCIP_CALL( SCIPaddVar(scip, newvar) );
10173 
10174 #ifdef WITH_DEBUG_SOLUTION
10175  if( SCIPdebugIsMainscip(scip) )
10176  {
10177  SCIP_Real varval;
10178  SCIP_CALL( SCIPdebugGetSolVal(scip, var, &varval) );
10179  SCIP_CALL( SCIPdebugAddSolVal(scip, newvar, absval * varval) );
10180  }
10181 #endif
10182 
10183  /* convert the continuous variable with coefficient 1.0 into an implicit integer variable */
10184  SCIPdebugMsg(scip, "linear constraint <%s>: aggregating continuous variable <%s> to newly created implicit integer variable <%s>, aggregation factor = %g\n",
10185  SCIPconsGetName(cons), SCIPvarGetName(var), SCIPvarGetName(newvar), absval);
10186 
10187  /* aggregate continuous and implicit variable */
10188  SCIP_CALL( SCIPaggregateVars(scip, var, newvar, absval, -1.0, 0.0, &infeasible, &redundant, &aggregated) );
10189 
10190  if( infeasible )
10191  {
10192  SCIPdebugMsg(scip, "infeasible aggregation of variable <%s> to implicit variable <%s>, domain is empty\n",
10193  SCIPvarGetName(var), SCIPvarGetName(newvar));
10194  *cutoff = TRUE;
10195 
10196  /* release implicit variable */
10197  SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
10198 
10199  return SCIP_OKAY;
10200  }
10201 
10202  /* release implicit variable */
10203  SCIP_CALL( SCIPreleaseVar(scip, &newvar) );
10204 
10205  if( aggregated )
10206  (*naggrvars)++;
10207  else
10208  return SCIP_OKAY;
10209  }
10210 
10211  /* we do not have any event on vartype changes, so we need to manually force this constraint to be presolved
10212  * again
10213  */
10214  consdata->boundstightened = 0;
10215  consdata->rangedrowpropagated = 0;
10216  consdata->presolved = FALSE;
10217  }
10218  }
10219  else if( ncontvars == 0 && nimplvars == 0 && nintvars == 1 && !coefszeroone )
10220  {
10221  SCIP_VAR* var;
10222 
10223  /* this seems to help for rococo instances, but does not for rout (where all coefficients are +/- 1.0)
10224  * -> we don't convert integers into implints if the row is a 0/1-row
10225  */
10226  assert(varsintegral);
10227  assert(0 <= intvarpos && intvarpos < consdata->nvars);
10228  var = vars[intvarpos];
10229  assert(SCIPvarGetType(var) == SCIP_VARTYPE_INTEGER);
10230 
10231  if( coefsintegral
10232  && SCIPisEQ(scip, REALABS(vals[intvarpos]), 1.0)
10233  && SCIPisFeasIntegral(scip, consdata->rhs) )
10234  {
10235  /* convert the integer variable with coefficient 1.0 into an implicit integer variable */
10236  SCIPdebugMsg(scip, "linear constraint <%s>: converting integer variable <%s> to implicit integer variable\n",
10237  SCIPconsGetName(cons), SCIPvarGetName(var));
10238  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
10239  if( infeasible )
10240  {
10241  SCIPdebugMsg(scip, "infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
10242  *cutoff = TRUE;
10243 
10244  return SCIP_OKAY;
10245  }
10246  }
10247  }
10248 
10249  return SCIP_OKAY;
10250 }
10251 
10252 /** checks if the given variables and their coefficient are equal (w.r.t. scaling factor) to the objective function */
10253 static
10255  SCIP* scip, /**< SCIP data structure */
10256  SCIP_CONSDATA* consdata, /**< linear constraint data */
10257  SCIP_Real* scale, /**< pointer to store the scaling factor between the constraint and the
10258  * objective function */
10259  SCIP_Real* offset /**< pointer to store the offset of the objective function resulting by
10260  * this constraint */
10261  )
10262 {
10263  SCIP_VAR** vars;
10264  SCIP_VAR* var;
10265  SCIP_Real objval;
10266  SCIP_Bool negated;
10267  int nvars;
10268  int v;
10269 
10270  vars = consdata->vars;
10271  nvars = consdata->nvars;
10272 
10273  assert(vars != NULL);
10274 
10275  for( v = 0; v < nvars; ++v )
10276  {
10277  negated = FALSE;
10278  var = vars[v];
10279  assert(var != NULL);
10280 
10281  if( SCIPvarIsNegated(var) )
10282  {
10283  negated = TRUE;
10284  var = SCIPvarGetNegatedVar(var);
10285  assert(var != NULL);
10286  }
10287 
10288  objval = SCIPvarGetObj(var);
10289 
10290  /* if a variable has a zero objective coefficient the linear constraint is not a subset of the objective
10291  * function
10292  */
10293  if( SCIPisZero(scip, objval) )
10294  return FALSE;
10295  else
10296  {
10297  SCIP_Real val;
10298 
10299  val = consdata->vals[v];
10300 
10301  if( negated )
10302  {
10303  if( v == 0 )
10304  {
10305  /* the first variable defines the scale */
10306  (*scale) = val / -objval;
10307 
10308  (*offset) += val;
10309  }
10310  else if( SCIPisEQ(scip, -objval * (*scale), val) )
10311  (*offset) += val;
10312  else
10313  return FALSE;
10314  }
10315  else if( v == 0 )
10316  {
10317  /* the first variable defines the scale */
10318  (*scale) = val / objval;
10319  }
10320  else if( !SCIPisEQ(scip, objval * (*scale), val) )
10321  return FALSE;
10322  }
10323  }
10324 
10325  return TRUE;
10326 }
10327 
10328 /** check if the linear equality constraint is equal to a subset of the objective function; if so we can remove the
10329  * objective coefficients and add an objective offset
10330  */
10331 static
10333  SCIP* scip, /**< SCIP data structure */
10334  SCIP_CONS* cons, /**< linear equation constraint */
10335  SCIP_CONSHDLRDATA* conshdlrdata /**< linear constraint handler data */
10336  )
10337 {
10338  SCIP_CONSDATA* consdata;
10339  SCIP_Real offset;
10340  SCIP_Real scale;
10341  SCIP_Bool applicable;
10342  int nobjvars;
10343  int nvars;
10344  int v;
10345 
10346  assert(scip != NULL);
10347  assert(cons != NULL);
10348  assert(conshdlrdata != NULL);
10349 
10350  consdata = SCIPconsGetData(cons);
10351  assert(consdata != NULL);
10352  assert(SCIPisEQ(scip, consdata->lhs, consdata->rhs));
10353 
10354  nvars = consdata->nvars;
10355  nobjvars = SCIPgetNObjVars(scip);
10356 
10357  /* check if the linear equality constraints does not have more variables than the objective function */
10358  if( nvars > nobjvars || nvars == 0 )
10359  return SCIP_OKAY;
10360 
10361  /* check for allowance of algorithm */
10362  if( (nvars < nobjvars && !conshdlrdata->detectpartialobjective) ||
10363  (nvars == nobjvars && (!conshdlrdata->detectcutoffbound || !conshdlrdata->detectlowerbound)) )
10364  return SCIP_OKAY;
10365 
10366  offset = consdata->rhs;
10367  scale = 1.0;
10368 
10369  /* checks if the variables and their coefficients are equal (w.r.t. scaling factor) to the objective function */
10370  applicable = checkEqualObjective(scip, consdata, &scale, &offset);
10371 
10372  if( applicable )
10373  {
10374  SCIP_VAR** vars;
10375 
10376  vars = consdata->vars;
10377  assert(vars != NULL);
10378 
10379  offset /= scale;
10380 
10381  SCIPdebugMsg(scip, "linear equality constraint <%s> == %g (offset %g) is a subset of the objective function\n",
10382  SCIPconsGetName(cons), consdata->rhs, offset);
10383 
10384  /* set all objective coefficient to zero */
10385  for( v = 0; v < nvars; ++v )
10386  {
10387  SCIP_CALL( SCIPchgVarObj(scip, vars[v], 0.0) );
10388  }
10389 
10390  /* add an objective offset */
10391  SCIP_CALL( SCIPaddObjoffset(scip, offset) );
10392  }
10393 
10394  return SCIP_OKAY;
10395 }
10396 
10397 /** updates the cutoff if the given primal bound (which is implied by the given constraint) is better */
10398 static
10400  SCIP* scip, /**< SCIP data structure */
10401  SCIP_CONS* cons, /**< constraint */
10402  SCIP_Real primalbound /**< feasible primal bound */
10403  )
10404 {
10405  SCIP_Real cutoffbound;
10406 
10407  /* increase the cutoff bound value by an epsilon to ensue that solution with the value of the cutoff bound are still
10408  * accepted
10409  */
10410  cutoffbound = primalbound + SCIPcutoffbounddelta(scip);
10411 
10412  if( cutoffbound < SCIPgetCutoffbound(scip) )
10413  {
10414  SCIPdebugMsg(scip, "update cutoff bound <%g>\n", cutoffbound);
10415 
10416  SCIP_CALL( SCIPupdateCutoffbound(scip, cutoffbound) );
10417  }
10418  else
10419  {
10420  SCIP_CONSDATA* consdata;
10421 
10422  consdata = SCIPconsGetData(cons);
10423  assert(consdata != NULL);
10424 
10425  /* we cannot disable the enforcement and propagation on ranged rows, because the cutoffbound could only have
10426  * resulted from one side
10427  */
10428  if( SCIPisInfinity(scip, -consdata->lhs) || SCIPisInfinity(scip, consdata->rhs) )
10429  {
10430  /* in case the cutoff bound is worse then the currently known one, we additionally avoid enforcement and
10431  * propagation
10432  */
10433  SCIP_CALL( SCIPsetConsEnforced(scip, cons, FALSE) );
10434  SCIP_CALL( SCIPsetConsPropagated(scip, cons, FALSE) );
10435  }
10436  }
10437 
10438  return SCIP_OKAY;
10439 }
10440 
10441 /** check if the linear constraint is parallel to objective function; if so update the cutoff bound and avoid that the
10442  * constraint enters the LP by setting the initial and separated flag to FALSE
10443  */
10444 static
10446  SCIP* scip, /**< SCIP data structure */
10447  SCIP_CONS* cons, /**< linear constraint */
10448  SCIP_CONSHDLRDATA* conshdlrdata /**< linear constraint handler data */
10449  )
10450 {
10451  SCIP_CONSDATA* consdata;
10452  SCIP_Real offset;
10453  SCIP_Real scale;
10454  SCIP_Bool applicable;
10455  int nobjvars;
10456  int nvars;
10457 
10458  assert(scip != NULL);
10459  assert(cons != NULL);
10460  assert(conshdlrdata != NULL);
10461 
10462  consdata = SCIPconsGetData(cons);
10463  assert(consdata != NULL);
10465  /* ignore equalities since these are covered by the method checkPartialObjective() */
10466  if( SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
10467  return SCIP_OKAY;
10468 
10469  nvars = consdata->nvars;
10470  nobjvars = SCIPgetNObjVars(scip);
10471 
10472  /* check if the linear inequality constraints has the same number of variables as the objective function and if the
10473  * initial and/or separated flag is set to FALSE
10474  */
10475  if( nvars != nobjvars || (!SCIPconsIsInitial(cons) && !SCIPconsIsSeparated(cons)) )
10476  return SCIP_OKAY;
10477 
10478  offset = 0.0;
10479  scale = 1.0;
10480 
10481  /* There are no variables in the objective function and in the constraint. Thus, the constraint is redundant or proves
10482  * infeasibility. Since we have a pure feasibility problem, we do not want to set a cutoff or lower bound.
10483  */
10484  if( nobjvars == 0 )
10485  return SCIP_OKAY;
10486 
10487  /* checks if the variables and their coefficients are equal (w.r.t. scaling factor) to the objective function */
10488  applicable = checkEqualObjective(scip, consdata, &scale, &offset);
10489 
10490  if( applicable )
10491  {
10492  SCIP_Bool rhsfinite = !SCIPisInfinity(scip, consdata->rhs);
10493  SCIP_Bool lhsfinite = !SCIPisInfinity(scip, -consdata->lhs);
10494 
10495  assert(scale != 0.0);
10496 
10497  if( scale > 0.0 )
10498  {
10499  if( conshdlrdata->detectcutoffbound && rhsfinite )
10500  {
10501  SCIP_Real primalbound;
10502 
10503  primalbound = (consdata->rhs - offset) / scale;
10504 
10505  SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a cutoff bound <%g>\n",
10506  SCIPconsGetName(cons), primalbound);
10507 
10508  SCIP_CALL( updateCutoffbound(scip, cons, primalbound) );
10509  }
10510 
10511  if( conshdlrdata->detectlowerbound && lhsfinite )
10512  {
10513  SCIP_Real lowerbound;
10514 
10515  lowerbound = (consdata->lhs - offset) / scale;
10516 
10517  SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a lower bound <%g>\n",
10518  SCIPconsGetName(cons), lowerbound);
10519 
10520  SCIP_CALL( SCIPupdateLocalLowerbound(scip, lowerbound) );
10521  }
10522 
10523  if( (conshdlrdata->detectcutoffbound && (conshdlrdata->detectlowerbound || !lhsfinite)) ||
10524  (conshdlrdata->detectlowerbound && !rhsfinite) )
10525  {
10526  /* avoid that the linear constraint enters the LP since it is parallel to the objective function */
10527  SCIP_CALL( SCIPsetConsInitial(scip, cons, FALSE) );
10528  SCIP_CALL( SCIPsetConsSeparated(scip, cons, FALSE) );
10529  }
10530  }
10531  else
10532  {
10533  if( conshdlrdata->detectlowerbound && rhsfinite )
10534  {
10535  SCIP_Real lowerbound;
10536 
10537  lowerbound = (consdata->rhs - offset) / scale;
10538 
10539  SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a lower bound <%g>\n",
10540  SCIPconsGetName(cons), lowerbound);
10541 
10542  SCIP_CALL( SCIPupdateLocalLowerbound(scip, lowerbound) );
10543  }
10544 
10545  if( conshdlrdata->detectcutoffbound && lhsfinite )
10546  {
10547  SCIP_Real primalbound;
10548 
10549  primalbound = (consdata->lhs - offset) / scale;
10550 
10551  SCIPdebugMsg(scip, "constraint <%s> is parallel to objective function and provides a cutoff bound <%g>\n",
10552  SCIPconsGetName(cons), primalbound);
10553 
10554  SCIP_CALL( updateCutoffbound(scip, cons, primalbound) );
10555  }
10556 
10557  if( (conshdlrdata->detectcutoffbound && (conshdlrdata->detectlowerbound || !rhsfinite)) ||
10558  (conshdlrdata->detectlowerbound && !lhsfinite) )
10559  {
10560  /* avoid that the linear constraint enters the LP since it is parallel to the objective function */
10561  SCIP_CALL( SCIPsetConsInitial(scip, cons, FALSE) );
10562  SCIP_CALL( SCIPsetConsSeparated(scip, cons, FALSE) );
10563  }
10564  }
10565  }
10566 
10567  return SCIP_OKAY;
10568 }
10569 
10570 /** converts special equalities */
10571 static
10573  SCIP* scip, /**< SCIP data structure */
10574  SCIP_CONS* cons, /**< linear constraint */
10575  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
10576  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
10577  int* nfixedvars, /**< pointer to count number of fixed variables */
10578  int* naggrvars, /**< pointer to count number of aggregated variables */
10579  int* ndelconss /**< pointer to count number of deleted constraints */
10580  )
10581 {
10582  SCIP_CONSDATA* consdata;
10583 
10584  assert(scip != NULL);
10585  assert(cons != NULL);
10586  assert(conshdlrdata != NULL);
10587  assert(cutoff != NULL);
10588  assert(nfixedvars != NULL);
10589  assert(naggrvars != NULL);
10590  assert(ndelconss != NULL);
10592  consdata = SCIPconsGetData(cons);
10593  assert(consdata != NULL);
10594  assert(consdata->removedfixings);
10595 
10596  /* do nothing on inequalities */
10597  if( !SCIPisEQ(scip, consdata->lhs, consdata->rhs) )
10598  return SCIP_OKAY;
10599 
10600  /* depending on the number of variables, call a special conversion method */
10601  if( consdata->nvars == 1 )
10602  {
10603  /* fix variable */
10604  SCIP_CALL( convertUnaryEquality(scip, cons, cutoff, nfixedvars, ndelconss) );
10605  }
10606  else if( consdata->nvars == 2 )
10607  {
10608  /* aggregate one of the variables */
10609  SCIP_CALL( convertBinaryEquality(scip, cons, cutoff, naggrvars, ndelconss) );
10610  }
10611  else
10612  {
10613  /* check if the equality is part of the objective function */
10614  SCIP_CALL( checkPartialObjective(scip, cons, conshdlrdata) );
10615 
10616  /* try to multi-aggregate one of the variables */
10617  SCIP_CALL( convertLongEquality(scip, conshdlrdata, cons, cutoff, naggrvars, ndelconss) );
10618  }
10619 
10620  return SCIP_OKAY;
10621 }
10622 
10623 /** returns whether the linear sum of all variables/coefficients except the given one divided by the given value is always
10624  * integral
10625  */
10626 static
10628  SCIP* scip, /**< SCIP data structure */
10629  SCIP_CONSDATA* consdata, /**< linear constraint */
10630  int pos, /**< position of variable to be left out */
10631  SCIP_Real val /**< value to divide the coefficients by */
10632  )
10633 {
10634  int v;
10635 
10636  assert(scip != NULL);
10637  assert(consdata != NULL);
10638  assert(0 <= pos && pos < consdata->nvars);
10639 
10640  for( v = 0; v < consdata->nvars; ++v )
10641  {
10642  if( v != pos && (!SCIPvarIsIntegral(consdata->vars[v]) || !SCIPisIntegral(scip, consdata->vals[v]/val)) )
10643  return FALSE;
10644  }
10645 
10646  return TRUE;
10647 }
10648 
10649 /** 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$,
10650  * 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$
10651  */
10652 static
10654  SCIP* scip, /**< SCIP data structure */
10655  SCIP_Real side, /**< lhs or rhs */
10656  SCIP_Real val, /**< coefficient */
10657  SCIP_Real minresactivity, /**< minimal residual activity */
10658  SCIP_Real maxresactivity, /**< maximal residual activity */
10659  SCIP_Real* minval, /**< pointer to store calculated minval */
10660  SCIP_Real* maxval /**< pointer to store calculated maxval */
10661  )
10662 {
10663  assert(scip != NULL);
10664  assert(minval != NULL);
10665  assert(maxval != NULL);
10666 
10667  if( val > 0.0 )
10668  {
10669  if( SCIPisInfinity(scip, ABS(maxresactivity)) )
10670  *minval = -maxresactivity;
10671  else
10672  *minval = (side - maxresactivity)/val;
10673 
10674  if( SCIPisInfinity(scip, ABS(minresactivity)) )
10675  *maxval = -minresactivity;
10676  else
10677  *maxval = (side - minresactivity)/val;
10678  }
10679  else
10680  {
10681  if( SCIPisInfinity(scip, ABS(minresactivity)) )
10682  *minval = minresactivity;
10683  else
10684  *minval = (side - minresactivity)/val;
10685 
10686  if( SCIPisInfinity(scip, ABS(maxresactivity)) )
10687  *maxval = maxresactivity;
10688  else
10689  *maxval = (side - maxresactivity)/val;
10690  }
10691 }
10692 
10693 
10694 /** applies dual presolving for variables that are locked only once in a direction, and this locking is due to a
10695  * linear inequality
10696  */
10697 static
10699  SCIP* scip, /**< SCIP data structure */
10700  SCIP_CONSHDLRDATA* conshdlrdata, /**< linear constraint handler data */
10701  SCIP_CONS* cons, /**< linear constraint */
10702  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
10703  int* nfixedvars, /**< pointer to count number of fixed variables */
10704  int* naggrvars, /**< pointer to count number of aggregated variables */
10705  int* ndelconss /**< pointer to count number of deleted constraints */
10706  )
10707 {
10708  SCIP_CONSDATA* consdata;
10709  SCIP_Bool lhsexists;
10710  SCIP_Bool rhsexists;
10711  SCIP_Bool bestisint;
10712  SCIP_Bool bestislhs;
10713  SCIP_Real minabsval;
10714  SCIP_Real maxabsval;
10715  int bestpos;
10716  int i;
10717  int maxotherlocks;
10718 
10719  assert(scip != NULL);
10720  assert(cons != NULL);
10721  assert(cutoff != NULL);
10722  assert(nfixedvars != NULL);
10723  assert(naggrvars != NULL);
10724  assert(ndelconss != NULL);
10725 
10726  /* only process checked constraints (for which the locks are increased);
10727  * otherwise we would have to check for variables with nlocks == 0, and these are already processed by the
10728  * dualfix presolver
10729  */
10730  if( !SCIPconsIsChecked(cons) )
10731  return SCIP_OKAY;
10732 
10733  consdata = SCIPconsGetData(cons);
10734  assert(consdata != NULL);
10735 
10736  lhsexists = !SCIPisInfinity(scip, -consdata->lhs);
10737  rhsexists = !SCIPisInfinity(scip, consdata->rhs);
10738 
10739  /* search for a single-locked variable which can be multi-aggregated; if a valid continuous variable was found, we
10740  * can use it safely for aggregation and break the search loop
10741  */
10742  bestpos = -1;
10743  bestisint = TRUE;
10744  bestislhs = FALSE;
10745 
10746  /* We only want to multi-aggregate variables, if they appear in maximal one additional constraint,
10747  * everything else would produce fill-in. Exceptions:
10748  * - If there are only two variables in the constraint from which the multi-aggregation arises, no fill-in will be
10749  * produced.
10750  * - If there are three variables in the constraint, multi-aggregation in three additional constraints will remove
10751  * six nonzeros (three from the constraint and the three entries of the multi-aggregated variable) and add
10752  * six nonzeros (two variables per substitution).
10753  * - If there at most four variables in the constraint, multi-aggregation in two additional constraints will remove
10754  * six nonzeros (four from the constraint and the two entries of the multi-aggregated variable) and add
10755  * six nonzeros (three variables per substitution). God exists!
10756  */
10757  if( consdata->nvars <= 2 )
10758  maxotherlocks = INT_MAX;
10759  else if( consdata->nvars == 3 )
10760  maxotherlocks = 3;
10761  else if( consdata->nvars == 4 )
10762  maxotherlocks = 2;
10763  else
10764  maxotherlocks = 1;
10765 
10766  /* if this constraint has both sides, it also provides a lock for the other side and thus we can allow one more lock */
10767  if( lhsexists && rhsexists && maxotherlocks < INT_MAX )
10768  maxotherlocks++;
10769 
10770  minabsval = SCIPinfinity(scip);
10771  maxabsval = -1.0;
10772  for( i = 0; i < consdata->nvars && bestisint; ++i )
10773  {
10774  SCIP_VAR* var;
10775  SCIP_Bool isint;
10776  SCIP_Real val;
10777  SCIP_Real absval;
10778  SCIP_Real obj;
10779  SCIP_Real lb;
10780  SCIP_Real ub;
10781  SCIP_Bool agglhs;
10782  SCIP_Bool aggrhs;
10783 
10784  val = consdata->vals[i];
10785  absval = REALABS(val);
10786 
10787  /* calculate minimal and maximal absolute value */
10788  if( absval < minabsval )
10789  minabsval = absval;
10790  if( absval > maxabsval )
10791  maxabsval = absval;
10792 
10793  /* do not try to multi aggregate, when numerical bad */
10794  if( maxabsval / minabsval > conshdlrdata->maxdualmultaggrquot )
10795  return SCIP_OKAY;
10796 
10797  var = consdata->vars[i];
10799 
10800  /* if we already found a candidate, skip integers */
10801  if( bestpos >= 0 && isint )
10802  continue;
10803 
10804  /* better do not multi-aggregate binary variables, since most plugins rely on their binary variables to be either
10805  * active, fixed, or single-aggregated with another binary variable
10806  */
10807  if( SCIPvarIsBinary(var) && consdata->nvars > 2 )
10808  continue;
10809 
10810  if ( SCIPdoNotMultaggrVar(scip, var) )
10811  continue;
10812 
10813  val = consdata->vals[i];
10814  obj = SCIPvarGetObj(var);
10815  lb = SCIPvarGetLbGlobal(var);
10816  ub = SCIPvarGetUbGlobal(var);
10817 
10818  /* lhs <= a_0 * x_0 + a_1 * x_1 + ... + a_{n-1} * x_{n-1} <= rhs
10819  *
10820  * a_i >= 0, c_i >= 0, lhs exists, nlocksdown(x_i) == 1:
10821  * - constraint is the only one that forbids fixing the variable to its lower bound
10822  * - 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
10823  *
10824  * a_i <= 0, c_i <= 0, lhs exists, nlocksup(x_i) == 1:
10825  * - constraint is the only one that forbids fixing the variable to its upper bound
10826  * - 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
10827  *
10828  * a_i >= 0, c_i <= 0, rhs exists, nlocksup(x_i) == 1:
10829  * - constraint is the only one that forbids fixing the variable to its upper bound
10830  * - 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
10831  *
10832  * a_i <= 0, c_i >= 0, rhs exists, nlocksdown(x_i) == 1:
10833  * - constraint is the only one that forbids fixing the variable to its lower bound
10834  * - 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
10835  *
10836  * but: all this is only applicable, if the aggregated value is inside x_i's bounds for all possible values
10837  * of all x_j
10838  * furthermore: we only want to apply this, if no fill-in will be produced
10839  */
10840  agglhs = lhsexists
10841  && ((val > 0.0 && !SCIPisNegative(scip, obj) && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == 1
10842  && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks)
10843  || (val < 0.0 && !SCIPisPositive(scip, obj) && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == 1
10844  && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks));
10845  aggrhs = rhsexists
10846  && ((val > 0.0 && !SCIPisPositive(scip, obj) && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == 1
10847  && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks)
10848  || (val < 0.0 && !SCIPisNegative(scip, obj) && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == 1
10849  && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) <= maxotherlocks));
10850  if( agglhs || aggrhs )
10851  {
10852  SCIP_Real minresactivity;
10853  SCIP_Real maxresactivity;
10854  SCIP_Real minval;
10855  SCIP_Real maxval;
10856  SCIP_Bool minisrelax;
10857  SCIP_Bool maxisrelax;
10858  SCIP_Bool isminsettoinfinity;
10859  SCIP_Bool ismaxsettoinfinity;
10860 
10861  /* calculate bounds for \sum_{j \neq i} a_j * x_j */
10862  consdataGetActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
10863  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
10864  assert(SCIPisLE(scip, minresactivity, maxresactivity));
10865 
10866  /* We called consdataGetActivityResiduals() saying that we do not need a good relaxation,
10867  * so whenever we have a relaxed activity, it should be relaxed to +/- infinity.
10868  * This is needed, because we do not want to rely on relaxed finite resactivities.
10869  */
10870  assert((!minisrelax || isminsettoinfinity) && (!maxisrelax || ismaxsettoinfinity));
10871 
10872  if( agglhs )
10873  {
10874  /* check if lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10875  calculateMinvalAndMaxval(scip, consdata->lhs, val, minresactivity, maxresactivity, &minval, &maxval);
10876 
10877  assert(SCIPisLE(scip, minval, maxval));
10878  if( (!SCIPisInfinity(scip, -minval) && SCIPisFeasGE(scip, minval, lb)) &&
10879  (!SCIPisInfinity(scip, maxval) && SCIPisFeasLE(scip, maxval, ub)) )
10880  {
10881  SCIP_Real oldmaxresactivity;
10882  SCIP_Real oldminresactivity;
10883  SCIP_Bool recalculated;
10884 
10885  recalculated = FALSE;
10886  oldmaxresactivity = maxresactivity;
10887  oldminresactivity = minresactivity;
10888 
10889  /* check minresactivity for reliability */
10890  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
10891  {
10892  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
10893  recalculated = !SCIPisEQ(scip, oldminresactivity, minresactivity);
10894  isminsettoinfinity = TRUE; /* here it means only that it was even calculated */
10895  }
10896 
10897  /* check maxresactivity for reliability */
10898  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
10899  {
10900  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
10901  recalculated = recalculated || !SCIPisEQ(scip, oldmaxresactivity, maxresactivity);
10902  ismaxsettoinfinity = TRUE; /* here it means only that it was even calculated */
10903  }
10904 
10905  /* minresactivity or maxresactivity wasn't reliable so recalculate min- and maxval*/
10906  if( recalculated )
10907  {
10908  assert(SCIPisLE(scip, minresactivity, maxresactivity));
10909 
10910  /* check again if lhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10911  calculateMinvalAndMaxval(scip, consdata->lhs, val, minresactivity, maxresactivity, &minval, &maxval);
10912 
10913  assert(SCIPisLE(scip, minval, maxval));
10914  }
10915 
10916  if( !recalculated || (SCIPisFeasGE(scip, minval, lb) && SCIPisFeasLE(scip, maxval, ub)) )
10917  {
10918  /* if the variable is integer, we have to check whether the integrality condition would always be satisfied
10919  * in the multi-aggregation
10920  */
10921  if( !isint || (SCIPisIntegral(scip, consdata->lhs/val) && consdataIsResidualIntegral(scip, consdata, i, val)) )
10922  {
10923  bestpos = i;
10924  bestisint = isint;
10925  bestislhs = TRUE;
10926  continue; /* no need to also look at the right hand side */
10927  }
10928  }
10929  }
10930  }
10931 
10932  if( aggrhs )
10933  {
10934  /* check if rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10935  calculateMinvalAndMaxval(scip, consdata->rhs, val, minresactivity, maxresactivity, &minval, &maxval);
10936 
10937  assert(SCIPisLE(scip,minval,maxval));
10938  if( (!SCIPisInfinity(scip, -minval) && SCIPisFeasGE(scip, minval, lb)) &&
10939  (!SCIPisInfinity(scip, maxval) && SCIPisFeasLE(scip, maxval, ub)) )
10940  {
10941  SCIP_Real oldmaxresactivity;
10942  SCIP_Real oldminresactivity;
10943  SCIP_Bool recalculated;
10944 
10945  recalculated = FALSE;
10946  oldmaxresactivity = maxresactivity;
10947  oldminresactivity = minresactivity;
10948 
10949  /* check minresactivity for reliability */
10950  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastminactivity) )
10951  {
10952  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, FALSE);
10953  recalculated = !SCIPisEQ(scip, oldminresactivity, minresactivity);
10954  }
10955 
10956  /* check maxresactivity for reliability */
10957  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastmaxactivity) )
10958  {
10959  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, FALSE);
10960  recalculated = recalculated || !SCIPisEQ(scip, oldmaxresactivity, maxresactivity);
10961  }
10962 
10963  /* minresactivity or maxresactivity wasn't reliable so recalculate min- and maxval*/
10964  if( recalculated )
10965  {
10966  /* check again if rhs/a_i - \sum_{j \neq i} a_j/a_i * x_j is always inside the bounds of x_i */
10967  calculateMinvalAndMaxval(scip, consdata->rhs, val, minresactivity, maxresactivity, &minval, &maxval);
10968  assert(SCIPisLE(scip,minval,maxval));
10969  }
10970 
10971  if( !recalculated || (SCIPisFeasGE(scip, minval, lb) && SCIPisFeasLE(scip, maxval, ub)) )
10972  {
10973  /* if the variable is integer, we have to check whether the integrality condition would always be satisfied
10974  * in the multi-aggregation
10975  */
10976  if( !isint || (SCIPisIntegral(scip, consdata->rhs/val) && consdataIsResidualIntegral(scip, consdata, i, val)) )
10977  {
10978  bestpos = i;
10979  bestisint = isint;
10980  bestislhs = FALSE;
10981  }
10982  }
10983  }
10984  }
10985  }
10986  }
10987 
10988  if( bestpos >= 0 )
10989  {
10990  SCIP_VAR** aggrvars;
10991  SCIP_Real* aggrcoefs;
10992  SCIP_Real aggrconst;
10993  SCIP_VAR* bestvar;
10994  SCIP_Real bestval;
10995  SCIP_Real epsilon;
10996  int naggrs;
10997  int j;
10998  SCIP_Bool infeasible;
10999  SCIP_Bool aggregated;
11000  SCIP_Bool samevar;
11001  int supinf; /* counter for infinite contributions to the supremum of a possible
11002  * multi-aggregation
11003  */
11004  int infinf; /* counter for infinite contributions to the infimum of a possible
11005  * multi-aggregation
11006  */
11007 
11008  assert(!bestislhs || lhsexists);
11009  assert(bestislhs || rhsexists);
11010 
11011  bestvar = consdata->vars[bestpos];
11012  bestval = consdata->vals[bestpos];
11013  assert(bestisint ==
11015 
11016  /* allocate temporary memory */
11017  SCIP_CALL( SCIPallocBufferArray(scip, &aggrvars, consdata->nvars-1) );
11018  SCIP_CALL( SCIPallocBufferArray(scip, &aggrcoefs, consdata->nvars-1) );
11019 
11020  /* set up the multi-aggregation */
11021  SCIPdebugPrintCons(scip, cons, NULL);
11022  SCIPdebugMsg(scip, "linear constraint <%s> (dual): multi-aggregate <%s> ==", SCIPconsGetName(cons), SCIPvarGetName(bestvar));
11023  naggrs = 0;
11024  supinf = 0;
11025  infinf = 0;
11026  samevar = FALSE;
11027  epsilon = SCIPepsilon(scip);
11028 
11029  for( j = 0; j < consdata->nvars; ++j )
11030  {
11031  if( j != bestpos )
11032  {
11033  SCIP_Real absaggrcoef;
11034 
11035  aggrvars[naggrs] = consdata->vars[j];
11036  aggrcoefs[naggrs] = -consdata->vals[j]/consdata->vals[bestpos];
11037  SCIPdebugMsgPrint(scip, " %+.15g<%s>", aggrcoefs[naggrs], SCIPvarGetName(aggrvars[naggrs]));
11038 
11039  absaggrcoef = REALABS(aggrcoefs[naggrs]);
11040 
11041  /* do not try to multi aggregate, when numerical bad */
11042  if( absaggrcoef < epsilon )
11043  {
11044  SCIPdebugMsg(scip, "do not perform multi-aggregation: too large aggregation coefficients\n");
11045 
11046  /* free temporary memory */
11047  SCIPfreeBufferArray(scip, &aggrcoefs);
11048  SCIPfreeBufferArray(scip, &aggrvars);
11049 
11050  return SCIP_OKAY;
11051  }
11052 
11053  if( bestisint )
11054  {
11055  /* coefficient must be integral: round it to exact integral value */
11056  assert(SCIPisIntegral(scip, aggrcoefs[naggrs]));
11057  aggrcoefs[naggrs] = SCIPfloor(scip, aggrcoefs[naggrs]+0.5);
11058  }
11059 
11060  if( SCIPisPositive(scip, aggrcoefs[naggrs]) )
11061  {
11062  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
11063  {
11064  ++supinf;
11065  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
11066  {
11067  ++infinf;
11068  samevar = TRUE;
11069  }
11070  }
11071  else if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
11072  ++infinf;
11073  }
11074  else if( SCIPisNegative(scip, aggrcoefs[naggrs]) )
11075  {
11076  if( SCIPisInfinity(scip, -SCIPvarGetLbGlobal(consdata->vars[j])) )
11077  {
11078  ++supinf;
11079  if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
11080  {
11081  ++infinf;
11082  samevar = TRUE;
11083  }
11084  }
11085  else if( SCIPisInfinity(scip, SCIPvarGetUbGlobal(consdata->vars[j])) )
11086  ++infinf;
11087  }
11088 
11089  naggrs++;
11090  }
11091  }
11092  assert(!samevar || (supinf > 0 && infinf > 0));
11093 
11094  aggrconst = (bestislhs ? consdata->lhs/bestval : consdata->rhs/bestval);
11095  SCIPdebugMsgPrint(scip, " %+.15g, bounds of <%s>: [%.15g,%.15g]\n", aggrconst, SCIPvarGetName(bestvar),
11096  SCIPvarGetLbGlobal(bestvar), SCIPvarGetUbGlobal(bestvar));
11097  assert(naggrs == consdata->nvars-1);
11098 
11099  /* right hand side must be integral: round it to exact integral value */
11100  if( bestisint )
11101  {
11102  assert(SCIPisIntegral(scip, aggrconst));
11103  aggrconst = SCIPfloor(scip, aggrconst+0.5);
11104  }
11105 
11106  aggregated = FALSE;
11107  infeasible = FALSE;
11108 
11109  /* perform the multi-aggregation */
11110  if( (samevar && supinf == 1 && infinf == 1) || (!samevar && (supinf == 0 || infinf == 0)) )
11111  {
11112  /* @todo if multi-aggregate makes them numerical trouble, avoid them if the coefficients differ to much, see
11113  * also convertLongEquality() early termination due to coefficients
11114  */
11115  SCIP_CALL( SCIPmultiaggregateVar(scip, bestvar, naggrs, aggrvars, aggrcoefs, aggrconst, &infeasible, &aggregated) );
11116 
11117  /** if the multi-aggregate bestvar is integer, we need to convert implicit integers to integers because
11118  * the implicitness might rely on the constraint and the integrality of bestvar
11119  */
11120  if( !infeasible && aggregated && SCIPvarGetType(bestvar) == SCIP_VARTYPE_INTEGER )
11121  {
11122  SCIP_Bool infeasiblevartypechg;
11123 
11124  for( j = 0; j < naggrs; ++j)
11125  {
11126  /** If the multi-aggregation was not infeasible, then setting implicit integers to integers should not
11127  * lead to infeasibility
11128  */
11129  if( SCIPvarGetType(aggrvars[j]) == SCIP_VARTYPE_IMPLINT )
11130  {
11131  SCIP_CALL( SCIPchgVarType(scip, aggrvars[j], SCIP_VARTYPE_INTEGER, &infeasiblevartypechg) );
11132  assert(!infeasiblevartypechg);
11133  }
11134  }
11135  }
11136  }
11137  else
11138  {
11139  /* If the infimum and the supremum of a multi-aggregation are both infinite, then the multi-aggregation might not be resolvable.
11140  * E.g., consider the equality z = x-y. If x and y are both fixed to +infinity, the value for z is not determined */
11141  SCIPdebugMsg(scip, "do not perform multi-aggregation: infimum and supremum are both infinite\n");
11142  }
11143  /* free temporary memory */
11144  SCIPfreeBufferArray(scip, &aggrcoefs);
11145  SCIPfreeBufferArray(scip, &aggrvars);
11146 
11147  /* check for infeasible aggregation */
11148  if( infeasible )
11149  {
11150  SCIPdebugMsg(scip, "linear constraint <%s>: infeasible multi-aggregation\n", SCIPconsGetName(cons));
11151  *cutoff = TRUE;
11152  return SCIP_OKAY;
11153  }
11154 
11155  /* delete the constraint, if the aggregation was successful */
11156  if( aggregated )
11157  {
11158  SCIP_CALL( SCIPdelCons(scip, cons) );
11159 
11160  if( !consdata->upgraded )
11161  (*ndelconss)++;
11162  (*naggrvars)++;
11163  }
11164  else
11165  {
11166  SCIPdebugMsg(scip, "aggregation non successful!\n");
11167  }
11168  }
11169 
11170  return SCIP_OKAY;
11171 }
11172 
11173 #define BINWEIGHT 1
11174 #define INTWEIGHT 4
11175 #define CONTWEIGHT 8
11176 
11177 /** gets weight for variable in a "weighted number of variables" sum */
11178 static
11179 int getVarWeight(
11180  SCIP_VAR* var /**< variable to get weight for */
11181  )
11182 {
11183  switch( SCIPvarGetType(var) )
11184  {
11185  case SCIP_VARTYPE_BINARY:
11186  return BINWEIGHT;
11187  case SCIP_VARTYPE_INTEGER:
11188  case SCIP_VARTYPE_IMPLINT:
11189  return INTWEIGHT;
11191  return CONTWEIGHT;
11192  default:
11193  SCIPerrorMessage("invalid variable type\n");
11195  return 0; /*lint !e527*/
11196  }
11197 }
11199 /** tries to aggregate variables in equations a^Tx = lhs
11200  * in case there are at most two binary variables with an odd coefficient and all other
11201  * variables are not continuous and have an even coefficient then:
11202  * - exactly one odd binary variables
11203  * this binary variables y can be fixed to 0 if the lhs is even and to 1 if the lhs is odd
11204  * - lhs is odd -> y = 1
11205  * - lhs is even -> y = 0
11206  * - exactly two odd binary variables
11207  * aggregate the two binary variables with odd coefficient
11208  * - lhs is odd -> exactly one of the variable has to be 1 -> var1 + var2 = 1
11209  * - lhs is even -> both have to take the same value -> var1 - var2 = 0
11210  */
11211 static
11213  SCIP* scip, /**< SCIP data structure */
11214  SCIP_CONS* cons, /**< linear constraint */
11215  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
11216  int* nfixedvars, /**< pointer to count number of fixed variables */
11217  int* naggrvars /**< pointer to count number of aggregated variables */
11218  )
11219 { /*lint --e{715}*/
11220  SCIP_CONSDATA* consdata;
11221  SCIP_Bool success;
11222 
11223  assert( scip != NULL );
11224  assert( cons != NULL );
11225 
11226  consdata = SCIPconsGetData(cons);
11227  assert( consdata != NULL );
11228 
11229  /* check if the linear constraint is an equation with integral right hand side */
11230  if( !SCIPisEQ(scip, consdata->lhs, consdata->rhs) || !SCIPisIntegral(scip, consdata->lhs) )
11231  return SCIP_OKAY;
11232 
11233  /* try to fix and aggregated variables until nothing is possible anymore */
11234  do
11235  {
11236  int v;
11237  int nvars;
11238  SCIP_VAR** vars;
11239  SCIP_Real* vals;
11240  SCIP_Real lhs;
11241  SCIP_Bool lhsodd;
11242 
11243  SCIP_Bool infeasible;
11244  SCIP_Bool fixed;
11245  SCIP_Bool aggregated;
11246  SCIP_Bool redundant;
11247 
11248  SCIP_VAR* var1;
11249  SCIP_VAR* var2;
11250  int noddvars;
11251 
11252  success = FALSE;
11253 
11254  lhs = consdata->lhs;
11255  vars = consdata->vars;
11256  vals = consdata->vals;
11257  nvars = consdata->nvars;
11258 
11259  assert( !SCIPisInfinity(scip, ABS(lhs)) );
11260 
11261  var1 = NULL;
11262  var2 = NULL;
11263  noddvars = 0;
11264 
11265  /* search for binary variables with an odd coefficient */
11266  for( v = 0; v < nvars && noddvars < 3; ++v )
11267  {
11268  SCIP_Longint val;
11269 
11270  /* all coefficients and variables have to be integral */
11271  if( !SCIPisIntegral(scip, vals[v]) || SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11272  return SCIP_OKAY;
11273 
11274  val = (SCIP_Longint)SCIPfeasFloor(scip, vals[v]);
11275  if( val % 2 != 0 )
11276  {
11277  /* the odd values have to belong to binary variables */
11278  if( !SCIPvarIsBinary(vars[v]) )
11279  return SCIP_OKAY;
11280 
11281  if( noddvars == 0 )
11282  var1 = vars[v];
11283  else
11284  var2 = vars[v];
11285 
11286  noddvars++;
11287  }
11288  }
11289 
11290  /* check lhs is odd or even */
11291  lhsodd = (((SCIP_Longint)SCIPfeasFloor(scip, lhs)) % 2 != 0);
11292 
11293  if( noddvars == 1 )
11294  {
11295  assert( var1 != NULL );
11296 
11297  SCIPdebugMsg(scip, "linear constraint <%s>: try fixing variable <%s> to <%g>\n",
11298  SCIPconsGetName(cons), SCIPvarGetName(var1), lhsodd ? 1.0 : 0.0);
11299 
11300  SCIP_CALL( SCIPfixVar(scip, var1, lhsodd? 1.0 : 0.0, &infeasible, &fixed) );
11301 
11302  /* check for infeasibility of fixing */
11303  if( infeasible )
11304  {
11305  SCIPdebugMsg(scip, " -> infeasible fixing\n");
11306  *cutoff = TRUE;
11307  return SCIP_OKAY;
11308  }
11309 
11310  if( fixed )
11311  {
11312  SCIPdebugMsg(scip, " -> feasible fixing\n");
11313  (*nfixedvars)++;
11314  success = TRUE;
11315  }
11316  }
11317  else if( noddvars == 2 )
11318  {
11319  assert( var1 != NULL );
11320  assert( var2 != NULL );
11321 
11322  /* aggregate the two variables with odd coefficient
11323  * - lhs is odd -> exactly one of the variable has to be 1 -> var1 + var2 = 1
11324  * - lhs is even -> both have to take the same value -> var1 - var2 = 0
11325  */
11326  SCIPdebugMsg(scip, "linear constraint <%s>: try aggregation of variables <%s> and <%s>\n",
11327  SCIPconsGetName(cons), SCIPvarGetName(var1), SCIPvarGetName(var2));
11328 
11329  SCIP_CALL( SCIPaggregateVars(scip, var1, var2, 1.0, lhsodd ? 1.0 : -1.0,
11330  lhsodd ? 1.0 : 0.0, &infeasible, &redundant, &aggregated) );
11331 
11332  /* check for infeasibility of aggregation */
11333  if( infeasible )
11334  {
11335  SCIPdebugMsg(scip, " -> infeasible aggregation\n");
11336  *cutoff = TRUE;
11337  return SCIP_OKAY;
11338  }
11339 
11340  /* count the aggregation */
11341  if( aggregated )
11342  {
11343  SCIPdebugMsg(scip, " -> feasible aggregation\n");
11344  (*naggrvars)++;
11345  success = TRUE;
11346  }
11347  }
11348 
11349  if( success )
11350  {
11351  /* apply fixings and aggregation to successfully rerun this presolving step */
11352  SCIP_CALL( applyFixings(scip, cons, &infeasible) );
11353 
11354  if( infeasible )
11355  {
11356  SCIPdebugMsg(scip, " -> infeasible fixing\n");
11357  *cutoff = TRUE;
11358  return SCIP_OKAY;
11359  }
11360 
11361  /* normalize constraint */
11362  SCIP_CALL( normalizeCons(scip, cons, &infeasible) );
11363 
11364  if( infeasible )
11365  {
11366  SCIPdebugMsg(scip, " -> infeasible normalization\n");
11367  *cutoff = TRUE;
11368  return SCIP_OKAY;
11369  }
11370  }
11371  }
11372  while( success );
11373 
11374  return SCIP_OKAY;
11375 }
11376 
11377 
11378 
11379 /** sorting method for constraint data, compares two variables on given indices, continuous variables will be sorted to
11380  * the end and for all other variables the sortation will be in non-increasing order of their absolute value of the
11381  * coefficients
11382  */
11383 static
11384 SCIP_DECL_SORTINDCOMP(consdataCompSim)
11385 { /*lint --e{715}*/
11386  SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
11387  SCIP_VARTYPE vartype1;
11388  SCIP_VARTYPE vartype2;
11389  SCIP_Real value;
11390 
11391  assert(consdata != NULL);
11392  assert(0 <= ind1 && ind1 < consdata->nvars);
11393  assert(0 <= ind2 && ind2 < consdata->nvars);
11394 
11395  vartype1 = SCIPvarGetType(consdata->vars[ind1]);
11396  vartype2 = SCIPvarGetType(consdata->vars[ind2]);
11397 
11398  if( vartype1 == SCIP_VARTYPE_CONTINUOUS )
11399  {
11400  /* continuous varibles will be sorted to the back */
11401  if( vartype2 != vartype1 )
11402  return +1;
11403  /* both variables are continuous */
11404  else
11405  return 0;
11406  }
11407  /* continuous variables will be sorted to the back */
11408  else if( vartype2 == SCIP_VARTYPE_CONTINUOUS )
11409  return -1;
11410 
11411  value = REALABS(consdata->vals[ind2]) - REALABS(consdata->vals[ind1]);
11412 
11413  /* for all non-continuous variables, the variables are sorted after decreasing absolute coefficients */
11414  return (value > 0 ? +1 : (value < 0 ? -1 : 0));
11415 }
11416 
11417 /** tries to simplify coefficients and delete variables in ranged row of the form lhs <= a^Tx <= rhs, e.g. using the greatest
11418  * common divisor
11419  *
11420  * 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
11421  * constraint to 1^Tx = 1
11422  */
11423 static
11425  SCIP* scip, /**< SCIP data structure */
11426  SCIP_CONS* cons, /**< linear constraint */
11427  int* nchgcoefs, /**< pointer to store the amount of changed coefficients */
11428  int* nchgsides /**< pointer to store the amount of changed sides */
11429  )
11430 {
11431  SCIP_CONSDATA* consdata;
11432  SCIP_VAR** vars;
11433  SCIP_Real* vals;
11434  SCIP_Real minval;
11435  SCIP_Real secondminval;
11436  SCIP_Real maxval;
11437  SCIP_Real lhs;
11438  SCIP_Real rhs;
11439  int nvars;
11440  int v;
11441 
11442  /* we must not change a modifiable constraint in any way */
11444  return SCIP_OKAY;
11445 
11446  if( SCIPconsIsDeleted(cons) )
11447  return SCIP_OKAY;
11448 
11449  consdata = SCIPconsGetData(cons);
11450  assert(consdata != NULL);
11451 
11452  nvars = consdata->nvars;
11453 
11454  /* do not check empty or bound-constraints */
11455  if( nvars < 2 )
11456  return SCIP_OKAY;
11457 
11458  vals = consdata->vals;
11459  vars = consdata->vars;
11460  assert(vars != NULL);
11461  assert(vals != NULL);
11462 
11463  lhs = consdata->lhs;
11464  rhs = consdata->rhs;
11465  assert(!SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs));
11466  assert(!SCIPisNegative(scip, rhs));
11467 
11468  minval = SCIP_INVALID;
11469  secondminval = SCIP_INVALID;
11470  maxval = -SCIP_INVALID;
11471 
11472  for( v = nvars - 1; v >= 0; --v )
11473  {
11474  if( SCIPvarIsBinary(vars[v]) )
11475  {
11476  if( minval > vals[v] || minval == SCIP_INVALID ) /*lint !e777*/
11477  {
11478  secondminval = minval;
11479  minval = vals[v];
11480  }
11481  else if( secondminval > vals[v] || secondminval == SCIP_INVALID ) /*lint !e777*/
11482  secondminval = vals[v];
11483 
11484  if( maxval < vals[v] || maxval == -SCIP_INVALID ) /*lint !e777*/
11485  maxval = vals[v];
11486  }
11487  else
11488  break;
11489  }
11490 
11491  /* check if all variables are binary */
11492  if( v == -1 )
11493  {
11494  if( SCIPisEQ(scip, minval, maxval) && SCIPisEQ(scip, lhs, rhs) )
11495  return SCIP_OKAY;
11496 
11497  /* check if we can and need to choose exactly one binary variable */
11498  if( SCIPisGE(scip, minval, lhs) && SCIPisLE(scip, maxval, rhs) && SCIPisGT(scip, minval + secondminval, rhs) )
11499  {
11500  /* change all coefficients to 1.0 */
11501  for( v = nvars - 1; v >= 0; --v )
11502  {
11503  SCIP_CALL( chgCoefPos(scip, cons, v, 1.0) );
11504  }
11505  (*nchgcoefs) += nvars;
11506 
11507  /* replace old right and left hand side with 1.0 */
11508  SCIP_CALL( chgRhs(scip, cons, 1.0) );
11509  SCIP_CALL( chgLhs(scip, cons, 1.0) );
11510  (*nchgsides) += 2;
11511  }
11512  }
11513 
11514  return SCIP_OKAY;
11515 }
11516 
11517 /** tries to simplify coefficients and delete variables in constraints of the form lhs <= a^Tx <= rhs
11518  * for equations @see rangedRowSimplify() will be called
11519  *
11520  * there are several different coefficient reduction steps which will be applied
11521  *
11522  * 1. We try to determine parts of the constraint which will not change anything on (in-)feasibility of the constraint
11523  *
11524  * e.g. 5x1 + 5x2 + 3z1 <= 8 => 3z1 is redundant if all x are binary and -2 < 3z1 <= 3
11525  *
11526  * 2. We try to remove redundant fractional parts in a constraint
11527  *
11528  * e.g. 5.2x1 + 5.1x2 + 3x3 <= 8.3 => will be changed to 5x1 + 5x2 + 3x3 <= 8 if all x are binary
11529  *
11530  * 3. We are using the greatest common divisor for further reductions
11531  *
11532  * e.g. 10x1 + 5y2 + 5x3 + 3x4 <= 15 => will be changed to 2x1 + y2 + x3 + x4 <= 3 if all xi are binary and y2 is
11533  * integral
11534  */
11535 static
11537  SCIP* scip, /**< SCIP data structure */
11538  SCIP_CONS* cons, /**< linear constraint */
11539  int* nchgcoefs, /**< pointer to store the amount of changed coefficients */
11540  int* nchgsides, /**< pointer to store the amount of changed sides */
11541  SCIP_Bool* infeasible /**< pointer to store whether infeasibility was detected */
11542  )
11543 {
11544  SCIP_CONSDATA* consdata;
11545  SCIP_VAR** vars;
11546  SCIP_Real* vals;
11547  int* perm;
11548  SCIP_Real minactsub;
11549  SCIP_Real maxactsub;
11550  SCIP_Real siderest;
11551  SCIP_Real feastol;
11552  SCIP_Real newcoef;
11553  SCIP_Real absval;
11554  SCIP_Real minact;
11555  SCIP_Real maxact;
11556  SCIP_Real side;
11557  SCIP_Real lhs;
11558  SCIP_Real rhs;
11559  SCIP_Real lb;
11560  SCIP_Real ub;
11561  SCIP_Longint restcoef;
11562  SCIP_Longint oldgcd;
11563  SCIP_Longint rest;
11564  SCIP_Longint gcd;
11565  SCIP_Bool isminsettoinfinity;
11566  SCIP_Bool ismaxsettoinfinity;
11567  SCIP_Bool isminrelax;
11568  SCIP_Bool ismaxrelax;
11569  SCIP_Bool allcoefintegral;
11570  SCIP_Bool onlybin;
11571  SCIP_Bool hasrhs;
11572  SCIP_Bool haslhs;
11573  int oldnchgcoefs;
11574  int oldnchgsides;
11575  int foundbin;
11576  int candpos;
11577  int candpos2;
11578  int offsetv;
11579  int nvars;
11580  int v;
11581  int w;
11582 
11583  assert(scip != NULL);
11584  assert(cons != NULL);
11585  assert(nchgcoefs != NULL);
11586  assert(nchgsides != NULL);
11587 
11588  *infeasible = FALSE;
11589 
11590  /* we must not change a modifiable constraint in any way */
11591  if( SCIPconsIsModifiable(cons) )
11592  return SCIP_OKAY;
11593 
11594  if( SCIPconsIsDeleted(cons) )
11595  return SCIP_OKAY;
11596 
11597  consdata = SCIPconsGetData(cons);
11598  assert(consdata != NULL);
11599 
11600  nvars = consdata->nvars;
11601 
11602  /* do not check empty or bound-constraints */
11603  if( nvars <= 2 )
11604  return SCIP_OKAY;
11605 
11606  /* update maximal activity delta if necessary */
11607  if( consdata->maxactdelta == SCIP_INVALID ) /*lint !e777*/
11608  consdataRecomputeMaxActivityDelta(scip, consdata);
11609 
11610  assert(consdata->maxactdelta != SCIP_INVALID); /*lint !e777*/
11611  assert(!SCIPisFeasNegative(scip, consdata->maxactdelta));
11612  checkMaxActivityDelta(scip, consdata);
11613 
11614  /* @todo the following might be too hard, check which steps can be applied and what code must be corrected
11615  * accordingly
11616  */
11617  /* can only work with valid non-infinity activities per variable */
11618  if( SCIPisInfinity(scip, consdata->maxactdelta) )
11619  return SCIP_OKAY;
11620 
11621  /* @todo: change the following: due to vartype changes, the status of the normalization can be wrong, need an event
11622  * but the eventsystem seems to be full
11623  */
11624  consdata->normalized = FALSE;
11625 
11626  /* normalize constraint */
11627  SCIP_CALL( normalizeCons(scip, cons, infeasible) );
11628  assert(nvars == consdata->nvars);
11629 
11630  if( *infeasible )
11631  return SCIP_OKAY;
11632 
11633  if( !consdata->normalized )
11634  return SCIP_OKAY;
11635 
11636  lhs = consdata->lhs;
11637  rhs = consdata->rhs;
11638  assert(!SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs));
11639  assert(!SCIPisNegative(scip, rhs));
11640 
11641  if( !SCIPisInfinity(scip, -lhs) )
11642  haslhs = TRUE;
11643  else
11644  haslhs = FALSE;
11645 
11646  if( !SCIPisInfinity(scip, rhs) )
11647  hasrhs = TRUE;
11648  else
11649  hasrhs = FALSE;
11650 
11651  SCIPdebug( oldnchgcoefs = *nchgcoefs; )
11652  SCIPdebug( oldnchgsides = *nchgsides; )
11653 
11654  /* @todo also work on ranged rows */
11655  if( haslhs && hasrhs )
11656  {
11657  SCIP_CALL( rangedRowSimplify(scip, cons, nchgcoefs, nchgsides ) );
11658 
11659  return SCIP_OKAY;
11660  }
11661  assert(haslhs != hasrhs);
11662 
11663  /* if we have a normalized inequality (not ranged) the one side should be positive, @see normalizeCons() */
11664  assert(!hasrhs || !SCIPisNegative(scip, rhs));
11665  assert(!haslhs || !SCIPisNegative(scip, lhs));
11666 
11667  /* get temporary memory to store the sorted permutation */
11668  SCIP_CALL( SCIPallocBufferArray(scip, &perm, nvars) );
11669 
11670  /* call sorting method, order continuous variables to the end and all other variables after non-increasing absolute
11671  * value of their coefficients
11672  */
11673  SCIPsort(perm, consdataCompSim, (void*)consdata, nvars);
11674 
11675  /* perform sorting after permutation array */
11676  permSortConsdata(consdata, perm, nvars);
11677  consdata->indexsorted = FALSE;
11678  consdata->coefsorted = FALSE;
11679 
11680  vars = consdata->vars;
11681  vals = consdata->vals;
11682  assert(vars != NULL);
11683  assert(vals != NULL);
11684  assert(consdata->validmaxabsval ? (SCIPisFeasEQ(scip, consdata->maxabsval, REALABS(vals[0])) || SCIPvarGetType(vars[nvars - 1]) == SCIP_VARTYPE_CONTINUOUS) : TRUE);
11685 
11686  /* free temporary memory */
11687  SCIPfreeBufferArray(scip, &perm);
11688 
11689  /* only check constraints with at least two non continuous variables */
11690  if( SCIPvarGetType(vars[1]) == SCIP_VARTYPE_CONTINUOUS )
11691  return SCIP_OKAY;
11692 
11693  /* do not process constraints when all coefficients are 1.0 */
11694  if( SCIPisEQ(scip, REALABS(vals[0]), 1.0) && ((hasrhs && SCIPisIntegral(scip, rhs)) || (haslhs && SCIPisIntegral(scip, lhs))) )
11695  return SCIP_OKAY;
11696 
11697  feastol = SCIPfeastol(scip);
11698 
11699  SCIPdebugMsg(scip, "starting simplification of coefficients\n");
11700  SCIPdebugPrintCons(scip, cons, NULL);
11701 
11702  /* get global activities */
11703  consdataGetGlbActivityBounds(scip, consdata, FALSE, &minact, &maxact,
11704  &isminrelax, &ismaxrelax, &isminsettoinfinity, &ismaxsettoinfinity);
11705 
11706  /* cannot work with infinite activities */
11707  if( isminsettoinfinity || ismaxsettoinfinity )
11708  return SCIP_OKAY;
11709 
11710  assert(!isminrelax);
11711  assert(!ismaxrelax);
11712  assert(maxact > minact);
11713  assert(!SCIPisInfinity(scip, -minact));
11714  assert(!SCIPisInfinity(scip, maxact));
11715 
11716  v = 0;
11717  offsetv = -1;
11718  side = haslhs ? lhs : rhs;
11719  minactsub = minact;
11720  maxactsub = maxact;
11721 
11722  /* we now determine coefficients as large as the side of the constraint to retrieve a better reduction where we
11723  * do not need to look at the large coefficients
11724  *
11725  * e.g. all x are binary, z are positive integer
11726  * c1: +5x1 + 5x2 + 3x3 + 3x4 + x5 >= 5 (x5 is redundant and does not change (in-)feasibility of this constraint)
11727  * c2: +4x1 + 4x2 + 3x3 + 3x4 + x5 >= 4 (gcd (without the coefficient of x5) after the large coefficients is 3
11728  * c3: +30x1 + 29x2 + 14x3 + 14z1 + 7x5 + 7x6 <= 30 (gcd (without the coefficient of x2) after the large coefficients is 7
11729  *
11730  * can be changed to
11731  *
11732  * c1: +6x1 + 6x2 + 3x3 + 3x4 >= 6 (will be changed to c1: +2x1 + 2x2 + x3 + x4 >= 2)
11733  * c2: +6x1 + 6x2 + 3x3 + 3x4 + 3x5 >= 6 (will be changed to c2: +2x1 + 2x2 + x3 + x4 + x5 >= 2)
11734  * c3: +28x1 + 28x2 + 14x3 + 14z1 + 7x5 + 7x6 <= 28 (will be changed to c3: +4x1 + 4x2 + 2x3 + 2z1 + x5 + x6 <= 4)
11735  */
11736 
11737  /* if the minimal activity is negative and we found more than one variable with a coefficient bigger than the left
11738  * hand side, we cannot apply the extra reduction step and need to reset v
11739  *
11740  * 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
11741  * coefficients due to the gcd on the "small" coefficients we would get 8x1 + 8x2 - 4x3 - 4x4 >= 8 were xi = 1
11742  * for all i is a solution
11743  *
11744  * also redundancy of variables would not be correctly determined in such a case
11745  */
11746  if( nvars > 2 && SCIPisEQ(scip, vals[0], side) && !SCIPisNegative(scip, minactsub) )
11747  {
11748  v = 1;
11749 
11750  while( v < nvars && SCIPisEQ(scip, side, vals[v]) )
11751  {
11752  /* if we have integer variable with "side"-coefficients but also with a lower bound greater than 0 we stop this
11753  * extra step, which might have worked
11754  */
11755  if( SCIPvarGetLbGlobal(vars[v]) > 0.5 )
11756  {
11757  v = 0;
11758  break;
11759  }
11760 
11761  ++v;
11762  }
11763 
11764  /* easy and quick fix: if all coefficients were equal to the side, we cannot apply further simplifications */
11765  /* todo find numerically stable normalization conditions to scale this cons to have coefficients almost equal to 1 */
11766  if( v == nvars )
11767  return SCIP_OKAY;
11768 
11769  /* cannot work with continuous variables which have a big coefficient */
11770  if( v > 0 && SCIPvarGetType(vars[v - 1]) == SCIP_VARTYPE_CONTINUOUS )
11771  return SCIP_OKAY;
11772 
11773  /* big negative coefficient, do not try to use the extra coefficient reduction step */
11774  if( SCIPisEQ(scip, side, -vals[v]) )
11775  v = 0;
11776 
11777  /* all but one variable are processed or the next variable is continuous we cannot perform the extra coefficient
11778  * reduction
11779  */
11780  if( v == nvars - 1 || SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11781  v = 0;
11782 
11783  if( v > 0 )
11784  {
11785  assert(v < nvars);
11786 
11787  offsetv = v - 1;
11788 
11789  for( w = 0; w < v; ++w )
11790  {
11791  lb = SCIPvarGetLbGlobal(vars[w]);
11792  ub = SCIPvarGetUbGlobal(vars[w]);
11793 
11794  assert(vals[w] > 0);
11795 
11796  /* update residual activities */
11797  maxactsub -= ub * vals[w];
11798  minactsub -= lb * vals[w];
11799  assert(maxactsub > minactsub);
11800  }
11801  }
11802  }
11803 
11804  /* find and remove redundant variables which do not interact with the (in-)feasibility of this constraint
11805  *
11806  * e.g. let all x are binary and y1 is continuous with bounds [-3,1] then we can reduce
11807  *
11808  * 15x1 + 15x2 + 7x3 + 3x4 + y1 <= 26
11809  * to
11810  * 15x1 + 15x2 <= 26 <=> x1 + x2 <= 1
11811  */
11812  if( nvars > 2 && SCIPisIntegral(scip, vals[v]) )
11813  {
11814  SCIP_Bool redundant = FALSE;
11815  SCIP_Bool numericsok;
11816  SCIP_Bool rredundant;
11817  SCIP_Bool lredundant;
11818 
11819 
11820  gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
11821  assert(gcd >= 1);
11822 
11823  if( v == 0 )
11824  {
11825  lb = SCIPvarGetLbGlobal(vars[0]);
11826  ub = SCIPvarGetUbGlobal(vars[0]);
11827 
11828  /* update residual activities */
11829  if( vals[0] > 0 )
11830  {
11831  maxactsub -= ub * vals[0];
11832  minactsub -= lb * vals[0];
11833  }
11834  else
11835  {
11836  maxactsub -= lb * vals[0];
11837  minactsub -= ub * vals[0];
11838  }
11839  assert(maxactsub > minactsub);
11840  ++v;
11841  }
11842 
11843  siderest = -SCIP_INVALID;
11844  allcoefintegral = TRUE;
11845 
11846  /* check if some variables always fit into the given constraint */
11847  for( ; v < nvars - 1; ++v )
11848  {
11849  if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
11850  break;
11851 
11852  if( !SCIPisIntegral(scip, vals[v]) )
11853  {
11854  allcoefintegral = FALSE;
11855  break;
11856  }
11857 
11858  /* calculate greatest common divisor for all general and binary variables */
11859  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
11860 
11861  if( gcd == 1 )
11862  break;
11863 
11864  lb = SCIPvarGetLbGlobal(vars[v]);
11865  ub = SCIPvarGetUbGlobal(vars[v]);
11866 
11867  assert(!SCIPisInfinity(scip, -lb));
11868  assert(!SCIPisInfinity(scip, ub));
11869 
11870  /* update residual activities */
11871  if( vals[v] > 0 )
11872  {
11873  maxactsub -= ub * vals[v];
11874  minactsub -= lb * vals[v];
11875  }
11876  else
11877  {
11878  maxactsub -= lb * vals[v];
11879  minactsub -= ub * vals[v];
11880  }
11881  assert(SCIPisGE(scip, maxactsub, minactsub));
11882 
11883  if( hasrhs )
11884  {
11885  /* determine the remainder of the right hand side and the gcd */
11886  siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11887  }
11888  else
11889  {
11890  /* determine the remainder of the left hand side and the gcd */
11891  siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11892  if( SCIPisZero(scip, siderest) )
11893  siderest = gcd;
11894  }
11895 
11896  rredundant = hasrhs && maxactsub <= siderest && SCIPisGT(scip, minactsub, siderest - gcd);
11897  lredundant = haslhs && SCIPisLT(scip, maxactsub, siderest) && minactsub >= siderest - gcd;
11898 
11899  /* early termination if the activities deceed the gcd */
11900  if( offsetv == -1 && (rredundant || lredundant) )
11901  {
11902  redundant = TRUE;
11903  break;
11904  }
11905  }
11906  assert(v < nvars || (offsetv >= 0 && gcd > 1));
11907 
11908  if( !redundant )
11909  {
11910  if( hasrhs )
11911  {
11912  /* determine the remainder of the right hand side and the gcd */
11913  siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11914  }
11915  else
11916  {
11917  /* determine the remainder of the left hand side and the gcd */
11918  siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11919  if( SCIPisZero(scip, siderest) )
11920  siderest = gcd;
11921  }
11922  }
11923  else
11924  ++v;
11925 
11926  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",
11927  v, nvars, minactsub, maxactsub, redundant, hasrhs, siderest, gcd, offsetv);
11928 
11929  /* to avoid inconsistencies due to numerics, check that the full and partial activities have
11930  * reasonable absolute values */
11931  numericsok = REALABS(maxact) < MAXACTVAL && REALABS(maxactsub) < MAXACTVAL && REALABS(minact) < MAXACTVAL &&
11932  REALABS(minactsub) < MAXACTVAL;
11933 
11934  rredundant = hasrhs && maxactsub <= siderest && SCIPisGT(scip, minactsub, siderest - gcd);
11935  lredundant = haslhs && SCIPisLT(scip, maxactsub, siderest) && minactsub >= siderest - gcd;
11936 
11937  /* check if we can remove redundant variables */
11938  if( v < nvars && numericsok && (redundant || (offsetv == -1 && (rredundant || lredundant))) )
11939  {
11940  SCIP_Real oldcoef;
11941 
11942  /* double check the redundancy */
11943 #ifndef NDEBUG
11944  SCIP_Real tmpminactsub = 0.0;
11945  SCIP_Real tmpmaxactsub = 0.0;
11946 
11947  /* recompute residual activities */
11948  for( w = v; w < nvars; ++w )
11949  {
11950  lb = SCIPvarGetLbGlobal(vars[w]);
11951  ub = SCIPvarGetUbGlobal(vars[w]);
11952 
11953  assert(!SCIPisInfinity(scip, -lb));
11954  assert(!SCIPisInfinity(scip, ub));
11955 
11956  /* update residual activities */
11957  if( vals[w] > 0 )
11958  {
11959  tmpmaxactsub += ub * vals[w];
11960  tmpminactsub += lb * vals[w];
11961  }
11962  else
11963  {
11964  tmpmaxactsub += lb * vals[w];
11965  tmpminactsub += ub * vals[w];
11966  }
11967  assert(tmpmaxactsub >= tmpminactsub);
11968  }
11969 
11970  if( hasrhs )
11971  {
11972  assert(offsetv == -1);
11973 
11974  /* determine the remainder of the right hand side and the gcd */
11975  siderest = rhs - SCIPfeasFloor(scip, rhs/gcd) * gcd;
11976  }
11977  else
11978  {
11979  /* determine the remainder of the left hand side and the gcd */
11980  siderest = lhs - SCIPfeasFloor(scip, lhs/gcd) * gcd;
11981  if( SCIPisZero(scip, siderest) )
11982  siderest = gcd;
11983  }
11984 
11985  /* is the redundancy really fulfilled */
11986  assert((hasrhs && SCIPisLE(scip, tmpmaxactsub, siderest) && tmpminactsub > siderest - gcd) ||
11987  (haslhs && tmpmaxactsub < siderest && SCIPisGE(scip, tmpminactsub, siderest - gcd)));
11988 #endif
11989 
11990  SCIPdebugMsg(scip, "removing %d last variables from constraint <%s>, because they never change anything on the feasibility of this constraint\n",
11991  nvars - v, SCIPconsGetName(cons));
11992 
11993  /* remove redundant variables */
11994  for( w = nvars - 1; w >= v; --w )
11995  {
11996  SCIP_CALL( delCoefPos(scip, cons, w) );
11997  }
11998  (*nchgcoefs) += (nvars - v);
11999 
12000  assert(w >= 0);
12001 
12002  oldcoef = vals[w];
12003 
12004  /* normalize constraint */
12005  SCIP_CALL( normalizeCons(scip, cons, infeasible) );
12006  assert(vars == consdata->vars);
12007  assert(vals == consdata->vals);
12008  assert(w < consdata->nvars);
12009 
12010  if( *infeasible )
12011  return SCIP_OKAY;
12012 
12013  /* compute new greatest common divisor due to normalization */
12014  gcd = (SCIP_Longint)(gcd / (oldcoef/vals[w]) + feastol);
12015  assert(gcd >= 1);
12016 
12017  /* update side */
12018  if( hasrhs )
12019  {
12020  /* replace old with new right hand side */
12021  SCIP_CALL( chgRhs(scip, cons, SCIPfeasFloor(scip, consdata->rhs)) );
12022  rhs = consdata->rhs;
12023  }
12024  else
12025  {
12026  if( SCIPisFeasGT(scip, oldcoef/vals[w], 1.0) )
12027  {
12028  SCIP_CALL( chgLhs(scip, cons, SCIPfeasCeil(scip, consdata->lhs)) );
12029  lhs = consdata->lhs;
12030  }
12031  else
12032  assert(offsetv == -1 || SCIPisEQ(scip, vals[offsetv], consdata->lhs));
12033  }
12034  ++(*nchgsides);
12035 
12036  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12037  assert(!haslhs || !SCIPisNegative(scip, lhs));
12038 
12039  /* get new constraint data */
12040  nvars = consdata->nvars;
12041  assert(nvars > 0);
12042 
12043  allcoefintegral = TRUE;
12044 
12045 #ifndef NDEBUG
12046  /* check integrality */
12047  for( w = offsetv + 1; w < nvars; ++w )
12048  {
12049  assert(SCIPisIntegral(scip, vals[w]));
12050  }
12051 #endif
12052  SCIPdebugPrintCons(scip, cons, NULL);
12053  }
12054 
12055  /* try to find a better gcd, when having large coefficients */
12056  if( offsetv >= 0 && gcd == 1 )
12057  {
12058  /* calculate greatest common divisor for all general variables */
12059  gcd = (SCIP_Longint)(REALABS(vals[nvars - 1]) + feastol);
12060 
12061  if( gcd > 1 )
12062  {
12063  gcd = -1;
12064  candpos = -1;
12065 
12066  for( v = nvars - 1; v > offsetv; --v )
12067  {
12068  assert(!SCIPisZero(scip, vals[v]));
12069  if( SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS )
12070  break;
12071 
12072  if( !SCIPisIntegral(scip, vals[v]) )
12073  {
12074  allcoefintegral = FALSE;
12075  break;
12076  }
12077 
12078  oldgcd = gcd;
12079 
12080  if( gcd == -1 )
12081  {
12082  gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
12083  assert(gcd >= 1);
12084  }
12085  else
12086  {
12087  /* calculate greatest common divisor for all general and binary variables */
12088  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
12089  }
12090 
12091  /* if the greatest commmon divisor has become 1, we might have found the possible coefficient to change or we
12092  * can stop searching
12093  */
12094  if( gcd == 1 )
12095  {
12096  if( !SCIPvarIsBinary(vars[v]) )
12097  break;
12098 
12099  /* found candidate */
12100  if( candpos == -1 )
12101  {
12102  gcd = oldgcd;
12103  candpos = v;
12104  }
12105  /* two different binary variables lead to a gcd of one, so we cannot change a coefficient */
12106  else
12107  break;
12108  }
12109  }
12110  assert(v > offsetv || candpos > offsetv);
12111  }
12112  else
12113  candpos = -1;
12114  }
12115  else
12116  candpos = nvars - 1;
12117 
12118  /* check last coefficient for integrality */
12119  if( gcd > 1 && allcoefintegral && !redundant )
12120  {
12121  if( !SCIPisIntegral(scip, vals[nvars - 1]) )
12122  allcoefintegral = FALSE;
12123  }
12124 
12125  /* check for further necessary coefficient adjustments */
12126  if( offsetv >= 0 && gcd > 1 && allcoefintegral )
12127  {
12128  assert(offsetv + 1 < nvars);
12129  assert(0 <= candpos && candpos < nvars);
12130 
12131  if( SCIPvarGetType(vars[candpos]) != SCIP_VARTYPE_CONTINUOUS )
12132  {
12133  SCIP_Bool notchangable = FALSE;
12134 
12135 #ifndef NDEBUG
12136  /* check integrality */
12137  for( w = offsetv + 1; w < nvars; ++w )
12138  {
12139  assert(SCIPisIntegral(scip, vals[w]));
12140  }
12141 #endif
12142 
12143  if( vals[candpos] > 0 && SCIPvarIsBinary(vars[candpos]) &&
12144  SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) < gcd )
12145  {
12146  /* determine the remainder of the side and the gcd */
12147  if( hasrhs )
12148  rest = ((SCIP_Longint)(rhs + feastol)) % gcd;
12149  else
12150  rest = ((SCIP_Longint)(lhs + feastol)) % gcd;
12151  assert(rest >= 0);
12152  assert(rest < gcd);
12153 
12154  /* determine the remainder of the coefficient candidate and the gcd */
12155  restcoef = ((SCIP_Longint)(vals[candpos] + feastol)) % gcd;
12156  assert(restcoef >= 1);
12157  assert(restcoef < gcd);
12158 
12159  if( hasrhs )
12160  {
12161  /* calculate new coefficient */
12162  if( restcoef > rest )
12163  newcoef = vals[candpos] - restcoef + gcd;
12164  else
12165  newcoef = vals[candpos] - restcoef;
12166  }
12167  else
12168  {
12169  /* calculate new coefficient */
12170  if( rest == 0 || restcoef < rest )
12171  newcoef = vals[candpos] - restcoef;
12172  else
12173  newcoef = vals[candpos] - restcoef + gcd;
12174  }
12175 
12176  /* done */
12177 
12178  /* new coeffcient must not be zero if we would loose the implication that a variable needs to be 0 if
12179  * another with the big coefficient was set to 1
12180  */
12181  if( hasrhs && SCIPisZero(scip, newcoef) )
12182  {
12183  notchangable = TRUE;
12184  }
12185  else if( SCIPisZero(scip, newcoef) )
12186  {
12187  /* delete old redundant coefficient */
12188  SCIP_CALL( delCoefPos(scip, cons, candpos) );
12189  ++(*nchgcoefs);
12190  }
12191  else
12192  {
12193  /* replace old with new coefficient */
12194  SCIP_CALL( chgCoefPos(scip, cons, candpos, newcoef) );
12195  ++(*nchgcoefs);
12196  }
12197  }
12198  else if( vals[candpos] < 0 || !SCIPvarIsBinary(vars[candpos]) )
12199  {
12200  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol));
12201  }
12202 
12203  /* correct side and big coefficients */
12204  if( (!notchangable && hasrhs && ((!SCIPisFeasIntegral(scip, rhs) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(rhs + feastol)) < gcd) && (SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) == gcd))) ||
12205  ( haslhs && (!SCIPisFeasIntegral(scip, lhs) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(lhs + feastol)) < gcd) && (SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[candpos]) + feastol)) == gcd)) )
12206  {
12207  if( haslhs )
12208  {
12209  newcoef = (SCIP_Real)((SCIP_Longint)(SCIPfeasCeil(scip, lhs/gcd) * gcd + feastol));
12210 
12211  SCIP_CALL( chgLhs(scip, cons, newcoef) );
12212  ++(*nchgsides);
12213  }
12214  else
12215  {
12216  assert(hasrhs);
12217  newcoef = (SCIP_Real)((SCIP_Longint)(SCIPfeasFloor(scip, rhs/gcd) * gcd + feastol));
12218 
12219  SCIP_CALL( chgRhs(scip, cons, newcoef) );
12220  ++(*nchgsides);
12221  }
12222 
12223  /* correct coefficients up front */
12224  for( w = offsetv; w >= 0; --w )
12225  {
12226  assert(vals[w] > 0);
12227 
12228  SCIP_CALL( chgCoefPos(scip, cons, w, newcoef) );
12229  }
12230  (*nchgcoefs) += (offsetv + 1);
12231  }
12232 
12233  if( !notchangable )
12234  {
12235  /* normalize constraint */
12236  SCIP_CALL( normalizeCons(scip, cons, infeasible) );
12237  assert(vars == consdata->vars);
12238  assert(vals == consdata->vals);
12239 
12240  if( *infeasible )
12241  return SCIP_OKAY;
12242 
12243  /* get new constraint data */
12244  nvars = consdata->nvars;
12245  assert(nvars >= 2);
12246 
12247  SCIPdebugPrintCons(scip, cons, NULL);
12248 
12249  lhs = consdata->lhs;
12250  rhs = consdata->rhs;
12251  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12252  assert(!haslhs || !SCIPisNegative(scip, lhs));
12253  }
12254  }
12255  }
12256  }
12257 
12258  /* @todo we still can remove continuous variables if they are redundant due to the non-integrality argument */
12259  /* no continuous variables are left over */
12260  if( SCIPvarGetType(vars[nvars - 1]) == SCIP_VARTYPE_CONTINUOUS )
12261  return SCIP_OKAY;
12262 
12263  onlybin = TRUE;
12264  allcoefintegral = TRUE;
12265  /* check if all variables are of binary type */
12266  for( v = nvars - 1; v >= 0; --v )
12267  {
12268  if( !SCIPvarIsBinary(vars[v]) )
12269  onlybin = FALSE;
12270  if( !SCIPisIntegral(scip, vals[v]) )
12271  allcoefintegral = FALSE;
12272  }
12273 
12274  /* check if the non-integrality part of all integral variables is smaller than the non-inegrality part of the right
12275  * hand side or bigger than the left hand side respectively, so we can make all of them integral
12276  *
12277  * @todo there are some steps missing ....
12278  */
12279  if( (hasrhs && !SCIPisFeasIntegral(scip, rhs)) || (haslhs && !SCIPisFeasIntegral(scip, lhs)) )
12280  {
12281  SCIP_Real val;
12282  SCIP_Real newval;
12283  SCIP_Real frac = 0.0;
12284  SCIP_Bool found = FALSE;
12285 
12286  if( hasrhs )
12287  {
12288  if( allcoefintegral )
12289  {
12290  /* replace old with new right hand side */
12291  SCIP_CALL( chgRhs(scip, cons, SCIPfloor(scip, rhs)) );
12292  ++(*nchgsides);
12293  }
12294  else
12295  {
12296  siderest = rhs - SCIPfloor(scip, rhs);
12297 
12298  /* try to round down all non-integral coefficients */
12299  for( v = nvars - 1; v >= 0; --v )
12300  {
12301  val = vals[v];
12302 
12303  /* add up all possible fractional parts */
12304  if( !SCIPisIntegral(scip, val) )
12305  {
12306  lb = SCIPvarGetLbGlobal(vars[v]);
12307  ub = SCIPvarGetUbGlobal(vars[v]);
12308 
12309  /* at least one bound need to be at zero */
12310  if( !onlybin && !SCIPisFeasZero(scip, lb) && !SCIPisFeasZero(scip, ub) )
12311  return SCIP_OKAY;
12312 
12313  /* swap bounds for 'standard' form */
12314  if( !SCIPisFeasZero(scip, lb) )
12315  {
12316  ub = lb;
12317  val *= -1;
12318  }
12319 
12320  found = TRUE;
12321 
12322  frac += (val - SCIPfloor(scip, val)) * ub;
12323 
12324  /* if we exceed the fractional part of the right hand side, we cannot tighten the coefficients
12325  *
12326  * e.g. 1.1x1 + 1.1x2 + 1.4x3 + 1.02x4 <= 2.4, here we cannot floor all fractionals because
12327  * x3, x4 set to 1 would be infeasible but feasible after flooring
12328  */
12329  if( SCIPisGT(scip, frac, siderest) )
12330  return SCIP_OKAY;
12331  }
12332  }
12333  assert(v == -1);
12334 
12335  SCIPdebugMsg(scip, "rounding all non-integral coefficients and the right hand side down\n");
12336 
12337  /* round rhs and coefficients to integral values */
12338  if( found )
12339  {
12340  for( v = nvars - 1; v >= 0; --v )
12341  {
12342  val = vals[v];
12343 
12344  /* add the whole fractional part */
12345  if( !SCIPisIntegral(scip, val) )
12346  {
12347  lb = SCIPvarGetLbGlobal(vars[v]);
12348 
12349  if( SCIPisFeasZero(scip, lb) )
12350  newval = SCIPfloor(scip, val);
12351  else
12352  newval = SCIPceil(scip, val);
12353 
12354  if( SCIPisZero(scip, newval) )
12355  {
12356  /* delete old redundant coefficient */
12357  SCIP_CALL( delCoefPos(scip, cons, v) );
12358  ++(*nchgcoefs);
12359  }
12360  else
12361  {
12362  /* replace old with new coefficient */
12363  SCIP_CALL( chgCoefPos(scip, cons, v, newval) );
12364  ++(*nchgcoefs);
12365  }
12366  }
12367  }
12368  }
12369 
12370  /* replace old with new right hand side */
12371  SCIP_CALL( chgRhs(scip, cons, SCIPfloor(scip, rhs)) );
12372  ++(*nchgsides);
12373  }
12374  }
12375  else
12376  {
12377  if( allcoefintegral )
12378  {
12379  /* replace old with new left hand side */
12380  SCIP_CALL( chgLhs(scip, cons, SCIPceil(scip, lhs)) );
12381  ++(*nchgsides);
12382  }
12383  else
12384  {
12385  /* cannot floor left hand side to zero */
12386  if( SCIPisLT(scip, lhs, 1.0) )
12387  return SCIP_OKAY;
12388 
12389  siderest = lhs - SCIPfloor(scip, lhs);
12390 
12391  /* try to round down all non-integral coefficients */
12392  for( v = nvars - 1; v >= 0; --v )
12393  {
12394  val = vals[v];
12395 
12396  /* add up all possible fractional parts */
12397  if( !SCIPisIntegral(scip, val) )
12398  {
12399  lb = SCIPvarGetLbGlobal(vars[v]);
12400  ub = SCIPvarGetUbGlobal(vars[v]);
12401 
12402  /* at least one bound need to be at zero */
12403  if( !SCIPisFeasZero(scip, lb) && !SCIPisFeasZero(scip, ub) )
12404  return SCIP_OKAY;
12405 
12406  /* swap bounds for 'standard' form */
12407  if( !SCIPisFeasZero(scip, lb) )
12408  {
12409  ub = lb;
12410  val *= -1;
12411  }
12412 
12413  /* cannot floor to zero */
12414  if( SCIPisLT(scip, val, 1.0) )
12415  return SCIP_OKAY;
12416 
12417  /* the fractional part on each variable need to exceed the fractional part on the left hand side */
12418  if( SCIPisLT(scip, val - SCIPfloor(scip, val), siderest) )
12419  return SCIP_OKAY;
12420 
12421  found = TRUE;
12422 
12423  frac += (val - SCIPfloor(scip, val)) * ub;
12424 
12425  /* if we exceed the fractional part of the left hand side plus one by summing up all maximal
12426  * fractional parts of the variables, we cannot tighten the coefficients
12427  *
12428  * e.g. 4.3x1 + 1.3x2 + 1.3x3 + 1.6x4 >= 4.2, here we cannot floor all fractionals because
12429  * x2-x4 set to 1 would be feasible but not after flooring
12430  */
12431  if( SCIPisGE(scip, frac, 1 + siderest) )
12432  return SCIP_OKAY;
12433  }
12434  /* all coefficients need to be integral, otherwise we might do an invalid reduction */
12435  else
12436  return SCIP_OKAY;
12437  }
12438  assert(v == -1);
12439 
12440  SCIPdebugMsg(scip, "rounding all non-integral coefficients and the left hand side down\n");
12441 
12442  /* round lhs and coefficients to integral values */
12443  if( found )
12444  {
12445  for( v = nvars - 1; v >= 0; --v )
12446  {
12447  val = vals[v];
12448 
12449  /* add the whole fractional part */
12450  if( !SCIPisIntegral(scip, val) )
12451  {
12452  lb = SCIPvarGetLbGlobal(vars[v]);
12453 
12454  if( SCIPisFeasZero(scip, lb) )
12455  newval = SCIPfloor(scip, val);
12456  else
12457  newval = SCIPceil(scip, val);
12458 
12459  if( SCIPisZero(scip, newval) )
12460  {
12461  /* delete old redundant coefficient */
12462  SCIP_CALL( delCoefPos(scip, cons, v) );
12463  ++(*nchgcoefs);
12464  }
12465  else
12466  {
12467  /* replace old with new coefficient */
12468  SCIP_CALL( chgCoefPos(scip, cons, v, newval) );
12469  ++(*nchgcoefs);
12470  }
12471  }
12472  }
12473  }
12474 
12475  /* replace old with new left hand side */
12476  SCIP_CALL( chgLhs(scip, cons, SCIPfloor(scip, lhs)) );
12477  ++(*nchgsides);
12478  }
12479  }
12480 
12481  /* normalize constraint */
12482  SCIP_CALL( normalizeCons(scip, cons, infeasible) );
12483  assert(vars == consdata->vars);
12484  assert(vals == consdata->vals);
12485 
12486  if( *infeasible )
12487  return SCIP_OKAY;
12488 
12489  rhs = consdata->rhs;
12490  lhs = consdata->lhs;
12491 
12492  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12493  assert(!haslhs || !SCIPisNegative(scip, lhs));
12494 
12495  SCIPdebugPrintCons(scip, cons, NULL);
12496 
12497  nvars = consdata->nvars;
12498  if( nvars < 2 )
12499  return SCIP_OKAY;
12500 
12501  allcoefintegral = TRUE;
12502 #ifndef NDEBUG
12503  /* debug check if all coefficients are really integral */
12504  for( v = nvars - 1; v >= 0; --v )
12505  assert(SCIPisIntegral(scip, vals[v]));
12506 #endif
12507  }
12508 
12509  /* @todo following can also work on non integral coefficients, need more investigation */
12510  /* only check constraints with integral coefficients on all integral variables */
12511  if( !allcoefintegral )
12512  return SCIP_OKAY;
12513 
12514  /* we want to avoid numerical troubles, therefore we do not change non-integral sides */
12515  if( (hasrhs && !SCIPisIntegral(scip, rhs)) || (haslhs && !SCIPisIntegral(scip, lhs)) )
12516  return SCIP_OKAY;
12517 
12518  /* maximal absolute value of coefficients in constraint is one, so we cannot tighten it further */
12519  if( SCIPisEQ(scip, REALABS(vals[0]), 1.0) )
12520  return SCIP_OKAY;
12521 
12522  /* stop if the last coeffcients is one in absolute value and the variable is not binary */
12523  if( !SCIPvarIsBinary(vars[nvars - 1]) && SCIPisEQ(scip, REALABS(vals[nvars - 1]), 1.0) )
12524  return SCIP_OKAY;
12525 
12526  assert(nvars >= 2);
12527 
12528  /* start gcd procedure for all variables */
12529  do
12530  {
12531  SCIPdebug( oldnchgcoefs = *nchgcoefs; )
12532  SCIPdebug( oldnchgsides = *nchgsides; )
12533 
12534  /* stop if we have two coeffcients which are one in absolute value */
12535  if( SCIPisEQ(scip, REALABS(vals[nvars - 1]), 1.0) && SCIPisEQ(scip, REALABS(vals[nvars - 2]), 1.0) )
12536  return SCIP_OKAY;
12537 
12538  gcd = -1;
12539 
12540  /* calculate greatest common divisor over all integer variables; note that the onlybin flag needs to be recomputed
12541  * because coefficients of non-binary variables might have changed to zero */
12542  if( !onlybin )
12543  {
12544  foundbin = -1;
12545  onlybin = TRUE;
12546 
12547  for( v = nvars - 1; v >= 0; --v )
12548  {
12549  assert(!SCIPisZero(scip, vals[v]));
12550  assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_CONTINUOUS);
12551 
12552  if( SCIPvarIsBinary(vars[v]) )
12553  {
12554  if( foundbin == -1 )
12555  foundbin = v;
12556  continue;
12557  }
12558  else
12559  onlybin = FALSE;
12560 
12561  absval = REALABS(vals[v]);
12562  /* arithmetic precision can lead to the absolute value only being integral up to feasibility tolerance,
12563  * even though the value itself is feasible up to epsilon, but since we add feastol later, this is enough
12564  */
12565  assert(SCIPisFeasIntegral(scip, absval));
12566 
12567  if( gcd == -1 )
12568  {
12569  gcd = (SCIP_Longint)(absval + feastol);
12570  assert(gcd >= 1);
12571  }
12572  else
12573  {
12574  /* calculate greatest common divisor for all general variables */
12575  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(absval + feastol));
12576  }
12577  if( gcd == 1 )
12578  break;
12579  }
12580  }
12581  else
12582  foundbin = nvars - 1;
12583 
12584  /* we need at least one binary variable and a gcd greater than 1 to try to perform further coefficient changes */
12585  if( gcd == 1 || foundbin == -1)
12586  return SCIP_OKAY;
12587 
12588  assert((onlybin && gcd == -1) || (!onlybin && gcd > 1));
12589 
12590  candpos = -1;
12591  candpos2 = -1;
12592 
12593  /* calculate greatest common divisor over all integer and binary variables and determine the candidate where we might
12594  * change the coefficient
12595  */
12596  for( v = foundbin; v >= 0; --v )
12597  {
12598  if( onlybin || SCIPvarIsBinary(vars[v]) )
12599  {
12600  absval = REALABS(vals[v]);
12601  /* arithmetic precision can lead to the absolute value only being integral up to feasibility tolerance,
12602  * even though the value itself is feasible up to epsilon, but since we add feastol later, this is enough
12603  */
12604  assert(SCIPisFeasIntegral(scip, absval));
12605 
12606  oldgcd = gcd;
12607 
12608  if( gcd == -1 )
12609  {
12610  gcd = (SCIP_Longint)(REALABS(vals[v]) + feastol);
12611  assert(gcd >= 1);
12612  }
12613  else
12614  {
12615  /* calculate greatest common divisor for all general and binary variables */
12616  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
12617  }
12618 
12619  /* if the greatest commmon divisor has become 1, we might have found the possible coefficient to change or we
12620  * can terminate
12621  */
12622  if( gcd == 1 )
12623  {
12624  /* found candidate */
12625  if( candpos == -1 )
12626  {
12627  gcd = oldgcd;
12628  candpos = v;
12629 
12630  /* if we have only binary variables and both first coefficients have a gcd of 1, both are candidates for
12631  * the coefficient change
12632  */
12633  if( onlybin && v == foundbin - 1 )
12634  candpos2 = foundbin;
12635  }
12636  /* two different binary variables lead to a gcd of one, so we cannot change a coefficient */
12637  else
12638  {
12639  if( onlybin && candpos == v + 1 && candpos2 == v + 2 )
12640  {
12641  assert(candpos2 == nvars - 1);
12642 
12643  /* take new candidates */
12644  candpos = candpos2;
12645 
12646  /* recalculate gcd from scratch */
12647  gcd = (SCIP_Longint)(REALABS(vals[v+1]) + feastol);
12648  assert(gcd >= 1);
12649 
12650  /* calculate greatest common divisor for all general and binary variables */
12651  gcd = SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(vals[v]) + feastol));
12652  if( gcd == 1 )
12653  return SCIP_OKAY;
12654  }
12655  else
12656  /* cannot determine a possible coefficient for reduction */
12657  return SCIP_OKAY;
12658  }
12659  }
12660  }
12661  }
12662  assert(gcd >= 2);
12663 
12664  /* we should have found one coefficient, that led to a gcd of 1, otherwise we could normalize the constraint
12665  * further
12666  */
12667  assert(candpos >= 0 && candpos < nvars);
12668 
12669  /* all variables and all coefficients are integral, so the side should be too */
12670  assert((hasrhs && SCIPisIntegral(scip, rhs)) || (haslhs && SCIPisIntegral(scip, lhs)));
12671 
12672  /* check again, if we have a normalized inequality (not ranged) the one side should be positive,
12673  * @see normalizeCons()
12674  */
12675  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12676  assert(!haslhs || !SCIPisNegative(scip, lhs));
12677 
12678  /* determine the remainder of the side and the gcd */
12679  if( hasrhs )
12680  rest = ((SCIP_Longint)(rhs + feastol)) % gcd;
12681  else
12682  rest = ((SCIP_Longint)(lhs + feastol)) % gcd;
12683  assert(rest >= 0);
12684  assert(rest < gcd);
12685 
12686  /* determine the remainder of the coefficient candidate and the gcd */
12687  if( vals[candpos] < 0 )
12688  {
12689  restcoef = ((SCIP_Longint)(vals[candpos] - feastol)) % gcd;
12690  assert(restcoef <= -1);
12691  restcoef += gcd;
12692  }
12693  else
12694  restcoef = ((SCIP_Longint)(vals[candpos] + feastol)) % gcd;
12695  assert(restcoef >= 1);
12696  assert(restcoef < gcd);
12697 
12698  if( hasrhs )
12699  {
12700  if( rest > 0 )
12701  {
12702  /* replace old with new right hand side */
12703  SCIP_CALL( chgRhs(scip, cons, rhs - rest) );
12704  ++(*nchgsides);
12705  }
12706 
12707  /* calculate new coefficient */
12708  if( restcoef > rest )
12709  newcoef = vals[candpos] - restcoef + gcd;
12710  else
12711  newcoef = vals[candpos] - restcoef;
12712  }
12713  else
12714  {
12715  if( rest > 0 )
12716  {
12717  /* replace old with new left hand side */
12718  SCIP_CALL( chgLhs(scip, cons, lhs - rest + gcd) );
12719  ++(*nchgsides);
12720  }
12721 
12722  /* calculate new coefficient */
12723  if( rest == 0 || restcoef < rest )
12724  newcoef = vals[candpos] - restcoef;
12725  else
12726  newcoef = vals[candpos] - restcoef + gcd;
12727  }
12728  assert(SCIPisZero(scip, newcoef) || SCIPcalcGreComDiv(gcd, (SCIP_Longint)(REALABS(newcoef) + feastol)) == gcd);
12729 
12730  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));
12731 
12732  if( SCIPisZero(scip, newcoef) )
12733  {
12734  /* delete redundant coefficient */
12735  SCIP_CALL( delCoefPos(scip, cons, candpos) );
12736  }
12737  else
12738  {
12739  /* replace old with new coefficient */
12740  SCIP_CALL( chgCoefPos(scip, cons, candpos, newcoef) );
12741  }
12742  ++(*nchgcoefs);
12743 
12744  /* now constraint can be normalized, might be directly done by dividing it by the gcd */
12745  SCIP_CALL( normalizeCons(scip, cons, infeasible) );
12746  assert(vars == consdata->vars);
12747  assert(vals == consdata->vals);
12748 
12749  if( *infeasible )
12750  return SCIP_OKAY;
12751 
12752  SCIPdebugPrintCons(scip, cons, NULL);
12753 
12754  rhs = consdata->rhs;
12755  lhs = consdata->lhs;
12756  assert(!hasrhs || !SCIPisNegative(scip, rhs));
12757  assert(!haslhs || !SCIPisNegative(scip, lhs));
12758 
12759  nvars = consdata->nvars;
12760 
12761  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));
12762  }
12763  while( nvars >= 2 );
12764 
12765  return SCIP_OKAY;
12766 }
12767 
12768 
12769 /** tries to aggregate an (in)equality and an equality in order to decrease the number of variables in the (in)equality:
12770  * cons0 := a * cons0 + b * cons1,
12771  * where a = val1[v] and b = -val0[v] for common variable v which removes most variable weight;
12772  * for numerical stability, we will only accept integral a and b;
12773  * the variable weight is a weighted sum over all included variables, where each binary variable weighs BINWEIGHT,
12774  * each integer or implicit integer variable weighs INTWEIGHT and each continuous variable weighs CONTWEIGHT
12775  */
12776 static
12778  SCIP* scip, /**< SCIP data structure */
12779  SCIP_CONS* cons0, /**< (in)equality to modify */
12780  SCIP_CONS* cons1, /**< equality to use for aggregation of cons0 */
12781  int* commonidx0, /**< array with indices of variables in cons0, that appear also in cons1 */
12782  int* commonidx1, /**< array with indices of variables in cons1, that appear also in cons0 */
12783  int* diffidx0minus1, /**< array with indices of variables in cons0, that don't appear in cons1 */
12784  int* diffidx1minus0, /**< array with indices of variables in cons1, that don't appear in cons0 */
12785  int nvarscommon, /**< number of variables, that appear in both constraints */
12786  int commonidxweight, /**< variable weight sum of common variables */
12787  int diffidx0minus1weight, /**< variable weight sum of variables in cons0, that don't appear in cons1 */
12788  int diffidx1minus0weight, /**< variable weight sum of variables in cons1, that don't appear in cons0 */
12789  SCIP_Real maxaggrnormscale, /**< maximal allowed relative gain in maximum norm for constraint aggregation */
12790  int* nchgcoefs, /**< pointer to count the number of changed coefficients */
12791  SCIP_Bool* aggregated, /**< pointer to store whether an aggregation was made */
12792  SCIP_Bool* infeasible /**< pointer to store whether infeasibility was detected */
12793  )
12794 {
12795  SCIP_CONSDATA* consdata0;
12796  SCIP_CONSDATA* consdata1;
12797  SCIP_Real a;
12798  SCIP_Real b;
12799  SCIP_Real aggrcoef;
12800  SCIP_Real scalarsum;
12801  SCIP_Real bestscalarsum;
12802  SCIP_Bool betterscalarsum;
12803  SCIP_Bool commonvarlindependent; /* indicates whether coefficient vector of common variables in linearly dependent */
12804  int varweight;
12805  int nvars;
12806  int bestvarweight;
12807  int bestnvars;
12808  int bestv;
12809  int v;
12810  int i;
12811 
12812  assert(scip != NULL);
12813  assert(cons0 != NULL);
12814  assert(cons1 != NULL);
12815  assert(commonidx0 != NULL);
12816  assert(commonidx1 != NULL);
12817  assert(diffidx0minus1 != NULL);
12818  assert(diffidx1minus0 != NULL);
12819  assert(nvarscommon >= 1);
12820  assert(commonidxweight >= nvarscommon);
12821  assert(nchgcoefs != NULL);
12822  assert(aggregated != NULL);
12823 
12824  assert(SCIPconsIsActive(cons0));
12825  assert(SCIPconsIsActive(cons1));
12826 
12827  *infeasible = FALSE;
12828 
12829  SCIPdebugMsg(scip, "try aggregation of <%s> and <%s>\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
12830 
12831  /* cons0 is an (in)equality */
12832  consdata0 = SCIPconsGetData(cons0);
12833  assert(consdata0 != NULL);
12834  assert(consdata0->nvars >= 1);
12835  assert(SCIPisLE(scip, consdata0->lhs, consdata0->rhs));
12836  assert(diffidx0minus1weight >= consdata0->nvars - nvarscommon);
12837 
12838  /* cons1 is an equality */
12839  consdata1 = SCIPconsGetData(cons1);
12840  assert(consdata1 != NULL);
12841  assert(consdata1->nvars >= 1);
12842  assert(SCIPisEQ(scip, consdata1->lhs, consdata1->rhs));
12843  assert(diffidx1minus0weight >= consdata1->nvars - nvarscommon);
12844 
12845  *aggregated = FALSE;
12846 
12847  /* search for the best common variable such that
12848  * val1[var] * consdata0 - val0[var] * consdata1
12849  * has least weighted number of variables
12850  */
12851  bestvarweight = commonidxweight + diffidx0minus1weight;
12852  bestnvars = consdata0->nvars;
12853  bestv = -1;
12854  bestscalarsum = 0.0;
12855  commonvarlindependent = TRUE;
12856  for( v = 0; v < nvarscommon; ++v )
12857  {
12858  assert(consdata0->vars[commonidx0[v]] == consdata1->vars[commonidx1[v]]);
12859  a = consdata1->vals[commonidx1[v]];
12860  b = -consdata0->vals[commonidx0[v]];
12861 
12862  /* only try aggregation, if coefficients are integral (numerical stability) */
12863  if( SCIPisIntegral(scip, a) && SCIPisIntegral(scip, b) )
12864  {
12865  /* count the number of variables in the potential new constraint a * consdata0 + b * consdata1 */
12866  varweight = diffidx0minus1weight + diffidx1minus0weight;
12867  nvars = consdata0->nvars + consdata1->nvars - 2*nvarscommon;
12868  scalarsum = REALABS(a) + REALABS(b);
12869  betterscalarsum = (scalarsum < bestscalarsum);
12870  for( i = 0; i < nvarscommon
12871  && (varweight < bestvarweight || (varweight == bestvarweight && betterscalarsum)); ++i )
12872  {
12873  aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
12874  if( !SCIPisZero(scip, aggrcoef) )
12875  {
12876  varweight += getVarWeight(consdata0->vars[commonidx0[i]]);
12877  nvars++;
12878  }
12879  }
12880  if( varweight < bestvarweight || (varweight == bestvarweight && betterscalarsum) )
12881  {
12882  bestv = v;
12883  bestvarweight = varweight;
12884  bestnvars = nvars;
12885  bestscalarsum = scalarsum;
12886  }
12887  }
12888 
12889  /* update commonvarlindependent flag, if still TRUE:
12890  * 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
12891  */
12892  if( commonvarlindependent && v > 0 )
12893  commonvarlindependent = SCIPisEQ(scip,
12894  consdata1->vals[commonidx1[v]] * consdata0->vals[commonidx0[0]],
12895  consdata1->vals[commonidx1[0]] * consdata0->vals[commonidx0[v]]);
12896  }
12897 
12898  /* if better aggregation was found, create new constraint and delete old one */
12899  if( (bestv != -1 || commonvarlindependent) && SCIPconsGetNUpgradeLocks(cons0) == 0 )
12900  {
12901  SCIP_CONS* newcons;
12902  SCIP_CONSDATA* newconsdata;
12903  SCIP_VAR** newvars;
12904  SCIP_Real* newvals;
12905  SCIP_Real newlhs;
12906  SCIP_Real newrhs;
12907  int newnvars;
12908 
12909  if( bestv != -1 )
12910  {
12911  /* choose multipliers such that the multiplier for the (in)equality cons0 is positive */
12912  if( consdata1->vals[commonidx1[bestv]] > 0.0 )
12913  {
12914  a = consdata1->vals[commonidx1[bestv]];
12915  b = -consdata0->vals[commonidx0[bestv]];
12916  }
12917  else
12918  {
12919  a = -consdata1->vals[commonidx1[bestv]];
12920  b = consdata0->vals[commonidx0[bestv]];
12921  }
12922  assert(SCIPisIntegral(scip, a));
12923  assert(SCIPisPositive(scip, a));
12924  assert(SCIPisIntegral(scip, b));
12925  assert(!SCIPisZero(scip, b));
12926  }
12927  else
12928  {
12929  assert(commonvarlindependent);
12930  if( consdata1->vals[commonidx1[0]] > 0.0 )
12931  {
12932  a = consdata1->vals[commonidx1[0]];
12933  b = -consdata0->vals[commonidx0[0]];
12934  }
12935  else
12936  {
12937  a = -consdata1->vals[commonidx1[0]];
12938  b = consdata0->vals[commonidx0[0]];
12939  }
12940  assert(SCIPisPositive(scip, a));
12941  assert(!SCIPisZero(scip, b));
12942 
12943  /* if a/b is integral, then we can easily choose integer multipliers */
12944  if( SCIPisIntegral(scip, a/b) )
12945  {
12946  if( a/b > 0 )
12947  {
12948  a /= b;
12949  b = 1.0;
12950  }
12951  else
12952  {
12953  a /= -b;
12954  b = -1.0;
12955  }
12956  }
12957 
12958  /* setup best* variables that were not setup above because we are in the commonvarlindependent case */
12959  SCIPdebug( bestvarweight = diffidx0minus1weight + diffidx1minus0weight; )
12960  bestnvars = consdata0->nvars + consdata1->nvars - 2*nvarscommon;
12961  }
12962 
12963  SCIPdebugMsg(scip, "aggregate linear constraints <%s> := %.15g*<%s> + %.15g*<%s> -> nvars: %d -> %d, weight: %d -> %d\n",
12964  SCIPconsGetName(cons0), a, SCIPconsGetName(cons0), b, SCIPconsGetName(cons1),
12965  consdata0->nvars, bestnvars, commonidxweight + diffidx0minus1weight, bestvarweight);
12966  SCIPdebugPrintCons(scip, cons0, NULL);
12967  SCIPdebugPrintCons(scip, cons1, NULL);
12968 
12969  /* get temporary memory for creating the new linear constraint */
12970  SCIP_CALL( SCIPallocBufferArray(scip, &newvars, bestnvars) );
12971  SCIP_CALL( SCIPallocBufferArray(scip, &newvals, bestnvars) );
12972 
12973  /* calculate the common coefficients, if we have not recognized linear dependency */
12974  newnvars = 0;
12975  if( !commonvarlindependent )
12976  {
12977  for( i = 0; i < nvarscommon; ++i )
12978  {
12979  assert(0 <= commonidx0[i] && commonidx0[i] < consdata0->nvars);
12980  assert(0 <= commonidx1[i] && commonidx1[i] < consdata1->nvars);
12981 
12982  aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
12983  if( !SCIPisZero(scip, aggrcoef) )
12984  {
12985  assert(newnvars < bestnvars);
12986  newvars[newnvars] = consdata0->vars[commonidx0[i]];
12987  newvals[newnvars] = aggrcoef;
12988  newnvars++;
12989  }
12990  }
12991  }
12992  else
12993  {
12994  /* if we recognized linear dependency of the common coefficients, then the aggregation coefficient should be 0.0 for every common variable */
12995 #ifndef NDEBUG
12996  for( i = 0; i < nvarscommon; ++i )
12997  {
12998  assert(0 <= commonidx0[i] && commonidx0[i] < consdata0->nvars);
12999  assert(0 <= commonidx1[i] && commonidx1[i] < consdata1->nvars);
13000 
13001  aggrcoef = a * consdata0->vals[commonidx0[i]] + b * consdata1->vals[commonidx1[i]];
13002  assert(SCIPisZero(scip, aggrcoef));
13003  }
13004 #endif
13005  }
13006 
13007  /* calculate the coefficients appearing in cons0 but not in cons1 */
13008  for( i = 0; i < consdata0->nvars - nvarscommon; ++i )
13009  {
13010  assert(0 <= diffidx0minus1[i] && diffidx0minus1[i] < consdata0->nvars);
13011 
13012  aggrcoef = a * consdata0->vals[diffidx0minus1[i]];
13013  assert(!SCIPisZero(scip, aggrcoef));
13014  assert(newnvars < bestnvars);
13015  newvars[newnvars] = consdata0->vars[diffidx0minus1[i]];
13016  newvals[newnvars] = aggrcoef;
13017  newnvars++;
13018  }
13019 
13020  /* calculate the coefficients appearing in cons1 but not in cons0 */
13021  for( i = 0; i < consdata1->nvars - nvarscommon; ++i )
13022  {
13023  assert(0 <= diffidx1minus0[i] && diffidx1minus0[i] < consdata1->nvars);
13024 
13025  aggrcoef = b * consdata1->vals[diffidx1minus0[i]];
13026  assert(!SCIPisZero(scip, aggrcoef));
13027  assert(newnvars < bestnvars);
13028  newvars[newnvars] = consdata1->vars[diffidx1minus0[i]];
13029  newvals[newnvars] = aggrcoef;
13030  newnvars++;
13031  }
13032  assert(newnvars == bestnvars);
13033 
13034  /* calculate the new left and right hand side of the (in)equality */
13035  assert(!SCIPisInfinity(scip, -consdata1->lhs));
13036  assert(!SCIPisInfinity(scip, consdata1->rhs));
13037  if( SCIPisInfinity(scip, -consdata0->lhs) )
13038  newlhs = -SCIPinfinity(scip);
13039  else
13040  newlhs = a * consdata0->lhs + b * consdata1->lhs;
13041  if( SCIPisInfinity(scip, consdata0->rhs) )
13042  newrhs = SCIPinfinity(scip);
13043  else
13044  newrhs = a * consdata0->rhs + b * consdata1->rhs;
13045 
13046  /* create the new linear constraint */
13047  SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, SCIPconsGetName(cons0), newnvars, newvars, newvals, newlhs, newrhs,
13049  SCIPconsIsChecked(cons0), SCIPconsIsPropagated(cons0),
13050  SCIPconsIsLocal(cons0), SCIPconsIsModifiable(cons0),
13052 
13053  newconsdata = SCIPconsGetData(newcons);
13054  assert(newconsdata != NULL);
13055 
13056  /* copy the upgraded flag from the old cons0 to the new constraint */
13057  newconsdata->upgraded = consdata0->upgraded;
13058 
13059  /* normalize the new constraint */
13060  SCIP_CALL( normalizeCons(scip, newcons, infeasible) );
13061 
13062  if( *infeasible )
13063  goto TERMINATE;
13064 
13065  /* check, if we really want to use the new constraint instead of the old one:
13066  * use the new one, if the maximum norm doesn't grow too much
13067  */
13068  if( consdataGetMaxAbsval(SCIPconsGetData(newcons)) <= maxaggrnormscale * consdataGetMaxAbsval(consdata0) )
13069  {
13070  SCIPdebugMsg(scip, " -> aggregated to <%s>\n", SCIPconsGetName(newcons));
13071  SCIPdebugPrintCons(scip, newcons, NULL);
13072 
13073  /* update the statistics: we changed all coefficients */
13074  if( !consdata0->upgraded )
13075  (*nchgcoefs) += consdata0->nvars + consdata1->nvars - nvarscommon;
13076  *aggregated = TRUE;
13077 
13078  /* delete the old constraint, and add the new linear constraint to the problem */
13079  SCIP_CALL( SCIPdelCons(scip, cons0) );
13080  SCIP_CALL( SCIPaddCons(scip, newcons) );
13081  }
13082 
13083  TERMINATE:
13084  /* release the new constraint */
13085  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
13086 
13087  /* free temporary memory */
13088  SCIPfreeBufferArray(scip, &newvals);
13089  SCIPfreeBufferArray(scip, &newvars);
13090  }
13091 
13092  return SCIP_OKAY;
13093 }
13094 
13095 /** gets the key of the given element */
13096 static
13097 SCIP_DECL_HASHGETKEY(hashGetKeyLinearcons)
13098 { /*lint --e{715}*/
13099  /* the key is the element itself */
13100  return elem;
13101 }
13102 
13103 /** returns TRUE iff both keys are equal; two constraints are equal if they have the same variables and the
13104  * coefficients are either equal or negated
13105  */
13106 static
13107 SCIP_DECL_HASHKEYEQ(hashKeyEqLinearcons)
13108 {
13109  SCIP* scip;
13110  SCIP_CONSDATA* consdata1;
13111  SCIP_CONSDATA* consdata2;
13112  SCIP_Real cons1scale;
13113  SCIP_Real cons2scale;
13114  int i;
13115 
13116  assert(key1 != NULL);
13117  assert(key2 != NULL);
13118  consdata1 = SCIPconsGetData((SCIP_CONS*)key1);
13119  consdata2 = SCIPconsGetData((SCIP_CONS*)key2);
13120  assert(consdata1->indexsorted);
13121  assert(consdata2->indexsorted);
13122 
13123  scip = (SCIP*)userptr;
13124  assert(scip != NULL);
13125 
13126  /* if it is the same constraint we dont need to check anything */
13127  if( key1 == key2 )
13128  return TRUE;
13129 
13130  /* checks trivial case */
13131  if( consdata1->nvars != consdata2->nvars )
13132  return FALSE;
13133 
13134  /* tests if variables are equal */
13135  for( i = 0; i < consdata1->nvars; ++i )
13136  {
13137  if( consdata1->vars[i] != consdata2->vars[i] )
13138  {
13139  assert(SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == 1 ||
13140  SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == -1);
13141  return FALSE;
13142  }
13143  assert(SCIPvarCompare(consdata1->vars[i], consdata2->vars[i]) == 0);
13144  }
13145 
13146  /* compute scale before comparing coefficients of constraints */
13147  cons1scale = COPYSIGN(1.0/consdata1->maxabsval, consdata1->vals[0]);
13148  cons2scale = COPYSIGN(1.0/consdata2->maxabsval, consdata2->vals[0]);
13149 
13150  /* tests if coefficients are equal with the computed scale */
13151  for( i = 0; i < consdata1->nvars; ++i )
13152  {
13153  SCIP_Real val1;
13154  SCIP_Real val2;
13155 
13156  val1 = consdata1->vals[i] * cons1scale;
13157  val2 = consdata2->vals[i] * cons2scale;
13158 
13159  if( !SCIPisEQ(scip, val1, val2) )
13160  return FALSE;
13161  }
13162 
13163  return TRUE;
13164 }
13165 
13166 /** returns the hash value of the key */
13167 static
13168 SCIP_DECL_HASHKEYVAL(hashKeyValLinearcons)
13169 {
13170  SCIP_CONSDATA* consdata;
13171  int minidx;
13172  int mididx;
13173  int maxidx;
13174  SCIP_Real scale;
13175 #ifndef NDEBUG
13176  SCIP* scip;
13177 
13178  scip = (SCIP*)userptr;
13179  assert(scip != NULL);
13180 #endif
13181 
13182  assert(key != NULL);
13183  consdata = SCIPconsGetData((SCIP_CONS*)key);
13184  assert(consdata != NULL);
13185  assert(consdata->nvars > 0);
13186 
13187  assert(consdata->indexsorted);
13188 
13189  minidx = SCIPvarGetIndex(consdata->vars[0]);
13190  mididx = SCIPvarGetIndex(consdata->vars[consdata->nvars / 2]);
13191  maxidx = SCIPvarGetIndex(consdata->vars[consdata->nvars - 1]);
13192  scale = COPYSIGN(1.0/consdata->maxabsval, consdata->vals[0]);
13193 
13194  /* using only the variable indices as hash, since the values are compared by epsilon */
13195  return SCIPhashSeven(consdata->nvars, minidx, SCIPrealHashCode(consdata->vals[0] * scale),
13196  mididx, SCIPrealHashCode(consdata->vals[consdata->nvars / 2] * scale),
13197  maxidx, SCIPrealHashCode(consdata->vals[consdata->nvars - 1] * scale));
13198 }
13199 
13200 /** returns the key for deciding which of two parallel constraints should be kept (smaller key should be kept);
13201  * prefers non-upgraded constraints and as second criterion the constraint with the smallest position
13202  */
13203 static
13204 unsigned int getParallelConsKey(
13205  SCIP_CONS* cons /**< linear constraint */
13206  )
13207 {
13208  SCIP_CONSDATA* consdata;
13209 
13210  assert(cons != NULL);
13211 
13212  consdata = SCIPconsGetData(cons);
13213  assert(consdata != NULL);
13214 
13215  return (((unsigned int)consdata->upgraded)<<31) + (unsigned int)SCIPconsGetPos(cons); /*lint !e571*/
13216 }
13217 
13218 /** updates the hashtable such that out of all constraints in the hashtable that are detected
13219  * to be parallel to *querycons, only one is kept in the hashtable and stored into *querycons,
13220  * and all others are removed from the hashtable and stored in the given array
13221  */
13222 static
13224  SCIP_HASHTABLE* hashtable, /**< hashtable containing linear constraints */
13225  SCIP_CONS** querycons, /**< pointer to linear constraint used to look for duplicates in the hash table;
13226  * upon return will contain the constraint that should be kept */
13227  SCIP_CONS** parallelconss, /**< array to return constraints that are parallel to the given;
13228  * these constraints where removed from the hashtable */
13229  int* nparallelconss /**< pointer to return number of parallel constraints */
13230  )
13231 {
13232  SCIP_CONS* parallelcons;
13233  unsigned int querykey;
13234 
13235  *nparallelconss = 0;
13236  querykey = getParallelConsKey(*querycons);
13237 
13238  while( (parallelcons = (SCIP_CONS*)SCIPhashtableRetrieve(hashtable, (void*)(*querycons))) != NULL )
13239  {
13240  unsigned int conskey = getParallelConsKey(parallelcons);
13241 
13242  if( conskey < querykey )
13243  {
13244  parallelconss[(*nparallelconss)++] = *querycons;
13245  *querycons = parallelcons;
13246  querykey = conskey;
13247  }
13248  else
13249  {
13250  parallelconss[(*nparallelconss)++] = parallelcons;
13251  }
13252 
13253  /* if the constraint that just came out of the hash table is the one that is kept,
13254  * we do not need to look into the hashtable again, since the invariant is that
13255  * in the hashtable only pair-wise non-parallel constraints are contained.
13256  * For the original querycons, however, multiple constraints that compare equal (=parallel)
13257  * could be contained due to non-transitivity of the equality comparison.
13258  * Also we can return immediately, since parallelcons is already contained in the
13259  * hashtable and we do not need to remove and reinsert it.
13260  */
13261  if( *querycons == parallelcons )
13262  return SCIP_OKAY;
13263 
13264  /* remove parallelcons from the hashtable, since it will be replaced by querycons */
13265  SCIP_CALL( SCIPhashtableRemove(hashtable, (void*) parallelcons) );
13266  }
13267 
13268  /* in debug mode we make sure, that the hashtable cannot contain a constraint that
13269  * comnpares equal to querycons at this point
13270  */
13271 #ifndef NDEBUG
13272  SCIP_CALL_ABORT( SCIPhashtableSafeInsert(hashtable, *querycons) );
13273 #else
13274  SCIP_CALL( SCIPhashtableInsert(hashtable, *querycons) );
13275 #endif
13276 
13277  return SCIP_OKAY;
13278 }
13279 
13280 /** compares each constraint with all other constraints for possible redundancy and removes or changes constraint
13281  * accordingly; in contrast to preprocessConstraintPairs(), it uses a hash table
13282  */
13283 static
13285  SCIP* scip, /**< SCIP data structure */
13286  BMS_BLKMEM* blkmem, /**< block memory */
13287  SCIP_CONS** conss, /**< constraint set */
13288  int nconss, /**< number of constraints in constraint set */
13289  int* firstchange, /**< pointer to store first changed constraint */
13290  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
13291  int* ndelconss, /**< pointer to count number of deleted constraints */
13292  int* nchgsides /**< pointer to count number of changed left/right hand sides */
13293  )
13294 {
13295  SCIP_HASHTABLE* hashtable;
13296  SCIP_CONS** parallelconss;
13297  int nparallelconss;
13298  int hashtablesize;
13299  int c;
13300 
13301  assert(scip != NULL);
13302  assert(blkmem != NULL);
13303  assert(conss != NULL);
13304  assert(firstchange != NULL);
13305  assert(cutoff != NULL);
13306  assert(ndelconss != NULL);
13307  assert(nchgsides != NULL);
13308 
13309  /* create a hash table for the constraint set */
13310  hashtablesize = nconss;
13311  SCIP_CALL( SCIPhashtableCreate(&hashtable, blkmem, hashtablesize,
13312  hashGetKeyLinearcons, hashKeyEqLinearcons, hashKeyValLinearcons, (void*) scip) );
13313 
13314  SCIP_CALL( SCIPallocBufferArray(scip, &parallelconss, nconss) );
13315 
13316  /* check all constraints in the given set for redundancy */
13317  for( c = 0; c < nconss; ++c )
13318  {
13319  SCIP_CONS* cons0;
13320  SCIP_CONSDATA* consdata0;
13321 
13322  cons0 = conss[c];
13323 
13324  if( !SCIPconsIsActive(cons0) || SCIPconsIsModifiable(cons0) )
13325  continue;
13326 
13327  /* check for interuption */
13328  if( c % 1000 == 0 && SCIPisStopped(scip) )
13329  break;
13330 
13331  /* sorts the constraint */
13332  consdata0 = SCIPconsGetData(cons0);
13333  assert(consdata0 != NULL);
13334  SCIP_CALL( consdataSort(scip, consdata0) );
13335  assert(consdata0->indexsorted);
13336 
13337  /* get constraints from current hash table with same variables as cons0 and with coefficients equal
13338  * to the ones of cons0 when both are scaled such that maxabsval is 1.0 and the coefficient of the
13339  * first variable is positive
13340  * Also inserts cons0 into the hashtable.
13341  */
13342  SCIP_CALL( retrieveParallelConstraints(hashtable, &cons0, parallelconss, &nparallelconss) );
13343 
13344  if( nparallelconss != 0 )
13345  {
13346  SCIP_Real lhs;
13347  SCIP_Real rhs;
13348 
13349  int i;
13350 
13351  /* cons0 may have been changed in retrieveParallelConstraints() */
13352  consdata0 = SCIPconsGetData(cons0);
13353 
13354  lhs = consdata0->lhs;
13355  rhs = consdata0->rhs;
13356 
13357  for( i = 0; i < nparallelconss; ++i )
13358  {
13359  SCIP_CONS* consdel;
13360  SCIP_CONSDATA* consdatadel;
13361  SCIP_Real scale;
13362 
13363  consdel = parallelconss[i];
13364  consdatadel = SCIPconsGetData(consdel);
13365 
13366  assert(SCIPconsIsActive(consdel));
13367  assert(!SCIPconsIsModifiable(consdel));
13368 
13369  /* constraint found: create a new constraint with same coefficients and best left and right hand side;
13370  * delete old constraints afterwards
13371  */
13372  assert(consdatadel != NULL);
13373  assert(consdata0->nvars >= 1 && consdata0->nvars == consdatadel->nvars);
13374 
13375  assert(consdatadel->indexsorted);
13376  assert(consdata0->vars[0] == consdatadel->vars[0]);
13377 
13378  scale = consdata0->vals[0] / consdatadel->vals[0];
13379  assert(scale != 0.0);
13380 
13381  /* in debug mode, check that all coefficients are equal with respect to epsilon
13382  * if the constraints are in equilibrium scale
13383  */
13384 #ifndef NDEBUG
13385  {
13386  int k;
13387  SCIP_Real scale0 = 1.0 / consdata0->maxabsval;
13388  SCIP_Real scaledel = COPYSIGN(1.0 / consdatadel->maxabsval, scale);
13389 
13390  for( k = 0; k < consdata0->nvars; ++k )
13391  {
13392  assert(SCIPisEQ(scip, scale0 * consdata0->vals[k], scaledel * consdatadel->vals[k]));
13393  }
13394  }
13395 #endif
13396 
13397  if( scale > 0.0 )
13398  {
13399  /* the coefficients of both constraints are parallel with a positive scale */
13400  SCIPdebugMsg(scip, "aggregate linear constraints <%s> and <%s> with equal coefficients into single ranged row\n",
13401  SCIPconsGetName(cons0), SCIPconsGetName(consdel));
13402  SCIPdebugPrintCons(scip, cons0, NULL);
13403  SCIPdebugPrintCons(scip, consdel, NULL);
13404 
13405  if( ! SCIPisInfinity(scip, -consdatadel->lhs) )
13406  lhs = MAX(scale * consdatadel->lhs, lhs);
13407 
13408  if( ! SCIPisInfinity(scip, consdatadel->rhs) )
13409  rhs = MIN(scale * consdatadel->rhs, rhs);
13410  }
13411  else
13412  {
13413  /* the coefficients of both rows are negations */
13414  SCIPdebugMsg(scip, "aggregate linear constraints <%s> and <%s> with negated coefficients into single ranged row\n",
13415  SCIPconsGetName(cons0), SCIPconsGetName(consdel));
13416  SCIPdebugPrintCons(scip, cons0, NULL);
13417  SCIPdebugPrintCons(scip, consdel, NULL);
13418 
13419  if( ! SCIPisInfinity(scip, consdatadel->rhs) )
13420  lhs = MAX(scale * consdatadel->rhs, lhs);
13421 
13422  if( ! SCIPisInfinity(scip, -consdatadel->lhs) )
13423  rhs = MIN(scale * consdatadel->lhs, rhs);
13424  }
13425 
13426  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13427  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, consdel) );
13428 
13429  /* delete consdel */
13430  assert( ! consdata0->upgraded || consdatadel->upgraded );
13431  SCIP_CALL( SCIPdelCons(scip, consdel) );
13432  if( !consdatadel->upgraded )
13433  (*ndelconss)++;
13434  }
13435 
13436  if( SCIPisFeasLT(scip, rhs, lhs) )
13437  {
13438  SCIPdebugMsg(scip, "aggregated linear constraint <%s> is infeasible\n", SCIPconsGetName(cons0));
13439  *cutoff = TRUE;
13440  break;
13441  }
13442 
13443  /* ensure that lhs <= rhs holds without tolerances as we only allow such rows to enter the LP */
13444  if( lhs > rhs )
13445  {
13446  rhs = (lhs + rhs)/2;
13447  lhs = rhs;
13448  }
13449 
13450  /* update lhs and rhs of cons0 */
13451  SCIP_CALL( chgLhs(scip, cons0, lhs) );
13452  SCIP_CALL( chgRhs(scip, cons0, rhs) );
13453 
13454  /* update the first changed constraint to begin the next aggregation round with */
13455  if( consdata0->changed && SCIPconsGetPos(cons0) < *firstchange )
13456  *firstchange = SCIPconsGetPos(cons0);
13457 
13458  assert(SCIPconsIsActive(cons0));
13459  }
13460  }
13461 #ifdef SCIP_MORE_DEBUG
13462  SCIPinfoMessage(scip, NULL, "linear pairwise comparison hashtable statistics:\n");
13464 #endif
13465 
13466  SCIPfreeBufferArray(scip, &parallelconss);
13467 
13468  /* free hash table */
13469  SCIPhashtableFree(&hashtable);
13470 
13471  return SCIP_OKAY;
13472 }
13473 
13474 /** compares constraint with all prior constraints for possible redundancy or aggregation,
13475  * and removes or changes constraint accordingly
13476  */
13477 static
13479  SCIP* scip, /**< SCIP data structure */
13480  SCIP_CONS** conss, /**< constraint set */
13481  int firstchange, /**< first constraint that changed since last pair preprocessing round */
13482  int chkind, /**< index of constraint to check against all prior indices upto startind */
13483  SCIP_Real maxaggrnormscale, /**< maximal allowed relative gain in maximum norm for constraint aggregation */
13484  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
13485  int* ndelconss, /**< pointer to count number of deleted constraints */
13486  int* nchgsides, /**< pointer to count number of changed left/right hand sides */
13487  int* nchgcoefs /**< pointer to count number of changed coefficients */
13488  )
13489 {
13490  SCIP_CONS* cons0;
13491  SCIP_CONSDATA* consdata0;
13492  int* commonidx0;
13493  int* commonidx1;
13494  int* diffidx0minus1;
13495  int* diffidx1minus0;
13496  uint64_t possignature0;
13497  uint64_t negsignature0;
13498  SCIP_Bool cons0changed;
13499  SCIP_Bool cons0isequality;
13500  int diffidx1minus0size;
13501  int c;
13502  SCIP_Real cons0lhs;
13503  SCIP_Real cons0rhs;
13504  SCIP_Bool cons0upgraded;
13505 
13506  assert(scip != NULL);
13507  assert(conss != NULL);
13508  assert(firstchange <= chkind);
13509  assert(cutoff != NULL);
13510  assert(ndelconss != NULL);
13511  assert(nchgsides != NULL);
13512  assert(nchgcoefs != NULL);
13513 
13514  /* get the constraint to be checked against all prior constraints */
13515  cons0 = conss[chkind];
13516  assert(cons0 != NULL);
13517  assert(SCIPconsIsActive(cons0));
13518  assert(!SCIPconsIsModifiable(cons0));
13519 
13520  consdata0 = SCIPconsGetData(cons0);
13521  assert(consdata0 != NULL);
13522  assert(consdata0->nvars >= 1);
13523  cons0isequality = SCIPisEQ(scip, consdata0->lhs, consdata0->rhs);
13524 
13525  /* sort the constraint */
13526  SCIP_CALL( consdataSort(scip, consdata0) );
13527 
13528  /* calculate bit signatures of cons0 for potentially positive and negative coefficients */
13529  consdataCalcSignatures(consdata0);
13530  possignature0 = consdata0->possignature;
13531  negsignature0 = consdata0->negsignature;
13532 
13533  /* get temporary memory for indices of common variables */
13534  SCIP_CALL( SCIPallocBufferArray(scip, &commonidx0, consdata0->nvars) );
13535  SCIP_CALL( SCIPallocBufferArray(scip, &commonidx1, consdata0->nvars) );
13536  SCIP_CALL( SCIPallocBufferArray(scip, &diffidx0minus1, consdata0->nvars) );
13537  SCIP_CALL( SCIPallocBufferArray(scip, &diffidx1minus0, consdata0->nvars) );
13538  diffidx1minus0size = consdata0->nvars;
13539 
13540  cons0lhs = consdata0->lhs;
13541  cons0rhs = consdata0->rhs;
13542  cons0upgraded = consdata0->upgraded;
13543 
13544  /* check constraint against all prior constraints */
13545  cons0changed = consdata0->changed;
13546  consdata0->changed = FALSE;
13547  for( c = (cons0changed ? 0 : firstchange); c < chkind && !(*cutoff) && conss[chkind] != NULL; ++c )
13548  {
13549  SCIP_CONS* cons1;
13550  SCIP_CONSDATA* consdata1;
13551  uint64_t possignature1;
13552  uint64_t negsignature1;
13553  SCIP_Bool cons0dominateslhs;
13554  SCIP_Bool cons1dominateslhs;
13555  SCIP_Bool cons0dominatesrhs;
13556  SCIP_Bool cons1dominatesrhs;
13557  SCIP_Bool cons1isequality;
13558  SCIP_Bool coefsequal;
13559  SCIP_Bool coefsnegated;
13560  SCIP_Bool tryaggregation;
13561  int nvarscommon;
13562  int nvars0minus1;
13563  int nvars1minus0;
13564  int commonidxweight;
13565  int diffidx0minus1weight;
13566  int diffidx1minus0weight;
13567  int v0;
13568  int v1;
13569 
13570  assert(cons0lhs == consdata0->lhs); /*lint !e777*/
13571  assert(cons0rhs == consdata0->rhs); /*lint !e777*/
13572  assert(cons0upgraded == consdata0->upgraded);
13573 
13574  cons1 = conss[c];
13575 
13576  /* cons1 has become inactive during presolving of constraint pairs */
13577  if( cons1 == NULL )
13578  continue;
13579 
13580  assert(SCIPconsIsActive(cons0) && !SCIPconsIsModifiable(cons0));
13581  assert(SCIPconsIsActive(cons1) && !SCIPconsIsModifiable(cons1));
13582 
13583  consdata1 = SCIPconsGetData(cons1);
13584  assert(consdata1 != NULL);
13585 
13586  /* SCIPdebugMsg(scip, "preprocess linear constraint pair <%s>[chgd:%d, upgd:%d] and <%s>[chgd:%d, upgd:%d]\n",
13587  SCIPconsGetName(cons0), cons0changed, cons0upgraded,
13588  SCIPconsGetName(cons1), consdata1->changed, consdata1->upgraded); */
13589 
13590  /* if both constraints didn't change since last pair processing, we can ignore the pair */
13591  if( !cons0changed && !consdata1->changed )
13592  continue;
13593 
13594  /* if both constraints are already upgraded, skip the pair;
13595  * because changes on these constraints cannot be applied to the instance anymore */
13596  if( cons0upgraded && consdata1->upgraded )
13597  continue;
13598 
13599  assert(consdata1->nvars >= 1);
13600 
13601  /* sort the constraint */
13602  SCIP_CALL( consdataSort(scip, consdata1) );
13603 
13604  /* calculate bit signatures of cons1 for potentially positive and negative coefficients */
13605  consdataCalcSignatures(consdata1);
13606  possignature1 = consdata1->possignature;
13607  negsignature1 = consdata1->negsignature;
13608 
13609  /* the signatures give a quick test to check for domination and equality of coefficients */
13610  coefsequal = (possignature0 == possignature1) && (negsignature0 == negsignature1);
13611  coefsnegated = (possignature0 == negsignature1) && (negsignature0 == possignature1);
13612  cons0dominateslhs = SCIPisGE(scip, cons0lhs, consdata1->lhs)
13613  && ((possignature0 | possignature1) == possignature1) /* possignature0 <= possignature1 (as bit vector) */
13614  && ((negsignature0 | negsignature1) == negsignature0); /* negsignature0 >= negsignature1 (as bit vector) */
13615  cons1dominateslhs = SCIPisGE(scip, consdata1->lhs, cons0lhs)
13616  && ((possignature0 | possignature1) == possignature0) /* possignature0 >= possignature1 (as bit vector) */
13617  && ((negsignature0 | negsignature1) == negsignature1); /* negsignature0 <= negsignature1 (as bit vector) */
13618  cons0dominatesrhs = SCIPisLE(scip, cons0rhs, consdata1->rhs)
13619  && ((possignature0 | possignature1) == possignature0) /* possignature0 >= possignature1 (as bit vector) */
13620  && ((negsignature0 | negsignature1) == negsignature1); /* negsignature0 <= negsignature1 (as bit vector) */
13621  cons1dominatesrhs = SCIPisLE(scip, consdata1->rhs, cons0rhs)
13622  && ((possignature0 | possignature1) == possignature1) /* possignature0 <= possignature1 (as bit vector) */
13623  && ((negsignature0 | negsignature1) == negsignature0); /* negsignature0 >= negsignature1 (as bit vector) */
13624  cons1isequality = SCIPisEQ(scip, consdata1->lhs, consdata1->rhs);
13625  tryaggregation = (cons0isequality || cons1isequality) && (maxaggrnormscale > 0.0);
13626  if( !cons0dominateslhs && !cons1dominateslhs && !cons0dominatesrhs && !cons1dominatesrhs
13627  && !coefsequal && !coefsnegated && !tryaggregation )
13628  continue;
13629 
13630  /* make sure, we have enough memory for the index set of V_1 \ V_0 */
13631  if( tryaggregation && consdata1->nvars > diffidx1minus0size )
13632  {
13633  SCIP_CALL( SCIPreallocBufferArray(scip, &diffidx1minus0, consdata1->nvars) );
13634  diffidx1minus0size = consdata1->nvars;
13635  }
13636 
13637  /* check consdata0 against consdata1:
13638  * - if lhs0 >= lhs1 and for each variable v and each solution value x_v val0[v]*x_v <= val1[v]*x_v,
13639  * consdata0 dominates consdata1 w.r.t. left hand side
13640  * - if rhs0 <= rhs1 and for each variable v and each solution value x_v val0[v]*x_v >= val1[v]*x_v,
13641  * consdata0 dominates consdata1 w.r.t. right hand side
13642  * - if val0[v] == -val1[v] for all variables v, the two inequalities can be replaced by a single
13643  * ranged row (or equality)
13644  * - if at least one constraint is an equality, count the weighted number of common variables W_c
13645  * and the weighted number of variable in the difference sets W_0 = w(V_0 \ V_1), W_1 = w(V_1 \ V_0),
13646  * where the weight of each variable depends on its type, such that aggregations in order to remove the
13647  * number of continuous and integer variables are preferred:
13648  * - if W_c > W_1, try to aggregate consdata0 := a * consdata0 + b * consdata1 in order to decrease the
13649  * variable weight in consdata0, where a = +/- val1[v] and b = -/+ val0[v] for common v which leads to
13650  * the smallest weight; for numerical stability, we will only accept integral a and b; the sign of a has
13651  * to be positive to not switch the sense of the (in)equality cons0
13652  * - if W_c > W_0, try to aggregate consdata1 := a * consdata1 + b * consdata0 in order to decrease the
13653  * variable weight in consdata1, where a = +/- val0[v] and b = -/+ val1[v] for common v which leads to
13654  * the smallest weight; for numerical stability, we will only accept integral a and b; the sign of a has
13655  * to be positive to not switch the sense of the (in)equality cons1
13656  */
13657 
13658  /* check consdata0 against consdata1 for redundancy, or ranged row accumulation */
13659  nvarscommon = 0;
13660  commonidxweight = 0;
13661  nvars0minus1 = 0;
13662  diffidx0minus1weight = 0;
13663  nvars1minus0 = 0;
13664  diffidx1minus0weight = 0;
13665  v0 = 0;
13666  v1 = 0;
13667  while( (v0 < consdata0->nvars || v1 < consdata1->nvars)
13668  && (cons0dominateslhs || cons1dominateslhs || cons0dominatesrhs || cons1dominatesrhs
13669  || coefsequal || coefsnegated || tryaggregation) )
13670  {
13671  SCIP_VAR* var;
13672  SCIP_Real val0;
13673  SCIP_Real val1;
13674  int varcmp;
13675 
13676  /* test, if variable appears in only one or in both constraints */
13677  if( v0 < consdata0->nvars && v1 < consdata1->nvars )
13678  varcmp = SCIPvarCompare(consdata0->vars[v0], consdata1->vars[v1]);
13679  else if( v0 < consdata0->nvars )
13680  varcmp = -1;
13681  else
13682  varcmp = +1;
13683 
13684  switch( varcmp )
13685  {
13686  case -1:
13687  /* variable doesn't appear in consdata1 */
13688  var = consdata0->vars[v0];
13689  val0 = consdata0->vals[v0];
13690  val1 = 0.0;
13691  if( tryaggregation )
13692  {
13693  diffidx0minus1[nvars0minus1] = v0;
13694  nvars0minus1++;
13695  diffidx0minus1weight += getVarWeight(var);
13696  }
13697  v0++;
13698  coefsequal = FALSE;
13699  coefsnegated = FALSE;
13700  break;
13701 
13702  case +1:
13703  /* variable doesn't appear in consdata0 */
13704  var = consdata1->vars[v1];
13705  val0 = 0.0;
13706  val1 = consdata1->vals[v1];
13707  if( tryaggregation )
13708  {
13709  diffidx1minus0[nvars1minus0] = v1;
13710  nvars1minus0++;
13711  diffidx1minus0weight += getVarWeight(var);
13712  }
13713  v1++;
13714  coefsequal = FALSE;
13715  coefsnegated = FALSE;
13716  break;
13717 
13718  case 0:
13719  /* variable appears in both constraints */
13720  assert(consdata0->vars[v0] == consdata1->vars[v1]);
13721  var = consdata0->vars[v0];
13722  val0 = consdata0->vals[v0];
13723  val1 = consdata1->vals[v1];
13724  if( tryaggregation )
13725  {
13726  commonidx0[nvarscommon] = v0;
13727  commonidx1[nvarscommon] = v1;
13728  nvarscommon++;
13729  commonidxweight += getVarWeight(var);
13730  }
13731  v0++;
13732  v1++;
13733  coefsequal = coefsequal && (SCIPisEQ(scip, val0, val1));
13734  coefsnegated = coefsnegated && (SCIPisEQ(scip, val0, -val1));
13735  break;
13736 
13737  default:
13738  SCIPerrorMessage("invalid comparison result\n");
13739  SCIPABORT();
13740  var = NULL;
13741  val0 = 0.0;
13742  val1 = 0.0;
13743  }
13744  assert(var != NULL);
13745 
13746  /* update domination criteria w.r.t. the coefficient and the variable's bounds */
13747  if( SCIPisGT(scip, val0, val1) )
13748  {
13749  if( SCIPisNegative(scip, SCIPvarGetLbGlobal(var)) )
13750  {
13751  cons0dominatesrhs = FALSE;
13752  cons1dominateslhs = FALSE;
13753  }
13754  if( SCIPisPositive(scip, SCIPvarGetUbGlobal(var)) )
13755  {
13756  cons0dominateslhs = FALSE;
13757  cons1dominatesrhs = FALSE;
13758  }
13759  }
13760  else if( SCIPisLT(scip, val0, val1) )
13761  {
13762  if( SCIPisNegative(scip, SCIPvarGetLbGlobal(var)) )
13763  {
13764  cons0dominateslhs = FALSE;
13765  cons1dominatesrhs = FALSE;
13766  }
13767  if( SCIPisPositive(scip, SCIPvarGetUbGlobal(var)) )
13768  {
13769  cons0dominatesrhs = FALSE;
13770  cons1dominateslhs = FALSE;
13771  }
13772  }
13773  }
13774 
13775  /* check for disaggregated ranged rows */
13776  if( coefsequal || coefsnegated )
13777  {
13778  SCIP_CONS* consstay;
13779  SCIP_CONS* consdel;
13780 #ifndef NDEBUG
13781  SCIP_CONSDATA* consdatastay;
13782 #endif
13783  SCIP_CONSDATA* consdatadel;
13784  SCIP_Real lhs;
13785  SCIP_Real rhs;
13786  int consinddel;
13787 
13788  /* the coefficients in both rows are either equal or negated: create a new constraint with same coefficients and
13789  * best left and right hand sides; delete the old constraints afterwards
13790  */
13791  SCIPdebugMsg(scip, "aggregate linear constraints <%s> and <%s> with %s coefficients into single ranged row\n",
13792  SCIPconsGetName(cons0), SCIPconsGetName(cons1), coefsequal ? "equal" : "negated");
13793  SCIPdebugPrintCons(scip, cons0, NULL);
13794  SCIPdebugPrintCons(scip, cons1, NULL);
13795 
13796  if( coefsequal )
13797  {
13798  /* the coefficients of both rows are equal */
13799  lhs = MAX(consdata0->lhs, consdata1->lhs);
13800  rhs = MIN(consdata0->rhs, consdata1->rhs);
13801  }
13802  else
13803  {
13804  /* the coefficients of both rows are negations */
13805  lhs = MAX(consdata0->lhs, -consdata1->rhs);
13806  rhs = MIN(consdata0->rhs, -consdata1->lhs);
13807  }
13808  if( SCIPisFeasLT(scip, rhs, lhs) )
13809  {
13810  SCIPdebugMsg(scip, "aggregated linear constraint <%s> is infeasible\n", SCIPconsGetName(cons0));
13811  *cutoff = TRUE;
13812  break;
13813  }
13814 
13815  /* check which constraint has to stay;
13816  * changes applied to an upgraded constraint will not be considered in the instance */
13817  if( consdata0->upgraded )
13818  {
13819  assert(!consdata1->upgraded);
13820  consstay = cons1;
13821 #ifndef NDEBUG
13822  consdatastay = consdata1;
13823 #endif
13824 
13825  consdel = cons0;
13826  consdatadel = consdata0;
13827  consinddel = chkind;
13828  }
13829  else
13830  {
13831  consstay = cons0;
13832 #ifndef NDEBUG
13833  consdatastay = consdata0;
13834 #endif
13835 
13836  consdel = cons1;
13837  consdatadel = consdata1;
13838  consinddel = c;
13839  }
13840 
13841  /* update the sides of consstay */
13842  SCIP_CALL( chgLhs(scip, consstay, lhs) );
13843  SCIP_CALL( chgRhs(scip, consstay, rhs) );
13844  if( !consdata0->upgraded )
13845  {
13846  assert(consstay == cons0);
13847  cons0lhs = consdata0->lhs;
13848  cons0rhs = consdata0->rhs;
13849  }
13850 
13851  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13852  SCIP_CALL( SCIPupdateConsFlags(scip, consstay, consdel) );
13853 
13854  assert( !consdatastay->upgraded );
13855  /* delete consdel */
13856  SCIP_CALL( SCIPdelCons(scip, consdel) );
13857  conss[consinddel] = NULL;
13858  if( !consdatadel->upgraded )
13859  (*ndelconss)++;
13860  continue;
13861  }
13862 
13863  /* check for domination: remove dominated sides, but don't touch equalities as long as they are not totally
13864  * redundant
13865  */
13866  if( cons1dominateslhs && (!cons0isequality || cons1dominatesrhs || SCIPisInfinity(scip, consdata0->rhs) ) )
13867  {
13868  /* left hand side is dominated by consdata1: delete left hand side of consdata0 */
13869  SCIPdebugMsg(scip, "left hand side of linear constraint <%s> is dominated by <%s>:\n",
13870  SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13871  SCIPdebugPrintCons(scip, cons0, NULL);
13872  SCIPdebugPrintCons(scip, cons1, NULL);
13873 
13874  /* check for infeasibility */
13875  if( SCIPisFeasGT(scip, consdata1->lhs, consdata0->rhs) )
13876  {
13877  SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13878  *cutoff = TRUE;
13879  break;
13880  }
13881 
13882  /* remove redundant left hand side */
13883  if( !SCIPisInfinity(scip, -consdata0->lhs) )
13884  {
13885  SCIP_CALL( chgLhs(scip, cons0, -SCIPinfinity(scip)) );
13886  cons0lhs = consdata0->lhs;
13887  cons0isequality = FALSE;
13888  if( !consdata0->upgraded )
13889  {
13890  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13891  SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
13892 
13893  (*nchgsides)++;
13894  }
13895  }
13896  }
13897  else if( cons0dominateslhs && (!cons1isequality || cons0dominatesrhs || SCIPisInfinity(scip, consdata1->rhs)) )
13898  {
13899  /* left hand side is dominated by consdata0: delete left hand side of consdata1 */
13900  SCIPdebugMsg(scip, "left hand side of linear constraint <%s> is dominated by <%s>:\n",
13901  SCIPconsGetName(cons1), SCIPconsGetName(cons0));
13902  SCIPdebugPrintCons(scip, cons1, NULL);
13903  SCIPdebugPrintCons(scip, cons0, NULL);
13904 
13905  /* check for infeasibility */
13906  if( SCIPisFeasGT(scip, consdata0->lhs, consdata1->rhs) )
13907  {
13908  SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13909  *cutoff = TRUE;
13910  break;
13911  }
13912 
13913  /* remove redundant left hand side */
13914  if( !SCIPisInfinity(scip, -consdata1->lhs) )
13915  {
13916  SCIP_CALL( chgLhs(scip, cons1, -SCIPinfinity(scip)) );
13917  cons1isequality = FALSE;
13918  if( !consdata1->upgraded )
13919  {
13920  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13921  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
13922 
13923  (*nchgsides)++;
13924  }
13925  }
13926  }
13927  if( cons1dominatesrhs && (!cons0isequality || cons1dominateslhs || SCIPisInfinity(scip, -consdata0->lhs)) )
13928  {
13929  /* right hand side is dominated by consdata1: delete right hand side of consdata0 */
13930  SCIPdebugMsg(scip, "right hand side of linear constraint <%s> is dominated by <%s>:\n",
13931  SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13932  SCIPdebugPrintCons(scip, cons0, NULL);
13933  SCIPdebugPrintCons(scip, cons1, NULL);
13934 
13935  /* check for infeasibility */
13936  if( SCIPisFeasLT(scip, consdata1->rhs, consdata0->lhs) )
13937  {
13938  SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13939  *cutoff = TRUE;
13940  break;
13941  }
13942 
13943  /* remove redundant right hand side */
13944  if( !SCIPisInfinity(scip, consdata0->rhs) )
13945  {
13946  SCIP_CALL( chgRhs(scip, cons0, SCIPinfinity(scip)) );
13947  cons0rhs = consdata0->rhs;
13948  cons0isequality = FALSE;
13949  if( !consdata0->upgraded )
13950  {
13951  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13952  SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
13953 
13954  (*nchgsides)++;
13955  }
13956  }
13957  }
13958  else if( cons0dominatesrhs && (!cons1isequality || cons0dominateslhs || SCIPisInfinity(scip, -consdata1->lhs)) )
13959  {
13960  /* right hand side is dominated by consdata0: delete right hand side of consdata1 */
13961  SCIPdebugMsg(scip, "right hand side of linear constraint <%s> is dominated by <%s>:\n",
13962  SCIPconsGetName(cons1), SCIPconsGetName(cons0));
13963  SCIPdebugPrintCons(scip, cons1, NULL);
13964  SCIPdebugPrintCons(scip, cons0, NULL);
13965 
13966  /* check for infeasibility */
13967  if( SCIPisFeasLT(scip, consdata0->rhs, consdata1->lhs) )
13968  {
13969  SCIPdebugMsg(scip, "linear constraints <%s> and <%s> are infeasible\n", SCIPconsGetName(cons0), SCIPconsGetName(cons1));
13970  *cutoff = TRUE;
13971  break;
13972  }
13973 
13974  /* remove redundant right hand side */
13975  if( !SCIPisInfinity(scip, consdata1->rhs) )
13976  {
13977  SCIP_CALL( chgRhs(scip, cons1, SCIPinfinity(scip)) );
13978  cons1isequality = FALSE;
13979  if( !consdata1->upgraded )
13980  {
13981  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13982  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
13983 
13984  (*nchgsides)++;
13985  }
13986  }
13987  }
13988 
13989  /* check for now redundant constraints */
13990  if( SCIPisInfinity(scip, -consdata0->lhs) && SCIPisInfinity(scip, consdata0->rhs) )
13991  {
13992  /* consdata0 became redundant */
13993  SCIPdebugMsg(scip, "linear constraint <%s> is redundant\n", SCIPconsGetName(cons0));
13994  SCIP_CALL( SCIPdelCons(scip, cons0) );
13995  conss[chkind] = NULL;
13996  if( !consdata0->upgraded )
13997  {
13998  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
13999  SCIP_CALL( SCIPupdateConsFlags(scip, cons1, cons0) );
14000 
14001  (*ndelconss)++;
14002  }
14003  continue;
14004  }
14005  if( SCIPisInfinity(scip, -consdata1->lhs) && SCIPisInfinity(scip, consdata1->rhs) )
14006  {
14007  /* consdata1 became redundant */
14008  SCIPdebugMsg(scip, "linear constraint <%s> is redundant\n", SCIPconsGetName(cons1));
14009  SCIP_CALL( SCIPdelCons(scip, cons1) );
14010  conss[c] = NULL;
14011  if( !consdata1->upgraded )
14012  {
14013  /* update flags of constraint which caused the redundancy s.t. nonredundant information doesn't get lost */
14014  SCIP_CALL( SCIPupdateConsFlags(scip, cons0, cons1) );
14015 
14016  (*ndelconss)++;
14017  }
14018  continue;
14019  }
14020 
14021  /* check, if we want to aggregate an (in)equality with an equality:
14022  * consdata0 := a * consdata0 + b * consdata1 or consdata1 := a * consdata1 + b * consdata0
14023  */
14024  if( tryaggregation )
14025  {
14026  SCIP_Bool aggregated;
14027 
14028  assert(consdata0->nvars == nvarscommon + nvars0minus1);
14029  assert(consdata1->nvars == nvarscommon + nvars1minus0);
14030 
14031  aggregated = FALSE;
14032  if( cons1isequality && !consdata0->upgraded && commonidxweight > diffidx1minus0weight )
14033  {
14034  /* W_c > W_1: try to aggregate consdata0 := a * consdata0 + b * consdata1 */
14035  SCIP_CALL( aggregateConstraints(scip, cons0, cons1, commonidx0, commonidx1, diffidx0minus1, diffidx1minus0,
14036  nvarscommon, commonidxweight, diffidx0minus1weight, diffidx1minus0weight, maxaggrnormscale,
14037  nchgcoefs, &aggregated, cutoff) );
14038 
14039  if( *cutoff )
14040  break;
14041 
14042  /* update array of active constraints */
14043  if( aggregated )
14044  {
14045  assert(!SCIPconsIsActive(cons0));
14046  assert(SCIPconsIsActive(cons1));
14047  conss[chkind] = NULL;
14048  }
14049  }
14050  if( !aggregated && cons0isequality && !consdata1->upgraded && commonidxweight > diffidx0minus1weight )
14051  {
14052  /* W_c > W_0: try to aggregate consdata1 := a * consdata1 + b * consdata0 */
14053  SCIP_CALL( aggregateConstraints(scip, cons1, cons0, commonidx1, commonidx0, diffidx1minus0, diffidx0minus1,
14054  nvarscommon, commonidxweight, diffidx1minus0weight, diffidx0minus1weight, maxaggrnormscale,
14055  nchgcoefs, &aggregated, cutoff) );
14056 
14057  if( *cutoff )
14058  break;
14059 
14060  /* update array of active constraints */
14061  if( aggregated )
14062  {
14063  assert(!SCIPconsIsActive(cons1));
14064  assert(SCIPconsIsActive(cons0));
14065  conss[c] = NULL;
14066  }
14067  }
14068  }
14069  }
14070 
14071  /* free temporary memory */
14072  SCIPfreeBufferArray(scip, &diffidx1minus0);
14073  SCIPfreeBufferArray(scip, &diffidx0minus1);
14074  SCIPfreeBufferArray(scip, &commonidx1);
14075  SCIPfreeBufferArray(scip, &commonidx0);
14076 
14077  return SCIP_OKAY;
14078 }
14079 
14080 /** do stuffing presolving on a single constraint */
14081 static
14083  SCIP* scip, /**< SCIP data structure */
14084  SCIP_CONS* cons, /**< linear constraint */
14085  SCIP_Bool singletonstuffing, /**< should stuffing of singleton continuous variables be performed? */
14086  SCIP_Bool singlevarstuffing, /**< should single variable stuffing be performed, which tries to fulfill
14087  * constraints using the cheapest variable? */
14088  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
14089  int* nfixedvars, /**< pointer to count the total number of fixed variables */
14090  int* nchgbds /**< pointer to count the total number of tightened bounds */
14091  )
14092 {
14093  SCIP_CONSDATA* consdata;
14094  SCIP_Real* ratios;
14095  int* varpos;
14096  SCIP_Bool* swapped;
14097  SCIP_VAR** vars;
14098  SCIP_Real* vals;
14099  SCIP_VAR* var;
14100  SCIP_Real lb;
14102  SCIP_Real minactivity;
14103  SCIP_Real maxactivity;
14104  SCIP_Real maxcondactivity;
14105  SCIP_Real mincondactivity;
14106  SCIP_Real rhs;
14107  SCIP_Real val;
14108  SCIP_Real obj;
14109  SCIP_Real factor;
14110  SCIP_Bool minactisrelax;
14111  SCIP_Bool maxactisrelax;
14112  SCIP_Bool isminsettoinfinity;
14113  SCIP_Bool ismaxsettoinfinity;
14114  SCIP_Bool tryfixing;
14115  int nsingletons;
14116  int idx;
14117  int v;
14118  int nvars;
14119 
14120  assert(scip != NULL);
14121  assert(cons != NULL);
14122  assert(nfixedvars != NULL);
14123 
14124  consdata = SCIPconsGetData(cons);
14125 
14126  /* we only want to run for inequalities */
14127  if( !SCIPisInfinity(scip, consdata->rhs) && !SCIPisInfinity(scip, -consdata->lhs) )
14128  return SCIP_OKAY;
14129 
14130  if( singlevarstuffing )
14131  {
14132  consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
14133  &isminsettoinfinity, &ismaxsettoinfinity);
14134  }
14135  else
14136  {
14137  minactivity = SCIP_INVALID;
14138  maxactivity = SCIP_INVALID;
14139  isminsettoinfinity = FALSE;
14140  ismaxsettoinfinity = FALSE;
14141  }
14142 
14143  /* we want to have a <= constraint, if the rhs is infinite, we implicitly multiply the constraint by -1,
14144  * the new maxactivity is minus the old minactivity then
14145  */
14146  if( SCIPisInfinity(scip, consdata->rhs) )
14147  {
14148  rhs = -consdata->lhs;
14149  factor = -1.0;
14150  maxactivity = -minactivity;
14151  ismaxsettoinfinity = isminsettoinfinity;
14152  }
14153  else
14154  {
14155  assert(SCIPisInfinity(scip, -consdata->lhs));
14156  rhs = consdata->rhs;
14157  factor = 1.0;
14158  }
14159 
14160  nvars = consdata->nvars;
14161  vars = consdata->vars;
14162  vals = consdata->vals;
14163 
14164  /* check for continuous singletons */
14165  if( singletonstuffing )
14166  {
14167  for( v = 0; v < nvars; ++v )
14168  {
14169  var = vars[v];
14170 
14173  break;
14174  }
14175  }
14176  else
14177  /* we don't want to go into the next block */
14178  v = nvars;
14179 
14180  /* a singleton was found -> perform singleton variable stuffing */
14181  if( v < nvars )
14182  {
14183  assert(singletonstuffing);
14184 
14185  SCIP_CALL( SCIPallocBufferArray(scip, &varpos, nvars) );
14186  SCIP_CALL( SCIPallocBufferArray(scip, &ratios, nvars) );
14187  SCIP_CALL( SCIPallocBufferArray(scip, &swapped, nvars) );
14188 
14189  tryfixing = TRUE;
14190  nsingletons = 0;
14191  mincondactivity = 0.0;
14192  maxcondactivity = 0.0;
14193 
14194  for( v = 0; v < nvars; ++v )
14195  {
14196  var = vars[v];
14197  lb = SCIPvarGetLbGlobal(var);
14198  ub = SCIPvarGetUbGlobal(var);
14199  obj = SCIPvarGetObj(var);
14200  val = factor * vals[v];
14201 
14202  assert(!SCIPisZero(scip, val));
14203 
14204  /* the variable is a singleton and continuous */
14207  {
14208  if( SCIPisNegative(scip, obj) && val > 0 )
14209  {
14210  /* case 1: obj < 0 and coef > 0 */
14211  if( SCIPisInfinity(scip, -lb) )
14212  {
14213  tryfixing = FALSE;
14214  break;
14215  }
14216 
14217  maxcondactivity += val * lb;
14218  mincondactivity += val * lb;
14219  swapped[v] = FALSE;
14220  ratios[nsingletons] = obj / val;
14221  varpos[nsingletons] = v;
14222  nsingletons++;
14223  }
14224  else if( SCIPisPositive(scip, obj) && val < 0 )
14225  {
14226  /* case 2: obj > 0 and coef < 0 */
14227  if( SCIPisInfinity(scip, ub) )
14228  {
14229  tryfixing = FALSE;
14230  break;
14231  }
14232  /* multiply column by (-1) to become case 1.
14233  * now bounds are swapped: ub := -lb, lb := -ub
14234  */
14235 
14236  maxcondactivity += val * ub;
14237  mincondactivity += val * ub;
14238  swapped[v] = TRUE;
14239  ratios[nsingletons] = obj / val;
14240  varpos[nsingletons] = v;
14241  nsingletons++;
14242  }
14243  else if( val > 0 )
14244  {
14245  /* case 3: obj >= 0 and coef >= 0 is handled by duality fixing.
14246  * we only consider the lower bound for the constants
14247  */
14248  assert(!SCIPisNegative(scip, obj));
14249 
14250  if( SCIPisInfinity(scip, -lb) )
14251  {
14252  /* maybe unbounded */
14253  tryfixing = FALSE;
14254  break;
14255  }
14256 
14257  maxcondactivity += val * lb;
14258  mincondactivity += val * lb;
14259  }
14260  else
14261  {
14262  /* case 4: obj <= 0 and coef <= 0 is also handled by duality fixing.
14263  * we only consider the upper bound for the constants
14264  */
14265  assert(!SCIPisPositive(scip, obj));
14266  assert(val < 0);
14267 
14268  if( SCIPisInfinity(scip, ub) )
14269  {
14270  /* maybe unbounded */
14271  tryfixing = FALSE;
14272  break;
14273  }
14274 
14275  maxcondactivity += val * ub;
14276  mincondactivity += val * ub;
14277  }
14278  }
14279  else
14280  {
14281  /* consider contribution of discrete variables, non-singleton
14282  * continuous variables and variables with more than one lock
14283  */
14284  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
14285  {
14286  tryfixing = FALSE;
14287  break;
14288  }
14289 
14290  if( val > 0 )
14291  {
14292  maxcondactivity += val * ub;
14293  mincondactivity += val * lb;
14294  }
14295  else
14296  {
14297  maxcondactivity += val * lb;
14298  mincondactivity += val * ub;
14299  }
14300  }
14301  }
14302  if( tryfixing && nsingletons > 0 && (SCIPisGT(scip, rhs, maxcondactivity) || SCIPisLE(scip, rhs, mincondactivity)) )
14303  {
14304  SCIP_Real delta;
14305  SCIP_Bool tightened;
14306 #ifdef SCIP_DEBUG
14307  int oldnfixedvars = *nfixedvars;
14308  int oldnchgbds = *nchgbds;
14309 #endif
14310 
14311  SCIPsortRealInt(ratios, varpos, nsingletons);
14312 
14313  /* verify which singleton continuous variables can be fixed */
14314  for( v = 0; v < nsingletons; ++v )
14315  {
14316  idx = varpos[v];
14317  var = vars[idx];
14318  val = factor * vals[idx];
14319  lb = SCIPvarGetLbGlobal(var);
14320  ub = SCIPvarGetUbGlobal(var);
14321 
14322  assert(val > 0 || SCIPisPositive(scip, SCIPvarGetObj(var)));
14323  assert((val < 0) == swapped[idx]);
14324  val = REALABS(val);
14325 
14326  /* stop fixing if variable bounds are not finite */
14327  if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
14328  break;
14329 
14332  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
14333 
14334  /* calculate the change in the row activities if this variable changes
14335  * its value from its worst to its best bound
14336  */
14337  if( swapped[idx] )
14338  delta = -(lb - ub) * val;
14339  else
14340  delta = (ub - lb) * val;
14341 
14342  assert(!SCIPisNegative(scip, delta));
14343 
14344  if( SCIPisLE(scip, delta, rhs - maxcondactivity) )
14345  {
14346  if( swapped[idx] )
14347  {
14348  SCIPdebugMsg(scip, "fix <%s> to its lower bound %g\n", SCIPvarGetName(var), lb);
14349  SCIP_CALL( SCIPfixVar(scip, var, lb, cutoff, &tightened) );
14350  }
14351  else
14352  {
14353  SCIPdebugMsg(scip, "fix <%s> to its upper bound %g\n", SCIPvarGetName(var), ub);
14354  SCIP_CALL( SCIPfixVar(scip, var, ub, cutoff, &tightened) );
14355  }
14356 
14357  if( *cutoff )
14358  break;
14359  if( tightened )
14360  {
14361  (*nfixedvars)++;
14362  }
14363  }
14364  /* @note: we could in theory tighten the bound of the first singleton variable which does not fall into the above case,
14365  * since it cannot be fully fixed. However, this is not needed and should be done by activity-based bound tightening
14366  * anyway after all other continuous singleton columns were fixed; doing it here may introduce numerical
14367  * troubles in case of large bounds.
14368  */
14369  else if( SCIPisLE(scip, rhs, mincondactivity) )
14370  {
14371  if( swapped[idx] )
14372  {
14373  SCIPdebugMsg(scip, "fix <%s> to its upper bound %g\n", SCIPvarGetName(var), ub);
14374  SCIP_CALL( SCIPfixVar(scip, var, ub, cutoff, &tightened) );
14375  }
14376  else
14377  {
14378  SCIPdebugMsg(scip, "fix <%s> to its lower bound %g\n", SCIPvarGetName(var), lb);
14379  SCIP_CALL( SCIPfixVar(scip, var, lb, cutoff, &tightened) );
14380  }
14381 
14382  if( *cutoff )
14383  break;
14384  if( tightened )
14385  {
14386  (*nfixedvars)++;
14387  }
14388  }
14389 
14390  maxcondactivity += delta;
14391  mincondactivity += delta;
14392  }
14393 
14394 #ifdef SCIP_DEBUG
14395  if( *nfixedvars - oldnfixedvars > 0 || *nchgbds - oldnchgbds > 0 )
14396  {
14397  SCIPdebugMsg(scip, "### stuffing fixed %d variables and changed %d bounds\n", *nfixedvars - oldnfixedvars, *nchgbds - oldnchgbds);
14398  }
14399 #endif
14400  }
14401 
14402  SCIPfreeBufferArray(scip, &swapped);
14403  SCIPfreeBufferArray(scip, &ratios);
14404  SCIPfreeBufferArray(scip, &varpos);
14405  }
14406 
14407  /* perform single-variable stuffing:
14408  * for a linear inequality
14409  * a_1 x_1 + a_2 x_2 + ... + a_n x_n <= b
14410  * with a_i > 0 and objective coefficients c_i < 0,
14411  * setting all variables to their upper bound (giving us the maximal activity of the constraint) is worst w.r.t.
14412  * feasibility of the constraint. On the other hand, this gives the best objective function contribution of the
14413  * variables contained in the constraint. The maximal activity should be larger than the rhs, otherwise the constraint
14414  * is redundant.
14415  * Now we are searching for a variable x_k with maximal ratio c_k / a_k (note that all these ratios are negative), so
14416  * that by reducing the value of this variable we reduce the activity of the constraint while having the smallest
14417  * objective deterioration per activity unit. If x_k has no downlocks, is continuous, and can be reduced enough to
14418  * render the constraint feasible, and ALL other variables have only the one uplock installed by the current constraint,
14419  * we can reduce the upper bound of x_k such that the maxactivity equals the rhs and fix all other variables to their
14420  * upper bound.
14421  * Note that the others variables may have downlocks from other constraints, which we do not need to care
14422  * about since we are setting them to the highest possible value. Also, they may be integer or binary, because the
14423  * computed ratio is still a lower bound on the change in the objective caused by reducing those variable to reach
14424  * constraint feasibility. On the other hand, uplocks on x_k from other constraint do no interfer with the method.
14425  * With a slight adjustment, the procedure even works for integral x_k. If (maxactivity - rhs)/val is integral,
14426  * the variable gets an integral value in order to fulfill the constraint tightly, and we can just apply the procedure.
14427  * If (maxactivity - rhs)/val is fractional, we need to check, if overfulfilling the constraint by setting x_k to
14428  * ceil((maxactivity - rhs)/val) is still better than setting x_k to ceil((maxactivity - rhs)/val) - 1 and
14429  * filling the remaining gap in the constraint with the next-best variable. For this, we check that
14430  * c_k * ceil((maxactivity - rhs)/val) is still better than
14431  * c_k * floor((maxactivity - rhs)/val) + c_j * ((maxactivity - rhs) - (floor((maxactivity - rhs)/val) * val))/a_j.
14432  * In this case, the upper bound of x_k is decreased to ub_k - ceil(maxactivity - rhs).
14433  * If there are variables with a_i < 0 and c_i > 0, they are negated to obtain the above form, variables with same
14434  * sign of coefficients in constraint and objective prevent the use of this method.
14435  */
14436  if( singlevarstuffing && !ismaxsettoinfinity )
14437  {
14438  SCIP_Real bestratio = -SCIPinfinity(scip);
14439  SCIP_Real secondbestratio = -SCIPinfinity(scip);
14440  SCIP_Real ratio;
14441  int bestindex = -1;
14442  int bestuplocks = 0;
14443  int bestdownlocks = 1;
14444  int downlocks;
14445  int uplocks;
14446  SCIPdebug( int oldnfixedvars = *nfixedvars; )
14447  SCIPdebug( int oldnchgbds = *nchgbds; )
14448 
14449  /* loop over all variables to identify the best and second-best ratio */
14450  for( v = 0; v < nvars; ++v )
14451  {
14452  var = vars[v];
14453  obj = SCIPvarGetObj(var);
14454  val = factor * vals[v];
14455 
14456  assert(!SCIPisZero(scip, val));
14457 
14458  ratio = obj / val;
14459 
14460  /* if both objective and constraint push the variable to the same direction, we can do nothing here */
14461  if( !SCIPisNegative(scip, ratio) )
14462  {
14463  bestindex = -1;
14464  break;
14465  }
14466 
14467  if( val > 0 )
14468  {
14471  }
14472  else
14473  {
14474  downlocks = SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL);
14476  }
14477 
14478  /* better ratio, update best candidate
14479  * @todo use some tolerance
14480  * @todo check size of domain and updated ratio for integer variables already?
14481  */
14482  if( ratio > bestratio || ((ratio == bestratio) && downlocks == 0 && (bestdownlocks > 0 /*lint !e777*/
14483  || (SCIPvarGetType(vars[bestindex]) != SCIP_VARTYPE_CONTINUOUS
14484  && SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS))) )
14485  {
14486  /* best index becomes second-best*/
14487  if( bestindex != -1 )
14488  {
14489  /* second-best index must not have more than 1 uplock */
14490  if( bestuplocks > 1 )
14491  {
14492  bestindex = -1;
14493  break;
14494  }
14495  else
14496  {
14497  secondbestratio = bestratio;
14498  }
14499  }
14500  bestdownlocks = downlocks;
14501  bestuplocks = uplocks;
14502  bestratio = ratio;
14503  bestindex = v;
14504 
14505  /* if this variable is the best in the end, we cannot do reductions since it has a downlocks,
14506  * if it is not the best, it has too many uplocks -> not applicable
14507  */
14508  if( bestdownlocks > 0 && bestuplocks > 1 )
14509  {
14510  bestindex = -1;
14511  break;
14512  }
14513  }
14514  else
14515  {
14516  /* non-best index must not have more than 1 uplock */
14517  if( uplocks > 1 )
14518  {
14519  bestindex = -1;
14520  break;
14521  }
14522  /* update second-best ratio */
14523  if( ratio > secondbestratio )
14524  {
14525  secondbestratio = ratio;
14526  }
14527  }
14528  }
14529 
14530  /* check if we can apply single variable stuffing */
14531  if( bestindex != -1 && bestdownlocks == 0 )
14532  {
14533  SCIP_Bool tightened = FALSE;
14534  SCIP_Real bounddelta;
14535 
14536  var = vars[bestindex];
14537  obj = SCIPvarGetObj(var);
14538  val = factor * vals[bestindex];
14539  lb = SCIPvarGetLbGlobal(var);
14540  ub = SCIPvarGetUbGlobal(var);
14541  tryfixing = TRUE;
14542 
14543  if( val < 0 )
14544  {
14545  assert(!SCIPisNegative(scip, obj));
14546 
14547  /* the best variable is integer, and we need to overfulfill the constraint when using just the variable */
14548  if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisIntegral(scip, (maxactivity - rhs)/-val) )
14549  {
14550  SCIP_Real bestvarfloor = SCIPfloor(scip, (maxactivity - rhs)/-val);
14551  SCIP_Real activitydelta = (maxactivity - rhs) - (bestvarfloor * -val);
14552  assert(SCIPisPositive(scip, activitydelta));
14553 
14554  tryfixing = SCIPisLE(scip, obj, -activitydelta * secondbestratio);
14555 
14556  bounddelta = SCIPceil(scip, (maxactivity - rhs)/-val);
14557  assert(SCIPisPositive(scip, bounddelta));
14558  }
14559  else
14560  bounddelta = (maxactivity - rhs)/-val;
14561 
14562  tryfixing = tryfixing && SCIPisLE(scip, bounddelta, ub - lb);
14563 
14564  if( tryfixing )
14565  {
14566  assert(SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == 0);
14567 
14568  if( SCIPisEQ(scip, lb + bounddelta, ub) )
14569  {
14570  SCIPdebugMsg(scip, "fix var <%s> to %g\n", SCIPvarGetName(var), lb + bounddelta);
14571  SCIP_CALL( SCIPfixVar(scip, var, lb + bounddelta, cutoff, &tightened) );
14572  }
14573  else
14574  {
14575  SCIPdebugMsg(scip, "tighten the lower bound of <%s> from %g to %g (ub=%g)\n", SCIPvarGetName(var), lb, lb + bounddelta, ub);
14576  SCIP_CALL( SCIPtightenVarLb(scip, var, lb + bounddelta, FALSE, cutoff, &tightened) );
14577  }
14578  }
14579  }
14580  else
14581  {
14582  assert(!SCIPisPositive(scip, obj));
14583 
14584  /* the best variable is integer, and we need to overfulfill the constraint when using just the variable */
14585  if( SCIPvarGetType(var) != SCIP_VARTYPE_CONTINUOUS && !SCIPisIntegral(scip, (maxactivity - rhs)/val))
14586  {
14587  SCIP_Real bestvarfloor = SCIPfloor(scip, (maxactivity - rhs)/val);
14588  SCIP_Real activitydelta = (maxactivity - rhs) - (bestvarfloor * val);
14589  assert(SCIPisPositive(scip, activitydelta));
14590 
14591  tryfixing = SCIPisLE(scip, -obj, activitydelta * secondbestratio);
14592 
14593  bounddelta = SCIPceil(scip, (maxactivity - rhs)/val);
14594  assert(SCIPisPositive(scip, bounddelta));
14595  }
14596  else
14597  bounddelta = (maxactivity - rhs)/val;
14598 
14599  tryfixing = tryfixing && SCIPisLE(scip, bounddelta, ub - lb);
14600 
14601  if( tryfixing )
14602  {
14603  assert(SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == 0);
14604 
14605  if( SCIPisEQ(scip, ub - bounddelta, lb) )
14606  {
14607  SCIPdebugMsg(scip, "fix var <%s> to %g\n", SCIPvarGetName(var), ub - bounddelta);
14608  SCIP_CALL( SCIPfixVar(scip, var, ub - bounddelta, cutoff, &tightened) );
14609  }
14610  else
14611  {
14612  SCIPdebugMsg(scip, "tighten the upper bound of <%s> from %g to %g (lb=%g)\n", SCIPvarGetName(var), ub, ub - bounddelta, lb);
14613  SCIP_CALL( SCIPtightenVarUb(scip, var, ub - bounddelta, FALSE, cutoff, &tightened) );
14614  }
14615  }
14616  }
14617 
14618  if( *cutoff )
14619  return SCIP_OKAY;
14620  if( tightened )
14621  {
14622  if( SCIPisEQ(scip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)) )
14623  ++(*nfixedvars);
14624  else
14625  ++(*nchgbds);
14626 
14627  SCIPdebugMsg(scip, "cons <%s>: %g <=\n", SCIPconsGetName(cons), factor > 0 ? consdata->lhs : -consdata->rhs);
14628  for( v = 0; v < nvars; ++v )
14629  {
14630  SCIPdebugMsg(scip, "%+g <%s>([%g,%g],%g,[%d,%d],%s)\n", factor * vals[v], SCIPvarGetName(vars[v]),
14631  SCIPvarGetLbGlobal(vars[v]), SCIPvarGetUbGlobal(vars[v]), SCIPvarGetObj(vars[v]),
14634  SCIPvarGetType(vars[v]) == SCIP_VARTYPE_CONTINUOUS ? "C" : "I");
14635  }
14636  SCIPdebugMsg(scip, "<= %g\n", factor > 0 ? consdata->rhs : -consdata->lhs);
14637 
14638  for( v = 0; v < nvars; ++v )
14639  {
14640  if( v == bestindex )
14641  continue;
14642 
14643  if( factor * vals[v] < 0 )
14644  {
14645  assert(SCIPvarGetNLocksDownType(vars[v], SCIP_LOCKTYPE_MODEL) == 1);
14646  SCIPdebugMsg(scip, "fix <%s> to its lower bound (%g)\n",
14647  SCIPvarGetName(vars[v]), SCIPvarGetLbGlobal(vars[v]));
14648  SCIP_CALL( SCIPfixVar(scip, vars[v], SCIPvarGetLbGlobal(vars[v]), cutoff, &tightened) );
14649  }
14650  else
14651  {
14652  assert(SCIPvarGetNLocksUpType(vars[v], SCIP_LOCKTYPE_MODEL) == 1);
14653  SCIPdebugMsg(scip, "fix <%s> to its upper bound (%g)\n",
14654  SCIPvarGetName(vars[v]), SCIPvarGetUbGlobal(vars[v]));
14655  SCIP_CALL( SCIPfixVar(scip, vars[v], SCIPvarGetUbGlobal(vars[v]), cutoff, &tightened) );
14656  }
14657 
14658  if( *cutoff )
14659  return SCIP_OKAY;
14660  if( tightened )
14661  ++(*nfixedvars);
14662  }
14663  SCIPdebug( SCIPdebugMsg(scip, "### new stuffing fixed %d vars, tightened %d bounds\n", *nfixedvars - oldnfixedvars, *nchgbds - oldnchgbds); )
14664  }
14665  }
14666  }
14667 
14668  return SCIP_OKAY;
14669 }
14670 
14671 /** applies full dual presolving on variables that only appear in linear constraints */
14672 static
14674  SCIP* scip, /**< SCIP data structure */
14675  SCIP_CONS** conss, /**< constraint set */
14676  int nconss, /**< number of constraints */
14677  SCIP_Bool* cutoff, /**< pointer to store TRUE, if a cutoff was found */
14678  int* nchgbds /**< pointer to count the number of bound changes */
14679  )
14680 {
14681  SCIP_Real* redlb;
14682  SCIP_Real* redub;
14683  int* nlocksdown;
14684  int* nlocksup;
14685  SCIP_Bool* isimplint;
14686  SCIP_VAR** origvars;
14687  SCIP_VAR** vars;
14688  SCIP_VAR** conscontvars;
14689  int nvars;
14690  int nbinvars;
14691  int nintvars;
14692  int ncontvars;
14693  int v;
14694  int c;
14695 
14696  /* we calculate redundancy bounds with the following meaning:
14697  * redlb[v] == k : if x_v >= k, we can always round x_v down to x_v == k without violating any constraint
14698  * redub[v] == k : if x_v <= k, we can always round x_v up to x_v == k without violating any constraint
14699  * then:
14700  * c_v >= 0 : x_v <= redlb[v] is feasible due to optimality
14701  * c_v <= 0 : x_v >= redub[v] is feasible due to optimality
14702  */
14703 
14704  /* Additionally, we detect continuous variables that are implicitly integral.
14705  * A continuous variable j is implicit integral if it only has only +/-1 coefficients,
14706  * and all constraints (including the bounds as trivial constraints) in which:
14707  * c_j > 0: the variable is down-locked,
14708  * c_j < 0: the variable is up-locked,
14709  * c_j = 0: the variable appears
14710  * have, apart from j, only integer variables with integral coefficients and integral sides.
14711  * This is because then, the value of the variable is either determined by one of its bounds or
14712  * by one of these constraints, and in all cases, the value of the variable is integral.
14713  */
14714 
14715  assert(scip != NULL);
14716  assert(nconss == 0 || conss != NULL);
14717  assert(nchgbds != NULL);
14718  assert(!SCIPinProbing(scip));
14719 
14720  /* get active variables */
14721  nvars = SCIPgetNVars(scip);
14722  origvars = SCIPgetVars(scip);
14723 
14724  /* if the problem is a pure binary program, nothing can be achieved by full dual presolve */
14725  nbinvars = SCIPgetNBinVars(scip);
14726  if( nbinvars == nvars )
14727  return SCIP_OKAY;
14728 
14729  /* get number of continuous variables */
14730  ncontvars = SCIPgetNContVars(scip);
14731  nintvars = nvars - ncontvars;
14732 
14733  /* copy the variable array since this array might change during the curse of this algorithm */
14734  nvars = nvars - nbinvars;
14735  SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, &(origvars[nbinvars]), nvars) );
14736 
14737  /* allocate temporary memory */
14738  SCIP_CALL( SCIPallocBufferArray(scip, &redlb, nvars) );
14739  SCIP_CALL( SCIPallocBufferArray(scip, &redub, nvars) );
14740  SCIP_CALL( SCIPallocBufferArray(scip, &nlocksdown, nvars) );
14741  SCIP_CALL( SCIPallocBufferArray(scip, &nlocksup, nvars) );
14742  SCIP_CALL( SCIPallocBufferArray(scip, &isimplint, ncontvars) );
14743  SCIP_CALL( SCIPallocBufferArray(scip, &conscontvars, ncontvars) );
14744 
14745  /* initialize redundancy bounds */
14746  for( v = 0; v < nvars; ++v )
14747  {
14748  assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_BINARY);
14749  redlb[v] = SCIPvarGetLbGlobal(vars[v]);
14750  redub[v] = SCIPvarGetUbGlobal(vars[v]);
14751  }
14752  BMSclearMemoryArray(nlocksdown, nvars);
14753  BMSclearMemoryArray(nlocksup, nvars);
14754 
14755  /* Initialize isimplint array: variable may be implied integer if rounded to their best bound they are integral.
14756  * We better not use SCIPisFeasIntegral() in these checks.
14757  */
14758  for( v = 0; v < ncontvars; v++ )
14759  {
14760  SCIP_VAR* var;
14761  SCIP_Real obj;
14762  SCIP_Real lb;
14763  SCIP_Real ub;
14764 
14765  var = vars[v + nintvars - nbinvars];
14766  lb = SCIPvarGetLbGlobal(var);
14767  ub = SCIPvarGetUbGlobal(var);
14768 
14769  obj = SCIPvarGetObj(var);
14770  if( SCIPisZero(scip, obj) )
14771  isimplint[v] = (SCIPisInfinity(scip, -lb) || SCIPisIntegral(scip, lb)) && (SCIPisInfinity(scip, ub) || SCIPisIntegral(scip, ub));
14772  else
14773  {
14774  if( SCIPisPositive(scip, obj) )
14775  isimplint[v] = (SCIPisInfinity(scip, -lb) || SCIPisIntegral(scip, lb));
14776  else
14777  {
14778  assert(SCIPisNegative(scip, obj));
14779  isimplint[v] = (SCIPisInfinity(scip, ub) || SCIPisIntegral(scip, ub));
14780  }
14781  }
14782  }
14783 
14784  /* scan all constraints */
14785  for( c = 0; c < nconss; ++c )
14786  {
14787  /* we only need to consider constraints that have been locked (i.e., checked constraints or constraints that are
14788  * part of checked disjunctions)
14789  */
14790  if( SCIPconsIsLocked(conss[c]) )
14791  {
14792  SCIP_CONSDATA* consdata;
14793  SCIP_Bool lhsexists;
14794  SCIP_Bool rhsexists;
14795  SCIP_Bool hasimpliedpotential;
14796  SCIP_Bool integralcoefs;
14797  int nlockspos;
14798  int contvarpos;
14799  int nconscontvars;
14800  int i;
14801 
14802  consdata = SCIPconsGetData(conss[c]);
14803  assert(consdata != NULL);
14804 
14805  /* get number of times the constraint was locked */
14806  nlockspos = SCIPconsGetNLocksPos(conss[c]);
14807 
14808  /* we do not want to include constraints with locked negation (this would be too weird) */
14809  if( SCIPconsGetNLocksNeg(conss[c]) > 0 )
14810  {
14811  /* mark all continuous variables as not being implicit integral */
14812  for( i = 0; i < consdata->nvars; ++i )
14813  {
14814  SCIP_VAR* var;
14815 
14816  var = consdata->vars[i];
14818  {
14819  int contv;
14820  contv = SCIPvarGetProbindex(var) - nintvars;
14821  assert(0 <= contv && contv < ncontvars); /* variable should be active due to applyFixings() */
14822  isimplint[contv] = FALSE;
14823  }
14824  }
14825  continue;
14826  }
14827 
14828  /* check for existing sides */
14829  lhsexists = !SCIPisInfinity(scip, -consdata->lhs);
14830  rhsexists = !SCIPisInfinity(scip, consdata->rhs);
14831 
14832  /* count locks and update redundancy bounds */
14833  contvarpos = -1;
14834  nconscontvars = 0;
14835  hasimpliedpotential = FALSE;
14836  integralcoefs = !SCIPconsIsModifiable(conss[c]);
14837 
14838  for( i = 0; i < consdata->nvars; ++i )
14839  {
14840  SCIP_VAR* var;
14841  SCIP_Real val;
14842  SCIP_Real minresactivity;
14843  SCIP_Real maxresactivity;
14844  SCIP_Real newredlb;
14845  SCIP_Real newredub;
14846  SCIP_Bool minisrelax;
14847  SCIP_Bool maxisrelax;
14848  SCIP_Bool isminsettoinfinity;
14849  SCIP_Bool ismaxsettoinfinity;
14850  int arrayindex;
14851 
14852  var = consdata->vars[i];
14853  val = consdata->vals[i];
14854 
14855  /* check if still all integer variables have integral coefficients */
14856  if( SCIPvarIsIntegral(var) )
14857  integralcoefs = integralcoefs && SCIPisIntegral(scip, val);
14858 
14859  /* we do not need to process binary variables */
14860  if( SCIPvarIsBinary(var) )
14861  continue;
14862 
14863  if( SCIPconsIsModifiable(conss[c]) )
14864  {
14865  minresactivity = -SCIPinfinity(scip);
14866  maxresactivity = SCIPinfinity(scip);
14867  isminsettoinfinity = TRUE;
14868  ismaxsettoinfinity = TRUE;
14869  }
14870  else
14871  {
14872  /* calculate residual activity bounds if variable would be fixed to zero */
14873  consdataGetGlbActivityResiduals(scip, consdata, var, val, FALSE, &minresactivity, &maxresactivity,
14874  &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
14875 
14876  /* We called consdataGetGlbActivityResiduals() saying that we do not need a good relaxation,
14877  * so whenever we have a relaxed activity, it should be relaxed to +/- infinity.
14878  * This is needed, because we do not want to rely on relaxed finite resactivities.
14879  */
14880  assert((!minisrelax || isminsettoinfinity) && (!maxisrelax || ismaxsettoinfinity));
14881 
14882  /* check minresactivity for reliability */
14883  if( !isminsettoinfinity && SCIPisUpdateUnreliable(scip, minresactivity, consdata->lastglbminactivity) )
14884  consdataGetReliableResidualActivity(scip, consdata, var, &minresactivity, TRUE, TRUE);
14885 
14886  /* check maxresactivity for reliability */
14887  if( !ismaxsettoinfinity && SCIPisUpdateUnreliable(scip, maxresactivity, consdata->lastglbmaxactivity) )
14888  consdataGetReliableResidualActivity(scip, consdata, var, &maxresactivity, FALSE, TRUE);
14889  }
14890 
14891  arrayindex = SCIPvarGetProbindex(var) - nbinvars;
14892 
14893  assert(0 <= arrayindex && arrayindex < nvars); /* variable should be active due to applyFixings() */
14894 
14895  newredlb = redlb[arrayindex];
14896  newredub = redub[arrayindex];
14897  if( val > 0.0 )
14898  {
14899  if( lhsexists )
14900  {
14901  /* lhs <= d*x + a*y, d > 0 -> redundant in y if x >= (lhs - min{a*y})/d */
14902  nlocksdown[arrayindex] += nlockspos;
14903  newredlb = (isminsettoinfinity ? SCIPinfinity(scip) : (consdata->lhs - minresactivity)/val);
14904  }
14905  if( rhsexists )
14906  {
14907  /* d*x + a*y <= rhs, d > 0 -> redundant in y if x <= (rhs - max{a*y})/d */
14908  nlocksup[arrayindex] += nlockspos;
14909  newredub = (ismaxsettoinfinity ? -SCIPinfinity(scip) : (consdata->rhs - maxresactivity)/val);
14910  }
14911  }
14912  else
14913  {
14914  if( lhsexists )
14915  {
14916  /* lhs <= d*x + a*y, d < 0 -> redundant in y if x <= (lhs - min{a*y})/d */
14917  nlocksup[arrayindex] += nlockspos;
14918  newredub = (isminsettoinfinity ? -SCIPinfinity(scip) : (consdata->lhs - minresactivity)/val);
14919  }
14920  if( rhsexists )
14921  {
14922  /* d*x + a*y <= rhs, d < 0 -> redundant in y if x >= (rhs - max{a*y})/d */
14923  nlocksdown[arrayindex] += nlockspos;
14924  newredlb = (ismaxsettoinfinity ? SCIPinfinity(scip) : (consdata->rhs - maxresactivity)/val);
14925  }
14926  }
14927 
14928  /* if the variable is integer, we have to round the value to the next integral value */
14929  if( SCIPvarIsIntegral(var) )
14930  {
14931  if( !SCIPisInfinity(scip, newredlb) )
14932  newredlb = SCIPceil(scip, newredlb);
14933  if( !SCIPisInfinity(scip, -newredub) )
14934  newredub = SCIPfloor(scip, newredub);
14935  }
14936 
14937  /* update redundancy bounds */
14938  redlb[arrayindex] = MAX(redlb[arrayindex], newredlb);
14939  redub[arrayindex] = MIN(redub[arrayindex], newredub);
14940 
14941  /* collect the continuous variables of the constraint */
14943  {
14944  int contv;
14945 
14946  assert(nconscontvars < ncontvars);
14947  contvarpos = i;
14948  conscontvars[nconscontvars] = var;
14949  nconscontvars++;
14950 
14951  contv = SCIPvarGetProbindex(var) - nintvars;
14952  assert(0 <= contv && contv < ncontvars);
14953  hasimpliedpotential = hasimpliedpotential || isimplint[contv];
14954  }
14955  }
14956 
14957  /* update implied integer status of continuous variables */
14958  if( hasimpliedpotential )
14959  {
14960  if( nconscontvars > 1 || !integralcoefs )
14961  {
14962  /* there is more than one continuous variable or the integer variables have fractional coefficients:
14963  * none of the continuous variables is implied integer
14964  */
14965  for( i = 0; i < nconscontvars; i++ )
14966  {
14967  int contv;
14968  contv = SCIPvarGetProbindex(conscontvars[i]) - nintvars;
14969  assert(0 <= contv && contv < ncontvars);
14970  isimplint[contv] = FALSE;
14971  }
14972  }
14973  else
14974  {
14975  SCIP_VAR* var;
14976  SCIP_Real val;
14977  SCIP_Real absval;
14978  int contv;
14979 
14980  /* there is exactly one continuous variable and the integer variables have integral coefficients:
14981  * this is the interesting case, and we have to check whether the coefficient is +/-1 and the corresponding
14982  * side(s) of the constraint is integral
14983  */
14984  assert(nconscontvars == 1);
14985  assert(0 <= contvarpos && contvarpos < consdata->nvars);
14986  var = consdata->vars[contvarpos];
14987  val = consdata->vals[contvarpos];
14988  contv = SCIPvarGetProbindex(var) - nintvars;
14989  assert(0 <= contv && contv < ncontvars);
14990  assert(isimplint[contv]);
14991 
14992  absval = REALABS(val);
14993  if( !SCIPisEQ(scip, absval, 1.0) )
14994  isimplint[contv] = FALSE;
14995  else
14996  {
14997  SCIP_Real obj;
14998 
14999  obj = SCIPvarGetObj(var);
15000  if( obj * val >= 0.0 && lhsexists )
15001  {
15002  /* the variable may be blocked by the constraint's left hand side */
15003  isimplint[contv] = isimplint[contv] && SCIPisIntegral(scip, consdata->lhs);
15004  }
15005  if( obj * val <= 0.0 && rhsexists )
15006  {
15007  /* the variable may be blocked by the constraint's left hand side */
15008  isimplint[contv] = isimplint[contv] && SCIPisIntegral(scip, consdata->rhs);
15009  }
15010  }
15011  }
15012  }
15013  }
15014  }
15015 
15016  /* check if any bounds can be tightened due to optimality */
15017  for( v = 0; v < nvars; ++v )
15018  {
15019  SCIP_VAR* var;
15020  SCIP_Real obj;
15021  SCIP_Bool infeasible;
15022  SCIP_Bool tightened;
15023 
15024  assert(SCIPvarGetType(vars[v]) != SCIP_VARTYPE_BINARY);
15025  assert(SCIPvarGetNLocksDownType(vars[v], SCIP_LOCKTYPE_MODEL) >= nlocksdown[v]);
15026  assert(SCIPvarGetNLocksUpType(vars[v], SCIP_LOCKTYPE_MODEL) >= nlocksup[v]);
15027 
15028  var = vars[v];
15029  obj = SCIPvarGetObj(var);
15030  if( obj >= 0.0 )
15031  {
15032  /* making the variable as small as possible does not increase the objective:
15033  * check if all down locks of the variables are due to linear constraints;
15034  * if largest bound to make constraints redundant is -infinity, we better do nothing for numerical reasons
15035  */
15036  if( SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == nlocksdown[v]
15037  && !SCIPisInfinity(scip, -redlb[v])
15038  && redlb[v] < SCIPvarGetUbGlobal(var) )
15039  {
15040  SCIP_Real ub;
15041 
15042  /* if x_v >= redlb[v], we can always round x_v down to x_v == redlb[v] without violating any constraint
15043  * -> tighten upper bound to x_v <= redlb[v]
15044  */
15045  SCIPdebugMsg(scip, "variable <%s> only locked down in linear constraints: dual presolve <%s>[%.15g,%.15g] <= %.15g\n",
15047  redlb[v]);
15048  SCIP_CALL( SCIPtightenVarUb(scip, var, redlb[v], FALSE, &infeasible, &tightened) );
15049  assert(!infeasible);
15050 
15051  ub = SCIPvarGetUbGlobal(var);
15052  redub[v] = MIN(redub[v], ub);
15053  if( tightened )
15054  (*nchgbds)++;
15055  }
15056  }
15057  if( obj <= 0.0 )
15058  {
15059  /* making the variable as large as possible does not increase the objective:
15060  * check if all up locks of the variables are due to linear constraints;
15061  * if smallest bound to make constraints redundant is +infinity, we better do nothing for numerical reasons
15062  */
15063  if( SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == nlocksup[v]
15064  && !SCIPisInfinity(scip, redub[v])
15065  && redub[v] > SCIPvarGetLbGlobal(var) )
15066  {
15067  SCIP_Real lb;
15068 
15069  /* if x_v <= redub[v], we can always round x_v up to x_v == redub[v] without violating any constraint
15070  * -> tighten lower bound to x_v >= redub[v]
15071  */
15072  SCIPdebugMsg(scip, "variable <%s> only locked up in linear constraints: dual presolve <%s>[%.15g,%.15g] >= %.15g\n",
15074  redub[v]);
15075  SCIP_CALL( SCIPtightenVarLb(scip, var, redub[v], FALSE, &infeasible, &tightened) );
15076  assert(!infeasible);
15077 
15078  lb = SCIPvarGetLbGlobal(var);
15079  redlb[v] = MAX(redlb[v], lb);
15080  if( tightened )
15081  (*nchgbds)++;
15082  }
15083  }
15084  }
15085 
15086  /* upgrade continuous variables to implied integers */
15087  for( v = nintvars - nbinvars; v < nvars; ++v )
15088  {
15089  SCIP_VAR* var;
15090  SCIP_Bool infeasible;
15091 
15092  var = vars[v];
15093  assert(var != NULL);
15094 
15095  assert(SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS);
15096  assert(SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) >= nlocksdown[v]);
15097  assert(SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) >= nlocksup[v]);
15098  assert(0 <= v - nintvars + nbinvars && v - nintvars + nbinvars < ncontvars);
15099 
15100  /* we can only conclude implied integrality if the variable appears in no other constraint */
15101  if( isimplint[v - nintvars + nbinvars]
15102  && SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) == nlocksdown[v]
15103  && SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) == nlocksup[v] )
15104  {
15105  /* since we locally copied the variable array we can change the variable type immediately */
15106  SCIP_CALL( SCIPchgVarType(scip, var, SCIP_VARTYPE_IMPLINT, &infeasible) );
15107 
15108  if( infeasible )
15109  {
15110  SCIPdebugMsg(scip, "infeasible upgrade of variable <%s> to integral type, domain is empty\n", SCIPvarGetName(var));
15111  *cutoff = TRUE;
15112 
15113  break;
15114  }
15115 
15116  SCIPdebugMsg(scip, "dual presolve: converting continuous variable <%s>[%g,%g] to implicit integer\n",
15118  }
15119  }
15120 
15121  /* free temporary memory */
15122  SCIPfreeBufferArray(scip, &conscontvars);
15123  SCIPfreeBufferArray(scip, &isimplint);
15124  SCIPfreeBufferArray(scip, &nlocksup);
15125  SCIPfreeBufferArray(scip, &nlocksdown);
15126  SCIPfreeBufferArray(scip, &redub);
15127  SCIPfreeBufferArray(scip, &redlb);
15128 
15129  SCIPfreeBufferArray(scip, &vars);
15130 
15131  return SCIP_OKAY;
15132 }
15133 
15134 /** helper function to enforce constraints */
15135 static
15137  SCIP* scip, /**< SCIP data structure */
15138  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
15139  SCIP_CONS** conss, /**< constraints to process */
15140  int nconss, /**< number of constraints */
15141  int nusefulconss, /**< number of useful (non-obsolete) constraints to process */
15142  SCIP_SOL* sol, /**< solution to enforce (NULL for the LP solution) */
15143  SCIP_RESULT* result /**< pointer to store the result of the enforcing call */
15144  )
15145 {
15146  SCIP_CONSHDLRDATA* conshdlrdata;
15147  SCIP_Bool checkrelmaxabs;
15148  SCIP_Bool violated;
15149  SCIP_Bool cutoff = FALSE;
15150  int c;
15151 
15152  assert(scip != NULL);
15153  assert(conshdlr != NULL);
15154  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15155  assert(result != NULL);
15156 
15157  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15158  assert(conshdlrdata != NULL);
15159 
15160  checkrelmaxabs = conshdlrdata->checkrelmaxabs;
15161 
15162  SCIPdebugMsg(scip, "Enforcement method of linear constraints for %s solution\n", sol == NULL ? "LP" : "relaxation");
15163 
15164  /* check for violated constraints
15165  * LP is processed at current node -> we can add violated linear constraints to the SCIP_LP
15166  */
15167  *result = SCIP_FEASIBLE;
15168 
15169  /* check all useful linear constraints for feasibility */
15170  for( c = 0; c < nusefulconss; ++c )
15171  {
15172  SCIP_CALL( checkCons(scip, conss[c], sol, FALSE, checkrelmaxabs, &violated) );
15173 
15174  if( violated )
15175  {
15176  /* insert LP row as cut */
15177  SCIP_CALL( addRelaxation(scip, conss[c], &cutoff) );
15178  if ( cutoff )
15179  *result = SCIP_CUTOFF;
15180  else
15181  *result = SCIP_SEPARATED;
15182  }
15183  }
15184 
15185  /* check all obsolete linear constraints for feasibility */
15186  for( c = nusefulconss; c < nconss && *result == SCIP_FEASIBLE; ++c )
15187  {
15188  SCIP_CALL( checkCons(scip, conss[c], sol, FALSE, checkrelmaxabs, &violated) );
15189 
15190  if( violated )
15191  {
15192  /* insert LP row as cut */
15193  SCIP_CALL( addRelaxation(scip, conss[c], &cutoff) );
15194  if ( cutoff )
15195  *result = SCIP_CUTOFF;
15196  else
15197  *result = SCIP_SEPARATED;
15198  }
15199  }
15200 
15201  SCIPdebugMsg(scip, "-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
15202 
15203  return SCIP_OKAY;
15204 }
15205 
15206 /*
15207  * Callback methods of constraint handler
15208  */
15209 
15210 /** copy method for constraint handler plugins (called when SCIP copies plugins) */
15211 static
15212 SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinear)
15213 { /*lint --e{715}*/
15214  assert(scip != NULL);
15215  assert(conshdlr != NULL);
15216  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15217 
15218  /* call inclusion method of constraint handler */
15220 
15221  *valid = TRUE;
15222 
15223  return SCIP_OKAY;
15224 }
15225 
15226 /** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
15227 static
15228 SCIP_DECL_CONSFREE(consFreeLinear)
15229 { /*lint --e{715}*/
15230  SCIP_CONSHDLRDATA* conshdlrdata;
15232  assert(scip != NULL);
15233  assert(conshdlr != NULL);
15234  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15235 
15236  /* free constraint handler data */
15237  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15238  assert(conshdlrdata != NULL);
15239 
15240  conshdlrdataFree(scip, &conshdlrdata);
15241 
15242  SCIPconshdlrSetData(conshdlr, NULL);
15243 
15244  return SCIP_OKAY;
15245 }
15246 
15248 /** initialization method of constraint handler (called after problem was transformed) */
15249 static
15250 SCIP_DECL_CONSINIT(consInitLinear)
15251 {
15252  SCIP_CONSHDLRDATA* conshdlrdata;
15253  int c;
15254 
15255  assert(scip != NULL);
15256 
15257  /* check for event handler */
15258  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15259  assert(conshdlrdata != NULL);
15260  assert(conshdlrdata->eventhdlr != NULL);
15261  assert(nconss == 0 || conss != NULL);
15262 
15263  conshdlrdata->naddconss = 0;
15264 
15265  /* catch events for the constraints */
15266  for( c = 0; c < nconss; ++c )
15267  {
15268  /* catch all events */
15269  SCIP_CALL( consCatchAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
15270  }
15271 
15272  return SCIP_OKAY;
15273 }
15274 
15275 
15276 /** deinitialization method of constraint handler (called before transformed problem is freed) */
15277 static
15278 SCIP_DECL_CONSEXIT(consExitLinear)
15279 {
15280  SCIP_CONSHDLRDATA* conshdlrdata;
15281  int c;
15282 
15283  assert(scip != NULL);
15284 
15285  /* check for event handler */
15286  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15287  assert(conshdlrdata != NULL);
15288  assert(conshdlrdata->eventhdlr != NULL);
15289 
15290  /* drop events for the constraints */
15291  for( c = nconss - 1; c >= 0; --c )
15292  {
15293  SCIP_CONSDATA* consdata;
15294 
15295  consdata = SCIPconsGetData(conss[c]);
15296  assert(consdata != NULL);
15298  if( consdata->eventdata != NULL )
15299  {
15300  /* drop all events */
15301  SCIP_CALL( consDropAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
15302  assert(consdata->eventdata == NULL);
15303  }
15304  }
15305 
15306  return SCIP_OKAY;
15307 }
15308 
15309 /** is constraint ranged row, i.e., -inf < lhs < rhs < inf? */
15310 static
15312  SCIP* scip, /**< SCIP data structure */
15313  SCIP_Real lhs, /**< left hand side */
15314  SCIP_Real rhs /**< right hand side */
15315  )
15316 {
15317  assert(scip != NULL);
15318 
15319  return !(SCIPisEQ(scip, lhs, rhs) || SCIPisInfinity(scip, -lhs) || SCIPisInfinity(scip, rhs) );
15320 }
15321 
15322 /** is constraint ranged row, i.e., -inf < lhs < rhs < inf? */
15323 static
15325  SCIP* scip, /**< SCIP data structure */
15326  SCIP_Real x /**< value */
15327  )
15328 {
15329  assert(scip != NULL);
15331  return (!SCIPisInfinity(scip, x) && !SCIPisNegative(scip, x) && SCIPisIntegral(scip, x));
15332 }
15333 
15334 /** performs linear constraint type classification as used for MIPLIB
15335  *
15336  * iterates through all linear constraints and stores relevant statistics in the linear constraint statistics \p linconsstats.
15337  *
15338  * @note only constraints are iterated that belong to the linear constraint handler. If the problem has been presolved already,
15339  * constraints that were upgraded to more special types such as, e.g., varbound constraints, will not be shown correctly anymore.
15340  * Similarly, if specialized constraints were created through the API, these are currently not present.
15341  */
15343  SCIP* scip, /**< SCIP data structure */
15344  SCIP_LINCONSSTATS* linconsstats /**< linear constraint type classification */
15345  )
15346 {
15347  int c;
15348  SCIP_CONSHDLR* conshdlr;
15349  SCIP_CONS** conss;
15350  int nconss;
15351 
15352  assert(scip != NULL);
15353  assert(linconsstats != NULL);
15354  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
15355  assert(conshdlr != NULL);
15356 
15357  if( SCIPgetStage(scip) == SCIP_STAGE_PROBLEM )
15358  {
15359  conss = SCIPgetConss(scip);
15360  nconss = SCIPgetNConss(scip);
15361  }
15362  else
15363  {
15364  conss = SCIPconshdlrGetConss(conshdlr);
15365  nconss = SCIPconshdlrGetNConss(conshdlr);
15366  }
15367 
15368  /* reset linear constraint type classification */
15369  SCIPlinConsStatsReset(linconsstats);
15370 
15371  /* loop through all constraints */
15372  for( c = 0; c < nconss; c++ )
15373  {
15374  SCIP_CONS* cons;
15375  SCIP_CONSDATA* consdata;
15376  SCIP_Real lhs;
15377  SCIP_Real rhs;
15378  int i;
15379 
15380  /* get constraint */
15381  cons = conss[c];
15382  assert(cons != NULL);
15383 
15384  /* skip constraints that are not handled by the constraint handler */
15385  if( SCIPconsGetHdlr(cons) != conshdlr )
15386  continue;
15387 
15388  /* get constraint data */
15389  consdata = SCIPconsGetData(cons);
15390  assert(consdata != NULL);
15391  rhs = consdata->rhs;
15392  lhs = consdata->lhs;
15393 
15394  /* merge multiples and delete variables with zero coefficient */
15395  SCIP_CALL( mergeMultiples(scip, cons) );
15396  for( i = 0; i < consdata->nvars; i++ )
15397  {
15398  assert(!SCIPisZero(scip, consdata->vals[i]));
15399  }
15400 
15401  /* is constraint of type SCIP_CONSTYPE_EMPTY? */
15402  if( consdata->nvars == 0 )
15403  {
15404  SCIPdebugMsg(scip, "classified as EMPTY: ");
15405  SCIPdebugPrintCons(scip, cons, NULL);
15407 
15408  continue;
15409  }
15410 
15411  /* is constraint of type SCIP_CONSTYPE_FREE? */
15412  if( SCIPisInfinity(scip, rhs) && SCIPisInfinity(scip, -lhs) )
15413  {
15414  SCIPdebugMsg(scip, "classified as FREE: ");
15415  SCIPdebugPrintCons(scip, cons, NULL);
15417 
15418  continue;
15419  }
15420 
15421  /* is constraint of type SCIP_CONSTYPE_SINGLETON? */
15422  if( consdata->nvars == 1 )
15423  {
15424  SCIPdebugMsg(scip, "classified as SINGLETON: ");
15425  SCIPdebugPrintCons(scip, cons, NULL);
15426  SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_SINGLETON, isRangedRow(scip, lhs, rhs) ? 2 : 1);
15427 
15428  continue;
15429  }
15430 
15431  /* is constraint of type SCIP_CONSTYPE_AGGREGATION? */
15432  if( consdata->nvars == 2 && SCIPisEQ(scip, lhs, rhs) )
15433  {
15434  SCIPdebugMsg(scip, "classified as AGGREGATION: ");
15435  SCIPdebugPrintCons(scip, cons, NULL);
15437 
15438  continue;
15439  }
15440 
15441  /* is constraint of type SCIP_CONSTYPE_{VARBOUND,PRECEDENCE}? */
15442  if( consdata->nvars == 2 )
15443  {
15444  SCIP_LINCONSTYPE constype;
15445 
15446  /* precedence constraints have the same coefficient, but with opposite sign for the same variable type */
15447  if( SCIPisEQ(scip, consdata->vals[0], -consdata->vals[1])
15448  && SCIPvarGetType(consdata->vars[0]) == SCIPvarGetType(consdata->vars[1]))
15449  {
15450  constype = SCIP_LINCONSTYPE_PRECEDENCE;
15451  SCIPdebugMsg(scip, "classified as PRECEDENCE: ");
15452  }
15453  else
15454  {
15455  constype = SCIP_LINCONSTYPE_VARBOUND;
15456  SCIPdebugMsg(scip, "classified as VARBOUND: ");
15457  }
15458  SCIPdebugPrintCons(scip, cons, NULL);
15459 
15460  SCIPlinConsStatsIncTypeCount(linconsstats, constype, isRangedRow(scip, lhs, rhs) ? 2 : 1);
15461 
15462  continue;
15463  }
15464 
15465  /* is constraint of type SCIP_CONSTYPE_{SETPARTITION, SETPACKING, SETCOVERING, CARDINALITY, INVKNAPSACK}? */
15466  {
15467  SCIP_Real scale;
15468  SCIP_Real b;
15469  SCIP_Bool unmatched;
15470  int nnegbinvars;
15471 
15472  unmatched = FALSE;
15473  nnegbinvars = 0;
15474 
15475  scale = REALABS(consdata->vals[0]);
15476 
15477  /* scan through variables and detect if all variables are binary and have a coefficient +/-1 */
15478  for( i = 0; i < consdata->nvars && !unmatched; i++ )
15479  {
15480  unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
15481  unmatched = unmatched || SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0);
15482  unmatched = unmatched || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0);
15483  unmatched = unmatched || !SCIPisEQ(scip, REALABS(consdata->vals[i]), scale);
15484 
15485  if( consdata->vals[i] < 0.0 )
15486  nnegbinvars++;
15487  }
15488 
15489  if( !unmatched )
15490  {
15491  if( SCIPisEQ(scip, lhs, rhs) )
15492  {
15493  b = rhs/scale + nnegbinvars;
15494  if( SCIPisEQ(scip, 1.0, b) )
15495  {
15496  SCIPdebugMsg(scip, "classified as SETPARTITION: ");
15497  SCIPdebugPrintCons(scip, cons, NULL);
15499 
15500  continue;
15501  }
15502  else if( SCIPisIntegral(scip, b) && !SCIPisNegative(scip, b) )
15503  {
15504  SCIPdebugMsg(scip, "classified as CARDINALITY: ");
15505  SCIPdebugPrintCons(scip, cons, NULL);
15507 
15508  continue;
15509  }
15510  }
15511 
15512  /* compute right hand side divided by scale */
15513  if( !SCIPisInfinity(scip, rhs) )
15514  b = rhs/scale + nnegbinvars;
15515  else
15516  b = SCIPinfinity(scip);
15517 
15518  if( SCIPisEQ(scip, 1.0, b) )
15519  {
15520  SCIPdebugMsg(scip, "classified as SETPACKING: ");
15521  SCIPdebugPrintCons(scip, cons, NULL);
15523 
15524  /* relax right hand side to prevent further classifications */
15525  rhs = SCIPinfinity(scip);
15526  }
15527  else if( !SCIPisInfinity(scip, b) && SCIPisIntegral(scip, b) && !SCIPisNegative(scip, b) )
15528  {
15529  SCIPdebugMsg(scip, "classified as INVKNAPSACK: ");
15530  SCIPdebugPrintCons(scip, cons, NULL);
15531 
15533 
15534  /* relax right hand side to prevent further classifications */
15535  rhs = SCIPinfinity(scip);
15536  }
15537 
15538  if( !SCIPisInfinity(scip, lhs) )
15539  b = lhs/scale + nnegbinvars;
15540  else
15541  b = SCIPinfinity(scip);
15542 
15543  if( SCIPisEQ(scip, 1.0, b) )
15544  {
15545  SCIPdebugMsg(scip, "classified as SETCOVERING: ");
15546  SCIPdebugPrintCons(scip, cons, NULL);
15548 
15549  /* relax left hand side to prevent further classifications */
15550  lhs = -SCIPinfinity(scip);
15551  }
15552 
15553  /* if both sides are infinite at this point, no further classification is necessary for this constraint */
15554  if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
15555  continue;
15556  }
15557  }
15558 
15559  /* is constraint of type SCIP_CONSTYPE_{EQKNAPSACK, BINPACKING, KNAPSACK}? */
15560  /* @todo If coefficients or rhs are not integral, we currently do not check
15561  * if the constraint could be scaled (finitely), such that they are.
15562  */
15563  {
15564  SCIP_Real b;
15565  SCIP_Bool unmatched;
15566 
15567  b = rhs;
15568  unmatched = FALSE;
15569  for( i = 0; i < consdata->nvars && !unmatched; i++ )
15570  {
15571  unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
15572  unmatched = unmatched || SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0);
15573  unmatched = unmatched || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0);
15574  unmatched = unmatched || !SCIPisIntegral(scip, consdata->vals[i]);
15575 
15576  if( SCIPisNegative(scip, consdata->vals[i]) )
15577  b -= consdata->vals[i];
15578  }
15579  unmatched = unmatched || !isFiniteNonnegativeIntegral(scip, b);
15580 
15581  if( !unmatched )
15582  {
15583  if( SCIPisEQ(scip, lhs, rhs) )
15584  {
15585  SCIPdebugMsg(scip, "classified as EQKNAPSACK: ");
15586  SCIPdebugPrintCons(scip, cons, NULL);
15587 
15589 
15590  continue;
15591  }
15592  else
15593  {
15594  SCIP_Bool matched;
15595 
15596  matched = FALSE;
15597  for( i = 0; i < consdata->nvars && !matched; i++ )
15598  {
15599  matched = matched || SCIPisEQ(scip, b, REALABS(consdata->vals[i]));
15600  }
15601 
15602  SCIPdebugMsg(scip, "classified as %s: ", matched ? "BINPACKING" : "KNAPSACK");
15603  SCIPdebugPrintCons(scip, cons, NULL);
15605  }
15606 
15607  /* check if finite left hand side allows for a second classification, relax already used right hand side */
15608  if( SCIPisInfinity(scip, -lhs) )
15609  continue;
15610  else
15611  rhs = SCIPinfinity(scip);
15612  }
15613  }
15614 
15615  /* is constraint of type SCIP_CONSTYPE_{INTKNAPSACK}? */
15616  {
15617  SCIP_Real b;
15618  SCIP_Bool unmatched;
15619 
15620  unmatched = FALSE;
15621 
15622  b = rhs;
15623  unmatched = unmatched || !isFiniteNonnegativeIntegral(scip, b);
15624 
15625  for( i = 0; i < consdata->nvars && !unmatched; i++ )
15626  {
15627  unmatched = unmatched || SCIPvarGetType(consdata->vars[i]) == SCIP_VARTYPE_CONTINUOUS;
15628  unmatched = unmatched || SCIPisNegative(scip, SCIPvarGetLbGlobal(consdata->vars[i]));
15629  unmatched = unmatched || !SCIPisIntegral(scip, consdata->vals[i]);
15630  unmatched = unmatched || SCIPisNegative(scip, consdata->vals[i]);
15631  }
15632 
15633  if( !unmatched )
15634  {
15635  SCIPdebugMsg(scip, "classified as INTKNAPSACK: ");
15636  SCIPdebugPrintCons(scip, cons, NULL);
15638 
15639  /* check if finite left hand side allows for a second classification, relax already used right hand side */
15640  if( SCIPisInfinity(scip, -lhs) )
15641  continue;
15642  else
15643  rhs = SCIPinfinity(scip);
15644  }
15645  }
15646 
15647  /* is constraint of type SCIP_CONSTYPE_{MIXEDBINARY}? */
15648  {
15649  SCIP_Bool unmatched;
15650 
15651  unmatched = FALSE;
15652  for( i = 0; i < consdata->nvars && !unmatched; i++ )
15653  {
15654  if( SCIPvarGetType(consdata->vars[i]) != SCIP_VARTYPE_CONTINUOUS
15655  && (SCIPisLE(scip, SCIPvarGetLbGlobal(consdata->vars[i]), -1.0)
15656  || SCIPisGE(scip, SCIPvarGetUbGlobal(consdata->vars[i]), 2.0)) )
15657  unmatched = TRUE;
15658  }
15659 
15660  if( !unmatched )
15661  {
15662  SCIPdebugMsg(scip, "classified as MIXEDBINARY (%d): ", isRangedRow(scip, lhs, rhs) ? 2 : 1);
15663  SCIPdebugPrintCons(scip, cons, NULL);
15664  SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_MIXEDBINARY, isRangedRow(scip, lhs, rhs) ? 2 : 1);
15665 
15666  continue;
15667  }
15668  }
15669 
15670  /* no special structure detected */
15671  SCIPdebugMsg(scip, "classified as GENERAL: ");
15672  SCIPdebugPrintCons(scip, cons, NULL);
15673  SCIPlinConsStatsIncTypeCount(linconsstats, SCIP_LINCONSTYPE_GENERAL, isRangedRow(scip, lhs, rhs) ? 2 : 1);
15674  }
15675 
15676  return SCIP_OKAY;
15677 }
15678 
15679 
15680 /** presolving deinitialization method of constraint handler (called after presolving has been finished) */
15681 static
15682 SCIP_DECL_CONSEXITPRE(consExitpreLinear)
15683 { /*lint --e{715}*/
15684  int c;
15685 #ifdef SCIP_STATISTIC
15686  SCIP_CONSHDLRDATA* conshdlrdata;
15687  int ngoodconss;
15688  int nallconss;
15689 #endif
15690 
15691  /* delete all linear constraints that were upgraded to a more specific constraint type;
15692  * make sure, only active variables remain in the remaining constraints
15693  */
15694  assert(scip != NULL);
15695 
15696 #ifdef SCIP_STATISTIC
15697  /* count number of well behaved linear constraints */
15698  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15699  assert(conshdlrdata != NULL);
15700 
15701  ngoodconss = 0;
15702  nallconss = 0;
15703 
15704  for( c = 0; c < nconss; ++c )
15705  {
15706  SCIP_CONSDATA* consdata;
15707 
15708  if( SCIPconsIsDeleted(conss[c]) )
15709  continue;
15710 
15711  consdata = SCIPconsGetData(conss[c]);
15712  assert(consdata != NULL);
15713 
15714  if( consdata->upgraded )
15715  continue;
15716 
15717  nallconss++;
15718 
15719  consdataRecomputeMaxActivityDelta(scip, consdata);
15720 
15721  if( SCIPisLT(scip, consdata->maxactdelta, conshdlrdata->maxeasyactivitydelta) )
15722  ngoodconss++;
15723  }
15724  if( nallconss )
15725  {
15726  SCIPstatisticMessage("below threshold: %d / %d ratio= %g\n", ngoodconss, nallconss, (100.0 * ngoodconss / nallconss));
15727  }
15728 #endif
15729 
15730  for( c = 0; c < nconss; ++c )
15731  {
15732  SCIP_CONSDATA* consdata;
15733 
15734  if( SCIPconsIsDeleted(conss[c]) )
15735  continue;
15736 
15737  consdata = SCIPconsGetData(conss[c]);
15738  assert(consdata != NULL);
15739 
15740  if( consdata->upgraded )
15741  {
15742  /* this is no problem reduction, because the upgraded constraint was added to the problem before, and the
15743  * (redundant) linear constraint was only kept in order to support presolving the the linear constraint handler
15744  */
15745  SCIP_CALL( SCIPdelCons(scip, conss[c]) );
15746  }
15747  else
15748  {
15749  /* since we are not allowed to detect infeasibility in the exitpre stage, we dont give an infeasible pointer */
15750  SCIP_CALL( applyFixings(scip, conss[c], NULL) );
15751  }
15752  }
15753 
15754  return SCIP_OKAY;
15755 }
15756 
15757 /** solving process initialization method of constraint handler */
15758 static
15759 SCIP_DECL_CONSINITSOL(consInitsolLinear)
15760 { /*lint --e{715}*/
15761 
15762  /* add nlrow representation to NLP, if NLP had been constructed */
15763  if( SCIPisNLPConstructed(scip) )
15764  {
15765  int c;
15766  for( c = 0; c < nconss; ++c )
15767  {
15768  SCIP_CALL( addNlrow(scip, conss[c]) );
15769  }
15770  }
15771 
15772  return SCIP_OKAY;
15773 }
15774 
15775 /** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
15776 static
15777 SCIP_DECL_CONSEXITSOL(consExitsolLinear)
15778 { /*lint --e{715}*/
15779  int c;
15780 
15781  assert(scip != NULL);
15782 
15783  /* release the rows and nlrows of all constraints */
15784  for( c = 0; c < nconss; ++c )
15785  {
15786  SCIP_CONSDATA* consdata;
15787 
15788  consdata = SCIPconsGetData(conss[c]);
15789  assert(consdata != NULL);
15790 
15791  if( consdata->row != NULL )
15792  {
15793  SCIP_CALL( SCIPreleaseRow(scip, &consdata->row) );
15794  }
15795 
15796  if( consdata->nlrow != NULL )
15797  {
15798  SCIP_CALL( SCIPreleaseNlRow(scip, &consdata->nlrow) );
15799  }
15800  }
15801 
15802  /* if this is a restart, convert cutpool rows into linear constraints */
15803  if( restart )
15804  {
15805  int ncutsadded;
15806 
15807  ncutsadded = 0;
15808 
15809  /* create out of all active cuts in cutpool linear constraints */
15810  SCIP_CALL( SCIPconvertCutsToConss(scip, NULL, NULL, TRUE, &ncutsadded) );
15811 
15812  if( ncutsadded > 0 )
15813  {
15815  "(restart) converted %d cuts from the global cut pool into linear constraints\n", ncutsadded);
15816  /* an extra blank line should be printed separately since the buffer message handler only handles up to one
15817  * line correctly
15818  */
15820  }
15821  }
15822 
15823  return SCIP_OKAY;
15824 }
15825 
15826 
15827 /** constraint activation notification method of constraint handler */
15828 static
15829 SCIP_DECL_CONSACTIVE(consActiveLinear)
15830 { /*lint --e{715}*/
15831  assert(cons != NULL);
15832 
15833  if( SCIPgetStage(scip) == SCIP_STAGE_SOLVING && SCIPisNLPConstructed(scip) )
15834  {
15835  SCIP_CALL( addNlrow(scip, cons) );
15836  }
15837 
15838  return SCIP_OKAY;
15839 }
15840 
15841 /** constraint deactivation notification method of constraint handler */
15842 static
15843 SCIP_DECL_CONSDEACTIVE(consDeactiveLinear)
15844 { /*lint --e{715}*/
15845  SCIP_CONSDATA* consdata;
15846 
15847  assert(scip != NULL);
15848  assert(conshdlr != NULL);
15849  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15850  assert(cons != NULL );
15851 
15852  /* get constraint data */
15853  consdata = SCIPconsGetData(cons);
15854  assert(consdata != NULL);
15855 
15856  if( SCIPconsIsDeleted(cons) )
15857  {
15858  SCIP_CONSHDLRDATA* conshdlrdata;
15859 
15860  /* check for event handler */
15861  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15862  assert(conshdlrdata != NULL);
15863  assert(conshdlrdata->eventhdlr != NULL);
15864 
15865  /* free event data */
15866  if( consdata->eventdata != NULL )
15867  {
15868  /* drop bound change events of variables */
15869  SCIP_CALL( consDropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
15870  }
15871  assert(consdata->eventdata == NULL);
15872  }
15873 
15874  /* remove row from NLP, if still in solving
15875  * if we are in exitsolve, the whole NLP will be freed anyway
15876  */
15877  if( SCIPgetStage(scip) == SCIP_STAGE_SOLVING && consdata->nlrow != NULL )
15878  {
15879  SCIP_CALL( SCIPdelNlRow(scip, consdata->nlrow) );
15880  }
15881 
15882  return SCIP_OKAY;
15883 }
15884 
15885 
15886 /** frees specific constraint data */
15887 static
15888 SCIP_DECL_CONSDELETE(consDeleteLinear)
15889 { /*lint --e{715}*/
15890  assert(scip != NULL);
15891  assert(conshdlr != NULL);
15892  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15893 
15894  if( (*consdata)->eventdata != NULL )
15895  {
15896  SCIP_CONSHDLRDATA* conshdlrdata;
15897 
15898  conshdlrdata = SCIPconshdlrGetData(conshdlr);
15899  assert(conshdlrdata != NULL);
15900 
15901  /* drop all events */
15902  SCIP_CALL( consDropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
15903  assert((*consdata)->eventdata == NULL);
15904  }
15905 
15906  /* free linear constraint */
15907  SCIP_CALL( consdataFree(scip, consdata) );
15908 
15909  return SCIP_OKAY;
15910 }
15911 
15912 
15913 /** transforms constraint data into data belonging to the transformed problem */
15914 static
15915 SCIP_DECL_CONSTRANS(consTransLinear)
15916 { /*lint --e{715}*/
15917  SCIP_CONSDATA* sourcedata;
15918  SCIP_CONSDATA* targetdata;
15919 
15920  /*debugMsg(scip, "Trans method of linear constraints\n");*/
15921 
15922  assert(scip != NULL);
15923  assert(conshdlr != NULL);
15924  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15925  assert(SCIPgetStage(scip) == SCIP_STAGE_TRANSFORMING);
15926  assert(sourcecons != NULL);
15927  assert(targetcons != NULL);
15928 
15929  sourcedata = SCIPconsGetData(sourcecons);
15930  assert(sourcedata != NULL);
15931  assert(sourcedata->row == NULL); /* in original problem, there cannot be LP rows */
15932 
15933  /* create linear constraint data for target constraint */
15934  SCIP_CALL( consdataCreate(scip, &targetdata, sourcedata->nvars, sourcedata->vars, sourcedata->vals, sourcedata->lhs, sourcedata->rhs) );
15935 
15936 #ifndef NDEBUG
15937  /* if this is a checked or enforced constraints, then there must be no relaxation-only variables */
15938  if( SCIPconsIsEnforced(sourcecons) || SCIPconsIsChecked(sourcecons) )
15939  {
15940  int n;
15941  for(n = targetdata->nvars - 1; n >= 0; --n )
15942  assert(!SCIPvarIsRelaxationOnly(targetdata->vars[n]));
15943  }
15944 #endif
15945 
15946  /* create target constraint */
15947  SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
15948  SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
15949  SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
15950  SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
15951  SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
15952 
15953  return SCIP_OKAY;
15954 }
15955 
15956 
15957 /** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
15958 static
15959 SCIP_DECL_CONSINITLP(consInitlpLinear)
15960 { /*lint --e{715}*/
15961  int c;
15962 
15963  assert(scip != NULL);
15964  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15965 
15966  *infeasible = FALSE;
15967 
15968  for( c = 0; c < nconss && !(*infeasible); ++c )
15969  {
15970  assert(SCIPconsIsInitial(conss[c]));
15971  SCIP_CALL( addRelaxation(scip, conss[c], infeasible) );
15972  }
15973 
15974  return SCIP_OKAY;
15975 }
15976 
15977 
15978 /** separation method of constraint handler for LP solutions */
15979 static
15980 SCIP_DECL_CONSSEPALP(consSepalpLinear)
15981 { /*lint --e{715}*/
15982  SCIP_CONSHDLRDATA* conshdlrdata;
15983  SCIP_Real loclowerbound;
15984  SCIP_Real glblowerbound;
15985  SCIP_Real cutoffbound;
15986  SCIP_Real maxbound;
15987  SCIP_Bool separatecards;
15988  SCIP_Bool cutoff;
15989  int c;
15990  int depth;
15991  int nrounds;
15992  int maxsepacuts;
15993  int ncuts;
15994 
15995  assert(scip != NULL);
15996  assert(conshdlr != NULL);
15997  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
15998  assert(result != NULL);
16000  conshdlrdata = SCIPconshdlrGetData(conshdlr);
16001  assert(conshdlrdata != NULL);
16002  depth = SCIPgetDepth(scip);
16003  nrounds = SCIPgetNSepaRounds(scip);
16004 
16005  /*debugMsg(scip, "Sepa method of linear constraints\n");*/
16006 
16007  *result = SCIP_DIDNOTRUN;
16008 
16009  /* only call the separator a given number of times at each node */
16010  if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
16011  || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
16012  return SCIP_OKAY;
16013 
16014  /* get the maximal number of cuts allowed in a separation round */
16015  maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
16016 
16017  /* check if we want to produce knapsack cardinality cuts at this node */
16018  loclowerbound = SCIPgetLocalLowerbound(scip);
16019  glblowerbound = SCIPgetLowerbound(scip);
16020  cutoffbound = SCIPgetCutoffbound(scip);
16021  maxbound = glblowerbound + conshdlrdata->maxcardbounddist * (cutoffbound - glblowerbound);
16022  separatecards = SCIPisLE(scip, loclowerbound, maxbound);
16023  separatecards = separatecards && (SCIPgetNLPBranchCands(scip) > 0);
16024 
16025  *result = SCIP_DIDNOTFIND;
16026  ncuts = 0;
16027  cutoff = FALSE;
16028 
16029  /* check all useful linear constraints for feasibility */
16030  for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
16031  {
16032  /*debugMsg(scip, "separating linear constraint <%s>\n", SCIPconsGetName(conss[c]));*/
16033  SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, NULL, separatecards, conshdlrdata->separateall, &ncuts, &cutoff) );
16034  }
16035 
16036  /* adjust return value */
16037  if( cutoff )
16038  *result = SCIP_CUTOFF;
16039  else if( ncuts > 0 )
16040  *result = SCIP_SEPARATED;
16041 
16042  /* combine linear constraints to get more cuts */
16043  /**@todo further cuts of linear constraints */
16044 
16045  return SCIP_OKAY;
16046 }
16047 
16048 
16049 /** separation method of constraint handler for arbitrary primal solutions */
16050 static
16051 SCIP_DECL_CONSSEPASOL(consSepasolLinear)
16052 { /*lint --e{715}*/
16053  SCIP_CONSHDLRDATA* conshdlrdata;
16054  int c;
16055  int depth;
16056  int nrounds;
16057  int maxsepacuts;
16058  int ncuts;
16059  SCIP_Bool cutoff;
16060 
16061  assert(scip != NULL);
16062  assert(conshdlr != NULL);
16063  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16064  assert(result != NULL);
16065 
16066  conshdlrdata = SCIPconshdlrGetData(conshdlr);
16067  assert(conshdlrdata != NULL);
16068  depth = SCIPgetDepth(scip);
16069  nrounds = SCIPgetNSepaRounds(scip);
16071  /*debugMsg(scip, "Sepa method of linear constraints\n");*/
16072 
16073  *result = SCIP_DIDNOTRUN;
16074 
16075  /* only call the separator a given number of times at each node */
16076  if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
16077  || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
16078  return SCIP_OKAY;
16079 
16080  /* get the maximal number of cuts allowed in a separation round */
16081  maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
16082 
16083  *result = SCIP_DIDNOTFIND;
16084  ncuts = 0;
16085  cutoff = FALSE;
16086 
16087  /* check all useful linear constraints for feasibility */
16088  for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
16089  {
16090  /*debugMsg(scip, "separating linear constraint <%s>\n", SCIPconsGetName(conss[c]));*/
16091  SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, sol, TRUE, conshdlrdata->separateall, &ncuts, &cutoff) );
16092  }
16093 
16094  /* adjust return value */
16095  if( cutoff )
16096  *result = SCIP_CUTOFF;
16097  else if( ncuts > 0 )
16098  *result = SCIP_SEPARATED;
16099 
16100  /* combine linear constraints to get more cuts */
16101  /**@todo further cuts of linear constraints */
16102 
16103  return SCIP_OKAY;
16104 }
16105 
16106 
16107 /** constraint enforcing method of constraint handler for LP solutions */
16108 static
16109 SCIP_DECL_CONSENFOLP(consEnfolpLinear)
16110 { /*lint --e{715}*/
16111  SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, NULL, result) );
16112 
16113  return SCIP_OKAY;
16114 }
16115 
16116 /** constraint enforcing method of constraint handler for relaxation solutions */
16117 static
16118 SCIP_DECL_CONSENFORELAX(consEnforelaxLinear)
16119 { /*lint --e{715}*/
16120  SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, sol, result) );
16121 
16122  return SCIP_OKAY;
16123 }
16124 
16125 /** constraint enforcing method of constraint handler for pseudo solutions */
16126 static
16127 SCIP_DECL_CONSENFOPS(consEnfopsLinear)
16128 { /*lint --e{715}*/
16129  SCIP_CONSHDLRDATA* conshdlrdata;
16130  SCIP_Bool checkrelmaxabs;
16131  SCIP_Bool violated;
16132  int c;
16133 
16134  assert(scip != NULL);
16135  assert(conshdlr != NULL);
16136  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16137  assert(result != NULL);
16138 
16139  conshdlrdata = SCIPconshdlrGetData(conshdlr);
16140  assert(conshdlrdata != NULL);
16141 
16142  checkrelmaxabs = conshdlrdata->checkrelmaxabs;
16143 
16144  SCIPdebugMsg(scip, "Enfops method of linear constraints\n");
16145 
16146  /* if the solution is infeasible anyway due to objective value, skip the enforcement */
16147  if( objinfeasible )
16148  {
16149  SCIPdebugMsg(scip, "-> pseudo solution is objective infeasible, return.\n");
16150 
16151  *result = SCIP_DIDNOTRUN;
16152  return SCIP_OKAY;
16153  }
16154 
16155  /* check all linear constraints for feasibility */
16156  violated = FALSE;
16157  for( c = 0; c < nconss && !violated; ++c )
16158  {
16159  SCIP_CALL( checkCons(scip, conss[c], NULL, TRUE, checkrelmaxabs, &violated) );
16160  }
16161 
16162  if( violated )
16163  *result = SCIP_INFEASIBLE;
16164  else
16165  *result = SCIP_FEASIBLE;
16166 
16167  SCIPdebugMsg(scip, "-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
16168 
16169  return SCIP_OKAY;
16170 }
16171 
16172 
16173 /** feasibility check method of constraint handler for integral solutions */
16174 static
16175 SCIP_DECL_CONSCHECK(consCheckLinear)
16176 { /*lint --e{715}*/
16177  SCIP_CONSHDLRDATA* conshdlrdata;
16178  SCIP_Bool checkrelmaxabs;
16179  int c;
16180 
16181  assert(scip != NULL);
16182  assert(conshdlr != NULL);
16183  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16184  assert(result != NULL);
16185 
16186  *result = SCIP_FEASIBLE;
16187 
16188  conshdlrdata = SCIPconshdlrGetData(conshdlr);
16189  assert(conshdlrdata != NULL);
16190 
16191  checkrelmaxabs = conshdlrdata->checkrelmaxabs;
16192 
16193  /*debugMsg(scip, "Check method of linear constraints\n");*/
16195  /* check all linear constraints for feasibility */
16196  for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
16197  {
16198  SCIP_Bool violated = FALSE;
16199  SCIP_CALL( checkCons(scip, conss[c], sol, checklprows, checkrelmaxabs, &violated) );
16200 
16201  if( violated )
16202  {
16203  *result = SCIP_INFEASIBLE;
16204 
16205  if( printreason )
16206  {
16207  SCIP_CONSDATA* consdata;
16208  SCIP_Real activity;
16209 
16210  consdata = SCIPconsGetData(conss[c]);
16211  assert( consdata != NULL);
16212 
16213  activity = consdataGetActivity(scip, consdata, sol);
16214 
16215  SCIP_CALL( consPrintConsSol(scip, conss[c], sol, NULL ) );
16216  SCIPinfoMessage(scip, NULL, ";\n");
16217 
16218  if( activity == SCIP_INVALID ) /*lint !e777*/
16219  SCIPinfoMessage(scip, NULL, "activity invalid due to positive and negative infinity contributions\n");
16220  else if( SCIPisFeasLT(scip, activity, consdata->lhs) )
16221  SCIPinfoMessage(scip, NULL, "violation: left hand side is violated by %.15g\n", consdata->lhs - activity);
16222  else if( SCIPisFeasGT(scip, activity, consdata->rhs) )
16223  SCIPinfoMessage(scip, NULL, "violation: right hand side is violated by %.15g\n", activity - consdata->rhs);
16224  }
16225  }
16226  }
16227 
16228  return SCIP_OKAY;
16229 }
16230 
16231 
16232 /** domain propagation method of constraint handler */
16233 static
16234 SCIP_DECL_CONSPROP(consPropLinear)
16235 { /*lint --e{715}*/
16236  SCIP_CONSHDLRDATA* conshdlrdata;
16237  SCIP_Bool rangedrowpropagation = FALSE;
16238  SCIP_Bool tightenbounds;
16239  SCIP_Bool cutoff;
16240 
16241  int nchgbds;
16242  int i;
16243 
16244  assert(scip != NULL);
16245  assert(conshdlr != NULL);
16246  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16247  assert(result != NULL);
16248 
16249  conshdlrdata = SCIPconshdlrGetData(conshdlr);
16250  assert(conshdlrdata != NULL);
16251 
16252  /*debugMsg(scip, "Prop method of linear constraints\n");*/
16254  /* check, if we want to tighten variable's bounds (in probing, we always want to tighten the bounds) */
16255  if( SCIPinProbing(scip) )
16256  tightenbounds = TRUE;
16257  else
16258  {
16259  int depth;
16260  int propfreq;
16261  int tightenboundsfreq;
16262  int rangedrowfreq;
16263 
16264  depth = SCIPgetDepth(scip);
16265  propfreq = SCIPconshdlrGetPropFreq(conshdlr);
16266  tightenboundsfreq = propfreq * conshdlrdata->tightenboundsfreq;
16267  tightenbounds = (conshdlrdata->tightenboundsfreq >= 0)
16268  && ((tightenboundsfreq == 0 && depth == 0) || (tightenboundsfreq >= 1 && (depth % tightenboundsfreq == 0)));
16269 
16270  /* check if we want to do ranged row propagation */
16271  rangedrowpropagation = conshdlrdata->rangedrowpropagation;
16272  rangedrowpropagation = rangedrowpropagation && !SCIPinRepropagation(scip);
16273  rangedrowpropagation = rangedrowpropagation && (depth <= conshdlrdata->rangedrowmaxdepth);
16274  rangedrowfreq = propfreq * conshdlrdata->rangedrowfreq;
16275  rangedrowpropagation = rangedrowpropagation && (conshdlrdata->rangedrowfreq >= 0)
16276  && ((rangedrowfreq == 0 && depth == 0) || (rangedrowfreq >= 1 && (depth % rangedrowfreq == 0)));
16277  }
16278 
16279  cutoff = FALSE;
16280  nchgbds = 0;
16281 
16282  /* process constraints marked for propagation */
16283  for( i = 0; i < nmarkedconss && !cutoff; i++ )
16284  {
16285  SCIP_CALL( SCIPunmarkConsPropagate(scip, conss[i]) );
16286  SCIP_CALL( propagateCons(scip, conss[i], tightenbounds, rangedrowpropagation,
16287  conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars, &cutoff, &nchgbds) );
16288  }
16289 
16290  /* adjust result code */
16291  if( cutoff )
16292  *result = SCIP_CUTOFF;
16293  else if( nchgbds > 0 )
16294  *result = SCIP_REDUCEDDOM;
16295  else
16296  *result = SCIP_DIDNOTFIND;
16297 
16298  return SCIP_OKAY;
16299 }
16300 
16301 
16302 #define MAXCONSPRESOLROUNDS 10
16303 /** presolving method of constraint handler */
16304 static
16305 SCIP_DECL_CONSPRESOL(consPresolLinear)
16306 { /*lint --e{715}*/
16307  SCIP_CONSHDLRDATA* conshdlrdata;
16308  SCIP_CONS* cons;
16309  SCIP_CONSDATA* consdata;
16310  SCIP_Real minactivity;
16311  SCIP_Real maxactivity;
16312  SCIP_Bool minactisrelax;
16313  SCIP_Bool maxactisrelax;
16314  SCIP_Bool isminsettoinfinity;
16315  SCIP_Bool ismaxsettoinfinity;
16316  SCIP_Bool cutoff;
16317  int oldnfixedvars;
16318  int oldnaggrvars;
16319  int oldnchgbds;
16320  int oldndelconss;
16321  int oldnupgdconss;
16322  int oldnchgcoefs;
16323  int oldnchgsides;
16324  int firstchange;
16325  int firstupgradetry;
16326  int c;
16327 
16328  assert(scip != NULL);
16329  assert(conshdlr != NULL);
16330  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
16331  assert(result != NULL);
16332 
16333  /*debugMsg(scip, "Presol method of linear constraints\n");*/
16334 
16335  /* remember old preprocessing counters */
16336  cutoff = FALSE;
16337  oldnfixedvars = *nfixedvars;
16338  oldnaggrvars = *naggrvars;
16339  oldnchgbds = *nchgbds;
16340  oldndelconss = *ndelconss;
16341  oldnupgdconss = *nupgdconss;
16342  oldnchgcoefs = *nchgcoefs;
16343  oldnchgsides = *nchgsides;
16344 
16345  /* get constraint handler data */
16346  conshdlrdata = SCIPconshdlrGetData(conshdlr);
16347  assert(conshdlrdata != NULL);
16348 
16349  /* process single constraints */
16350  firstchange = INT_MAX;
16351  firstupgradetry = INT_MAX;
16352  for( c = 0; c < nconss && !cutoff && !SCIPisStopped(scip); ++c )
16353  {
16354  int npresolrounds;
16355  SCIP_Bool infeasible;
16356 
16357  infeasible = FALSE;
16358 
16359  cons = conss[c];
16360  assert(SCIPconsIsActive(cons));
16361  consdata = SCIPconsGetData(cons);
16362  assert(consdata != NULL);
16363 
16364  /* ensure that rhs >= lhs is satisfied without numerical tolerance */
16365  if( SCIPisEQ(scip, consdata->rhs, consdata->lhs) )
16366  {
16367  consdata->lhs = consdata->rhs;
16368  assert(consdata->row == NULL);
16369  }
16370 
16371  if( consdata->eventdata == NULL )
16372  {
16373  /* catch bound change events of variables */
16374  SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
16375  assert(consdata->eventdata != NULL);
16376  }
16377 
16378  /* constraint should not be already presolved in the initial round */
16379  assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || SCIPconsIsMarkedPropagate(cons));
16380  assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || consdata->boundstightened == 0);
16381  assert(SCIPgetNRuns(scip) > 0 || nrounds > 0 || !consdata->presolved);
16382  assert(!SCIPconsIsMarkedPropagate(cons) || !consdata->presolved);
16383 
16384  /* incorporate fixings and aggregations in constraint */
16385  SCIP_CALL( applyFixings(scip, cons, &infeasible) );
16386 
16387  if( infeasible )
16388  {
16389  SCIPdebugMsg(scip, " -> infeasible fixing\n");
16390  cutoff = TRUE;
16391  break;
16392  }
16393 
16394  assert(consdata->removedfixings);
16395 
16396  /* we can only presolve linear constraints, that are not modifiable */
16397  if( SCIPconsIsModifiable(cons) )
16398  continue;
16399 
16400  /* remember the first changed constraint to begin the next aggregation round with */
16401  if( firstchange == INT_MAX && consdata->changed )
16402  firstchange = c;
16403 
16404  /* remember the first constraint that was not yet tried to be upgraded, to begin the next upgrading round with */
16405  if( firstupgradetry == INT_MAX && !consdata->upgradetried )
16406  firstupgradetry = c;
16407 
16408  /* check, if constraint is already preprocessed */
16409  if( consdata->presolved )
16410  continue;
16411 
16412  assert(SCIPconsIsActive(cons));
16413 
16414  SCIPdebugMsg(scip, "presolving linear constraint <%s>\n", SCIPconsGetName(cons));
16415  SCIPdebugPrintCons(scip, cons, NULL);
16416 
16417  /* apply presolving as long as possible on the single constraint (however, abort after a certain number of rounds
16418  * to avoid nearly infinite cycling due to very small bound changes)
16419  */
16420  npresolrounds = 0;
16421  while( !consdata->presolved && npresolrounds < MAXCONSPRESOLROUNDS && !SCIPisStopped(scip) )
16422  {
16423  assert(!cutoff);
16424  npresolrounds++;
16425 
16426  /* mark constraint being presolved and propagated */
16427  consdata->presolved = TRUE;
16428  SCIP_CALL( SCIPunmarkConsPropagate(scip, cons) );
16429 
16430  /* normalize constraint */
16431  SCIP_CALL( normalizeCons(scip, cons, &infeasible) );
16432 
16433  if( infeasible )
16434  {
16435  SCIPdebugMsg(scip, " -> infeasible normalization\n");
16436  cutoff = TRUE;
16437  break;
16438  }
16439 
16440  /* tighten left and right hand side due to integrality */
16441  SCIP_CALL( tightenSides(scip, cons, nchgsides, &infeasible) );
16442 
16443  if( infeasible )
16444  {
16445  SCIPdebugMsg(scip, " -> infeasibility detected during tightening sides\n");
16446  cutoff = TRUE;
16447  break;
16448  }
16449 
16450  /* check bounds */
16451  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
16452  {
16453  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
16454  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16455  cutoff = TRUE;
16456  break;
16457  }
16458 
16459  /* tighten variable's bounds */
16460  SCIP_CALL( tightenBounds(scip, cons, conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars, &cutoff, nchgbds) );
16461  if( cutoff )
16462  break;
16463 
16464  /* check for fixed variables */
16465  SCIP_CALL( fixVariables(scip, cons, &cutoff, nfixedvars) );
16466  if( cutoff )
16467  break;
16468 
16469  /* check constraint for infeasibility and redundancy */
16470  consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
16471  &isminsettoinfinity, &ismaxsettoinfinity);
16472  if( SCIPisFeasGT(scip, minactivity, consdata->rhs) || SCIPisFeasLT(scip, maxactivity, consdata->lhs) )
16473  {
16474  SCIPdebugMsg(scip, "linear constraint <%s> is infeasible: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
16475  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
16476  cutoff = TRUE;
16477  break;
16478  }
16479  else if( SCIPisGE(scip, minactivity, consdata->lhs) && SCIPisLE(scip, maxactivity, consdata->rhs) )
16480  {
16481  SCIPdebugMsg(scip, "linear constraint <%s> is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
16482  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
16483  SCIP_CALL( SCIPdelCons(scip, cons) );
16484  assert(!SCIPconsIsActive(cons));
16485 
16486  if( !consdata->upgraded )
16487  (*ndelconss)++;
16488  break;
16489  }
16490  else if( !SCIPisInfinity(scip, -consdata->lhs) && SCIPisGE(scip, minactivity, consdata->lhs) )
16491  {
16492  SCIPdebugMsg(scip, "linear constraint <%s> left hand side is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
16493  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
16494  SCIP_CALL( chgLhs(scip, cons, -SCIPinfinity(scip)) );
16495  if( !consdata->upgraded )
16496  (*nchgsides)++;
16497  }
16498  else if( !SCIPisInfinity(scip, consdata->rhs) && SCIPisLE(scip, maxactivity, consdata->rhs) )
16499  {
16500  SCIPdebugMsg(scip, "linear constraint <%s> right hand side is redundant: activitybounds=[%.15g,%.15g], sides=[%.15g,%.15g]\n",
16501  SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
16502  SCIP_CALL( chgRhs(scip, cons, SCIPinfinity(scip)) );
16503  if( !consdata->upgraded )
16504  (*nchgsides)++;
16505  }
16506 
16507  /* handle empty constraint */
16508  if( consdata->nvars == 0 )
16509  {
16510  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
16511  {
16512  SCIPdebugMsg(scip, "empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
16513  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16514  cutoff = TRUE;
16515  }
16516  else
16517  {
16518  SCIPdebugMsg(scip, "empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
16519  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16520  SCIP_CALL( SCIPdelCons(scip, cons) );
16521  assert(!SCIPconsIsActive(cons));
16522 
16523  if( !consdata->upgraded )
16524  (*ndelconss)++;
16525  }
16526  break;
16527  }
16528 
16529  /* reduce big-M coefficients, that make the constraint redundant if the variable is on a bound */
16530  SCIP_CALL( consdataTightenCoefs(scip, cons, nchgcoefs, nchgsides) );
16531 
16532  /* try to simplify inequalities */
16533  if( conshdlrdata->simplifyinequalities )
16534  {
16535  SCIP_CALL( simplifyInequalities(scip, cons, nchgcoefs, nchgsides, &cutoff) );
16536 
16537  if( cutoff )
16538  break;
16539  }
16540 
16541  /* aggregation variable in equations */
16542  if( conshdlrdata->aggregatevariables )
16543  {
16544  SCIP_CALL( aggregateVariables(scip, cons, &cutoff, nfixedvars, naggrvars) );
16545  if( cutoff )
16546  break;
16547  }
16548  }
16549 
16550  if( !cutoff && !SCIPisStopped(scip) )
16551  {
16552  /* perform ranged row propagation */
16553  if( conshdlrdata->rangedrowpropagation )
16554  {
16555  int lastnfixedvars;
16556 
16557  lastnfixedvars = *nfixedvars;
16558 
16559  SCIP_CALL( rangedRowPropagation(scip, cons, &cutoff, nfixedvars, nchgbds, naddconss) );
16560  if( !cutoff )
16561  {
16562  if( lastnfixedvars < *nfixedvars )
16563  {
16564  SCIP_CALL( applyFixings(scip, cons, &cutoff) );
16565  }
16566  }
16567  }
16568 
16569  /* extract cliques from constraint */
16570  if( conshdlrdata->extractcliques && !cutoff && SCIPconsIsActive(cons) )
16571  {
16572  SCIP_CALL( extractCliques(scip, cons, conshdlrdata->maxeasyactivitydelta, conshdlrdata->sortvars,
16573  nfixedvars, nchgbds, &cutoff) );
16574 
16575  /* check if the constraint got redundant or infeasible */
16576  if( !cutoff && SCIPconsIsActive(cons) && consdata->nvars == 0 )
16577  {
16578  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
16579  {
16580  SCIPdebugMsg(scip, "empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
16581  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16582  cutoff = TRUE;
16583  }
16584  else
16585  {
16586  SCIPdebugMsg(scip, "empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
16587  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16588  SCIP_CALL( SCIPdelCons(scip, cons) );
16589  assert(!SCIPconsIsActive(cons));
16590 
16591  if( !consdata->upgraded )
16592  (*ndelconss)++;
16593  }
16594  }
16595  }
16596 
16597  /* convert special equalities */
16598  if( !cutoff && SCIPconsIsActive(cons) )
16599  {
16600  SCIP_CALL( convertEquality(scip, cons, conshdlrdata, &cutoff, nfixedvars, naggrvars, ndelconss) );
16601  }
16602 
16603  /* apply dual presolving for variables that appear in only one constraint */
16604  if( !cutoff && SCIPconsIsActive(cons) && conshdlrdata->dualpresolving && SCIPallowStrongDualReds(scip) )
16605  {
16606  SCIP_CALL( dualPresolve(scip, conshdlrdata, cons, &cutoff, nfixedvars, naggrvars, ndelconss) );
16607  }
16608 
16609  /* check if an inequality is parallel to the objective function */
16610  if( !cutoff && SCIPconsIsActive(cons) )
16611  {
16612  SCIP_CALL( checkParallelObjective(scip, cons, conshdlrdata) );
16613  }
16614 
16615  /* remember the first changed constraint to begin the next aggregation round with */
16616  if( firstchange == INT_MAX && consdata->changed )
16617  firstchange = c;
16618 
16619  /* remember the first constraint that was not yet tried to be upgraded, to begin the next upgrading round with */
16620  if( firstupgradetry == INT_MAX && !consdata->upgradetried )
16621  firstupgradetry = c;
16622  }
16623 
16624  /* singleton column stuffing */
16625  if( !cutoff && SCIPconsIsActive(cons) && SCIPconsIsChecked(cons) &&
16626  (conshdlrdata->singletonstuffing || conshdlrdata->singlevarstuffing) && SCIPallowStrongDualReds(scip) )
16627  {
16628  SCIP_CALL( presolStuffing(scip, cons, conshdlrdata->singletonstuffing,
16629  conshdlrdata->singlevarstuffing, &cutoff, nfixedvars, nchgbds) );
16630 
16631  /* handle empty constraint */
16632  if( consdata->nvars == 0 )
16633  {
16634  if( SCIPisFeasGT(scip, consdata->lhs, consdata->rhs) )
16635  {
16636  SCIPdebugMsg(scip, "empty linear constraint <%s> is infeasible: sides=[%.15g,%.15g]\n",
16637  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16638  cutoff = TRUE;
16639  }
16640  else
16641  {
16642  SCIPdebugMsg(scip, "empty linear constraint <%s> is redundant: sides=[%.15g,%.15g]\n",
16643  SCIPconsGetName(cons), consdata->lhs, consdata->rhs);
16644  SCIP_CALL( SCIPdelCons(scip, cons) );
16645  assert(!SCIPconsIsActive(cons));
16646 
16647  if( !consdata->upgraded )
16648  (*ndelconss)++;
16649  }
16650  break;
16651  }
16652  }
16653  }
16654 
16655  /* process pairs of constraints: check them for redundancy and try to aggregate them;
16656  * only apply this expensive procedure in exhaustive presolving timing
16657  */
16658  if( !cutoff && (presoltiming & SCIP_PRESOLTIMING_EXHAUSTIVE) != 0 && (conshdlrdata->presolusehashing || conshdlrdata->presolpairwise) && !SCIPisStopped(scip) )
16659  {
16660  assert(firstchange >= 0);
16661 
16662  if( firstchange < nconss && conshdlrdata->presolusehashing )
16663  {
16664  /* detect redundant constraints; fast version with hash table instead of pairwise comparison */
16665  SCIP_CALL( detectRedundantConstraints(scip, SCIPblkmem(scip), conss, nconss, &firstchange, &cutoff,
16666  ndelconss, nchgsides) );
16667  }
16668 
16669  if( firstchange < nconss && conshdlrdata->presolpairwise )
16670  {
16671  SCIP_CONS** usefulconss;
16672  int nusefulconss;
16673  int firstchangenew;
16674  SCIP_Longint npaircomparisons;
16675 
16676  npaircomparisons = 0;
16677  oldndelconss = *ndelconss;
16678  oldnchgsides = *nchgsides;
16679  oldnchgcoefs = *nchgcoefs;
16680 
16681  /* allocate temporary memory */
16682  SCIP_CALL( SCIPallocBufferArray(scip, &usefulconss, nconss) );
16683 
16684  nusefulconss = 0;
16685  firstchangenew = -1;
16686  for( c = 0; c < nconss; ++c )
16687  {
16688  /* update firstchange */
16689  if( c == firstchange )
16690  firstchangenew = nusefulconss;
16691 
16692  /* ignore inactive and modifiable constraints */
16693  if( !SCIPconsIsActive(conss[c]) || SCIPconsIsModifiable(conss[c]) )
16694  continue;
16695 
16696  usefulconss[nusefulconss] = conss[c];
16697  ++nusefulconss;
16698  }
16699  firstchange = firstchangenew;
16700  assert(firstchangenew >= 0 && firstchangenew <= nusefulconss);
16701 
16702  for( c = firstchange; c < nusefulconss && !cutoff && !SCIPisStopped(scip); ++c )
16703  {
16704  /* constraint has become inactive or modifiable during pairwise presolving */
16705  if( usefulconss[c] == NULL )
16706  continue;
16707 
16708  npaircomparisons += (SCIPconsGetData(conss[c])->changed) ? c : (c - firstchange); /*lint !e776*/
16709 
16710  assert(SCIPconsIsActive(usefulconss[c]) && !SCIPconsIsModifiable(usefulconss[c]));
16711  SCIP_CALL( preprocessConstraintPairs(scip, usefulconss, firstchange, c, conshdlrdata->maxaggrnormscale,
16712  &cutoff, ndelconss, nchgsides, nchgcoefs) );
16713 
16714  if( npaircomparisons > conshdlrdata->nmincomparisons )
16715  {
16716  assert(npaircomparisons > 0);
16717  if( ((*ndelconss - oldndelconss) + (*nchgsides - oldnchgsides)/2.0 + (*nchgcoefs - oldnchgcoefs)/10.0) / ((SCIP_Real) npaircomparisons) < conshdlrdata->mingainpernmincomp )
16718  break;
16719  oldndelconss = *ndelconss;
16720  oldnchgsides = *nchgsides;
16721  oldnchgcoefs = *nchgcoefs;
16722  npaircomparisons = 0;
16723  }
16724  }
16725  /* free temporary memory */
16726  SCIPfreeBufferArray(scip, &usefulconss);
16727  }
16728  }
16729 
16730  /* before upgrading, check whether we can apply some additional dual presolving, because a variable only appears
16731  * in linear constraints and we therefore have full information about it
16732  */
16733  if( !cutoff && firstupgradetry < nconss
16734  && *nfixedvars == oldnfixedvars && *naggrvars == oldnaggrvars && *nchgbds == oldnchgbds && *ndelconss == oldndelconss
16735  && *nupgdconss == oldnupgdconss && *nchgcoefs == oldnchgcoefs && *nchgsides == oldnchgsides
16736  )
16737  {
16738  if( conshdlrdata->dualpresolving && SCIPallowStrongDualReds(scip) && !SCIPisStopped(scip) )
16739  {
16740  SCIP_CALL( fullDualPresolve(scip, conss, nconss, &cutoff, nchgbds) );
16741  }
16742  }
16743 
16744  /* try to upgrade constraints into a more specific constraint type;
16745  * only upgrade constraints, if no reductions were found in this round (otherwise, the linear constraint handler
16746  * may find additional reductions before giving control away to other (less intelligent?) constraint handlers)
16747  */
16748  if( !cutoff && (presoltiming & SCIP_PRESOLTIMING_EXHAUSTIVE) != 0 && SCIPisPresolveFinished(scip) )
16749  {
16750  for( c = firstupgradetry; c < nconss && !SCIPisStopped(scip); ++c )
16751  {
16752  cons = conss[c];
16753 
16754  /* don't upgrade modifiable constraints */
16755  if( SCIPconsIsModifiable(cons) )
16756  continue;
16757 
16758  consdata = SCIPconsGetData(cons);
16759  assert(consdata != NULL);
16760 
16761  /* only upgrade completely presolved constraints, that changed since the last upgrading call */
16762  if( consdata->upgradetried )
16763  continue;
16764  /* @todo force that upgrade will be performed later? */
16765  if( !consdata->presolved )
16766  continue;
16767 
16768  consdata->upgradetried = TRUE;
16769  if( SCIPconsIsActive(cons) )
16770  {
16771  SCIP_CONS* upgdcons;
16772 
16773  SCIP_CALL( SCIPupgradeConsLinear(scip, cons, &upgdcons) );
16774  if( upgdcons != NULL )
16775  {
16776  /* add the upgraded constraint to the problem */
16777  SCIP_CALL( SCIPaddCons(scip, upgdcons) );
16778  SCIP_CALL( SCIPreleaseCons(scip, &upgdcons) );
16779  (*nupgdconss)++;
16780 
16781  /* mark the linear constraint being upgraded and to be removed after presolving;
16782  * don't delete it directly, because it may help to preprocess other linear constraints
16783  */
16784  assert(!consdata->upgraded);
16785  consdata->upgraded = TRUE;
16786 
16787  /* delete upgraded inequalities immediately;
16788  * delete upgraded equalities, if we don't need it anymore for aggregation and redundancy checking
16789  */
16790  if( SCIPisLT(scip, consdata->lhs, consdata->rhs)
16791  || !conshdlrdata->presolpairwise
16792  || (conshdlrdata->maxaggrnormscale == 0.0) )
16793  {
16794  SCIP_CALL( SCIPdelCons(scip, cons) );
16795  }
16796  }
16797  }
16798  }
16799  }
16800 
16801  /* return the correct result code */
16802  if( cutoff )
16803  *result = SCIP_CUTOFF;
16804  else if( *nfixedvars > oldnfixedvars || *naggrvars > oldnaggrvars || *nchgbds > oldnchgbds || *ndelconss > oldndelconss
16805  || *nupgdconss > oldnupgdconss || *nchgcoefs > oldnchgcoefs || *nchgsides > oldnchgsides )
16806  *result = SCIP_SUCCESS;
16807  else
16808  *result = SCIP_DIDNOTFIND;
16809 
16810  return SCIP_OKAY;
16811 }
16812 
16813 
16814 /** propagation conflict resolving method of constraint handler */
16815 static
16816 SCIP_DECL_CONSRESPROP(consRespropLinear)
16817 { /*lint --e{715}*/
16818  assert(scip != NULL);
16819  assert(cons != NULL);
16820  assert(result != NULL);
16821 
16822  SCIP_CALL( resolvePropagation(scip, cons, infervar, intToInferInfo(inferinfo), boundtype, bdchgidx, result) );
16823 
16824  return SCIP_OKAY;
16825 }
16826 
16827 
16828 /** variable rounding lock method of constraint handler */
16829 static
16830 SCIP_DECL_CONSLOCK(consLockLinear)
16831 { /*lint --e{715}*/
16832  SCIP_CONSDATA* consdata;
16833  SCIP_Bool haslhs;
16834  SCIP_Bool hasrhs;
16835  int i;
16836 
16837  assert(scip != NULL);
16838  assert(cons != NULL);
16839  consdata = SCIPconsGetData(cons);
16840  assert(consdata != NULL);
16841 
16842  haslhs = !SCIPisInfinity(scip, -consdata->lhs);
16843  hasrhs = !SCIPisInfinity(scip, consdata->rhs);
16844 
16845  /* update rounding locks of every single variable */
16846  for( i = 0; i < consdata->nvars; ++i )
16847  {
16848  if( SCIPisPositive(scip, consdata->vals[i]) )
16849  {
16850  if( haslhs )
16851  {
16852  SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlockspos, nlocksneg) );
16853  }
16854  if( hasrhs )
16855  {
16856  SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlocksneg, nlockspos) );
16857  }
16858  }
16859  else
16860  {
16861  if( haslhs )
16862  {
16863  SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlocksneg, nlockspos) );
16864  }
16865  if( hasrhs )
16866  {
16867  SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlockspos, nlocksneg) );
16868  }
16869  }
16870  }
16871 
16872  return SCIP_OKAY;
16873 }
16874 
16875 
16876 /** variable deletion method of constraint handler */
16877 static
16878 SCIP_DECL_CONSDELVARS(consDelvarsLinear)
16879 {
16880  assert(scip != NULL);
16881  assert(conshdlr != NULL);
16882  assert(conss != NULL || nconss == 0);
16883 
16884  if( nconss > 0 )
16885  {
16886  SCIP_CALL( performVarDeletions(scip, conshdlr, conss, nconss) );
16887  }
16888 
16889  return SCIP_OKAY;
16890 }
16891 
16892 /** constraint display method of constraint handler */
16893 static
16894 SCIP_DECL_CONSPRINT(consPrintLinear)
16895 { /*lint --e{715}*/
16896  assert(scip != NULL);
16897  assert(conshdlr != NULL);
16898  assert(cons != NULL);
16899 
16900  SCIP_CALL( consdataPrint(scip, SCIPconsGetData(cons), file) );
16901 
16902  return SCIP_OKAY;
16903 }
16904 
16905 /** constraint copying method of constraint handler */
16906 static
16907 SCIP_DECL_CONSCOPY(consCopyLinear)
16908 { /*lint --e{715}*/
16909  SCIP_VAR** sourcevars;
16910  SCIP_Real* sourcecoefs;
16911  const char* consname;
16912  int nvars;
16914  assert(scip != NULL);
16915  assert(sourcescip != NULL);
16916  assert(sourcecons != NULL);
16917 
16918  /* get variables and coefficients of the source constraint */
16919  sourcevars = SCIPgetVarsLinear(sourcescip, sourcecons);
16920  sourcecoefs = SCIPgetValsLinear(sourcescip, sourcecons);
16921  nvars = SCIPgetNVarsLinear(sourcescip, sourcecons);
16922 
16923  if( name != NULL )
16924  consname = name;
16925  else
16926  consname = SCIPconsGetName(sourcecons);
16927 
16928  SCIP_CALL( SCIPcopyConsLinear(scip, cons, sourcescip, consname, nvars, sourcevars, sourcecoefs,
16929  SCIPgetLhsLinear(sourcescip, sourcecons), SCIPgetRhsLinear(sourcescip, sourcecons), varmap, consmap,
16930  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, global, valid) );
16931  assert(cons != NULL || *valid == FALSE);
16932 
16933  /* @todo should also the checkabsolute flag of the constraint be copied? */
16934 
16935  return SCIP_OKAY;
16936 }
16937 
16938 /** find operators '<=', '==', '>=', [free] in input string and return those places
16939  *
16940  * There should only be one operator, except for ranged rows for which exactly two operators '<=' must be present.
16941  */
16942 static
16943 void findOperators(
16944  const char* str, /**< null terminated input string */
16945  char** firstoperator, /**< pointer to store the string starting at the first operator */
16946  char** secondoperator, /**< pointer to store the string starting at the second operator */
16947  SCIP_Bool* success /**< pointer to store if the line contains a valid operator order */
16948  )
16949 {
16950  char* curr;
16951 
16952  assert(str != NULL);
16953  assert(firstoperator != NULL);
16954  assert(secondoperator != NULL);
16955 
16956  *firstoperator = NULL;
16957  *secondoperator = NULL;
16958 
16959  curr = (char*)str;
16960  *success = TRUE;
16961 
16962  /* loop over the input string to find all operators */
16963  while( *curr && *success )
16964  {
16965  SCIP_Bool found = FALSE;
16966  int increment = 1;
16967 
16968  /* try if we found a possible operator */
16969  switch( *curr )
16970  {
16971  case '<':
16972  case '=':
16973  case '>':
16974 
16975  /* check if the two characters curr[0,1] form an operator together */
16976  if( curr[1] == '=' )
16977  {
16978  found = TRUE;
16979 
16980  /* update increment to continue after this operator */
16981  increment = 2;
16982  }
16983  break;
16984  case '[':
16985  if( strncmp(curr, "[free]", 6) == 0 )
16986  {
16987  found = TRUE;
16988 
16989  /* update increment to continue after this operator */
16990  increment = 6;
16991  }
16992  break;
16993  default:
16994  break;
16995  }
16996 
16997  /* assign the found operator to the first or second pointer and check for violations of the linear constraint grammar */
16998  if( found )
16999  {
17000  if( *firstoperator == NULL )
17001  {
17002  *firstoperator = curr;
17003  }
17004  else
17005  {
17006  if( *secondoperator != NULL )
17007  {
17008  SCIPerrorMessage("Found more than two operators in line %s\n", str);
17009  *success = FALSE;
17010  }
17011  else if( strncmp(*firstoperator, "<=", 2) != 0 )
17012  {
17013  SCIPerrorMessage("Two operators in line that is not a ranged row: %s", str);
17014  *success = FALSE;
17015  }
17016  else if( strncmp(curr, "<=", 2) != 0 )
17017  {
17018  SCIPerrorMessage("Bad second operator, expected ranged row specification: %s", str);
17019  *success = FALSE;
17020  }
17021 
17022  *secondoperator = curr;
17023  }
17024  }
17025 
17026  curr += increment;
17027  }
17028 
17029  /* check if we did find at least one operator */
17030  if( *success )
17031  {
17032  if( *firstoperator == NULL )
17033  {
17034  SCIPerrorMessage("Could not find any operator in line %s\n", str);
17035  *success = FALSE;
17036  }
17037  }
17038 }
17039 
17040 /** constraint parsing method of constraint handler */
17041 static
17042 SCIP_DECL_CONSPARSE(consParseLinear)
17043 { /*lint --e{715}*/
17044  SCIP_VAR** vars;
17045  SCIP_Real* coefs;
17046  int nvars;
17047  int coefssize;
17048  int requsize;
17049  SCIP_Real lhs;
17050  SCIP_Real rhs;
17051  char* endptr;
17052  char* firstop;
17053  char* secondop;
17054  SCIP_Bool operatorsuccess;
17055  char* lhsstrptr;
17056  char* rhsstrptr;
17057  char* varstrptr;
17058 
17059  assert(scip != NULL);
17060  assert(success != NULL);
17061  assert(str != NULL);
17062  assert(name != NULL);
17063  assert(cons != NULL);
17064 
17065  /* set left and right hand side to their default values */
17066  lhs = -SCIPinfinity(scip);
17067  rhs = SCIPinfinity(scip);
17068 
17069  (*success) = FALSE;
17070 
17071  /* return of string empty */
17072  if( !*str )
17073  return SCIP_OKAY;
17074 
17075  /* ignore whitespace */
17076  while( isspace((unsigned char)*str) )
17077  ++str;
17078 
17079  /* find operators in the line first, all other remaining parsing depends on occurence of the operators '<=', '>=', '==',
17080  * and the special word [free]
17081  */
17082  findOperators(str, &firstop, &secondop, &operatorsuccess);
17083 
17084  /* if the grammar is not valid for parsing a linear constraint, return */
17085  if( ! operatorsuccess )
17086  return SCIP_OKAY;
17087 
17088  varstrptr = (char *)str;
17089  lhsstrptr = rhsstrptr = NULL;
17090  assert(firstop != NULL);
17091 
17092  /* assign the strings for parsing the left hand side, right hand side, and the linear variable sum */
17093  switch( *firstop )
17094  {
17095  case '<':
17096  assert(firstop[1] == '=');
17097  /* we have ranged row lhs <= a_1 x_1 + ... + a_n x_n <= rhs */
17098  if( secondop != NULL )
17099  {
17100  assert(secondop[0] == '<' && secondop[1] == '=');
17101  lhsstrptr = (char *)str;
17102  varstrptr = firstop + 2;
17103  rhsstrptr = secondop + 2;
17104  }
17105  else
17106  {
17107  /* we have an inequality with infinite left hand side a_1 x_1 + ... + a_n x_n <= rhs */
17108  lhsstrptr = NULL;
17109  varstrptr = (char *)str;
17110  rhsstrptr = firstop + 2;
17111  }
17112  break;
17113  case '>':
17114  assert(firstop[1] == '=');
17115  assert(secondop == NULL);
17116  /* we have a_1 x_1 + ... + a_n x_n >= lhs */
17117  lhsstrptr = firstop + 2;
17118  break;
17119  case '=':
17120  assert(firstop[1] == '=');
17121  assert(secondop == NULL);
17122  /* we have a_1 x_1 + ... + a_n x_n == lhs (rhs) */
17123  rhsstrptr = firstop + 2;
17124  lhsstrptr = firstop + 2;
17125  break;
17126  case '[':
17127  assert(strncmp(firstop, "[free]", 6) == 0);
17128  assert(secondop == NULL);
17129  /* nothing to assign in case of a free a_1 x_1 + ... + a_n x_n [free] */
17130  break;
17131  default:
17132  /* it should not be possible that a different character appears in that position */
17133  SCIPerrorMessage("Parsing has wrong operator character '%c', should be one of <=>[", *firstop);
17134  return SCIP_READERROR;
17135  }
17136 
17137  /* parse left hand side, if necessary */
17138  if( lhsstrptr != NULL )
17139  {
17140  if( ! SCIPparseReal(scip, lhsstrptr, &lhs, &endptr) )
17141  {
17142  SCIPerrorMessage("error parsing left hand side number from <%s>\n", lhsstrptr);
17143  return SCIP_OKAY;
17144  }
17145 
17146  /* in case of an equation, assign the left also to the right hand side */
17147  if( rhsstrptr == lhsstrptr )
17148  rhs = lhs;
17149  }
17150 
17151  /* parse right hand side, if different from left hand side */
17152  if( rhsstrptr != NULL && rhsstrptr != lhsstrptr )
17153  {
17154  if( ! SCIPparseReal(scip, rhsstrptr, &rhs, &endptr) )
17155  {
17156  SCIPerrorMessage("error parsing right hand side number from <%s>\n", lhsstrptr);
17157  return SCIP_OKAY;
17158  }
17159  }
17160 
17161  /* initialize buffers for storing the variables and coefficients */
17162  coefssize = 100;
17163  SCIP_CALL( SCIPallocBufferArray(scip, &vars, coefssize) );
17164  SCIP_CALL( SCIPallocBufferArray(scip, &coefs, coefssize) );
17165 
17166  assert(varstrptr != NULL);
17167 
17168  /* parse linear sum to get variables and coefficients */
17169  SCIP_CALL( SCIPparseVarsLinearsum(scip, varstrptr, vars, coefs, &nvars, coefssize, &requsize, &endptr, success) );
17170 
17171  if( *success && requsize > coefssize )
17172  {
17173  /* realloc buffers and try again */
17174  coefssize = requsize;
17175  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, coefssize) );
17176  SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, coefssize) );
17177 
17178  SCIP_CALL( SCIPparseVarsLinearsum(scip, varstrptr, vars, coefs, &nvars, coefssize, &requsize, &endptr, success) );
17179  assert(!*success || requsize <= coefssize); /* if successful, then should have had enough space now */
17180  }
17181 
17182  if( !*success )
17183  {
17184  SCIPerrorMessage("no luck in parsing linear sum '%s'\n", varstrptr);
17185  }
17186  else
17187  {
17188  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
17189  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
17190  }
17191 
17192  SCIPfreeBufferArray(scip, &coefs);
17193  SCIPfreeBufferArray(scip, &vars);
17194 
17195  return SCIP_OKAY;
17196 }
17197 
17198 
17199 /** constraint method of constraint handler which returns the variables (if possible) */
17200 static
17201 SCIP_DECL_CONSGETVARS(consGetVarsLinear)
17202 { /*lint --e{715}*/
17203  SCIP_CONSDATA* consdata;
17204 
17205  consdata = SCIPconsGetData(cons);
17206  assert(consdata != NULL);
17207 
17208  if( varssize < consdata->nvars )
17209  (*success) = FALSE;
17210  else
17211  {
17212  assert(vars != NULL);
17213 
17214  BMScopyMemoryArray(vars, consdata->vars, consdata->nvars);
17215  (*success) = TRUE;
17216  }
17217 
17218  return SCIP_OKAY;
17219 }
17221 /**! [Callback for the number of variables]*/
17222 /** constraint method of constraint handler which returns the number of variables (if possible) */
17223 static
17224 SCIP_DECL_CONSGETNVARS(consGetNVarsLinear)
17225 { /*lint --e{715}*/
17226  SCIP_CONSDATA* consdata;
17227 
17228  consdata = SCIPconsGetData(cons);
17229  assert(consdata != NULL);
17230 
17231  (*nvars) = consdata->nvars;
17232  (*success) = TRUE;
17233 
17234  return SCIP_OKAY;
17235 }
17236 /**! [Callback for the number of variables]*/
17237 
17238 /*
17239  * Callback methods of event handler
17240  */
17241 
17242 /** execution method of event handler */
17243 static
17244 SCIP_DECL_EVENTEXEC(eventExecLinear)
17245 { /*lint --e{715}*/
17246  SCIP_CONS* cons;
17247  SCIP_CONSDATA* consdata;
17248  SCIP_VAR* var;
17249  SCIP_EVENTTYPE eventtype;
17250 
17251  assert(scip != NULL);
17252  assert(eventhdlr != NULL);
17253  assert(eventdata != NULL);
17254  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
17255  assert(event != NULL);
17256 
17257  cons = eventdata->cons;
17258  assert(cons != NULL);
17259  consdata = SCIPconsGetData(cons);
17260  assert(consdata != NULL);
17261 
17262  /* we can skip events droped for deleted constraints */
17263  if( SCIPconsIsDeleted(cons) )
17264  return SCIP_OKAY;
17265 
17266  eventtype = SCIPeventGetType(event);
17267  var = SCIPeventGetVar(event);
17268 
17269  if( (eventtype & SCIP_EVENTTYPE_BOUNDCHANGED) != 0 )
17270  {
17271  SCIP_Real oldbound;
17272  SCIP_Real newbound;
17273  SCIP_Real val;
17274  int varpos;
17275 
17276  varpos = eventdata->varpos;
17277  assert(0 <= varpos && varpos < consdata->nvars);
17278  oldbound = SCIPeventGetOldbound(event);
17279  newbound = SCIPeventGetNewbound(event);
17280  assert(var != NULL);
17281  assert(consdata->vars[varpos] == var);
17282  val = consdata->vals[varpos];
17283 
17284  /* we only need to update the activities if the constraint is active,
17285  * otherwise we mark them to be invalid
17286  */
17287  if( SCIPconsIsActive(cons) )
17288  {
17289  /* update the activity values */
17290  if( (eventtype & SCIP_EVENTTYPE_LBCHANGED) != 0 )
17291  consdataUpdateActivitiesLb(scip, consdata, var, oldbound, newbound, val, TRUE);
17292  else
17293  {
17294  assert((eventtype & SCIP_EVENTTYPE_UBCHANGED) != 0);
17295  consdataUpdateActivitiesUb(scip, consdata, var, oldbound, newbound, val, TRUE);
17296  }
17297  }
17298  else
17299  consdataInvalidateActivities(consdata);
17300 
17301  consdata->presolved = FALSE;
17302  consdata->rangedrowpropagated = 0;
17303 
17304  /* bound change can turn the constraint infeasible or redundant only if it was a tightening */
17305  if( (eventtype & SCIP_EVENTTYPE_BOUNDTIGHTENED) != 0 )
17306  {
17307  SCIP_CALL( SCIPmarkConsPropagate(scip, cons) );
17308 
17309  /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
17310  if( consdata->maxactdeltavar == var )
17311  {
17312  consdata->maxactdelta = SCIP_INVALID;
17313  consdata->maxactdeltavar = NULL;
17314  }
17315 
17316  /* check whether bound tightening might now be successful */
17317  if( consdata->boundstightened > 0)
17318  {
17319  switch( eventtype )
17320  {
17322  if( (val > 0.0 ? !SCIPisInfinity(scip, consdata->rhs) : !SCIPisInfinity(scip, -consdata->lhs)) )
17323  consdata->boundstightened = 0;
17324  break;
17326  if( (val > 0.0 ? !SCIPisInfinity(scip, -consdata->lhs) : !SCIPisInfinity(scip, consdata->rhs)) )
17327  consdata->boundstightened = 0;
17328  break;
17329  default:
17330  SCIPerrorMessage("invalid event type %" SCIP_EVENTTYPE_FORMAT "\n", eventtype);
17331  return SCIP_INVALIDDATA;
17332  }
17333  }
17334  }
17335  /* update maximal activity delta if a bound was relaxed */
17336  else if( !SCIPisInfinity(scip, consdata->maxactdelta) )
17337  {
17338  SCIP_Real lb;
17339  SCIP_Real ub;
17340  SCIP_Real domain;
17341  SCIP_Real delta;
17342 
17343  assert((eventtype & SCIP_EVENTTYPE_BOUNDRELAXED) != 0);
17344 
17345  lb = SCIPvarGetLbLocal(var);
17346  ub = SCIPvarGetUbLocal(var);
17347 
17348  domain = ub - lb;
17349  delta = REALABS(val) * domain;
17350 
17351  if( delta > consdata->maxactdelta )
17352  {
17353  consdata->maxactdelta = delta;
17354  consdata->maxactdeltavar = var;
17355  }
17356  }
17357  }
17358  else if( (eventtype & SCIP_EVENTTYPE_VARFIXED) != 0 )
17359  {
17360  /* we want to remove the fixed variable */
17361  consdata->presolved = FALSE;
17362  consdata->removedfixings = FALSE;
17363  consdata->rangedrowpropagated = 0;
17364 
17365  /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
17366  if( consdata->maxactdeltavar == var )
17367  {
17368  consdata->maxactdelta = SCIP_INVALID;
17369  consdata->maxactdeltavar = NULL;
17370  }
17371  }
17372  else if( (eventtype & SCIP_EVENTTYPE_VARUNLOCKED) != 0 )
17373  {
17374  /* there is only one lock left: we may multi-aggregate the variable as slack of an equation */
17375  assert(SCIPvarGetNLocksDownType(var, SCIP_LOCKTYPE_MODEL) <= 1);
17376  assert(SCIPvarGetNLocksUpType(var, SCIP_LOCKTYPE_MODEL) <= 1);
17377  consdata->presolved = FALSE;
17378  }
17379  else if( (eventtype & SCIP_EVENTTYPE_GBDCHANGED) != 0 )
17380  {
17381  SCIP_Real oldbound;
17382  SCIP_Real newbound;
17383  SCIP_Real val;
17384  int varpos;
17385 
17386  varpos = eventdata->varpos;
17387  assert(0 <= varpos && varpos < consdata->nvars);
17388  oldbound = SCIPeventGetOldbound(event);
17389  newbound = SCIPeventGetNewbound(event);
17390  assert(var != NULL);
17391  assert(consdata->vars[varpos] == var);
17392  val = consdata->vals[varpos];
17393 
17394  consdata->rangedrowpropagated = 0;
17395 
17396  /* update the activity values */
17397  if( (eventtype & SCIP_EVENTTYPE_GLBCHANGED) != 0 )
17398  consdataUpdateActivitiesGlbLb(scip, consdata, oldbound, newbound, val, TRUE);
17399  else
17400  {
17401  assert((eventtype & SCIP_EVENTTYPE_GUBCHANGED) != 0);
17402  consdataUpdateActivitiesGlbUb(scip, consdata, oldbound, newbound, val, TRUE);
17403  }
17404 
17405  /* if the variable is binary but not fixed it had to become binary due to this global change */
17406  if( SCIPvarIsBinary(var) && SCIPisGT(scip, SCIPvarGetUbGlobal(var), SCIPvarGetLbGlobal(var)) )
17407  {
17408  if( SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE )
17409  consdata->indexsorted = FALSE;
17410  else
17411  consdata->coefsorted = FALSE;
17412  }
17413  }
17414  else if( (eventtype & SCIP_EVENTTYPE_TYPECHANGED) != 0 )
17415  {
17416  assert(SCIPgetStage(scip) < SCIP_STAGE_PRESOLVED);
17417 
17418  /* for presolving it only matters if a variable type changed from continuous to some kind of integer */
17419  consdata->presolved = (consdata->presolved && SCIPeventGetOldtype(event) < SCIP_VARTYPE_CONTINUOUS);
17420 
17421  /* the ordering is preserved if the type changes from something different to binary to binary but SCIPvarIsBinary() is true */
17422  consdata->indexsorted = (consdata->indexsorted && SCIPeventGetNewtype(event) == SCIP_VARTYPE_BINARY && SCIPvarIsBinary(var));
17423  }
17424  else
17425  {
17426  assert((eventtype & SCIP_EVENTTYPE_VARDELETED) != 0);
17427  consdata->varsdeleted = TRUE;
17428  }
17429 
17430  return SCIP_OKAY;
17431 }
17432 
17433 
17434 /*
17435  * Callback methods of conflict handler
17436  */
17437 
17438 /** conflict processing method of conflict handler (called when conflict was found) */
17439 static
17440 SCIP_DECL_CONFLICTEXEC(conflictExecLinear)
17441 { /*lint --e{715}*/
17442  SCIP_VAR** vars;
17443  SCIP_Real* vals;
17444  SCIP_Real lhs;
17445  int i;
17446 
17447  assert(scip != NULL);
17448  assert(conflicthdlr != NULL);
17449  assert(strcmp(SCIPconflicthdlrGetName(conflicthdlr), CONFLICTHDLR_NAME) == 0);
17450  assert(bdchginfos != NULL || nbdchginfos == 0);
17451  assert(result != NULL);
17452 
17453  /* don't process already resolved conflicts */
17454  if( resolved )
17455  {
17456  *result = SCIP_DIDNOTRUN;
17457  return SCIP_OKAY;
17458  }
17460  *result = SCIP_DIDNOTFIND;
17461 
17462  /* create array of variables and coefficients: sum_{i \in P} x_i - sum_{i \in N} x_i >= 1 - |N| */
17463  SCIP_CALL( SCIPallocBufferArray(scip, &vars, nbdchginfos) );
17464  SCIP_CALL( SCIPallocBufferArray(scip, &vals, nbdchginfos) );
17465  lhs = 1.0;
17466  for( i = 0; i < nbdchginfos; ++i )
17467  {
17468  assert(bdchginfos != NULL);
17469 
17470  vars[i] = SCIPbdchginfoGetVar(bdchginfos[i]);
17471 
17472  /* we can only treat binary variables */
17473  /**@todo extend linear conflict constraints to some non-binary cases */
17474  if( !SCIPvarIsBinary(vars[i]) )
17475  break;
17476 
17477  /* check whether the variable is fixed to zero (P) or one (N) in the conflict set */
17478  if( SCIPbdchginfoGetNewbound(bdchginfos[i]) < 0.5 )
17479  vals[i] = 1.0;
17480  else
17481  {
17482  vals[i] = -1.0;
17483  lhs -= 1.0;
17484  }
17485  }
17486 
17487  if( i == nbdchginfos )
17488  {
17489  SCIP_CONS* cons;
17490  SCIP_CONS* upgdcons;
17491  char consname[SCIP_MAXSTRLEN];
17492 
17493  /* create a constraint out of the conflict set */
17494  (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "cf%" SCIP_LONGINT_FORMAT, SCIPgetNConflictConssApplied(scip));
17495  SCIP_CALL( SCIPcreateConsLinear(scip, &cons, consname, nbdchginfos, vars, vals, lhs, SCIPinfinity(scip),
17496  FALSE, separate, FALSE, FALSE, TRUE, local, FALSE, dynamic, removable, FALSE) );
17497 
17498  /* try to automatically convert a linear constraint into a more specific and more specialized constraint */
17499  SCIP_CALL( SCIPupgradeConsLinear(scip, cons, &upgdcons) );
17500  if( upgdcons != NULL )
17501  {
17502  SCIP_CALL( SCIPreleaseCons(scip, &cons) );
17503  cons = upgdcons;
17504  }
17505 
17506  /* add conflict to SCIP */
17507  SCIP_CALL( SCIPaddConflict(scip, node, cons, validnode, conftype, cutoffinvolved) );
17508 
17509  *result = SCIP_CONSADDED;
17510  }
17511 
17512  /* free temporary memory */
17513  SCIPfreeBufferArray(scip, &vals);
17514  SCIPfreeBufferArray(scip, &vars);
17515 
17516  return SCIP_OKAY;
17517 }
17518 
17519 
17520 /*
17521  * Nonlinear constraint upgrading
17522  */
17523 
17524 /** tries to upgrade a nonlinear constraint into a linear constraint */
17525 static
17526 SCIP_DECL_NONLINCONSUPGD(upgradeConsNonlinear)
17527 {
17528  SCIP_CONSDATA* consdata;
17529  SCIP_EXPR* expr;
17530  SCIP_Real lhs;
17531  SCIP_Real rhs;
17532  int i;
17533 
17534  assert(nupgdconss != NULL);
17535  assert(upgdconss != NULL);
17536  assert(upgdconsssize > 0);
17537 
17538  expr = SCIPgetExprNonlinear(cons);
17539  assert(expr != NULL);
17540 
17541  /* not a linear constraint if the expression is not a sum
17542  * (unless the expression is a variable or a constant or a constant*variable, but these are simplified away in cons_nonlinear)
17543  */
17544  if( !SCIPisExprSum(scip, expr) )
17545  return SCIP_OKAY;
17546 
17547  /* if at least one child is not a variable, then not a linear constraint */
17548  for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
17549  if( !SCIPisExprVar(scip, SCIPexprGetChildren(expr)[i]) )
17550  return SCIP_OKAY;
17551 
17552  /* consider constant part of the sum expression */
17553  lhs = SCIPisInfinity(scip, -SCIPgetLhsNonlinear(cons)) ? -SCIPinfinity(scip) : (SCIPgetLhsNonlinear(cons) - SCIPgetConstantExprSum(expr));
17554  rhs = SCIPisInfinity(scip, SCIPgetRhsNonlinear(cons)) ? SCIPinfinity(scip) : (SCIPgetRhsNonlinear(cons) - SCIPgetConstantExprSum(expr));
17555 
17556  SCIP_CALL( SCIPcreateConsLinear(scip, &upgdconss[0], SCIPconsGetName(cons),
17557  0, NULL, NULL, lhs, rhs,
17561  SCIPconsIsStickingAtNode(cons)) );
17562  assert(upgdconss[0] != NULL);
17563 
17564  consdata = SCIPconsGetData(upgdconss[0]);
17565 
17566  /* add linear terms */
17567  SCIP_CALL( consdataEnsureVarsSize(scip, consdata, SCIPexprGetNChildren(expr)) );
17568  for( i = 0; i < SCIPexprGetNChildren(expr); ++i )
17569  {
17570  SCIP_CALL( addCoef(scip, upgdconss[0], SCIPgetVarExprVar(SCIPexprGetChildren(expr)[i]), SCIPgetCoefsExprSum(expr)[i]) );
17571  }
17572 
17573  /* check violation of this linear constraint with absolute tolerances, to be consistent with the original nonlinear constraint */
17574  consdata->checkabsolute = TRUE;
17575 
17576  *nupgdconss = 1;
17577 
17578  SCIPdebugMsg(scip, "created linear constraint:\n");
17579  SCIPdebugPrintCons(scip, upgdconss[0], NULL);
17580 
17581  return SCIP_OKAY;
17582 } /*lint !e715*/
17583 
17584 /*
17585  * constraint specific interface methods
17586  */
17587 
17588 /** creates the handler for linear constraints and includes it in SCIP */
17590  SCIP* scip /**< SCIP data structure */
17591  )
17592 {
17593  SCIP_CONSHDLRDATA* conshdlrdata;
17594  SCIP_CONSHDLR* conshdlr;
17595  SCIP_EVENTHDLR* eventhdlr;
17596  SCIP_CONFLICTHDLR* conflicthdlr;
17597 
17598  assert(scip != NULL);
17599 
17600  /* create event handler for bound change events */
17602  eventExecLinear, NULL) );
17603 
17604  /* create conflict handler for linear constraints */
17606  conflictExecLinear, NULL) );
17607 
17608  /* create constraint handler data */
17609  SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
17610 
17611  /* include constraint handler */
17614  consEnfolpLinear, consEnfopsLinear, consCheckLinear, consLockLinear,
17615  conshdlrdata) );
17616 
17617  assert(conshdlr != NULL);
17618 
17619  /* set non-fundamental callbacks via specific setter functions */
17620  SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyLinear, consCopyLinear) );
17621  SCIP_CALL( SCIPsetConshdlrActive(scip, conshdlr, consActiveLinear) );
17622  SCIP_CALL( SCIPsetConshdlrDeactive(scip, conshdlr, consDeactiveLinear) );
17623  SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteLinear) );
17624  SCIP_CALL( SCIPsetConshdlrDelvars(scip, conshdlr, consDelvarsLinear) );
17625  SCIP_CALL( SCIPsetConshdlrExit(scip, conshdlr, consExitLinear) );
17626  SCIP_CALL( SCIPsetConshdlrExitpre(scip, conshdlr, consExitpreLinear) );
17627  SCIP_CALL( SCIPsetConshdlrInitsol(scip, conshdlr, consInitsolLinear) );
17628  SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolLinear) );
17629  SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeLinear) );
17630  SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsLinear) );
17631  SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsLinear) );
17632  SCIP_CALL( SCIPsetConshdlrInit(scip, conshdlr, consInitLinear) );
17633  SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpLinear) );
17634  SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseLinear) );
17635  SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolLinear, CONSHDLR_MAXPREROUNDS, CONSHDLR_PRESOLTIMING) );
17636  SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintLinear) );
17637  SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropLinear, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP,
17639  SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropLinear) );
17640  SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpLinear, consSepasolLinear, CONSHDLR_SEPAFREQ,
17642  SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransLinear) );
17643  SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxLinear) );
17644 
17645  if( SCIPfindConshdlr(scip, "nonlinear") != NULL )
17646  {
17647  /* include the linear constraint upgrade in the nonlinear constraint handler */
17649  }
17650 
17651  /* add linear constraint handler parameters */
17652  SCIP_CALL( SCIPaddIntParam(scip,
17653  "constraints/" CONSHDLR_NAME "/tightenboundsfreq",
17654  "multiplier on propagation frequency, how often the bounds are tightened (-1: never, 0: only at root)",
17655  &conshdlrdata->tightenboundsfreq, TRUE, DEFAULT_TIGHTENBOUNDSFREQ, -1, SCIP_MAXTREEDEPTH, NULL, NULL) );
17656  SCIP_CALL( SCIPaddIntParam(scip,
17657  "constraints/" CONSHDLR_NAME "/maxrounds",
17658  "maximal number of separation rounds per node (-1: unlimited)",
17659  &conshdlrdata->maxrounds, FALSE, DEFAULT_MAXROUNDS, -1, INT_MAX, NULL, NULL) );
17660  SCIP_CALL( SCIPaddIntParam(scip,
17661  "constraints/" CONSHDLR_NAME "/maxroundsroot",
17662  "maximal number of separation rounds per node in the root node (-1: unlimited)",
17663  &conshdlrdata->maxroundsroot, FALSE, DEFAULT_MAXROUNDSROOT, -1, INT_MAX, NULL, NULL) );
17664  SCIP_CALL( SCIPaddIntParam(scip,
17665  "constraints/" CONSHDLR_NAME "/maxsepacuts",
17666  "maximal number of cuts separated per separation round",
17667  &conshdlrdata->maxsepacuts, FALSE, DEFAULT_MAXSEPACUTS, 0, INT_MAX, NULL, NULL) );
17668  SCIP_CALL( SCIPaddIntParam(scip,
17669  "constraints/" CONSHDLR_NAME "/maxsepacutsroot",
17670  "maximal number of cuts separated per separation round in the root node",
17671  &conshdlrdata->maxsepacutsroot, FALSE, DEFAULT_MAXSEPACUTSROOT, 0, INT_MAX, NULL, NULL) );
17673  "constraints/" CONSHDLR_NAME "/presolpairwise",
17674  "should pairwise constraint comparison be performed in presolving?",
17675  &conshdlrdata->presolpairwise, TRUE, DEFAULT_PRESOLPAIRWISE, NULL, NULL) );
17677  "constraints/" CONSHDLR_NAME "/presolusehashing",
17678  "should hash table be used for detecting redundant constraints in advance",
17679  &conshdlrdata->presolusehashing, TRUE, DEFAULT_PRESOLUSEHASHING, NULL, NULL) );
17680  SCIP_CALL( SCIPaddIntParam(scip,
17681  "constraints/" CONSHDLR_NAME "/nmincomparisons",
17682  "number for minimal pairwise presolve comparisons",
17683  &conshdlrdata->nmincomparisons, TRUE, DEFAULT_NMINCOMPARISONS, 1, INT_MAX, NULL, NULL) );
17685  "constraints/" CONSHDLR_NAME "/mingainpernmincomparisons",
17686  "minimal gain per minimal pairwise presolve comparisons to repeat pairwise comparison round",
17687  &conshdlrdata->mingainpernmincomp, TRUE, DEFAULT_MINGAINPERNMINCOMP, 0.0, 1.0, NULL, NULL) );
17689  "constraints/" CONSHDLR_NAME "/maxaggrnormscale",
17690  "maximal allowed relative gain in maximum norm for constraint aggregation (0.0: disable constraint aggregation)",
17691  &conshdlrdata->maxaggrnormscale, TRUE, DEFAULT_MAXAGGRNORMSCALE, 0.0, SCIP_REAL_MAX, NULL, NULL) );
17693  "constraints/" CONSHDLR_NAME "/maxeasyactivitydelta",
17694  "maximum activity delta to run easy propagation on linear constraint (faster, but numerically less stable)",
17695  &conshdlrdata->maxeasyactivitydelta, TRUE, DEFAULT_MAXEASYACTIVITYDELTA, 0.0, SCIP_REAL_MAX, NULL, NULL) );
17697  "constraints/" CONSHDLR_NAME "/maxcardbounddist",
17698  "maximal relative distance from current node's dual bound to primal bound compared to best node's dual bound for separating knapsack cardinality cuts",
17699  &conshdlrdata->maxcardbounddist, TRUE, DEFAULT_MAXCARDBOUNDDIST, 0.0, 1.0, NULL, NULL) );
17701  "constraints/" CONSHDLR_NAME "/separateall",
17702  "should all constraints be subject to cardinality cut generation instead of only the ones with non-zero dual value?",
17703  &conshdlrdata->separateall, FALSE, DEFAULT_SEPARATEALL, NULL, NULL) );
17705  "constraints/" CONSHDLR_NAME "/aggregatevariables",
17706  "should presolving search for aggregations in equations",
17707  &conshdlrdata->aggregatevariables, TRUE, DEFAULT_AGGREGATEVARIABLES, NULL, NULL) );
17709  "constraints/" CONSHDLR_NAME "/simplifyinequalities",
17710  "should presolving try to simplify inequalities",
17711  &conshdlrdata->simplifyinequalities, TRUE, DEFAULT_SIMPLIFYINEQUALITIES, NULL, NULL) );
17713  "constraints/" CONSHDLR_NAME "/dualpresolving",
17714  "should dual presolving steps be performed?",
17715  &conshdlrdata->dualpresolving, TRUE, DEFAULT_DUALPRESOLVING, NULL, NULL) );
17717  "constraints/" CONSHDLR_NAME "/singletonstuffing",
17718  "should stuffing of singleton continuous variables be performed?",
17719  &conshdlrdata->singletonstuffing, TRUE, DEFAULT_SINGLETONSTUFFING, NULL, NULL) );
17721  "constraints/" CONSHDLR_NAME "/singlevarstuffing",
17722  "should single variable stuffing be performed, which tries to fulfill constraints using the cheapest variable?",
17723  &conshdlrdata->singlevarstuffing, TRUE, DEFAULT_SINGLEVARSTUFFING, NULL, NULL) );
17725  "constraints/" CONSHDLR_NAME "/sortvars", "apply binaries sorting in decr. order of coeff abs value?",
17726  &conshdlrdata->sortvars, TRUE, DEFAULT_SORTVARS, NULL, NULL) );
17728  "constraints/" CONSHDLR_NAME "/checkrelmaxabs",
17729  "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)?",
17730  &conshdlrdata->checkrelmaxabs, TRUE, DEFAULT_CHECKRELMAXABS, NULL, NULL) );
17732  "constraints/" CONSHDLR_NAME "/detectcutoffbound",
17733  "should presolving try to detect constraints parallel to the objective function defining an upper bound and prevent these constraints from entering the LP?",
17734  &conshdlrdata->detectcutoffbound, TRUE, DEFAULT_DETECTCUTOFFBOUND, NULL, NULL) );
17736  "constraints/" CONSHDLR_NAME "/detectlowerbound",
17737  "should presolving try to detect constraints parallel to the objective function defining a lower bound and prevent these constraints from entering the LP?",
17738  &conshdlrdata->detectlowerbound, TRUE, DEFAULT_DETECTLOWERBOUND, NULL, NULL) );
17740  "constraints/" CONSHDLR_NAME "/detectpartialobjective",
17741  "should presolving try to detect subsets of constraints parallel to the objective function?",
17742  &conshdlrdata->detectpartialobjective, TRUE, DEFAULT_DETECTPARTIALOBJECTIVE, NULL, NULL) );
17744  "constraints/" CONSHDLR_NAME "/rangedrowpropagation",
17745  "should presolving and propagation try to improve bounds, detect infeasibility, and extract sub-constraints from ranged rows and equations?",
17746  &conshdlrdata->rangedrowpropagation, TRUE, DEFAULT_RANGEDROWPROPAGATION, NULL, NULL) );
17748  "constraints/" CONSHDLR_NAME "/rangedrowartcons",
17749  "should presolving and propagation extract sub-constraints from ranged rows and equations?",
17750  &conshdlrdata->rangedrowartcons, TRUE, DEFAULT_RANGEDROWARTCONS, NULL, NULL) );
17751  SCIP_CALL( SCIPaddIntParam(scip,
17752  "constraints/" CONSHDLR_NAME "/rangedrowmaxdepth",
17753  "maximum depth to apply ranged row propagation",
17754  &conshdlrdata->rangedrowmaxdepth, TRUE, DEFAULT_RANGEDROWMAXDEPTH, 0, INT_MAX, NULL, NULL) );
17755  SCIP_CALL( SCIPaddIntParam(scip,
17756  "constraints/" CONSHDLR_NAME "/rangedrowfreq",
17757  "frequency for applying ranged row propagation",
17758  &conshdlrdata->rangedrowfreq, TRUE, DEFAULT_RANGEDROWFREQ, 1, SCIP_MAXTREEDEPTH, NULL, NULL) );
17760  "constraints/" CONSHDLR_NAME "/multaggrremove",
17761  "should multi-aggregations only be performed if the constraint can be removed afterwards?",
17762  &conshdlrdata->multaggrremove, TRUE, DEFAULT_MULTAGGRREMOVE, NULL, NULL) );
17764  "constraints/" CONSHDLR_NAME "/maxmultaggrquot",
17765  "maximum coefficient dynamism (ie. maxabsval / minabsval) for primal multiaggregation",
17766  &conshdlrdata->maxmultaggrquot, TRUE, DEFAULT_MAXMULTAGGRQUOT, 1.0, SCIP_REAL_MAX, NULL, NULL) );
17768  "constraints/" CONSHDLR_NAME "/maxdualmultaggrquot",
17769  "maximum coefficient dynamism (ie. maxabsval / minabsval) for dual multiaggregation",
17770  &conshdlrdata->maxdualmultaggrquot, TRUE, DEFAULT_MAXDUALMULTAGGRQUOT, 1.0, SCIP_REAL_MAX, NULL, NULL) );
17772  "constraints/" CONSHDLR_NAME "/extractcliques",
17773  "should Cliques be extracted?",
17774  &conshdlrdata->extractcliques, TRUE, DEFAULT_EXTRACTCLIQUES, NULL, NULL) );
17775 
17776  return SCIP_OKAY;
17777 }
17778 
17779 /** includes a linear constraint update method into the linear constraint handler */
17781  SCIP* scip, /**< SCIP data structure */
17782  SCIP_DECL_LINCONSUPGD((*linconsupgd)), /**< method to call for upgrading linear constraint */
17783  int priority, /**< priority of upgrading method */
17784  const char* conshdlrname /**< name of the constraint handler */
17785  )
17786 {
17787  SCIP_CONSHDLR* conshdlr;
17788  SCIP_CONSHDLRDATA* conshdlrdata;
17789  SCIP_LINCONSUPGRADE* linconsupgrade;
17790  char paramname[SCIP_MAXSTRLEN];
17791  char paramdesc[SCIP_MAXSTRLEN];
17792 
17793  assert(scip != NULL);
17794  assert(linconsupgd != NULL);
17795  assert(conshdlrname != NULL );
17796 
17797  /* find the linear constraint handler */
17798  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
17799  if( conshdlr == NULL )
17800  {
17801  SCIPerrorMessage("linear constraint handler not found\n");
17802  return SCIP_PLUGINNOTFOUND;
17803  }
17804 
17805  conshdlrdata = SCIPconshdlrGetData(conshdlr);
17806  assert(conshdlrdata != NULL);
17807 
17808  /* check if linear constraint update method already exists in constraint handler data */
17809  if( !conshdlrdataHasUpgrade(scip, conshdlrdata, linconsupgd, conshdlrname) )
17810  {
17811  /* create a linear constraint upgrade data object */
17812  SCIP_CALL( linconsupgradeCreate(scip, &linconsupgrade, linconsupgd, priority) );
17813 
17814  /* insert linear constraint update method into constraint handler data */
17815  SCIP_CALL( conshdlrdataIncludeUpgrade(scip, conshdlrdata, linconsupgrade) );
17816 
17817  /* adds parameter to turn on and off the upgrading step */
17818  (void) SCIPsnprintf(paramname, SCIP_MAXSTRLEN, "constraints/linear/upgrade/%s", conshdlrname);
17819  (void) SCIPsnprintf(paramdesc, SCIP_MAXSTRLEN, "enable linear upgrading for constraint handler <%s>", conshdlrname);
17821  paramname, paramdesc,
17822  &linconsupgrade->active, FALSE, TRUE, NULL, NULL) );
17823  }
17824 
17825  return SCIP_OKAY;
17826 }
17827 
17828 /** creates and captures a linear constraint
17829  *
17830  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
17831  */
17833  SCIP* scip, /**< SCIP data structure */
17834  SCIP_CONS** cons, /**< pointer to hold the created constraint */
17835  const char* name, /**< name of constraint */
17836  int nvars, /**< number of nonzeros in the constraint */
17837  SCIP_VAR** vars, /**< array with variables of constraint entries */
17838  SCIP_Real* vals, /**< array with coefficients of constraint entries */
17839  SCIP_Real lhs, /**< left hand side of constraint */
17840  SCIP_Real rhs, /**< right hand side of constraint */
17841  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
17842  * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
17843  SCIP_Bool separate, /**< should the constraint be separated during LP processing?
17844  * Usually set to TRUE. */
17845  SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
17846  * TRUE for model constraints, FALSE for additional, redundant constraints. */
17847  SCIP_Bool check, /**< should the constraint be checked for feasibility?
17848  * TRUE for model constraints, FALSE for additional, redundant constraints. */
17849  SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
17850  * Usually set to TRUE. */
17851  SCIP_Bool local, /**< is constraint only valid locally?
17852  * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
17853  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
17854  * Usually set to FALSE. In column generation applications, set to TRUE if pricing
17855  * adds coefficients to this constraint. */
17856  SCIP_Bool dynamic, /**< is constraint subject to aging?
17857  * Usually set to FALSE. Set to TRUE for own cuts which
17858  * are separated as constraints. */
17859  SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
17860  * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
17861  SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
17862  * if it may be moved to a more global node?
17863  * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
17864  )
17865 {
17866  SCIP_CONSHDLR* conshdlr;
17867  SCIP_CONSDATA* consdata;
17868 
17869  assert(scip != NULL);
17870  assert(cons != NULL);
17871 
17872  /* find the linear constraint handler */
17873  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
17874  if( conshdlr == NULL )
17875  {
17876  SCIPerrorMessage("linear constraint handler not found\n");
17877  return SCIP_PLUGINNOTFOUND;
17878  }
17879 
17880  /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
17881  * constraint after presolving we have to ensure that it holds active variables
17882  */
17883  if( SCIPgetStage(scip) >= SCIP_STAGE_EXITPRESOLVE && nvars > 0 )
17884  {
17885  SCIP_VAR** consvars;
17886  SCIP_Real* consvals;
17887  SCIP_Real constant = 0.0;
17888  int nconsvars;
17889  int requiredsize;
17890 
17891  nconsvars = nvars;
17892  SCIP_CALL( SCIPduplicateBufferArray(scip, &consvars, vars, nconsvars) );
17893  SCIP_CALL( SCIPduplicateBufferArray(scip, &consvals, vals, nconsvars) );
17894 
17895  /* get active variables for new constraint */
17896  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, nconsvars, &constant, &requiredsize, TRUE) );
17897 
17898  /* if space was not enough we need to resize the buffers */
17899  if( requiredsize > nconsvars )
17900  {
17901  SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
17902  SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
17903 
17904  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize, TRUE) );
17905  assert(requiredsize <= nconsvars);
17906  }
17907 
17908  /* adjust sides and check that we do not subtract infinity values */
17909  if( SCIPisInfinity(scip, REALABS(constant)) )
17910  {
17911  if( constant < 0.0 )
17912  {
17913  if( SCIPisInfinity(scip, lhs) )
17914  {
17915  SCIPfreeBufferArray(scip, &consvals);
17916  SCIPfreeBufferArray(scip, &consvars);
17917 
17918  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);
17919 
17920  SCIPABORT();
17921  return SCIP_INVALIDDATA; /*lint !e527*/
17922  }
17923  if( SCIPisInfinity(scip, rhs) )
17924  {
17925  SCIPfreeBufferArray(scip, &consvals);
17926  SCIPfreeBufferArray(scip, &consvars);
17927 
17928  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);
17929 
17930  SCIPABORT();
17931  return SCIP_INVALIDDATA; /*lint !e527*/
17932  }
17933 
17934  lhs = -SCIPinfinity(scip);
17935  rhs = -SCIPinfinity(scip);
17936  }
17937  else
17938  {
17939  if( SCIPisInfinity(scip, -lhs) )
17940  {
17941  SCIPfreeBufferArray(scip, &consvals);
17942  SCIPfreeBufferArray(scip, &consvars);
17943 
17944  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);
17945 
17946  SCIPABORT();
17947  return SCIP_INVALIDDATA; /*lint !e527*/
17948  }
17949  if( SCIPisInfinity(scip, -rhs) )
17950  {
17951  SCIPfreeBufferArray(scip, &consvals);
17952  SCIPfreeBufferArray(scip, &consvars);
17953 
17954  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);
17955 
17956  SCIPABORT();
17957  return SCIP_INVALIDDATA; /*lint !e527*/
17958  }
17959 
17960  lhs = SCIPinfinity(scip);
17961  rhs = SCIPinfinity(scip);
17962  }
17963  }
17964  else
17965  {
17966  if( !SCIPisInfinity(scip, REALABS(lhs)) )
17967  lhs -= constant;
17968  if( !SCIPisInfinity(scip, REALABS(rhs)) )
17969  rhs -= constant;
17970 
17971  if( SCIPisInfinity(scip, -lhs) )
17972  lhs = -SCIPinfinity(scip);
17973  else if( SCIPisInfinity(scip, lhs) )
17974  lhs = SCIPinfinity(scip);
17975 
17976  if( SCIPisInfinity(scip, rhs) )
17977  rhs = SCIPinfinity(scip);
17978  else if( SCIPisInfinity(scip, -rhs) )
17979  rhs = -SCIPinfinity(scip);
17980  }
17981 
17982  /* create constraint data */
17983  SCIP_CALL( consdataCreate(scip, &consdata, nconsvars, consvars, consvals, lhs, rhs) );
17984  assert(consdata != NULL);
17985 
17986  SCIPfreeBufferArray(scip, &consvals);
17987  SCIPfreeBufferArray(scip, &consvars);
17988  }
17989  else
17990  {
17991  /* create constraint data */
17992  SCIP_CALL( consdataCreate(scip, &consdata, nvars, vars, vals, lhs, rhs) );
17993  assert(consdata != NULL);
17994  }
17995 
17996 #ifndef NDEBUG
17997  /* if this is a checked or enforced constraints, then there must be no relaxation-only variables */
17998  if( check || enforce )
17999  {
18000  int n;
18001  for(n = consdata->nvars - 1; n >= 0; --n )
18002  assert(!SCIPvarIsRelaxationOnly(consdata->vars[n]));
18003  }
18004 #endif
18005 
18006  /* create constraint */
18007  SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
18008  local, modifiable, dynamic, removable, stickingatnode) );
18009 
18010  return SCIP_OKAY;
18011 }
18012 
18013 /** creates and captures a linear constraint
18014  * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
18015  * method SCIPcreateConsLinear(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
18016  *
18017  * @see SCIPcreateConsLinear() for information about the basic constraint flag configuration
18018  *
18019  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
18020  */
18022  SCIP* scip, /**< SCIP data structure */
18023  SCIP_CONS** cons, /**< pointer to hold the created constraint */
18024  const char* name, /**< name of constraint */
18025  int nvars, /**< number of nonzeros in the constraint */
18026  SCIP_VAR** vars, /**< array with variables of constraint entries */
18027  SCIP_Real* vals, /**< array with coefficients of constraint entries */
18028  SCIP_Real lhs, /**< left hand side of constraint */
18029  SCIP_Real rhs /**< right hand side of constraint */
18030  )
18031 {
18032  assert(scip != NULL);
18033 
18034  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, vals, lhs, rhs,
18035  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
18036 
18037  return SCIP_OKAY;
18038 }
18039 
18040 /** creates by copying and captures a linear constraint */
18042  SCIP* scip, /**< target SCIP data structure */
18043  SCIP_CONS** cons, /**< pointer to store the created target constraint */
18044  SCIP* sourcescip, /**< source SCIP data structure */
18045  const char* name, /**< name of constraint */
18046  int nvars, /**< number of variables in source variable array */
18047  SCIP_VAR** sourcevars, /**< source variables of the linear constraints */
18048  SCIP_Real* sourcecoefs, /**< coefficient array of the linear constraint, or NULL if all coefficients are one */
18049  SCIP_Real lhs, /**< left hand side of the linear constraint */
18050  SCIP_Real rhs, /**< right hand side of the linear constraint */
18051  SCIP_HASHMAP* varmap, /**< a SCIP_HASHMAP mapping variables of the source SCIP to corresponding
18052  * variables of the target SCIP */
18053  SCIP_HASHMAP* consmap, /**< a hashmap to store the mapping of source constraints to the corresponding
18054  * target constraints */
18055  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP? */
18056  SCIP_Bool separate, /**< should the constraint be separated during LP processing? */
18057  SCIP_Bool enforce, /**< should the constraint be enforced during node processing? */
18058  SCIP_Bool check, /**< should the constraint be checked for feasibility? */
18059  SCIP_Bool propagate, /**< should the constraint be propagated during node processing? */
18060  SCIP_Bool local, /**< is constraint only valid locally? */
18061  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)? */
18062  SCIP_Bool dynamic, /**< is constraint subject to aging? */
18063  SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup? */
18064  SCIP_Bool stickingatnode, /**< should the constraint always be kept at the node where it was added, even
18065  * if it may be moved to a more global node? */
18066  SCIP_Bool global, /**< create a global or a local copy? */
18067  SCIP_Bool* valid /**< pointer to store if the copying was valid */
18068  )
18069 {
18070  SCIP_VAR** vars;
18071  SCIP_Real* coefs;
18072 
18073  SCIP_Real constant;
18074  int requiredsize;
18075  int v;
18076  SCIP_Bool success;
18077 
18078  if( SCIPisGT(scip, lhs, rhs) )
18079  {
18080  *valid = FALSE;
18081  return SCIP_OKAY;
18082  }
18083 
18084  (*valid) = TRUE;
18085 
18086  if( nvars == 0 )
18087  {
18088  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, 0, NULL, NULL, lhs, rhs,
18089  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
18090  return SCIP_OKAY;
18091  }
18092 
18093  /* duplicate variable array */
18094  SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, sourcevars, nvars) );
18095 
18096  /* duplicate coefficient array */
18097  if( sourcecoefs != NULL )
18098  {
18099  SCIP_CALL( SCIPduplicateBufferArray(scip, &coefs, sourcecoefs, nvars) );
18100  }
18101  else
18102  {
18103  SCIP_CALL( SCIPallocBufferArray(scip, &coefs, nvars) );
18104  for( v = 0; v < nvars; ++v )
18105  coefs[v] = 1.0;
18106  }
18107 
18108  constant = 0.0;
18109 
18110  /* transform source variable to active variables of the source SCIP since only these can be mapped to variables of
18111  * the target SCIP
18112  */
18113  if( !SCIPvarIsOriginal(vars[0]) )
18114  {
18115  SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, nvars, &constant, &requiredsize, TRUE) );
18116 
18117  if( requiredsize > nvars )
18118  {
18119  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requiredsize) );
18120  SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, requiredsize) );
18121 
18122  SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, requiredsize, &constant, &requiredsize, TRUE) );
18123  assert(requiredsize <= nvars);
18124  }
18125  }
18126  else
18127  {
18128  for( v = 0; v < nvars; ++v )
18129  {
18130  assert(SCIPvarIsOriginal(vars[v]));
18131  SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &coefs[v], &constant) );
18132  assert(vars[v] != NULL);
18133  }
18134  }
18135 
18136  success = TRUE;
18137  /* map variables of the source constraint to variables of the target SCIP */
18138  for( v = 0; v < nvars && success; ++v )
18139  {
18140  SCIP_VAR* var;
18141  var = vars[v];
18142 
18143  /* if this is a checked or enforced constraints, then there must be no relaxation-only variables */
18144  assert(!SCIPvarIsRelaxationOnly(var) || (!check && !enforce));
18145 
18146  SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, var, &vars[v], varmap, consmap, global, &success) );
18147  assert(!(success) || vars[v] != NULL);
18148  }
18149 
18150  /* only create the target constraint, if all variables could be copied */
18151  if( success )
18152  {
18153  if( !SCIPisInfinity(scip, -lhs) )
18154  lhs -= constant;
18155 
18156  if( !SCIPisInfinity(scip, rhs) )
18157  rhs -= constant;
18158 
18159  SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
18160  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
18161  }
18162  else
18163  *valid = FALSE;
18164 
18165  /* free buffer array */
18166  SCIPfreeBufferArray(scip, &coefs);
18167  SCIPfreeBufferArray(scip, &vars);
18168 
18169  return SCIP_OKAY;
18170 }
18171 
18172 /** adds coefficient to linear constraint (if it is not zero) */
18174  SCIP* scip, /**< SCIP data structure */
18175  SCIP_CONS* cons, /**< constraint data */
18176  SCIP_VAR* var, /**< variable of constraint entry */
18177  SCIP_Real val /**< coefficient of constraint entry */
18178  )
18179 {
18180  assert(scip != NULL);
18181  assert(cons != NULL);
18182  assert(var != NULL);
18183 
18184  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18185  {
18186  SCIPerrorMessage("constraint is not linear\n");
18187  return SCIP_INVALIDDATA;
18188  }
18189 
18190  /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
18191  * constraint after presolving we have to ensure that it holds active variables
18192  */
18193  if( SCIPgetStage(scip) >= SCIP_STAGE_EXITPRESOLVE )
18194  {
18195  SCIP_CONSDATA* consdata;
18196  SCIP_VAR** consvars;
18197  SCIP_Real* consvals;
18198  SCIP_Real constant = 0.0;
18199  SCIP_Real rhs;
18200  SCIP_Real lhs;
18201  int nconsvars;
18202  int requiredsize;
18203  int v;
18204 
18205  nconsvars = 1;
18206  SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nconsvars) );
18207  SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
18208  consvars[0] = var;
18209  consvals[0] = val;
18210 
18211  /* get active variables for new constraint */
18212  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, nconsvars, &constant, &requiredsize, TRUE) );
18213 
18214  /* if space was not enough we need to resize the buffers */
18215  if( requiredsize > nconsvars )
18216  {
18217  SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
18218  SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
18219 
18220  SCIP_CALL( SCIPgetProbvarLinearSum(scip, consvars, consvals, &nconsvars, requiredsize, &constant, &requiredsize, TRUE) );
18221  assert(requiredsize <= nconsvars);
18222  }
18223 
18224  consdata = SCIPconsGetData(cons);
18225  assert(consdata != NULL);
18226 
18227  lhs = consdata->lhs;
18228  rhs = consdata->rhs;
18229 
18230  /* adjust sides and check that we do not subtract infinity values */
18231  /* constant is infinite */
18232  if( SCIPisInfinity(scip, REALABS(constant)) )
18233  {
18234  if( constant < 0.0 )
18235  {
18236  if( SCIPisInfinity(scip, lhs) )
18237  {
18238  SCIPfreeBufferArray(scip, &consvals);
18239  SCIPfreeBufferArray(scip, &consvars);
18240 
18241  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));
18242 
18243  SCIPABORT();
18244  return SCIP_INVALIDDATA; /*lint !e527*/
18245  }
18246  if( SCIPisInfinity(scip, rhs) )
18247  {
18248  SCIPfreeBufferArray(scip, &consvals);
18249  SCIPfreeBufferArray(scip, &consvars);
18250 
18251  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));
18252 
18253  SCIPABORT();
18254  return SCIP_INVALIDDATA; /*lint !e527*/
18255  }
18256 
18257  lhs = -SCIPinfinity(scip);
18258  rhs = -SCIPinfinity(scip);
18259  }
18260  else
18261  {
18262  if( SCIPisInfinity(scip, -lhs) )
18263  {
18264  SCIPfreeBufferArray(scip, &consvals);
18265  SCIPfreeBufferArray(scip, &consvars);
18266 
18267  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));
18268 
18269  SCIPABORT();
18270  return SCIP_INVALIDDATA; /*lint !e527*/
18271  }
18272  if( SCIPisInfinity(scip, -rhs) )
18273  {
18274  SCIPfreeBufferArray(scip, &consvals);
18275  SCIPfreeBufferArray(scip, &consvars);
18276 
18277  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));
18278 
18279  SCIPABORT();
18280  return SCIP_INVALIDDATA; /*lint !e527*/
18281  }
18282 
18283  lhs = SCIPinfinity(scip);
18284  rhs = SCIPinfinity(scip);
18285  }
18286  }
18287  /* constant is not infinite */
18288  else
18289  {
18290  if( !SCIPisInfinity(scip, REALABS(lhs)) )
18291  lhs -= constant;
18292  if( !SCIPisInfinity(scip, REALABS(rhs)) )
18293  rhs -= constant;
18294 
18295  if( SCIPisInfinity(scip, -lhs) )
18296  lhs = -SCIPinfinity(scip);
18297  else if( SCIPisInfinity(scip, lhs) )
18298  lhs = SCIPinfinity(scip);
18299 
18300  if( SCIPisInfinity(scip, rhs) )
18301  rhs = SCIPinfinity(scip);
18302  else if( SCIPisInfinity(scip, -rhs) )
18303  rhs = -SCIPinfinity(scip);
18304  }
18305 
18306  /* add all active variables to constraint */
18307  for( v = nconsvars - 1; v >= 0; --v )
18308  {
18309  SCIP_CALL( addCoef(scip, cons, consvars[v], consvals[v]) );
18310  }
18311 
18312  /* update left and right hand sides */
18313  SCIP_CALL( chgLhs(scip, cons, lhs));
18314  SCIP_CALL( chgRhs(scip, cons, rhs));
18315 
18316  SCIPfreeBufferArray(scip, &consvals);
18317  SCIPfreeBufferArray(scip, &consvars);
18318  }
18319  else
18320  {
18321  SCIP_CALL( addCoef(scip, cons, var, val) );
18322  }
18323 
18324  return SCIP_OKAY;
18325 }
18326 
18327 /** changes coefficient of variable in linear constraint; deletes the variable if coefficient is zero; adds variable if
18328  * not yet contained in the constraint
18329  *
18330  * @note This method may only be called during problem creation stage for an original constraint and variable.
18331  *
18332  * @note This method requires linear time to search for occurences of the variable in the constraint data.
18333  */
18335  SCIP* scip, /**< SCIP data structure */
18336  SCIP_CONS* cons, /**< constraint data */
18337  SCIP_VAR* var, /**< variable of constraint entry */
18338  SCIP_Real val /**< new coefficient of constraint entry */
18339  )
18340 {
18341  SCIP_CONSDATA* consdata;
18342  SCIP_VAR** vars;
18343  SCIP_Bool found;
18344  int i;
18345 
18346  assert(scip != NULL);
18347  assert(cons != NULL);
18348  assert(var != NULL);
18349 
18350  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18351  {
18352  SCIPerrorMessage("constraint is not linear\n");
18354  }
18355 
18356  if( SCIPgetStage(scip) > SCIP_STAGE_PROBLEM || !SCIPconsIsOriginal(cons) || !SCIPvarIsOriginal(var) )
18357  {
18358  SCIPerrorMessage("method may only be called during problem creation stage for original constraints and variables\n");
18359  return SCIP_INVALIDDATA;
18360  }
18361 
18362  consdata = SCIPconsGetData(cons);
18363  assert(consdata != NULL);
18364 
18365  vars = consdata->vars;
18366  found = FALSE;
18367  i = 0;
18368  while( i < consdata->nvars )
18369  {
18370  if( vars[i] == var )
18371  {
18372  if( found || SCIPisZero(scip, val) )
18373  {
18374  SCIP_CALL( delCoefPos(scip, cons, i) );
18375 
18376  /* decrease i by one since otherwise we would skip the coefficient which has been switched to position i */
18377  i--;
18378  }
18379  else
18380  {
18381  SCIP_CALL( chgCoefPos(scip, cons, i, val) );
18382  }
18383  found = TRUE;
18384  }
18385  i++;
18386  }
18387 
18388  if( !found && !SCIPisZero(scip, val) )
18389  {
18390  SCIP_CALL( SCIPaddCoefLinear(scip, cons, var, val) );
18391  }
18392 
18393  return SCIP_OKAY;
18394 }
18395 
18396 /** deletes variable from linear constraint
18397  *
18398  * @note This method may only be called during problem creation stage for an original constraint and variable.
18399  *
18400  * @note This method requires linear time to search for occurences of the variable in the constraint data.
18401  */
18403  SCIP* scip, /**< SCIP data structure */
18404  SCIP_CONS* cons, /**< constraint data */
18405  SCIP_VAR* var /**< variable of constraint entry */
18406  )
18407 {
18408  assert(scip != NULL);
18409  assert(cons != NULL);
18410  assert(var != NULL);
18411 
18412  SCIP_CALL( SCIPchgCoefLinear(scip, cons, var, 0.0) );
18413 
18414  return SCIP_OKAY;
18415 }
18416 
18417 /** gets left hand side of linear constraint */
18419  SCIP* scip, /**< SCIP data structure */
18420  SCIP_CONS* cons /**< constraint data */
18421  )
18422 {
18423  SCIP_CONSDATA* consdata;
18424 
18425  assert(scip != NULL);
18426  assert(cons != NULL);
18427 
18428  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18429  {
18430  SCIPerrorMessage("constraint is not linear\n");
18431  SCIPABORT();
18432  return SCIP_INVALID; /*lint !e527*/
18433  }
18434 
18435  consdata = SCIPconsGetData(cons);
18436  assert(consdata != NULL);
18438  return consdata->lhs;
18439 }
18440 
18441 /** gets right hand side of linear constraint */
18443  SCIP* scip, /**< SCIP data structure */
18444  SCIP_CONS* cons /**< constraint data */
18445  )
18446 {
18447  SCIP_CONSDATA* consdata;
18448 
18449  assert(scip != NULL);
18450  assert(cons != NULL);
18451 
18452  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18453  {
18454  SCIPerrorMessage("constraint is not linear\n");
18455  SCIPABORT();
18456  return SCIP_INVALID; /*lint !e527*/
18457  }
18458 
18459  consdata = SCIPconsGetData(cons);
18460  assert(consdata != NULL);
18462  return consdata->rhs;
18463 }
18464 
18465 /** changes left hand side of linear constraint */
18467  SCIP* scip, /**< SCIP data structure */
18468  SCIP_CONS* cons, /**< constraint data */
18469  SCIP_Real lhs /**< new left hand side */
18470  )
18471 {
18472  assert(scip != NULL);
18473  assert(cons != NULL);
18474 
18475  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18476  {
18477  SCIPerrorMessage("constraint is not linear\n");
18478  return SCIP_INVALIDDATA;
18479  }
18480 
18481  SCIP_CALL( chgLhs(scip, cons, lhs) );
18482 
18483  return SCIP_OKAY;
18484 }
18486 /** changes right hand side of linear constraint */
18488  SCIP* scip, /**< SCIP data structure */
18489  SCIP_CONS* cons, /**< constraint data */
18490  SCIP_Real rhs /**< new right hand side */
18491  )
18492 {
18493  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18494  {
18495  SCIPerrorMessage("constraint is not linear\n");
18496  return SCIP_INVALIDDATA;
18497  }
18498 
18499  SCIP_CALL( chgRhs(scip, cons, rhs) );
18500 
18501  return SCIP_OKAY;
18502 }
18503 
18504 /** gets the number of variables in the linear constraint */
18505 int SCIPgetNVarsLinear(
18506  SCIP* scip, /**< SCIP data structure */
18507  SCIP_CONS* cons /**< constraint data */
18508  )
18509 {
18510  SCIP_CONSDATA* consdata;
18511 
18512  assert(scip != NULL);
18513  assert(cons != NULL);
18514 
18515  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18516  {
18517  SCIPerrorMessage("constraint is not linear\n");
18518  SCIPABORT();
18519  return -1; /*lint !e527*/
18520  }
18521 
18522  consdata = SCIPconsGetData(cons);
18523  assert(consdata != NULL);
18525  return consdata->nvars;
18526 }
18527 
18528 /** gets the array of variables in the linear constraint; the user must not modify this array! */
18530  SCIP* scip, /**< SCIP data structure */
18531  SCIP_CONS* cons /**< constraint data */
18532  )
18533 {
18534  SCIP_CONSDATA* consdata;
18535 
18536  assert(scip != NULL);
18537  assert(cons != NULL);
18538 
18539  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18540  {
18541  SCIPerrorMessage("constraint is not linear\n");
18542  SCIPABORT();
18543  return NULL; /*lint !e527*/
18544  }
18545 
18546  consdata = SCIPconsGetData(cons);
18547  assert(consdata != NULL);
18549  return consdata->vars;
18550 }
18551 
18552 /** gets the array of coefficient values in the linear constraint; the user must not modify this array! */
18554  SCIP* scip, /**< SCIP data structure */
18555  SCIP_CONS* cons /**< constraint data */
18556  )
18557 {
18558  SCIP_CONSDATA* consdata;
18559 
18560  assert(scip != NULL);
18561  assert(cons != NULL);
18562 
18563  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18564  {
18565  SCIPerrorMessage("constraint is not linear\n");
18566  SCIPABORT();
18567  return NULL; /*lint !e527*/
18568  }
18569 
18570  consdata = SCIPconsGetData(cons);
18571  assert(consdata != NULL);
18573  return consdata->vals;
18574 }
18575 
18576 /** gets the activity of the linear constraint in the given solution
18577  *
18578  * @note if the solution contains values at infinity, this method will return SCIP_INVALID in case the activity
18579  * comprises positive and negative infinity contributions
18580  */
18582  SCIP* scip, /**< SCIP data structure */
18583  SCIP_CONS* cons, /**< constraint data */
18584  SCIP_SOL* sol /**< solution, or NULL to use current node's solution */
18585  )
18586 {
18587  SCIP_CONSDATA* consdata;
18588 
18589  assert(scip != NULL);
18590  assert(cons != NULL);
18591 
18592  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18593  {
18594  SCIPerrorMessage("constraint is not linear\n");
18595  SCIPABORT();
18596  return SCIP_INVALID; /*lint !e527*/
18597  }
18598 
18599  consdata = SCIPconsGetData(cons);
18600  assert(consdata != NULL);
18601 
18602  if( consdata->row != NULL )
18603  return SCIPgetRowSolActivity(scip, consdata->row, sol);
18604  else
18605  return consdataGetActivity(scip, consdata, sol);
18606 }
18607 
18608 /** gets the feasibility of the linear constraint in the given solution */
18610  SCIP* scip, /**< SCIP data structure */
18611  SCIP_CONS* cons, /**< constraint data */
18612  SCIP_SOL* sol /**< solution, or NULL to use current node's solution */
18613  )
18614 {
18615  SCIP_CONSDATA* consdata;
18616 
18617  assert(scip != NULL);
18618  assert(cons != NULL);
18619 
18620  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18621  {
18622  SCIPerrorMessage("constraint is not linear\n");
18623  SCIPABORT();
18624  return SCIP_INVALID; /*lint !e527*/
18625  }
18626 
18627  consdata = SCIPconsGetData(cons);
18628  assert(consdata != NULL);
18629 
18630  if( consdata->row != NULL )
18631  return SCIPgetRowSolFeasibility(scip, consdata->row, sol);
18632  else
18633  return consdataGetFeasibility(scip, consdata, sol);
18634 }
18635 
18636 /** gets the dual solution of the linear constraint in the current LP */
18638  SCIP* scip, /**< SCIP data structure */
18639  SCIP_CONS* cons /**< constraint data */
18640  )
18641 {
18642  SCIP_CONSDATA* consdata;
18643 
18644  assert(scip != NULL);
18645  assert(cons != NULL);
18646  assert(!SCIPconsIsOriginal(cons)); /* original constraints would always return 0 */
18647 
18648  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18649  {
18650  SCIPerrorMessage("constraint is not linear\n");
18651  SCIPABORT();
18652  return SCIP_INVALID; /*lint !e527*/
18653  }
18654 
18655  consdata = SCIPconsGetData(cons);
18656  assert(consdata != NULL);
18657 
18658  if( consdata->row != NULL )
18659  return SCIProwGetDualsol(consdata->row);
18660  else
18661  return 0.0;
18662 }
18663 
18664 /** gets the dual Farkas value of the linear constraint in the current infeasible LP */
18666  SCIP* scip, /**< SCIP data structure */
18667  SCIP_CONS* cons /**< constraint data */
18668  )
18669 {
18670  SCIP_CONSDATA* consdata;
18671 
18672  assert(scip != NULL);
18673  assert(cons != NULL);
18674  assert(!SCIPconsIsOriginal(cons)); /* original constraints would always return 0 */
18675 
18676  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18677  {
18678  SCIPerrorMessage("constraint is not linear\n");
18679  SCIPABORT();
18680  return SCIP_INVALID; /*lint !e527*/
18681  }
18682 
18683  consdata = SCIPconsGetData(cons);
18684  assert(consdata != NULL);
18685 
18686  if( consdata->row != NULL )
18687  return SCIProwGetDualfarkas(consdata->row);
18688  else
18689  return 0.0;
18690 }
18691 
18692 /** returns the linear relaxation of the given linear constraint; may return NULL if no LP row was yet created;
18693  * the user must not modify the row!
18694  */
18696  SCIP* scip, /**< SCIP data structure */
18697  SCIP_CONS* cons /**< constraint data */
18698  )
18699 {
18700  SCIP_CONSDATA* consdata;
18701 
18702  assert(scip != NULL);
18703  assert(cons != NULL);
18704 
18705  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
18706  {
18707  SCIPerrorMessage("constraint is not linear\n");
18708  SCIPABORT();
18709  return NULL; /*lint !e527*/
18710  }
18711 
18712  consdata = SCIPconsGetData(cons);
18713  assert(consdata != NULL);
18715  return consdata->row;
18716 }
18717 
18718 /** tries to automatically convert a linear constraint into a more specific and more specialized constraint */
18720  SCIP* scip, /**< SCIP data structure */
18721  SCIP_CONS* cons, /**< source constraint to try to convert */
18722  SCIP_CONS** upgdcons /**< pointer to store upgraded constraint, or NULL if not successful */
18723  )
18724 {
18725  SCIP_CONSHDLR* conshdlr;
18726  SCIP_CONSHDLRDATA* conshdlrdata;
18727  SCIP_CONSDATA* consdata;
18728  SCIP_VAR* var;
18729  SCIP_Real val;
18730  SCIP_Real lb;
18731  SCIP_Real ub;
18732  SCIP_Real poscoeffsum;
18733  SCIP_Real negcoeffsum;
18734  SCIP_Bool infeasible;
18735  SCIP_Bool integral;
18736  int nchgsides = 0;
18737  int nposbin;
18738  int nnegbin;
18739  int nposint;
18740  int nnegint;
18741  int nposimpl;
18742  int nnegimpl;
18743  int nposimplbin;
18744  int nnegimplbin;
18745  int nposcont;
18746  int nnegcont;
18747  int ncoeffspone;
18748  int ncoeffsnone;
18749  int ncoeffspint;
18750  int ncoeffsnint;
18751  int ncoeffspfrac;
18752  int ncoeffsnfrac;
18753  int i;
18754 
18755  assert(scip != NULL);
18756  assert(cons != NULL);
18757  assert(upgdcons != NULL);
18758 
18759  *upgdcons = NULL;
18760 
18761  /* we cannot upgrade a modifiable linear constraint, since we don't know what additional coefficients to expect */
18762  if( SCIPconsIsModifiable(cons) )
18763  return SCIP_OKAY;
18764 
18765  /* check for upgradability */
18766  if( SCIPconsGetNUpgradeLocks(cons) > 0 )
18767  return SCIP_OKAY;
18768 
18769  /* get the constraint handler and check, if it's really a linear constraint */
18770  conshdlr = SCIPconsGetHdlr(cons);
18771  if( strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) != 0 )
18772  {
18773  SCIPerrorMessage("constraint is not linear\n");
18774  return SCIP_INVALIDDATA;
18775  }
18776 
18777  /* get constraint handler data and constraint data */
18778  conshdlrdata = SCIPconshdlrGetData(conshdlr);
18779  assert(conshdlrdata != NULL);
18780  consdata = SCIPconsGetData(cons);
18781  assert(consdata != NULL);
18782 
18783  /* check, if the constraint was already upgraded and will be deleted anyway after preprocessing */
18784  if( consdata->upgraded )
18785  return SCIP_OKAY;
18786 
18787  /* check, if the constraint is already stored as LP row */
18788  if( consdata->row != NULL )
18789  {
18790  if( SCIProwIsInLP(consdata->row) )
18791  {
18792  SCIPerrorMessage("cannot upgrade linear constraint that is already stored as row in the LP\n");
18793  return SCIP_INVALIDDATA;
18794  }
18795  else
18796  {
18797  SCIP_CALL( SCIPreleaseRow(scip, &consdata->row) );
18798  }
18799  }
18800 
18801  /* normalize constraint */
18802  SCIP_CALL( normalizeCons(scip, cons, &infeasible) );
18803 
18804  /* normalizeCons() can only detect infeasibility when scaling with the gcd. in that case, the scaling was
18805  * skipped and we hope that the infeasibility gets detected later again.
18806  *
18807  * TODO: do we want to try to upgrade the constraint anyway?
18808  *
18809  * TODO: this needs to be fixed on master by changing the API and passing a pointer to whether the constraint is
18810  * proven to be infeasible.
18811  */
18812  if( infeasible ) /*lint !e774*/
18813  return SCIP_OKAY;
18814 
18815  /* tighten sides */
18816  SCIP_CALL( tightenSides(scip, cons, &nchgsides, &infeasible) );
18817 
18818  if( infeasible ) /*lint !e774*/
18819  return SCIP_OKAY;
18820 
18821  /*
18822  * calculate some statistics on linear constraint
18823  */
18824 
18825  nposbin = 0;
18826  nnegbin = 0;
18827  nposint = 0;
18828  nnegint = 0;
18829  nposimpl = 0;
18830  nnegimpl = 0;
18831  nposimplbin = 0;
18832  nnegimplbin = 0;
18833  nposcont = 0;
18834  nnegcont = 0;
18835  ncoeffspone = 0;
18836  ncoeffsnone = 0;
18837  ncoeffspint = 0;
18838  ncoeffsnint = 0;
18839  ncoeffspfrac = 0;
18840  ncoeffsnfrac = 0;
18841  integral = TRUE;
18842  poscoeffsum = 0.0;
18843  negcoeffsum = 0.0;
18844 
18845  for( i = 0; i < consdata->nvars; ++i )
18846  {
18847  var = consdata->vars[i];
18848  val = consdata->vals[i];
18849  lb = SCIPvarGetLbLocal(var);
18850  ub = SCIPvarGetUbLocal(var);
18851  assert(!SCIPisZero(scip, val));
18852 
18853  switch( SCIPvarGetType(var) )
18854  {
18855  case SCIP_VARTYPE_BINARY:
18856  if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
18857  integral = integral && SCIPisIntegral(scip, val);
18858  if( val >= 0.0 )
18859  nposbin++;
18860  else
18861  nnegbin++;
18862  break;
18863  case SCIP_VARTYPE_INTEGER:
18864  if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
18865  integral = integral && SCIPisIntegral(scip, val);
18866  if( val >= 0.0 )
18867  nposint++;
18868  else
18869  nnegint++;
18870  break;
18871  case SCIP_VARTYPE_IMPLINT:
18872  if( SCIPvarIsBinary(var) )
18873  {
18874  if( val >= 0.0 )
18875  nposimplbin++;
18876  else
18877  nnegimplbin++;
18878  }
18879  if( !SCIPisZero(scip, lb) || !SCIPisZero(scip, ub) )
18880  integral = integral && SCIPisIntegral(scip, val);
18881  if( val >= 0.0 )
18882  nposimpl++;
18883  else
18884  nnegimpl++;
18885  break;
18887  integral = integral && SCIPisEQ(scip, lb, ub) && SCIPisIntegral(scip, val * lb);
18888  if( val >= 0.0 )
18889  nposcont++;
18890  else
18891  nnegcont++;
18892  break;
18893  default:
18894  SCIPerrorMessage("unknown variable type\n");
18895  return SCIP_INVALIDDATA;
18896  }
18897  if( SCIPisEQ(scip, val, 1.0) )
18898  ncoeffspone++;
18899  else if( SCIPisEQ(scip, val, -1.0) )
18900  ncoeffsnone++;
18901  else if( SCIPisIntegral(scip, val) )
18902  {
18903  if( SCIPisPositive(scip, val) )
18904  ncoeffspint++;
18905  else
18906  ncoeffsnint++;
18907  }
18908  else
18909  {
18910  if( SCIPisPositive(scip, val) )
18911  ncoeffspfrac++;
18912  else
18913  ncoeffsnfrac++;
18914  }
18915  if( SCIPisPositive(scip, val) )
18916  poscoeffsum += val;
18917  else
18918  negcoeffsum += val;
18919  }
18920 
18921  /*
18922  * call the upgrading methods
18923  */
18924 
18925  SCIPdebugMsg(scip, "upgrading linear constraint <%s> (%d upgrade methods):\n",
18926  SCIPconsGetName(cons), conshdlrdata->nlinconsupgrades);
18927  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",
18928  nposbin, nnegbin, nposint, nnegint, nposimpl, nnegimpl, nposcont, nnegcont,
18929  ncoeffspone, ncoeffsnone, ncoeffspint, ncoeffsnint, ncoeffspfrac, ncoeffsnfrac,
18930  poscoeffsum, negcoeffsum, integral);
18931 
18932  /* try all upgrading methods in priority order in case the upgrading step is enable */
18933  for( i = 0; i < conshdlrdata->nlinconsupgrades && *upgdcons == NULL; ++i )
18934  {
18935  if( conshdlrdata->linconsupgrades[i]->active )
18936  {
18937  SCIP_CALL( conshdlrdata->linconsupgrades[i]->linconsupgd(scip, cons, consdata->nvars,
18938  consdata->vars, consdata->vals, consdata->lhs, consdata->rhs,
18939  nposbin, nnegbin, nposint, nnegint, nposimpl, nnegimpl, nposimplbin, nnegimplbin, nposcont, nnegcont,
18940  ncoeffspone, ncoeffsnone, ncoeffspint, ncoeffsnint, ncoeffspfrac, ncoeffsnfrac,
18941  poscoeffsum, negcoeffsum, integral,
18942  upgdcons) );
18943  }
18944  }
18945 
18946 #ifdef SCIP_DEBUG
18947  if( *upgdcons != NULL )
18948  {
18949  SCIPdebugPrintCons(scip, cons, NULL);
18950  SCIPdebugMsg(scip, " -> upgraded to constraint type <%s>\n", SCIPconshdlrGetName(SCIPconsGetHdlr(*upgdcons)));
18951  SCIPdebugPrintCons(scip, *upgdcons, NULL);
18952  }
18953 #endif
18954 
18955  return SCIP_OKAY; /*lint !e438*/
18956 }
18957 
18958 /** cleans up (multi-)aggregations and fixings from linear constraints */
18960  SCIP* scip, /**< SCIP data structure */
18961  SCIP_Bool onlychecked, /**< should only checked constraints be cleaned up? */
18962  SCIP_Bool* infeasible /**< pointer to return whether the problem was detected to be infeasible */
18963  )
18964 {
18965  SCIP_CONSHDLR* conshdlr;
18966  SCIP_CONS** conss;
18967  int nconss;
18968  int i;
18969 
18970  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
18971  if( conshdlr == NULL )
18972  return SCIP_OKAY;
18973 
18974  assert(infeasible != NULL);
18975  *infeasible = FALSE;
18976 
18977  nconss = onlychecked ? SCIPconshdlrGetNCheckConss(conshdlr) : SCIPconshdlrGetNActiveConss(conshdlr);
18978  conss = onlychecked ? SCIPconshdlrGetCheckConss(conshdlr) : SCIPconshdlrGetConss(conshdlr);
18979 
18980  for( i = 0; i < nconss; ++i )
18981  {
18982  SCIP_CALL( applyFixings(scip, conss[i], infeasible) );
18983 
18984  if( *infeasible )
18985  break;
18986  }
18987 
18988  return SCIP_OKAY;
18989 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:61
#define EVENTHDLR_DESC
Definition: cons_linear.c:118
#define CONSHDLR_DELAYSEPA
Definition: cons_linear.c:110
void SCIPsortRealInt(SCIP_Real *realarray, int *intarray, int len)
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:110
#define SCIP_DECL_LINCONSUPGD(x)
Definition: cons_linear.h:120
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:59
void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
Definition: cons.c:4214
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
struct InferInfo INFERINFO
SCIP_RETCODE SCIPincConsAge(SCIP *scip, SCIP_CONS *cons)
Definition: scip_cons.c:1730
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:1422
SCIP_Real SCIPgetActivityLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip_mem.h:99
SCIP_RETCODE SCIPflattenVarAggregationGraph(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1699
enum SCIP_LinConstype SCIP_LINCONSTYPE
Definition: type_cons.h:90
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
Definition: scip_cons.c:572
SCIP_Bool SCIPinRepropagation(SCIP *scip)
Definition: scip_tree.c:146
static SCIP_RETCODE tightenVarBounds(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool force)
Definition: cons_linear.c:6833
static void consdataCalcMinAbsval(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1467
static SCIP_DECL_CONSDEACTIVE(consDeactiveLinear)
SCIP_Real SCIPfeastol(SCIP *scip)
SCIP_RETCODE SCIPincludeConshdlrLinear(SCIP *scip)
static SCIP_RETCODE consdataCreate(SCIP *scip, SCIP_CONSDATA **consdata, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs)
Definition: cons_linear.c:876
static int inferInfoGetPos(INFERINFO inferinfo)
Definition: cons_linear.c:427
static SCIP_RETCODE consCatchEvent(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
Definition: cons_linear.c:740
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:93
static SCIP_RETCODE chgCoefPos(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Real newval)
Definition: cons_linear.c:4038
SCIP_Bool SCIPisNLPConstructed(SCIP *scip)
Definition: scip_nlp.c:110
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5209
static SCIP_Real consdataGetFeasibility(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol)
Definition: cons_linear.c:3180
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2134
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
public methods for SCIP parameter handling
int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition: var.c:3298
#define DEFAULT_MAXAGGRNORMSCALE
Definition: cons_linear.c:141
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:365
#define DEFAULT_PRESOLPAIRWISE
Definition: cons_linear.c:129
#define SCIP_EVENTTYPE_VARFIXED
Definition: type_event.h:72
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:8353
SCIP_Real * SCIPvarGetMultaggrScalars(SCIP_VAR *var)
Definition: var.c:17711
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
Definition: scip_cons.c:595
SCIP_RETCODE SCIPincludeConsUpgradeNonlinear(SCIP *scip, SCIP_DECL_NONLINCONSUPGD((*nlconsupgd)), int priority, SCIP_Bool active, const char *conshdlrname)
SCIP_RETCODE SCIPcreateConsBasicLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs)
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define CONSHDLR_NAME
Definition: cons_linear.c:99
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:1998
#define CONSHDLR_MAXPREROUNDS
Definition: cons_linear.c:109
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:3201
SCIP_RETCODE SCIPhashtableInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2496
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:1634
public methods for memory management
#define DEFAULT_RANGEDROWFREQ
Definition: cons_linear.c:176
static void consdataRecomputeMaxActivityDelta(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1572
#define MAXSCALEDCOEF
Definition: cons_linear.c:186
SCIP_RETCODE SCIPcatchVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: scip_event.c:354
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:886
static SCIP_Bool checkEqualObjective(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real *scale, SCIP_Real *offset)
#define DEFAULT_CHECKRELMAXABS
Definition: cons_linear.c:138
SCIP_Real SCIPgetCutoffbound(SCIP *scip)
int SCIPexprGetNChildren(SCIP_EXPR *expr)
Definition: expr.c:3808
static SCIP_RETCODE fixVariables(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars)
Definition: cons_linear.c:7904
SCIP_VAR * SCIPbdchginfoGetVar(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18521
SCIP_Bool SCIPisUbBetter(SCIP *scip, SCIP_Real newub, SCIP_Real oldlb, SCIP_Real oldub)
#define DEFAULT_MAXROUNDS
Definition: cons_linear.c:125
#define DEFAULT_SORTVARS
Definition: cons_linear.c:135
static SCIP_RETCODE convertUnaryEquality(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *ndelconss)
Definition: cons_linear.c:9564
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:5445
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17919
SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETVARS((*consgetvars)))
Definition: scip_cons.c:825
SCIP_RETCODE SCIPcopyConsLinear(SCIP *scip, SCIP_CONS **cons, SCIP *sourcescip, const char *name, int nvars, SCIP_VAR **sourcevars, SCIP_Real *sourcecoefs, SCIP_Real lhs, SCIP_Real rhs, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode, SCIP_Bool global, SCIP_Bool *valid)
SCIP_RETCODE SCIPupdateCutoffbound(SCIP *scip, SCIP_Real cutoffbound)
#define SCIP_MAXSTRLEN
Definition: def.h:302
int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition: var.c:3356
SCIP_RETCODE SCIPcleanupConssLinear(SCIP *scip, SCIP_Bool onlychecked, SCIP_Bool *infeasible)
SCIP_Bool SCIPvarIsInitial(SCIP_VAR *var)
Definition: var.c:17461
SCIP_Bool SCIPparseReal(SCIP *scip, const char *str, SCIP_Real *value, char **endptr)
public methods for conflict handler plugins and conflict analysis
SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
Definition: scip_cons.c:317
SCIP_RETCODE SCIPresetConsAge(SCIP *scip, SCIP_CONS *cons)
Definition: scip_cons.c:1758
static SCIP_RETCODE consDropAllEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linear.c:845
void SCIPlinConsStatsIncTypeCount(SCIP_LINCONSSTATS *linconsstats, SCIP_LINCONSTYPE linconstype, int increment)
Definition: cons.c:7988
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2851
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip_mem.c:139
SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
Definition: var.c:17699
static long bound
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
Definition: scip_lp.c:1695
SCIP_RETCODE SCIPsetConsPropagated(SCIP *scip, SCIP_CONS *cons, SCIP_Bool propagate)
Definition: scip_cons.c:1317
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisSumRelEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static void consdataUpdateActivitiesGlbUb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real oldub, SCIP_Real newub, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:2092
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17975
SCIP_Bool SCIPisUpdateUnreliable(SCIP *scip, SCIP_Real newvalue, SCIP_Real oldvalue)
SCIP_Real SCIPgetConstantExprSum(SCIP_EXPR *expr)
Definition: expr_sum.c:1181
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPsetConshdlrDeactive(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDEACTIVE((*consdeactive)))
Definition: scip_cons.c:687
SCIP_VARTYPE SCIPeventGetNewtype(SCIP_EVENT *event)
Definition: event.c:1283
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:104
static SCIP_Real consdataGetMaxAbsval(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:2321
static SCIP_RETCODE linconsupgradeCreate(SCIP *scip, SCIP_LINCONSUPGRADE **linconsupgrade, SCIP_DECL_LINCONSUPGD((*linconsupgd)), int priority)
Definition: cons_linear.c:530
SCIP_Real SCIPgetRhsNonlinear(SCIP_CONS *cons)
static SCIP_DECL_CONSINITSOL(consInitsolLinear)
void SCIPsortDownRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
#define DEFAULT_MAXSEPACUTS
Definition: cons_linear.c:127
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:1445
SCIP_RETCODE SCIPupdateConsFlags(SCIP *scip, SCIP_CONS *cons0, SCIP_CONS *cons1)
Definition: scip_cons.c:1470
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1254
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17440
static void consdataRecomputeMinactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1335
SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE normalizeCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible)
Definition: cons_linear.c:4269
#define SCIP_EVENTTYPE_TYPECHANGED
Definition: type_event.h:86
#define DEFAULT_DETECTPARTIALOBJECTIVE
Definition: cons_linear.c:170
SCIP_RETCODE SCIPconvertCutsToConss(SCIP *scip, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, int *ncutsadded)
Definition: scip_copy.c:2063
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define NLOCKTYPES
Definition: type_var.h:90
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:2898
static void permSortConsdata(SCIP_CONSDATA *consdata, int *perm, int nvars)
Definition: cons_linear.c:3355
SCIP_CONS ** SCIPconshdlrGetConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4556
#define DEFAULT_AGGREGATEVARIABLES
Definition: cons_linear.c:153
#define FALSE
Definition: def.h:96
SCIP_Real SCIPadjustedVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real ub)
Definition: scip_var.c:4651
static SCIP_DECL_HASHGETKEY(hashGetKeyLinearcons)
static SCIP_DECL_CONSEXITSOL(consExitsolLinear)
static void consdataInvalidateActivities(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1236
int SCIPconsGetPos(SCIP_CONS *cons)
Definition: cons.c:8104
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:324
SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
Definition: misc.c:11072
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:175
static SCIP_DECL_CONSCOPY(consCopyLinear)
SCIP_Real SCIPinfinity(SCIP *scip)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10764
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
static void consdataGetGlbActivityResiduals(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real val, SCIP_Bool goodrelax, SCIP_Real *minresactivity, SCIP_Real *maxresactivity, SCIP_Bool *minisrelax, SCIP_Bool *maxisrelax, SCIP_Bool *isminsettoinfinity, SCIP_Bool *ismaxsettoinfinity)
Definition: cons_linear.c:2960
static SCIP_Bool conshdlrdataHasUpgrade(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_DECL_LINCONSUPGD((*linconsupgd)), const char *conshdlrname)
Definition: cons_linear.c:611
#define TRUE
Definition: def.h:95
#define SCIPdebug(x)
Definition: pub_message.h:93
#define DEFAULT_MAXCARDBOUNDDIST
Definition: cons_linear.c:147
SCIP_RETCODE SCIPunmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
Definition: scip_cons.c:1988
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
SCIP_Real SCIPgetLocalLowerbound(SCIP *scip)
Definition: scip_prob.c:3593
SCIP_Real SCIPvarGetNegationConstant(SCIP_VAR *var)
Definition: var.c:17756
#define DEFAULT_NMINCOMPARISONS
Definition: cons_linear.c:131
#define SCIPstatisticMessage
Definition: pub_message.h:123
SCIP_ROW * SCIPgetRowLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPaddConflictUb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
static SCIP_DECL_CONSINITLP(consInitlpLinear)
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition: cons.c:8373
#define SCIP_PRESOLTIMING_EXHAUSTIVE
Definition: type_timing.h:54
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:7666
static SCIP_Bool consdataIsResidualIntegral(SCIP *scip, SCIP_CONSDATA *consdata, int pos, SCIP_Real val)
enum SCIP_Varstatus SCIP_VARSTATUS
Definition: type_var.h:57
static SCIP_RETCODE preprocessConstraintPairs(SCIP *scip, SCIP_CONS **conss, int firstchange, int chkind, SCIP_Real maxaggrnormscale, SCIP_Bool *cutoff, int *ndelconss, int *nchgsides, int *nchgcoefs)
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition: var.c:17609
#define SCIP_EVENTTYPE_GLBCHANGED
Definition: type_event.h:75
static SCIP_DECL_CONSENFOPS(consEnfopsLinear)
void SCIPlinConsStatsReset(SCIP_LINCONSSTATS *linconsstats)
Definition: cons.c:7956
SCIP_Real SCIPvarGetAggrScalar(SCIP_VAR *var)
Definition: var.c:17663
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:8403
public methods for problem variables
static GRAPHNODE ** active
SCIP_RETCODE SCIPinitConflictAnalysis(SCIP *scip, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5326
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip_mem.h:108
#define SCIPdebugMessage
Definition: pub_message.h:96
#define DEFAULT_MINGAINPERNMINCOMP
Definition: cons_linear.c:132
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:229
SCIP_Real SCIPselectSimpleValue(SCIP_Real lb, SCIP_Real ub, SCIP_Longint maxdnom)
Definition: misc.c:9728
int SCIPconsGetNLocksNeg(SCIP_CONS *cons)
Definition: cons.c:8453
SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
Definition: scip_message.c:88
static SCIP_DECL_CONSEXITPRE(consExitpreLinear)
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip_mem.h:132
SCIP_CONS ** SCIPgetConss(SCIP *scip)
Definition: scip_prob.c:3096
enum Proprule PROPRULE
Definition: cons_linear.c:377
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static SCIP_DECL_CONSRESPROP(consRespropLinear)
static SCIP_RETCODE detectRedundantConstraints(SCIP *scip, BMS_BLKMEM *blkmem, SCIP_CONS **conss, int nconss, int *firstchange, SCIP_Bool *cutoff, int *ndelconss, int *nchgsides)
static SCIP_RETCODE aggregateConstraints(SCIP *scip, SCIP_CONS *cons0, SCIP_CONS *cons1, int *commonidx0, int *commonidx1, int *diffidx0minus1, int *diffidx1minus0, int nvarscommon, int commonidxweight, int diffidx0minus1weight, int diffidx1minus0weight, SCIP_Real maxaggrnormscale, int *nchgcoefs, SCIP_Bool *aggregated, SCIP_Bool *infeasible)
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip_mem.h:136
static INFERINFO getInferInfo(PROPRULE proprule, int pos)
Definition: cons_linear.c:436
static SCIP_RETCODE rangedRowPropagation(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *nchgbds, int *naddconss)
Definition: cons_linear.c:5848
SCIP_Real SCIPadjustedVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real lb)
Definition: scip_var.c:4619
SCIP_Bool SCIPvarIsRemovable(SCIP_VAR *var)
Definition: var.c:17471
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:89
#define SCIPdebugPrintCons(x, y, z)
Definition: pub_message.h:102
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip_general.c:575
SCIP_RETCODE SCIPdelCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
int SCIPgetNLPBranchCands(SCIP *scip)
Definition: scip_branch.c:428
static SCIP_RETCODE consDropEvent(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
Definition: cons_linear.c:779
public methods for SCIP variables
SCIP_RETCODE SCIPsetConshdlrDelvars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELVARS((*consdelvars)))
Definition: scip_cons.c:756
#define checkMaxActivityDelta(scip, consdata)
Definition: cons_linear.c:1567
SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition: var.c:17745
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:8363
#define SCIP_EVENTTYPE_BOUNDCHANGED
Definition: type_event.h:125
static SCIP_DECL_SORTINDCOMP(consdataCompVar)
Definition: cons_linear.c:3246
SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
Definition: scip_cons.c:618
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
Definition: lp.c:17304
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
#define SCIPdebugMsgPrint
Definition: scip_message.h:79
#define SCIPdebugMsg
Definition: scip_message.h:78
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:83
static SCIP_Real consdataGetMinAbsval(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:2337
SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip_var.c:1486
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
Definition: scip_cons.c:802
#define DEFAULT_SEPARATEALL
Definition: cons_linear.c:150
SCIP_VAR ** x
Definition: circlepacking.c:63
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition: cons.c:8155
static SCIP_RETCODE tightenSides(SCIP *scip, SCIP_CONS *cons, int *nchgsides, SCIP_Bool *infeasible)
Definition: cons_linear.c:9008
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
#define DEFAULT_MAXSEPACUTSROOT
Definition: cons_linear.c:128
int SCIPgetNContVars(SCIP *scip)
Definition: scip_prob.c:2180
static SCIP_RETCODE addConflictFixedVars(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *infervar, SCIP_BDCHGIDX *bdchgidx, int inferpos)
Definition: cons_linear.c:5115
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:943
SCIP_Real SCIPepsilon(SCIP *scip)
SCIP_RETCODE SCIPparseVarsLinearsum(SCIP *scip, const char *str, SCIP_VAR **vars, SCIP_Real *vals, int *nvars, int varssize, int *requiredsize, char **endptr, SCIP_Bool *success)
Definition: scip_var.c:709
#define CONSHDLR_PRESOLTIMING
Definition: cons_linear.c:114
SCIP_RETCODE SCIPaddConflictLb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
SCIP_Real SCIPfeasCeil(SCIP *scip, SCIP_Real val)
#define CONSHDLR_PROP_TIMING
Definition: cons_linear.c:115
public methods for numerical tolerances
static SCIP_RETCODE rangedRowSimplify(SCIP *scip, SCIP_CONS *cons, int *nchgcoefs, int *nchgsides)
SCIP_RETCODE SCIPhashtableCreate(SCIP_HASHTABLE **hashtable, BMS_BLKMEM *blkmem, int tablesize, SCIP_DECL_HASHGETKEY((*hashgetkey)), SCIP_DECL_HASHKEYEQ((*hashkeyeq)), SCIP_DECL_HASHKEYVAL((*hashkeyval)), void *userptr)
Definition: misc.c:2245
SCIP_Real SCIPfeasFloor(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPconsIsOriginal(SCIP_CONS *cons)
Definition: cons.c:8393
public functions to work with algebraic expressions
#define SCIP_EVENTTYPE_LBCHANGED
Definition: type_event.h:121
public methods for querying solving statistics
static SCIP_DECL_CONSFREE(consFreeLinear)
#define CONSHDLR_SEPAFREQ
Definition: cons_linear.c:104
SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
Definition: var.c:17735
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:17515
#define MAXCONSPRESOLROUNDS
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition: scip_var.c:4265
SCIP_Bool SCIPisConflictAnalysisApplicable(SCIP *scip)
public methods for the branch-and-bound tree
static SCIP_DECL_EVENTEXEC(eventExecLinear)
SCIP_Bool SCIPrealToRational(SCIP_Real val, SCIP_Real mindelta, SCIP_Real maxdelta, SCIP_Longint maxdnom, SCIP_Longint *nominator, SCIP_Longint *denominator)
Definition: misc.c:9304
SCIP_Bool SCIPisLbBetter(SCIP *scip, SCIP_Real newlb, SCIP_Real oldlb, SCIP_Real oldub)
static void linconsupgradeFree(SCIP *scip, SCIP_LINCONSUPGRADE **linconsupgrade)
Definition: cons_linear.c:551
SCIP_RETCODE SCIPsetConsSeparated(SCIP *scip, SCIP_CONS *cons, SCIP_Bool separate)
Definition: scip_cons.c:1242
SCIP_RETCODE SCIPchgVarType(SCIP *scip, SCIP_VAR *var, SCIP_VARTYPE vartype, SCIP_Bool *infeasible)
Definition: scip_var.c:8182
static SCIP_RETCODE analyzeConflict(SCIP *scip, SCIP_CONS *cons, SCIP_Bool reasonisrhs)
Definition: cons_linear.c:5324
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:7283
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:6927
SCIP_EXPR ** SCIPexprGetChildren(SCIP_EXPR *expr)
Definition: expr.c:3818
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17929
SCIP_RETCODE SCIPsetConshdlrInitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITSOL((*consinitsol)))
Definition: scip_cons.c:438
SCIP_VAR * w
Definition: circlepacking.c:67
static SCIP_RETCODE checkParallelObjective(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata)
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:105
#define CONFLICTHDLR_NAME
Definition: cons_linear.c:120
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:8541
public methods for managing constraints
Constraint handler for knapsack constraints of the form , x binary and .
#define DEFAULT_DETECTCUTOFFBOUND
Definition: cons_linear.c:160
static SCIP_RETCODE updateCutoffbound(SCIP *scip, SCIP_CONS *cons, SCIP_Real primalbound)
SCIP_Real SCIPeventGetNewbound(SCIP_EVENT *event)
Definition: event.c:1242
SCIP_Bool SCIPisPresolveFinished(SCIP *scip)
Definition: scip_general.c:612
SCIP_Bool SCIPnlrowIsInNLP(SCIP_NLROW *nlrow)
Definition: nlp.c:1872
SCIP_Bool SCIPconsIsLocked(SCIP_CONS *cons)
Definition: cons.c:8433
static SCIP_DECL_CONSDELETE(consDeleteLinear)
#define CONFLICTHDLR_PRIORITY
Definition: cons_linear.c:122
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
Definition: scip_cons.c:341
static SCIP_RETCODE simplifyInequalities(SCIP *scip, SCIP_CONS *cons, int *nchgcoefs, int *nchgsides, SCIP_Bool *infeasible)
SCIP_Real * SCIPgetCoefsExprSum(SCIP_EXPR *expr)
Definition: expr_sum.c:1166
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:5376
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:2518
enum SCIP_LockType SCIP_LOCKTYPE
Definition: type_var.h:96
SCIP_Bool SCIPisSumRelLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define SCIPerrorMessage
Definition: pub_message.h:64
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4184
SCIP_VARTYPE SCIPeventGetOldtype(SCIP_EVENT *event)
Definition: event.c:1266
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2778
#define CONSHDLR_PROPFREQ
Definition: cons_linear.c:105
SCIP_Real SCIPgetDualsolLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_RETCODE SCIPaddConsLocal(SCIP *scip, SCIP_CONS *cons, SCIP_NODE *validnode)
Definition: scip_prob.c:3401
static SCIP_DECL_CONSENFOLP(consEnfolpLinear)
SCIP_RETCODE SCIPaddNlRow(SCIP *scip, SCIP_NLROW *nlrow)
Definition: scip_nlp.c:363
SCIP_Bool SCIPdoNotMultaggrVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:8604
SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:3482
public methods for event handler plugins and event handlers
SCIP_RETCODE SCIPinferVarFixCons(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5438
SCIP_VAR * SCIPgetVarExprVar(SCIP_EXPR *expr)
Definition: expr_var.c:416
SCIP_RETCODE SCIPupgradeConsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **upgdcons)
static SCIP_DECL_CONSSEPALP(consSepalpLinear)
SCIP_RETCODE SCIPreleaseNlRow(SCIP *scip, SCIP_NLROW **nlrow)
Definition: scip_nlp.c:1025
SCIP_RETCODE SCIPgetProbvarSum(SCIP *scip, SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: scip_var.c:1800
static void consdataCalcMaxAbsval(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1443
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:6786
static INLINE uint32_t SCIPrealHashCode(double x)
Definition: pub_misc.h:544
#define DEFAULT_MULTAGGRREMOVE
Definition: cons_linear.c:178
static SCIP_RETCODE chgRhs(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
Definition: cons_linear.c:3624
static SCIP_RETCODE conshdlrdataEnsureLinconsupgradesSize(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, int num)
Definition: cons_linear.c:470
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:57
static void consdataUpdateDelCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:2165
static SCIP_RETCODE consdataSort(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:3431
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4443
static void consdataUpdateAddCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:2115
static int inferInfoGetProprule(INFERINFO inferinfo)
Definition: cons_linear.c:418
static SCIP_RETCODE consdataTightenCoefs(SCIP *scip, SCIP_CONS *cons, int *nchgcoefs, int *nchgsides)
Definition: cons_linear.c:9130
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8094
SCIP_Real SCIPvarGetAggrConstant(SCIP_VAR *var)
Definition: var.c:17675
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:8313
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:173
static SCIP_RETCODE aggregateVariables(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *naggrvars)
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17260
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
Definition: scip_cons.c:366
SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4204
SCIP_EXPR * SCIPgetExprNonlinear(SCIP_CONS *cons)
static SCIP_RETCODE addConflictReasonVars(SCIP *scip, SCIP_VAR **vars, int nvars, SCIP_VAR *var, SCIP_Real bound)
Definition: cons_linear.c:5180
#define NULL
Definition: lpi_spx1.cpp:164
SCIP_RETCODE SCIPmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
Definition: scip_cons.c:1960
static SCIP_RETCODE delCoefPos(SCIP *scip, SCIP_CONS *cons, int pos)
Definition: cons_linear.c:3917
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:5231
static int getInferInt(PROPRULE proprule, int pos)
Definition: cons_linear.c:455
#define SCIPhashSeven(a, b, c, d, e, f, g)
Definition: pub_misc.h:535
#define REALABS(x)
Definition: def.h:210
SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
Definition: scip_param.c:269
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:641
#define CONSHDLR_DELAYPROP
Definition: cons_linear.c:111
public methods for problem copies
int SCIPconsGetNLocksPos(SCIP_CONS *cons)
Definition: cons.c:8443
int SCIPconshdlrGetPropFreq(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:5103
SCIP_Bool SCIPisExprSum(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1452
#define SCIP_CALL(x)
Definition: def.h:393
SCIP_Real SCIPgetLowerbound(SCIP *scip)
#define SCIP_EVENTTYPE_LBTIGHTENED
Definition: type_event.h:77
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:2617
enum Proprule PROPRULE
Definition: cons_and.c:178
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
#define CONSHDLR_CHECKPRIORITY
Definition: cons_linear.c:103
static SCIP_RETCODE tightenVarBoundsEasy(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool force)
Definition: cons_linear.c:5514
#define SCIPhashSignature64(a)
Definition: pub_misc.h:517
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:1744
SCIP_Real SCIPvarGetMultaggrConstant(SCIP_VAR *var)
Definition: var.c:17723
SCIP_Bool SCIPvarIsRelaxationOnly(SCIP_VAR *var)
Definition: var.c:17547
SCIP_RETCODE SCIPhashtableRemove(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2626
void SCIPupdateSolLPConsViolation(SCIP *scip, SCIP_SOL *sol, SCIP_Real absviol, SCIP_Real relviol)
Definition: scip_sol.c:285
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static void getMinActivity(SCIP *scip, SCIP_CONSDATA *consdata, int posinf, int neginf, int poshuge, int neghuge, SCIP_Real delta, SCIP_Bool global, SCIP_Bool goodrelax, SCIP_Real *minactivity, SCIP_Bool *isrelax, SCIP_Bool *issettoinfinity)
Definition: cons_linear.c:2417
SCIP_RETCODE SCIPanalyzeConflictCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip_message.c:225
static SCIP_Bool isFiniteNonnegativeIntegral(SCIP *scip, SCIP_Real x)
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8333
static SCIP_RETCODE scaleCons(SCIP *scip, SCIP_CONS *cons, SCIP_Real scalar)
Definition: cons_linear.c:4117
SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
Definition: scip_cut.c:250
static SCIP_DECL_CONSINIT(consInitLinear)
SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
Definition: scip_cons.c:641
#define SCIPdebugGetSolVal(scip, var, val)
Definition: debug.h:299
struct SCIP_ConsData SCIP_CONSDATA
Definition: type_cons.h:65
static SCIP_DECL_CONSTRANS(consTransLinear)
SCIP_Bool SCIProwIsModifiable(SCIP_ROW *row)
Definition: lp.c:17403
#define SCIP_EVENTTYPE_BOUNDTIGHTENED
Definition: type_event.h:123
static SCIP_DECL_HASHKEYVAL(hashKeyValLinearcons)
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition: scip_lp.c:83
#define SCIP_EVENTTYPE_UBCHANGED
Definition: type_event.h:122
int SCIPconshdlrGetNConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4599
public methods for constraint handler plugins and constraints
static SCIP_RETCODE propagateCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool tightenbounds, SCIP_Bool rangedrowpropagation, SCIP_Real maxeasyactivitydelta, SCIP_Bool sortvars, SCIP_Bool *cutoff, int *nchgbds)
Definition: cons_linear.c:7756
SCIP_Real SCIPgetDualfarkasLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisHugeValue(SCIP *scip, SCIP_Real val)
static void consdataUpdateChgCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real oldval, SCIP_Real newval, SCIP_Bool checkreliability)
Definition: cons_linear.c:2222
#define DEFAULT_DETECTLOWERBOUND
Definition: cons_linear.c:165
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:4519
static SCIP_RETCODE consdataPrint(SCIP *scip, SCIP_CONSDATA *consdata, FILE *file)
Definition: cons_linear.c:1125
SCIP_Bool SCIPvarIsOriginal(SCIP_VAR *var)
Definition: var.c:17389
void SCIPhashtablePrintStatistics(SCIP_HASHTABLE *hashtable, SCIP_MESSAGEHDLR *messagehdlr)
Definition: misc.c:2753
static SCIP_RETCODE retrieveParallelConstraints(SCIP_HASHTABLE *hashtable, SCIP_CONS **querycons, SCIP_CONS **parallelconss, int *nparallelconss)
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:124
public data structures and miscellaneous methods
static SCIP_RETCODE chgLhs(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
Definition: cons_linear.c:3498
SCIP_Bool SCIPisSumGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
Definition: event.c:1053
#define SCIP_Bool
Definition: def.h:93
SCIP_RETCODE SCIPchgRowRhs(SCIP *scip, SCIP_ROW *row, SCIP_Real rhs)
Definition: scip_lp.c:1607
#define CONSHDLR_NEEDSCONS
Definition: cons_linear.c:112
#define CONSHDLR_EAGERFREQ
Definition: cons_linear.c:106
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:1030
static SCIP_RETCODE performVarDeletions(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss)
Definition: cons_linear.c:4210
static const char * paramname[]
Definition: lpi_msk.c:5040
static void consdataRecomputeGlbMaxactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1416
static SCIP_Real consdataGetActivity(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol)
Definition: cons_linear.c:3112
int SCIPgetDepth(SCIP *scip)
Definition: scip_tree.c:670
#define MAXTIGHTENROUNDS
Definition: cons_linear.c:7101
constraint handler for nonlinear constraints specified by algebraic expressions
static void conshdlrdataFree(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata)
Definition: cons_linear.c:589
#define DEFAULT_SINGLEVARSTUFFING
Definition: cons_linear.c:157
static SCIP_DECL_CONSPROP(consPropLinear)
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip_cons.c:2482
#define DEFAULT_DUALPRESOLVING
Definition: cons_linear.c:155
#define MAX(x, y)
Definition: tclique_def.h:92
static SCIP_RETCODE mergeMultiples(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:4602
static SCIP_RETCODE addRelaxation(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff)
Definition: cons_linear.c:7567
static SCIP_DECL_CONSDELVARS(consDelvarsLinear)
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8114
int SCIPvarCompare(SCIP_VAR *var1, SCIP_VAR *var2)
Definition: var.c:11950
methods for debugging
public methods for LP management
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition: cons.c:8223
SCIP_RETCODE SCIPhashtableSafeInsert(SCIP_HASHTABLE *hashtable, void *element)
Definition: misc.c:2528
static SCIP_RETCODE presolStuffing(SCIP *scip, SCIP_CONS *cons, SCIP_Bool singletonstuffing, SCIP_Bool singlevarstuffing, SCIP_Bool *cutoff, int *nfixedvars, int *nchgbds)
SCIP_RETCODE SCIPchgRowLhs(SCIP *scip, SCIP_ROW *row, SCIP_Real lhs)
Definition: scip_lp.c:1583
public methods for cuts and aggregation rows
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8293
static void consdataUpdateActivitiesGlbLb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real oldlb, SCIP_Real newlb, SCIP_Real val, SCIP_Bool checkreliability)
Definition: cons_linear.c:2069
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:8263
SCIP_Real SCIPvarGetObj(SCIP_VAR *var)
Definition: var.c:17767
static SCIP_Real consdataComputePseudoActivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1282
SCIP_RETCODE SCIPdropVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: scip_event.c:400
SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:18511
static void consdataCalcActivities(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:2355
#define NONLINCONSUPGD_PRIORITY
Definition: cons_linear.c:202
SCIP_VAR * SCIPvarGetAggrVar(SCIP_VAR *var)
Definition: var.c:17651
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:114
static int getVarWeight(SCIP_VAR *var)
SCIP_RETCODE SCIPcreateNlRow(SCIP *scip, SCIP_NLROW **nlrow, const char *name, SCIP_Real constant, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, SCIP_EXPR *expr, SCIP_Real lhs, SCIP_Real rhs, SCIP_EXPRCURV curvature)
Definition: scip_nlp.c:921
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip_var.c:8282
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:136
int SCIPgetNRuns(SCIP *scip)
SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
Definition: lp.c:17317
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4357
#define MAXDNOM
Definition: cons_linear.c:185
SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
Definition: scip_cons.c:779
#define SCIP_EVENTTYPE_UBTIGHTENED
Definition: type_event.h:79
Constraint handler for linear constraints in their most general form, .
int SCIPgetNObjVars(SCIP *scip)
Definition: scip_prob.c:2228
SCIP_Longint SCIPgetNConflictConssApplied(SCIP *scip)
void * SCIPhashtableRetrieve(SCIP_HASHTABLE *hashtable, void *key)
Definition: misc.c:2557
SCIP_RETCODE SCIPchgRhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real rhs)
int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
Definition: var.c:17687
SCIP_Bool SCIPisSumRelGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPgetRowSolActivity(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
Definition: scip_lp.c:2138
#define DEFAULT_MAXROUNDSROOT
Definition: cons_linear.c:126
#define SCIP_EVENTTYPE_GBDCHANGED
Definition: type_event.h:120
static void findOperators(const char *str, char **firstoperator, char **secondoperator, SCIP_Bool *success)
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition: var.c:12782
SCIP_Real SCIPgetFeasibilityLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
SCIP_RETCODE SCIPinferVarLbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5507
SCIP_RETCODE SCIPclassifyConstraintTypesLinear(SCIP *scip, SCIP_LINCONSSTATS *linconsstats)
#define DEFAULT_TIGHTENBOUNDSFREQ
Definition: cons_linear.c:124
#define SCIP_MAXTREEDEPTH
Definition: def.h:329
int SCIPgetNBinVars(SCIP *scip)
Definition: scip_prob.c:2045
int SCIPconshdlrGetNActiveConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4633
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip_probing.c:97
public methods for the LP relaxation, rows and columns
#define DEFAULT_SIMPLIFYINEQUALITIES
Definition: cons_linear.c:154
static SCIP_RETCODE createRow(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:7543
#define MINVALRECOMP
Definition: cons_linear.c:199
void SCIPhashtableFree(SCIP_HASHTABLE **hashtable)
Definition: misc.c:2295
SCIP_RETCODE SCIPincludeLinconsUpgrade(SCIP *scip, SCIP_DECL_LINCONSUPGD((*linconsupgd)), int priority, const char *conshdlrname)
#define CONSHDLR_SEPAPRIORITY
Definition: cons_linear.c:101
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:2000
int SCIPconsGetNUpgradeLocks(SCIP_CONS *cons)
Definition: cons.c:8545
#define SCIP_REAL_MAX
Definition: def.h:187
SCIP_RETCODE SCIPdelNlRow(SCIP *scip, SCIP_NLROW *nlrow)
Definition: scip_nlp.c:391
static void consdataGetReliableResidualActivity(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *cancelvar, SCIP_Real *resactivity, SCIP_Bool isminresact, SCIP_Bool useglobalbounds)
Definition: cons_linear.c:2666
static void consdataRecomputeMaxactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1362
SCIP_RETCODE SCIPwriteVarsLinearsum(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Bool type)
Definition: scip_var.c:343
SCIP_RETCODE SCIPupdateLocalLowerbound(SCIP *scip, SCIP_Real newbound)
Definition: scip_prob.c:3704
static SCIP_Bool canTightenBounds(SCIP_CONS *cons)
Definition: cons_linear.c:5348
static SCIP_DECL_CONSENFORELAX(consEnforelaxLinear)
#define MAXSCALEDCOEFINTEGER
Definition: cons_linear.c:187
static SCIP_DECL_CONSACTIVE(consActiveLinear)
methods for sorting joint arrays of various types
static SCIP_DECL_CONSCHECK(consCheckLinear)
SCIP_Bool SCIPconsIsLockedType(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition: cons.c:8487
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPsetConshdlrExitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITPRE((*consexitpre)))
Definition: scip_cons.c:510
#define EPSGT(x, y, eps)
Definition: def.h:214
static SCIP_RETCODE conshdlrdataCreate(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linear.c:565
public methods for branching rule plugins and branching
SCIP_VAR ** b
Definition: circlepacking.c:65
static void consdataCalcSignatures(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:3226
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition: scip_lp.c:1562
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:5790
static SCIP_RETCODE lockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
Definition: cons_linear.c:673
general public methods
static SCIP_DECL_CONSGETVARS(consGetVarsLinear)
void SCIPsort(int *perm, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
Definition: misc.c:5449
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
static void consdataGetActivityResiduals(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real val, SCIP_Bool goodrelax, SCIP_Real *minresactivity, SCIP_Real *maxresactivity, SCIP_Bool *minisrelax, SCIP_Bool *maxisrelax, SCIP_Bool *isminsettoinfinity, SCIP_Bool *ismaxsettoinfinity)
Definition: cons_linear.c:2747
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE fullDualPresolve(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_Bool *cutoff, int *nchgbds)
public methods for solutions
static const SCIP_Real scalars[]
Definition: lp.c:5747
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:711
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1676
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition: cons.c:8124
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:5621
SCIP_RETCODE SCIPsetConshdlrInit(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINIT((*consinit)))
Definition: scip_cons.c:390
#define CONTWEIGHT
SCIP_CONS ** SCIPconshdlrGetCheckConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4576
SCIP_Real SCIPgetHugeValue(SCIP *scip)
static SCIP_DECL_CONSLOCK(consLockLinear)
SCIP_RETCODE SCIPsetConsEnforced(SCIP *scip, SCIP_CONS *cons, SCIP_Bool enforce)
Definition: scip_cons.c:1267
static void consdataCheckNonbinvar(SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1496
static SCIP_RETCODE consCatchAllEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linear.c:813
SCIP_RETCODE SCIPsetConshdlrExit(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXIT((*consexit)))
Definition: scip_cons.c:414
static SCIP_DECL_CONSSEPASOL(consSepasolLinear)
#define SCIP_EVENTTYPE_FORMAT
Definition: type_event.h:152
public methods for conflict analysis handlers
int SCIPgetNConss(SCIP *scip)
Definition: scip_prob.c:3050
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:8039
SCIP_Bool SCIPisConsCompressionEnabled(SCIP *scip)
Definition: scip_copy.c:660
public methods for the probing mode
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1119
static SCIP_DECL_CONSPRINT(consPrintLinear)
static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinear)
SCIP_RETCODE SCIPincludeConflicthdlrBasic(SCIP *scip, SCIP_CONFLICTHDLR **conflicthdlrptr, const char *name, const char *desc, int priority, SCIP_DECL_CONFLICTEXEC((*conflictexec)), SCIP_CONFLICTHDLRDATA *conflicthdlrdata)
const char * SCIPconflicthdlrGetName(SCIP_CONFLICTHDLR *conflicthdlr)
Definition: conflict.c:772
SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
Definition: scip_cons.c:534
public methods for message output
SCIP_Real SCIPeventGetOldbound(SCIP_EVENT *event)
Definition: event.c:1218
SCIP_VAR * a
Definition: circlepacking.c:66
SCIP_Bool SCIPisFeasPositive(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisExprVar(SCIP *scip, SCIP_EXPR *expr)
Definition: scip_expr.c:1430
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition: message.c:618
static SCIP_RETCODE convertBinaryEquality(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *naggrvars, int *ndelconss)
Definition: cons_linear.c:9620
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip_prob.c:1955
static SCIP_DECL_HASHKEYEQ(hashKeyEqLinearcons)
#define CONFLICTHDLR_DESC
Definition: cons_linear.c:121
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17379
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:8407
#define DEFAULT_MAXDUALMULTAGGRQUOT
Definition: cons_linear.c:182
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1220
#define SCIP_Real
Definition: def.h:186
static SCIP_RETCODE tightenBounds(SCIP *scip, SCIP_CONS *cons, SCIP_Real maxeasyactivitydelta, SCIP_Bool sortvars, SCIP_Bool *cutoff, int *nchgbds)
Definition: cons_linear.c:7105
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8343
SCIP_RETCODE SCIPaddVarsToRow(SCIP *scip, SCIP_ROW *row, int nvars, SCIP_VAR **vars, SCIP_Real *vals)
Definition: scip_lp.c:1721
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip_general.c:703
#define SCIP_EVENTTYPE_VARUNLOCKED
Definition: type_event.h:73
static void getNewSidesAfterAggregation(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *slackvar, SCIP_Real slackcoef, SCIP_Real *newlhs, SCIP_Real *newrhs)
Definition: cons_linear.c:9678
#define DEFAULT_SINGLETONSTUFFING
Definition: cons_linear.c:156
SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETNVARS((*consgetnvars)))
Definition: scip_cons.c:848
#define EVENTHDLR_NAME
Definition: cons_linear.c:117
SCIP_Bool SCIPisScalingIntegral(SCIP *scip, SCIP_Real val, SCIP_Real scalar)
#define CONSHDLR_ENFOPRIORITY
Definition: cons_linear.c:102
static SCIP_RETCODE convertEquality(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_Bool *cutoff, int *nfixedvars, int *naggrvars, int *ndelconss)
static SCIP_RETCODE applyFixings(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible)
Definition: cons_linear.c:4673
int SCIPconshdlrGetNCheckConss(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4619
public methods for message handling
static SCIP_RETCODE consPrintConsSol(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, FILE *file)
Definition: cons_linear.c:1164
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:8283
SCIP_Bool SCIPdoNotAggr(SCIP *scip)
Definition: scip_var.c:8571
static unsigned int getParallelConsKey(SCIP_CONS *cons)
#define SCIP_INVALID
Definition: def.h:206
#define DEFAULT_RANGEDROWPROPAGATION
Definition: cons_linear.c:173
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8273
Proprule
Definition: cons_and.c:170
SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
Definition: scip_lp.c:2206
static SCIP_RETCODE addCoef(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
Definition: cons_linear.c:3752
static SCIP_DECL_CONFLICTEXEC(conflictExecLinear)
#define CONSHDLR_DESC
Definition: cons_linear.c:100
SCIP_Real SCIPcutoffbounddelta(SCIP *scip)
#define SCIP_Longint
Definition: def.h:171
SCIP_BOUNDTYPE SCIPvarGetBestBoundType(SCIP_VAR *var)
Definition: var.c:18031
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:17599
SCIP_Real SCIPgetRowSolFeasibility(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
Definition: scip_lp.c:2161
static SCIP_RETCODE consdataEnsureVarsSize(SCIP *scip, SCIP_CONSDATA *consdata, int num)
Definition: cons_linear.c:495
#define SCIPdebugAddSolVal(scip, var, val)
Definition: debug.h:298
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17425
static SCIP_DECL_NONLINCONSUPGD(upgradeConsNonlinear)
#define MAX_CLIQUE_NONZEROS_PER_CONS
Definition: cons_linear.c:7972
static void consdataRecomputeGlbMinactivity(SCIP *scip, SCIP_CONSDATA *consdata)
Definition: cons_linear.c:1389
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
enum SCIP_Vartype SCIP_VARTYPE
Definition: type_var.h:69
static SCIP_RETCODE convertLongEquality(SCIP *scip, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_CONS *cons, SCIP_Bool *cutoff, int *naggrvars, int *ndelconss)
Definition: cons_linear.c:9732
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition: type_cons.h:64
SCIP_RETCODE SCIPchgLhsLinear(SCIP *scip, SCIP_CONS *cons, SCIP_Real lhs)
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17985
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip_mem.h:111
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:17402
static int inferInfoToInt(INFERINFO inferinfo)
Definition: cons_linear.c:409
SCIP_Bool SCIPconsIsMarkedPropagate(SCIP_CONS *cons)
Definition: cons.c:8303
static SCIP_Bool isRangedRow(SCIP *scip, SCIP_Real lhs, SCIP_Real rhs)
#define MAXVALRECOMP
Definition: cons_linear.c:198
static SCIP_RETCODE unlockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
Definition: cons_linear.c:706
static SCIP_DECL_CONSPRESOL(consPresolLinear)
#define BMSclearMemoryArray(ptr, num)
Definition: memory.h:132
SCIP_RETCODE SCIPsetConshdlrActive(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSACTIVE((*consactive)))
Definition: scip_cons.c:664
#define DEFAULT_MAXEASYACTIVITYDELTA
Definition: cons_linear.c:144
struct BMS_BlkMem BMS_BLKMEM
Definition: memory.h:439
#define DEFAULT_EXTRACTCLIQUES
Definition: cons_linear.c:183
#define SCIP_EVENTTYPE_GUBCHANGED
Definition: type_event.h:76
SCIP_RETCODE SCIPaddConflict(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons, SCIP_NODE *validnode, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
Definition: scip_prob.c:3236
static SCIP_RETCODE enforceConstraint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss, int nusefulconss, SCIP_SOL *sol, SCIP_RESULT *result)
#define SCIP_CALL_ABORT(x)
Definition: def.h:372
static SCIP_DECL_CONSGETNVARS(consGetNVarsLinear)
SCIP_Real SCIPceil(SCIP *scip, SCIP_Real val)
static SCIP_DECL_CONSEXIT(consExitLinear)
#define DEFAULT_RANGEDROWMAXDEPTH
Definition: cons_linear.c:175
SCIP_RETCODE SCIPsetConshdlrExitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITSOL((*consexitsol)))
Definition: scip_cons.c:462
#define SCIPABORT()
Definition: def.h:365
SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
Definition: scip_var.c:230
public methods for global and local (sub)problems
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:17451
SCIP_Real SCIPgetLhsNonlinear(SCIP_CONS *cons)
SCIP_Longint SCIPcalcGreComDiv(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:9031
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1361
SCIP_Bool SCIPvarIsDeleted(SCIP_VAR *var)
Definition: var.c:17481
static INFERINFO intToInferInfo(int i)
Definition: cons_linear.c:396
SCIP_RETCODE SCIPaddObjoffset(SCIP *scip, SCIP_Real addval)
Definition: scip_prob.c:1276
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
#define MAXACTVAL
Definition: cons_linear.c:192
#define INTWEIGHT
SCIP_Bool SCIPallowStrongDualReds(SCIP *scip)
Definition: scip_var.c:8635
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:139
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:4933
SCIP_Longint SCIPcalcSmaComMul(SCIP_Longint val1, SCIP_Longint val2)
Definition: misc.c:9283
SCIP_Real SCIPfloor(SCIP *scip, SCIP_Real val)
static SCIP_RETCODE addNlrow(SCIP *scip, SCIP_CONS *cons)
Definition: cons_linear.c:7630
#define SCIP_EVENTTYPE_VARDELETED
Definition: type_event.h:71
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:2019
SCIP_RETCODE SCIPseparateRelaxedKnapsack(SCIP *scip, SCIP_CONS *cons, SCIP_SEPA *sepa, int nknapvars, SCIP_VAR **knapvars, SCIP_Real *knapvals, SCIP_Real valscale, SCIP_Real rhs, SCIP_SOL *sol, SCIP_Bool *cutoff, int *ncuts)
#define DEFAULT_MAXMULTAGGRQUOT
Definition: cons_linear.c:181
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:57
int SCIPgetNSepaRounds(SCIP *scip)
#define DEFAULT_PRESOLUSEHASHING
Definition: cons_linear.c:130
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17589
SCIP_RETCODE SCIPchgCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
SCIP_Bool SCIPvarIsNegated(SCIP_VAR *var)
Definition: var.c:17415
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:2044
static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata)
Definition: cons_linear.c:1084
uint64_t SCIP_EVENTTYPE
Definition: type_event.h:151
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip_mem.h:128
SCIP_RETCODE SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
Definition: scip_cons.c:275
SCIP_RETCODE SCIPsetConsInitial(SCIP *scip, SCIP_CONS *cons, SCIP_Bool initial)
Definition: scip_cons.c:1217
#define SCIP_EVENTTYPE_BOUNDRELAXED
Definition: type_event.h:124
memory allocation routines
#define DEFAULT_RANGEDROWARTCONS
Definition: cons_linear.c:174