SCIP Doxygen Documentation
Loading...
Searching...
No Matches
cons_exactlinear.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2026 Zuse Institute Berlin (ZIB) */
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_exactlinear.c
26 * @ingroup DEFPLUGINS_CONS
27 * @brief Constraint handler for exact linear constraints in their most general form, \f$lhs <= a^T x <= rhs\f$.
28 * @author Leon Eifler
29 * @author Sander Borst
30 */
31
32/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
33
34#include "scip/clock.h"
35#include "scip/def.h"
36#include "scip/struct_stat.h"
37#include "scip/type_retcode.h"
39#include "scip/cons_knapsack.h"
41#include "scip/cons_linear.h"
42#include "scip/cons_nonlinear.h"
43#include "scip/debug.h"
44#include "scip/intervalarith.h"
45#include "scip/pub_conflict.h"
46#include "scip/pub_cons.h"
47#include "scip/pub_event.h"
48#include "scip/pub_lp.h"
49#include "scip/pub_lpexact.h"
50#include "scip/pub_message.h"
51#include "scip/pub_misc.h"
52#include "scip/pub_misc_sort.h"
53#include "scip/pub_var.h"
54#include "scip/rational.h"
55#include "scip/scip_branch.h"
57#include "scip/scip_conflict.h"
58#include "scip/scip_cons.h"
59#include "scip/scip_copy.h"
60#include "scip/scip_cut.h"
61#include "scip/scip_event.h"
62#include "scip/scip_exact.h"
63#include "scip/scip_general.h"
64#include "scip/scip_lp.h"
65#include "scip/scip_lpexact.h"
66#include "scip/scip_mem.h"
67#include "scip/scip_message.h"
68#include "scip/scip_numerics.h"
69#include "scip/scip_param.h"
70#include "scip/scip_prob.h"
71#include "scip/scip_probing.h"
73#include "scip/scip_tree.h"
74#include "scip/scip_var.h"
75#include "scip/var.h"
76#include "scip/sepastoreexact.h"
77#include <ctype.h>
78#ifndef _WIN32
79#include <strings.h> /*lint --e{766}*/
80#endif
81
82
83#define CONSHDLR_NAME "exactlinear"
84#define CONSHDLR_DESC "exact linear constraints of the form lhs <= a^T x <= rhs"
85#define CONSHDLR_SEPAPRIORITY +100000 /**< priority of the constraint handler for separation */
86#define CONSHDLR_ENFOPRIORITY -1000000 /**< priority of the constraint handler for constraint enforcing */
87#define CONSHDLR_CHECKPRIORITY -1000000 /**< priority of the constraint handler for checking feasibility */
88#define CONSHDLR_SEPAFREQ 0 /**< frequency for separating cuts; zero means to separate only in the root node */
89#define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
90#define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
91 * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
92#define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
93#define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
94#define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
95
96#define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP
97
98#define EVENTHDLR_NAME "exactlinear"
99#define EVENTHDLR_DESC "bound change event handler for exact linear constraints"
100
101#define DEFAULT_TIGHTENBOUNDSFREQ 1 /**< multiplier on propagation frequency, how often the bounds are tightened */
102#define DEFAULT_MAXROUNDS 5 /**< maximal number of separation rounds per node (-1: unlimited) */
103#define DEFAULT_MAXROUNDSROOT -1 /**< maximal number of separation rounds in the root node (-1: unlimited) */
104#define DEFAULT_MAXSEPACUTS 50 /**< maximal number of cuts separated per separation round */
105#define DEFAULT_MAXSEPACUTSROOT 200 /**< maximal number of cuts separated per separation round in root node */
106#define DEFAULT_SORTVARS TRUE /**< should variables be sorted after presolve w.r.t their coefficient absolute for faster
107 * propagation? */
108#define DEFAULT_LIMITDENOM FALSE /**< should denominator sizes for continuous variables be controlled?*/
109#define DEFAULT_BOUNDMAXDENOM 256L /**< maximal denominator for rational bounds on continuous variables after propagation */
110
111
112/** constraint data for linear constraints */
113struct SCIP_ConsData
114{
115 SCIP_RATIONAL* lhs; /**< left hand side of row (for ranged rows) */
116 SCIP_RATIONAL* rhs; /**< right hand side of row */
117 SCIP_Real lhsreal; /**< real relaxation of lhs */
118 SCIP_Real rhsreal; /**< real relaxation of rhs */
119 SCIP_RATIONAL* violation; /**< used to store violation */
120 SCIP_RATIONAL* activity; /**< used to store activity */
121 SCIP_Real maxabsval; /**< maximum absolute value of all coefficients */
122 SCIP_Real minabsval; /**< minimal absolute value of all coefficients */
123 SCIP_Real minactivity; /**< minimal value w.r.t. the variable's local bounds for the constraint's
124 * activity, ignoring the coefficients contributing with infinite value */
125 SCIP_Real maxactivity; /**< maximal value w.r.t. the variable's local bounds for the constraint's
126 * activity, ignoring the coefficients contributing with infinite value */
127 SCIP_Real lastminactivity; /**< last minimal activity which was computed by complete summation
128 * over all contributing values */
129 SCIP_Real lastmaxactivity; /**< last maximal activity which was computed by complete summation
130 * over all contributing values */
131 SCIP_Real glbminactivity; /**< minimal value w.r.t. the variable's global bounds for the constraint's
132 * activity, ignoring the coefficients contributing with infinite value */
133 SCIP_Real glbmaxactivity; /**< maximal value w.r.t. the variable's global bounds for the constraint's
134 * activity, ignoring the coefficients contributing with infinite value */
135 SCIP_Real lastglbminactivity; /**< last global minimal activity which was computed by complete summation
136 * over all contributing values */
137 SCIP_Real lastglbmaxactivity; /**< last global maximal activity which was computed by complete summation
138 * over all contributing values */
139 SCIP_Real maxactdelta; /**< maximal activity contribution of a single variable, or SCIP_INVALID if invalid */
140 SCIP_VAR* maxactdeltavar; /**< variable with maximal activity contribution, or NULL if invalid */
141 SCIP_RATIONAL* maxabsvalexact; /**< exact maximum absolute value of all coefficients */
142 SCIP_RATIONAL* minabsvalexact; /**< exact minimal absolute value of all coefficients */
143 SCIP_ROW* rowlhs; /**< LP row, if constraint is already stored in LP row format; represents fp-relaxation of lhs-part of rowexact;
144 only this row will be added to the exact LP, rowrhs is used for safe aggregation of rows */
145 SCIP_ROW* rowrhs; /**< LP row, if constraint is already stored in LP row format; represents fp-relaxation of rhs-part of rowexact */
146 SCIP_ROWEXACT* rowexact; /**< Exact rational lp row */
147 SCIP_VAR** vars; /**< variables of constraint entries */
148 SCIP_RATIONAL** vals; /**< coefficients of constraint entries */
149 SCIP_INTERVAL* valsreal; /**< values of val rounded up/down to closest fp-representable numbers */
150 SCIP_EVENTDATA** eventdata; /**< event data for bound change events of the variables */
151 int minactivityneginf; /**< number of coefficients contributing with neg. infinite value to minactivity */
152 int minactivityposinf; /**< number of coefficients contributing with pos. infinite value to minactivity */
153 int maxactivityneginf; /**< number of coefficients contributing with neg. infinite value to maxactivity */
154 int maxactivityposinf; /**< number of coefficients contributing with pos. infinite value to maxactivity */
155 int minactivityneghuge; /**< number of coefficients contributing with huge neg. value to minactivity */
156 int minactivityposhuge; /**< number of coefficients contributing with huge pos. value to minactivity */
157 int maxactivityneghuge; /**< number of coefficients contributing with huge neg. value to maxactivity */
158 int maxactivityposhuge; /**< number of coefficients contributing with huge pos. value to maxactivity */
159 int glbminactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbminactivity */
160 int glbminactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbminactivity */
161 int glbmaxactivityneginf;/**< number of coefficients contrib. with neg. infinite value to glbmaxactivity */
162 int glbmaxactivityposinf;/**< number of coefficients contrib. with pos. infinite value to glbmaxactivity */
163 int glbminactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbminactivity */
164 int glbminactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbminactivity */
165 int glbmaxactivityneghuge;/**< number of coefficients contrib. with huge neg. value to glbmaxactivity */
166 int glbmaxactivityposhuge;/**< number of coefficients contrib. with huge pos. value to glbmaxactivity */
167 int varssize; /**< size of the vars- and vals-arrays */
168 int nvars; /**< number of nonzeros in constraint */
169 int nbinvars; /**< the number of binary variables in the constraint, only valid after
170 * sorting in stage >= SCIP_STAGE_INITSOLVE
171 */
172 unsigned int boundstightened:2; /**< is constraint already propagated with bound tightening? */
173 unsigned int rangedrowpropagated:2; /**< did we perform ranged row propagation on this constraint?
174 * (0: no, 1: yes, 2: with potentially adding artificial constraint */
175 unsigned int validmaxabsval:1; /**< is the maximum absolute value valid? */
176 unsigned int validminabsval:1; /**< is the minimum absolute value valid? */
177 unsigned int validactivities:1; /**< are the activity bounds (local and global) valid? */
178 unsigned int validminact:1; /**< is the local minactivity valid? */
179 unsigned int validmaxact:1; /**< is the local maxactivity valid? */
180 unsigned int validglbminact:1; /**< is the global minactivity valid? */
181 unsigned int validglbmaxact:1; /**< is the global maxactivity valid? */
182 unsigned int presolved:1; /**< is constraint already presolved? */
183 unsigned int removedfixings:1; /**< are all fixed variables removed from the constraint? */
184 unsigned int changed:1; /**< was constraint changed since last aggregation round in preprocessing? */
185 unsigned int normalized:1; /**< is the constraint in normalized form? */
186 unsigned int coefsorted :1; /**< are the constraint's variables sorted? */
187 unsigned int merged:1; /**< are the constraint's equal variables already merged? */
188 unsigned int cliquesadded:1; /**< were the cliques of the constraint already extracted? */
189 unsigned int implsadded:1; /**< were the implications of the constraint already extracted? */
190 unsigned int indexsorted:1; /**< are binary variables sorted w.r.t. the absolute value of their coefficient? */
191 unsigned int varsdeleted:1; /**< were variables deleted after last cleanup? */
192 unsigned int hascontvar:1; /**< does the constraint contain at least one continuous variable? */
193 unsigned int hasnonbinvar:1; /**< does the constraint contain at least one non-binary variable? */
194 unsigned int hasnonbinvalid:1; /**< is the information stored in hasnonbinvar and hascontvar valid? */
195 unsigned int onerowrelax:1; /**< is one floating-point row enough for the fp-relaxation? if so only rowlhs is used */
196 unsigned int hasfprelax:1; /**< is the constraint possible to be represented as a fp relaxation (only false if var without bound is present) */
197};
198
199/** event data for bound change event */
200struct SCIP_EventData
201{
202 SCIP_CONS* cons; /**< linear constraint to process the bound change for */
203 int varpos; /**< position of variable in vars array */
204 bool rowvar; /**< is the event a row event? */
205 int filterpos; /**< position of event in variable's event filter */
206};
207
208/** constraint handler data */
209struct SCIP_ConshdlrData
210{
211 SCIP_EVENTHDLR* eventhdlr; /**< event handler for bound change events */
212 SCIP_RATIONAL* maxaggrnormscale; /**< maximal allowed relative gain in maximum norm for constraint aggregation
213 * (0.0: disable constraint aggregation) */
214 SCIP_RATIONAL* maxcardbounddist; /**< maximal relative distance from current node's dual bound to primal bound compared
215 * to best node's dual bound for separating knapsack cardinality cuts */
216 SCIP_RATIONAL* mingainpernmincomp; /**< minimal gain per minimal pairwise presolving comparisons to repeat pairwise comparison round */
217 SCIP_RATIONAL* maxeasyactivitydelta;/**< maximum activity delta to run easy propagation on linear constraint
218 * (faster, but numerically less stable) */
219 int tightenboundsfreq; /**< multiplier on propagation frequency, how often the bounds are tightened */
220 int maxrounds; /**< maximal number of separation rounds per node (-1: unlimited) */
221 int maxroundsroot; /**< maximal number of separation rounds in the root node (-1: unlimited) */
222 int maxsepacuts; /**< maximal number of cuts separated per separation round */
223 int maxsepacutsroot; /**< maximal number of cuts separated per separation round in root node */
224 int naddconss; /**< number of added constraints */
225 SCIP_Longint ncheckserrorbound; /**< number of times running error analyis activity computation was called */
226 SCIP_Longint nsuccesserrorbound; /**< number of times running error analyis activity computation could determine feasibility */
227 SCIP_Longint nabotserrorbound; /**< number of times running error analysis activity computation not appliccable (e.g. row->len != fprow->len) */
228 SCIP_Longint nconsprop; /**< number of times a constraint was propagated */
229 SCIP_Longint nconspropnoninit; /**< number of times a non-initial (conflict) constraint was propagated */
230 SCIP_Longint propnonzeros; /**< number of nonzeros in propagated rows */
231 SCIP_Longint propnonzerosnoninit;/**< number of nonzeros in propagated rows in non-initial (conflict) propagations */
232 SCIP_Bool sortvars; /**< should binary variables be sorted for faster propagation? */
233 SCIP_Bool propcont; /**< should bounds on continuous variables be tightened by propagation?*/
234 SCIP_Bool limitdenom; /**< should denominator sizes for continuous variables be controlled?*/
235 SCIP_Longint boundmaxdenom; /**< maximal denominator for rational bounds on continuous variables after propagation */
236};
237
238
239/*
240 * Propagation rules
241 */
242
243/*lint --e{749} */
245{
246 PROPRULE_1_RHS = 1, /**< activity residuals of all other variables tighten bounds of single
247 * variable due to the right hand side of the inequality */
248 PROPRULE_1_LHS = 2, /**< activity residuals of all other variables tighten bounds of single
249 * variable due to the left hand side of the inequality */
250 PROPRULE_1_RANGEDROW = 3, /**< fixed variables and gcd of all left variables tighten bounds of a
251 * single variable in this reanged row */
252 PROPRULE_INVALID = 0 /**< propagation was applied without a specific propagation rule */
253};
254typedef enum Proprule PROPRULE;
255
256/** inference information */
257struct InferInfo
258{
259 union
260 {
261 struct
262 {
263 unsigned int proprule:8; /**< propagation rule that was applied */
264 unsigned int pos:24; /**< variable position, the propagation rule was applied at */
265 } asbits;
266 int asint; /**< inference information as a single int value */
267 } val;
268};
269
270typedef struct InferInfo INFERINFO;
271
272
273/** converts an inference information into an int */
274static
276 INFERINFO inferinfo /**< inference information to convert */
277 )
278{
279 return inferinfo.val.asint;
280}
281
282
283/** constructs an inference information out of a propagation rule and a position number */
284static
286 PROPRULE proprule, /**< propagation rule that deduced the value */
287 int pos /**< variable position, the propagation rule was applied at */
288 )
289{
290 INFERINFO inferinfo;
291
292 assert(pos >= 0);
293 /* in the inferinfo struct only 24 bits for 'pos' are reserved */
294 assert(pos < (1<<24));
295
296 inferinfo.val.asbits.proprule = (unsigned int) proprule; /*lint !e641*/
297 inferinfo.val.asbits.pos = (unsigned int) pos; /*lint !e732*/
298
299 return inferinfo;
300}
301
302/** constructs an inference information out of a propagation rule and a position number, returns info as int */
303static
305 PROPRULE proprule, /**< propagation rule that deduced the value */
306 int pos /**< variable position, the propagation rule was applied at */
307 )
308{
309 return inferInfoToInt(getInferInfo(proprule, pos));
310}
311
312/** ensures, that vars and vals arrays can store at least num entries */
313static
315 SCIP* scip, /**< SCIP data structure */
316 SCIP_CONSDATA* consdata, /**< linear constraint data */
317 int num /**< minimum number of entries to store */
318 )
319{
320 int k;
321 assert(scip != NULL);
322 assert(consdata != NULL);
323 assert(consdata->nvars <= consdata->varssize);
324
325 if( num > consdata->varssize )
326 {
327 int newsize;
328
329 newsize = SCIPcalcMemGrowSize(scip, num);
330 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vars, consdata->varssize, newsize) );
331 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vals, consdata->varssize, newsize) );
332 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->valsreal, consdata->varssize, newsize) );
333 for( k = consdata->varssize; k < newsize; ++k )
334 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &consdata->vals[k]) );
335
336 if( consdata->eventdata != NULL )
337 {
338 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize, newsize) );
339 }
340 consdata->varssize = newsize;
341 }
342 assert(num <= consdata->varssize);
343
344 return SCIP_OKAY;
345}
346
347
348/*
349 * local methods for managing linear constraint update methods
350 */
351
352
353/** creates constraint handler data for linear constraint handler */
354static
356 SCIP* scip, /**< SCIP data structure */
357 SCIP_CONSHDLRDATA** conshdlrdata, /**< pointer to store the constraint handler data */
358 SCIP_EVENTHDLR* eventhdlr /**< event handler */
359 )
360{
361 assert(scip != NULL);
362 assert(conshdlrdata != NULL);
363 assert(eventhdlr != NULL);
364
365 SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
366 (*conshdlrdata)->naddconss = 0;
367 (*conshdlrdata)->ncheckserrorbound = 0;
368 (*conshdlrdata)->nabotserrorbound = 0;
369 (*conshdlrdata)->nsuccesserrorbound = 0;
370 (*conshdlrdata)->nconsprop = 0;
371 (*conshdlrdata)->nconspropnoninit = 0;
372 (*conshdlrdata)->propnonzeros = 0;
373 (*conshdlrdata)->propnonzerosnoninit = 0;
374 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &(*conshdlrdata)->maxaggrnormscale) );
375 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &(*conshdlrdata)->maxcardbounddist) );
376 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &(*conshdlrdata)->maxeasyactivitydelta) );
377 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &(*conshdlrdata)->mingainpernmincomp) );
378
379 /* set event handler for updating linear constraint activity bounds */
380 (*conshdlrdata)->eventhdlr = eventhdlr;
381
382 return SCIP_OKAY;
383}
384
385/** frees constraint handler data for linear constraint handler */
386static
388 SCIP* scip, /**< SCIP data structure */
389 SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to the constraint handler data */
390 )
391{
392 assert(scip != NULL);
393 assert(conshdlrdata != NULL);
394 assert(*conshdlrdata != NULL);
395
396 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*conshdlrdata)->maxaggrnormscale);
397 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*conshdlrdata)->maxcardbounddist);
398 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*conshdlrdata)->maxeasyactivitydelta);
399 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*conshdlrdata)->mingainpernmincomp);
400
401 SCIPfreeBlockMemory(scip, conshdlrdata);
402}
403
404/*
405 * local methods
406 */
407
408/** installs rounding locks for the given variable associated to the given coefficient in the linear constraint */
409static
411 SCIP* scip, /**< SCIP data structure */
412 SCIP_CONS* cons, /**< linear constraint */
413 SCIP_VAR* var, /**< variable of constraint entry */
414 SCIP_RATIONAL* val /**< coefficient of constraint entry */
415 )
416{
417 SCIP_CONSDATA* consdata;
418
419 assert(scip != NULL);
420 assert(cons != NULL);
421 assert(var != NULL);
422
423 consdata = SCIPconsGetData(cons);
424 assert(consdata != NULL);
426
427 if( SCIPrationalIsPositive(val) )
428 {
430 !SCIPrationalIsNegInfinity(consdata->lhs), !SCIPrationalIsInfinity(consdata->rhs)) );
431 }
432 else
433 {
435 !SCIPrationalIsInfinity(consdata->rhs), !SCIPrationalIsNegInfinity(consdata->lhs)) );
436 }
437
438 return SCIP_OKAY;
439}
440
441/** removes rounding locks for the given variable associated to the given coefficient in the linear constraint */
442static
444 SCIP* scip, /**< SCIP data structure */
445 SCIP_CONS* cons, /**< linear constraint */
446 SCIP_VAR* var, /**< variable of constraint entry */
447 SCIP_RATIONAL* val /**< coefficient of constraint entry */
448 )
449{
450 SCIP_CONSDATA* consdata;
451
452 assert(scip != NULL);
453 assert(cons != NULL);
454 assert(var != NULL);
455
456 consdata = SCIPconsGetData(cons);
457 assert(consdata != NULL);
459
460 if( SCIPrationalIsPositive(val) )
461 {
463 !SCIPrationalIsInfinity(consdata->rhs)) );
464 }
465 else
466 {
468 !SCIPrationalIsNegInfinity(consdata->lhs)) );
469 }
470
471 return SCIP_OKAY;
472}
473
474/** creates event data for variable at given position, and catches events */
475/**! [SnippetDebugAssertions] */
476static
478 SCIP* scip, /**< SCIP data structure */
479 SCIP_CONS* cons, /**< linear constraint */
480 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
481 int pos /**< array position of variable to catch bound change events for */
482 )
483{
484 SCIP_CONSDATA* consdata;
485 assert(scip != NULL);
486 assert(cons != NULL);
487 assert(eventhdlr != NULL);
488
489 consdata = SCIPconsGetData(cons);
490 assert(consdata != NULL);
491
492 assert(0 <= pos && pos < consdata->nvars);
493 assert(consdata->vars != NULL);
494 assert(consdata->vars[pos] != NULL);
495 assert(SCIPvarIsTransformed(consdata->vars[pos]));
496 assert(consdata->eventdata != NULL);
497 assert(consdata->eventdata[pos] == NULL);
498
499 SCIP_CALL( SCIPallocBlockMemory(scip, &(consdata->eventdata[pos])) ); /*lint !e866*/
500 consdata->eventdata[pos]->cons = cons;
501 consdata->eventdata[pos]->varpos = pos;
502 consdata->eventdata[pos]->rowvar = false;
503
504 SCIP_CALL( SCIPcatchVarEvent(scip, consdata->vars[pos],
507 eventhdlr, consdata->eventdata[pos], &consdata->eventdata[pos]->filterpos) );
508
509 consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(consdata->vars[pos]);
510
511 return SCIP_OKAY;
512}
513
514/**! [SnippetDebugAssertions] */
515
516/** deletes event data for variable at given position, and drops events */
517static
519 SCIP* scip, /**< SCIP data structure */
520 SCIP_CONS* cons, /**< linear constraint */
521 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
522 int pos /**< array position of variable to catch bound change events for */
523 )
524{
525 SCIP_CONSDATA* consdata;
526 assert(scip != NULL);
527 assert(cons != NULL);
528 assert(eventhdlr != NULL);
529
530 consdata = SCIPconsGetData(cons);
531 assert(consdata != NULL);
532
533 assert(0 <= pos && pos < consdata->nvars);
534 assert(consdata->vars[pos] != NULL);
535 assert(consdata->eventdata != NULL);
536 assert(consdata->eventdata[pos] != NULL);
537 assert(consdata->eventdata[pos]->cons == cons);
538 assert(consdata->eventdata[pos]->varpos == pos);
539
540 SCIP_CALL( SCIPdropVarEvent(scip, consdata->vars[pos],
543 eventhdlr, consdata->eventdata[pos], consdata->eventdata[pos]->filterpos) );
544
545 SCIPfreeBlockMemory(scip, &consdata->eventdata[pos]); /*lint !e866*/
546
547 return SCIP_OKAY;
548}
549
550/** catches bound change events for all variables in transformed linear constraint */
551static
553 SCIP* scip, /**< SCIP data structure */
554 SCIP_CONS* cons, /**< linear constraint */
555 SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
556 )
557{
558 SCIP_CONSDATA* consdata;
559 int i;
560
561 assert(scip != NULL);
562 assert(cons != NULL);
563
564 consdata = SCIPconsGetData(cons);
565 assert(consdata != NULL);
566 assert(consdata->eventdata == NULL);
567
568 /* allocate eventdata array */
569 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize) );
570 assert(consdata->eventdata != NULL);
571 BMSclearMemoryArray(consdata->eventdata, consdata->nvars);
572
573 /* catch event for every single variable */
574 for( i = 0; i < consdata->nvars; ++i )
575 {
576 SCIP_CALL( consCatchEvent(scip, cons, eventhdlr, i) );
577 }
578
579 return SCIP_OKAY;
580}
581
582/** drops bound change events for all variables in transformed linear constraint */
583static
585 SCIP* scip, /**< SCIP data structure */
586 SCIP_CONS* cons, /**< linear constraint */
587 SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
588 )
589{
590 SCIP_CONSDATA* consdata;
591 int i;
592
593 assert(scip != NULL);
594 assert(cons != NULL);
595
596 consdata = SCIPconsGetData(cons);
597 assert(consdata != NULL);
598 assert(consdata->eventdata != NULL);
599
600 /* drop event of every single variable */
601 for( i = consdata->nvars - 1; i >= 0; --i )
602 {
603 SCIP_CALL( consDropEvent(scip, cons, eventhdlr, i) );
604 }
605
606 /* free eventdata array */
607 SCIPfreeBlockMemoryArray(scip, &consdata->eventdata, consdata->varssize);
608 assert(consdata->eventdata == NULL);
609
610 return SCIP_OKAY;
611}
612
613/** creates a linear constraint data */
614static
616 SCIP* scip, /**< SCIP data structure */
617 SCIP_CONSDATA** consdata, /**< pointer to linear constraint data */
618 int nvars, /**< number of nonzeros in the constraint */
619 SCIP_VAR** vars, /**< array with variables of constraint entries */
620 SCIP_RATIONAL** vals, /**< array with coefficients of constraint entries */
621 SCIP_RATIONAL* lhs, /**< left hand side of row */
622 SCIP_RATIONAL* rhs /**< right hand side of row */
623 )
624{
625 int v;
626 SCIP_RATIONAL* constant;
627 SCIP_Real lhsrel;
628 SCIP_Real rhsrel;
629
630 assert(scip != NULL);
631 assert(consdata != NULL);
632 assert(nvars == 0 || vars != NULL);
633 assert(nvars == 0 || vals != NULL);
634
635 if( SCIPrationalIsGT(lhs, rhs) )
636 {
637 SCIPwarningMessage(scip, "left hand side of linear constraint greater than right hand side\n");
638 SCIPwarningMessage(scip, " -> lhs=%g, rhs=%g\n", SCIPrationalGetReal(lhs), SCIPrationalGetReal(rhs));
639 }
640
641 SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
642
643 (*consdata)->varssize = 0;
644 (*consdata)->nvars = nvars;
645 (*consdata)->hascontvar = FALSE;
646 (*consdata)->hasnonbinvar = FALSE;
647 (*consdata)->hasnonbinvalid = TRUE;
648 (*consdata)->vars = NULL;
649 (*consdata)->vals = NULL;
650 (*consdata)->valsreal = NULL;
651
653 if( nvars > 0 )
654 {
655 int k;
656
657 SCIP_VAR** varsbuffer;
658 SCIP_RATIONAL** valsbuffer;
659 SCIP_INTERVAL* valsrealbuffer;
660
661 /* copy variables into temporary buffer */
662 SCIP_CALL( SCIPallocBufferArray(scip, &varsbuffer, nvars) );
664 SCIP_CALL( SCIPallocBufferArray(scip, &valsrealbuffer, nvars) );
665 k = 0;
666
667 /* loop over variables and sort out fixed ones */
668 for( v = 0; v < nvars; ++v )
669 {
670 SCIP_VAR* var;
671
672 var = vars[v];
673 assert(var != NULL);
675
676 if( !SCIPrationalIsZero(vals[v]) )
677 {
678 /* treat fixed variable as a constant if problem compression is enabled */
680 {
682 }
683 else
684 {
685 varsbuffer[k] = var;
686 SCIPrationalSetRational(valsbuffer[k], vals[v]);
687 SCIPintervalSetRational(&(valsrealbuffer[k]), vals[v]);
688 k++;
689
690 /* update hascontvar and hasnonbinvar flags */
691 if( !(*consdata)->hascontvar )
692 {
694
695 if( vartype != SCIP_VARTYPE_BINARY )
696 {
697 (*consdata)->hasnonbinvar = TRUE;
698
699 if( vartype == SCIP_VARTYPE_CONTINUOUS )
700 (*consdata)->hascontvar = TRUE;
701 }
702 }
703 }
704 }
705 }
706 (*consdata)->nvars = k;
707
708 if( k > 0 )
709 {
710 /* copy the possibly reduced buffer arrays into block */
711 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, varsbuffer, k) );
712 SCIP_CALL( SCIPrationalCopyBlockArray(SCIPblkmem(scip), &(*consdata)->vals, valsbuffer, k) );
713 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->valsreal, valsrealbuffer, k) );
714 (*consdata)->varssize = k;
715 }
716
717 SCIPfreeBufferArray(scip, &valsrealbuffer);
719 SCIPfreeBufferArray(scip, &varsbuffer);
720 }
721
722 (*consdata)->eventdata = NULL;
723
726
727 /* due to compressed copying, we may have fixed variables contributing to the left and right hand side */
728 if( !SCIPrationalIsZero(constant) )
729 {
730 if( !SCIPrationalIsAbsInfinity(lhs) )
731 SCIPrationalDiff(lhs, lhs, constant);
732
733 if( !SCIPrationalIsAbsInfinity(rhs) )
734 SCIPrationalDiff(rhs, rhs, constant);
735 }
736
737 (*consdata)->rowlhs = NULL;
738 (*consdata)->rowrhs = NULL;
739 (*consdata)->rowexact = NULL;
740 SCIP_CALL( SCIPrationalCopyBlock(SCIPblkmem(scip), &(*consdata)->lhs, lhs) );
741 SCIP_CALL( SCIPrationalCopyBlock(SCIPblkmem(scip), &(*consdata)->rhs, rhs) );
742 (*consdata)->lhsreal = lhsrel;
743 (*consdata)->rhsreal = rhsrel;
744 SCIP_CALL( SCIPrationalCreateString(SCIPblkmem(scip), &(*consdata)->maxabsvalexact, "inf") );
745 SCIP_CALL( SCIPrationalCreateString(SCIPblkmem(scip), &(*consdata)->minabsvalexact, "inf") );
746 (*consdata)->maxabsval = SCIP_INVALID;
747 (*consdata)->minabsval = SCIP_INVALID;
748 (*consdata)->minactivity = SCIP_INVALID;
749 (*consdata)->maxactivity = SCIP_INVALID;
750 (*consdata)->lastminactivity = SCIP_INVALID;
751 (*consdata)->lastmaxactivity = SCIP_INVALID;
752 (*consdata)->maxactdelta = SCIP_INVALID;
753 (*consdata)->maxactdeltavar = NULL;
754 (*consdata)->minactivityneginf = -1;
755 (*consdata)->minactivityposinf = -1;
756 (*consdata)->maxactivityneginf = -1;
757 (*consdata)->maxactivityposinf = -1;
758 (*consdata)->minactivityneghuge = -1;
759 (*consdata)->minactivityposhuge = -1;
760 (*consdata)->maxactivityneghuge = -1;
761 (*consdata)->maxactivityposhuge = -1;
762 (*consdata)->glbminactivity = SCIP_INVALID;
763 (*consdata)->glbmaxactivity = SCIP_INVALID;
764 (*consdata)->lastglbminactivity = SCIP_INVALID;
765 (*consdata)->lastglbmaxactivity = SCIP_INVALID;
766 (*consdata)->glbminactivityneginf = -1;
767 (*consdata)->glbminactivityposinf = -1;
768 (*consdata)->glbmaxactivityneginf = -1;
769 (*consdata)->glbmaxactivityposinf = -1;
770 (*consdata)->glbminactivityneghuge = -1;
771 (*consdata)->glbminactivityposhuge = -1;
772 (*consdata)->glbmaxactivityneghuge = -1;
773 (*consdata)->glbmaxactivityposhuge = -1;
774 (*consdata)->validmaxabsval = FALSE;
775 (*consdata)->validminabsval = FALSE;
776 (*consdata)->validactivities = FALSE;
777 (*consdata)->validminact = FALSE;
778 (*consdata)->validmaxact = FALSE;
779 (*consdata)->validglbminact = FALSE;
780 (*consdata)->validglbmaxact = FALSE;
781 (*consdata)->boundstightened = 0;
782 (*consdata)->presolved = FALSE;
783 (*consdata)->removedfixings = FALSE;
784 (*consdata)->changed = TRUE;
785 (*consdata)->normalized = FALSE;
786 (*consdata)->indexsorted = (nvars <= 1);
787 (*consdata)->merged = (nvars <= 1);
788 (*consdata)->cliquesadded = FALSE;
789 (*consdata)->implsadded = FALSE;
790 (*consdata)->coefsorted = FALSE;
791 (*consdata)->nbinvars = -1;
792 (*consdata)->varsdeleted = FALSE;
793 (*consdata)->rangedrowpropagated = 0;
794 (*consdata)->onerowrelax = FALSE;
795 (*consdata)->hasfprelax = FALSE;
796
797 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &(*consdata)->activity) );
798 SCIP_CALL( SCIPrationalCreateBlock(SCIPblkmem(scip), &(*consdata)->violation) );
799
801 {
802 /* get transformed variables */
803 SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
804 }
805
806 /* capture variables */
807 for( v = 0; v < (*consdata)->nvars; v++ )
808 {
809 assert((*consdata)->vars[v] != NULL);
810 assert(!SCIPrationalIsZero((*consdata)->vals[v]));
811 SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->vars[v]) );
812 }
813
815
816 return SCIP_OKAY;
817}
818
819/** frees a linear constraint data */
820static
822 SCIP* scip, /**< SCIP data structure */
823 SCIP_CONSDATA** consdata /**< pointer to linear constraint data */
824 )
825{
826 int v;
827
828 assert(scip != NULL);
829 assert(consdata != NULL);
830 assert(*consdata != NULL);
831 assert((*consdata)->varssize >= 0);
832
833 /* release the row */
834 if( (*consdata)->rowlhs != NULL )
835 {
836 SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->rowlhs) );
837 }
838 if( (*consdata)->rowrhs != NULL && !(*consdata)->onerowrelax )
839 {
840 SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->rowrhs) );
841 }
842
843 /* release variables */
844 for( v = 0; v < (*consdata)->nvars; v++ )
845 {
846 assert((*consdata)->vars[v] != NULL);
847 assert(!SCIPrationalIsZero((*consdata)->vals[v]));
848 SCIP_CALL( SCIPreleaseVar(scip, &((*consdata)->vars[v])) );
849 }
850
851 SCIPrationalFreeBlockArray(SCIPblkmem(scip), &(*consdata)->vals, (*consdata)->varssize);
852
853 SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vars, (*consdata)->varssize);
854 SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vals, (*consdata)->varssize);
855 SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->valsreal, (*consdata)->varssize);
856
857 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*consdata)->lhs);
858 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*consdata)->rhs);
859 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*consdata)->maxabsvalexact);
860 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*consdata)->minabsvalexact);
861 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*consdata)->violation);
862 SCIPrationalFreeBlock(SCIPblkmem(scip), &(*consdata)->activity);
863
864 SCIPfreeBlockMemory(scip, consdata);
865 return SCIP_OKAY;
866}
867/** prints linear constraint in CIP format to file stream */
868static
870 SCIP* scip, /**< SCIP data structure */
871 SCIP_CONSDATA* consdata, /**< linear constraint data */
872 FILE* file /**< output file (or NULL for standard output) */
873 )
874{
875 assert(scip != NULL);
876 assert(consdata != NULL);
877
878 /* print left hand side for ranged rows */
879 if( !SCIPrationalIsNegInfinity(consdata->lhs)
880 && !SCIPrationalIsInfinity(consdata->rhs)
881 && !SCIPrationalIsEQ(consdata->lhs, consdata->rhs) )
882 {
883 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->lhs);
884 SCIPinfoMessage(scip, file, " <= ");
885 }
886
887 /* print coefficients and variables */
888 if( consdata->nvars == 0 )
889 SCIPinfoMessage(scip, file, "0");
890 else
891 {
892 /* post linear sum of the linear constraint */
893 SCIP_CALL( SCIPwriteVarsLinearsumExact(scip, file, consdata->vars, consdata->vals, consdata->nvars, TRUE) );
894 }
895
896 /* print right hand side */
897 if( SCIPrationalIsEQ(consdata->lhs, consdata->rhs) )
898 {
899 SCIPinfoMessage(scip, file, " == ");
900 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->lhs);
901 }
902 else if( !SCIPrationalIsInfinity(consdata->rhs) )
903 {
904 SCIPinfoMessage(scip, file, " <= ");
905 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->rhs);
906 }
907 else if( !SCIPrationalIsNegInfinity(consdata->lhs) )
908 {
909 SCIPinfoMessage(scip, file, " >= ");
910 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->lhs);
911 }
912 else
913 SCIPinfoMessage(scip, file, " [free]");
914
915 return SCIP_OKAY;
916}
917
918/** prints linear constraint and contained solution values of variables to file stream */
919static
921 SCIP* scip, /**< SCIP data structure */
922 SCIP_CONS* cons, /**< linear constraint */
923 SCIP_SOL* sol, /**< solution to print */
924 SCIP_Bool useexactsol, /**< should the exact sol be used */
925 FILE* file /**< output file (or NULL for standard output) */
926 )
927{
928 SCIP_CONSDATA* consdata;
929
930 assert(scip != NULL);
931 assert(cons != NULL);
932
933 consdata = SCIPconsGetData(cons);
934 assert(consdata != NULL);
935
937
938 /* print left hand side for ranged rows */
939 /* print left hand side for ranged rows */
940 if( !SCIPrationalIsNegInfinity(consdata->lhs)
941 && !SCIPrationalIsInfinity(consdata->rhs)
942 && !SCIPrationalIsEQ(consdata->lhs, consdata->rhs) )
943 {
944 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->lhs);
945 SCIPinfoMessage(scip, file, " <= ");
946 }
947
948 /* print coefficients and variables */
949 if( consdata->nvars == 0 )
950 SCIPinfoMessage(scip, file, "0");
951 else
952 {
953 int v;
954
955 /* post linear sum of the linear constraint */
956 for( v = 0; v < consdata->nvars; ++v )
957 {
958 if( consdata->vals != NULL )
959 {
960 if( SCIPrationalIsEQReal(consdata->vals[v], 1.0) )
961 {
962 if( v > 0 )
963 SCIPinfoMessage(scip, file, " +");
964 }
965 else if( SCIPrationalIsEQReal(consdata->vals[v], -1.0) )
966 SCIPinfoMessage(scip, file, " -");
967 else
968 {
969 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->vals[v]);
970 }
971 }
972 else if( consdata->nvars > 0 )
973 SCIPinfoMessage(scip, file, " +");
974
975 /* print variable name */
976 SCIP_CALL( SCIPwriteVarName(scip, file, consdata->vars[v], TRUE) );
977
978 if( sol != NULL )
979 {
980 SCIPinfoMessage(scip, file, " (");
981 if( useexactsol )
982 {
983 SCIP_RATIONAL* tmp;
985 SCIPgetSolValExact(scip, sol, consdata->vars[v], tmp);
988 }
989 else
990 SCIPinfoMessage(scip, file, "%+.9g", SCIPgetSolVal(scip, sol, consdata->vars[v]));
991 SCIPinfoMessage(scip, file, ")");
992 }
993 }
994 }
995
996 /* print right hand side */
997 if( SCIPrationalIsEQ(consdata->lhs, consdata->rhs) )
998 {
999 SCIPinfoMessage(scip, file, " == ");
1000 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->lhs);
1001 }
1002 else if( !SCIPrationalIsInfinity(consdata->rhs) )
1003 {
1004 SCIPinfoMessage(scip, file, " <= ");
1005 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->rhs);
1006 }
1007 else if( !SCIPrationalIsNegInfinity(consdata->lhs) )
1008 {
1009 SCIPinfoMessage(scip, file, " >= ");
1010 SCIPrationalMessage(SCIPgetMessagehdlr(scip), file, consdata->lhs);
1011 }
1012 else
1013 SCIPinfoMessage(scip, file, " [free]");
1014
1015 SCIPinfoMessage(scip, file, ";\n");
1016
1017 return SCIP_OKAY;
1018}
1019
1020/** invalidates activity bounds, such that they are recalculated in next get */
1021static
1023 SCIP_CONSDATA* consdata /**< linear constraint */
1024 )
1025{
1026 assert(consdata != NULL);
1027
1028 consdata->validactivities = FALSE;
1029 consdata->validminact = FALSE;
1030 consdata->validmaxact = FALSE;
1031 consdata->validglbminact = FALSE;
1032 consdata->validglbmaxact = FALSE;
1033 consdata->validmaxabsval = FALSE;
1034 consdata->validminabsval = FALSE;
1035 consdata->hasnonbinvalid = FALSE;
1036 consdata->minactivity = SCIP_INVALID;
1037 consdata->maxactivity = SCIP_INVALID;
1038 consdata->lastminactivity = SCIP_INVALID;
1039 consdata->lastmaxactivity = SCIP_INVALID;
1040 consdata->maxabsval = SCIP_INVALID;
1041 consdata->minabsval = SCIP_INVALID;
1042 consdata->maxactdelta = SCIP_INVALID;
1043 SCIPrationalSetInfinity(consdata->maxabsvalexact);
1044 SCIPrationalSetInfinity(consdata->minabsvalexact);
1045 consdata->maxactdeltavar = NULL;
1046 consdata->minactivityneginf = -1;
1047 consdata->minactivityposinf = -1;
1048 consdata->maxactivityneginf = -1;
1049 consdata->maxactivityposinf = -1;
1050 consdata->minactivityneghuge = -1;
1051 consdata->minactivityposhuge = -1;
1052 consdata->maxactivityneghuge = -1;
1053 consdata->maxactivityposhuge = -1;
1054 consdata->glbminactivity = SCIP_INVALID;
1055 consdata->glbmaxactivity = SCIP_INVALID;
1056 consdata->lastglbminactivity = SCIP_INVALID;
1057 consdata->lastglbmaxactivity = SCIP_INVALID;
1058 consdata->glbminactivityneginf = -1;
1059 consdata->glbminactivityposinf = -1;
1060 consdata->glbmaxactivityneginf = -1;
1061 consdata->glbmaxactivityposinf = -1;
1062 consdata->glbminactivityneghuge = -1;
1063 consdata->glbminactivityposhuge = -1;
1064 consdata->glbmaxactivityneghuge = -1;
1065 consdata->glbmaxactivityposhuge = -1;
1066}
1067
1068/** computes the pseudo activity of a constraint */
1069static
1071 SCIP_CONSDATA* consdata, /**< linear constraint data */
1072 SCIP_RATIONAL* pseudoactivity /**< buffer to store pseudoactivity */
1073 )
1074{
1075 int i;
1076 int pseudoactivityposinf;
1077 int pseudoactivityneginf;
1079 SCIP_RATIONAL* val;
1080
1081 SCIPrationalSetFraction(pseudoactivity, 0LL, 1LL);
1082
1083 pseudoactivityposinf = 0;
1084 pseudoactivityneginf = 0;
1085
1086 for( i = consdata->nvars - 1; i >= 0; --i )
1087 {
1088 bound = SCIPvarGetBestBoundLocalExact(consdata->vars[i]);
1089 val = consdata->vals[i];
1091
1093 {
1094 if( SCIPrationalIsNegative(val) )
1095 ++pseudoactivityposinf;
1096 else
1097 ++pseudoactivityneginf;
1098 }
1099 else if( SCIPrationalIsInfinity(bound) )
1100 {
1101 if( SCIPrationalIsNegative(val) )
1102 ++pseudoactivityneginf;
1103 else
1104 ++pseudoactivityposinf;
1105 }
1106 else
1107 SCIPrationalAddProd(pseudoactivity, val, bound);
1108 }
1109
1110 /* set pseudo activity to infeasible infinity for contradicting contributions */
1111 if( pseudoactivityneginf > 0 && ( pseudoactivityposinf == 0 || !SCIPrationalIsNegInfinity(consdata->lhs) ) )
1112 SCIPrationalSetNegInfinity(pseudoactivity);
1113 else if( pseudoactivityposinf > 0 && ( pseudoactivityneginf == 0 || !SCIPrationalIsInfinity(consdata->rhs) ) )
1114 SCIPrationalSetInfinity(pseudoactivity);
1115}
1116
1117/** recompute the minactivity of a constraint */
1118static
1120 SCIP* scip, /**< SCIP data structure */
1121 SCIP_CONSDATA* consdata /**< linear constraint data */
1122 )
1123{
1124 SCIP_ROUNDMODE prevmode;
1125 SCIP_Real contribution;
1126 int i;
1127
1128 consdata->minactivity = 0.0;
1129 prevmode = SCIPintervalGetRoundingMode();
1131
1132 for( i = consdata->nvars - 1; i >= 0; --i )
1133 {
1134 if( consdata->valsreal[i].sup < 0.0 )
1135 {
1136 assert(consdata->valsreal[i].inf <= 0.0);
1137
1138 contribution = SCIPvarGetUbLocal(consdata->vars[i]);
1139
1140 if( SCIPisInfinity(scip, contribution) )
1141 continue;
1142 }
1143 else
1144 {
1145 assert(consdata->valsreal[i].inf >= 0.0);
1146
1147 contribution = SCIPvarGetLbLocal(consdata->vars[i]);
1148
1149 if( SCIPisInfinity(scip, -contribution) )
1150 continue;
1151 }
1152
1153 contribution *= contribution < 0.0 ? consdata->valsreal[i].sup : consdata->valsreal[i].inf;
1154
1155 if( SCIPisHugeValue(scip, REALABS(contribution)) )
1156 continue;
1157
1158 consdata->minactivity += contribution;
1159 }
1160
1161 /* the activity was just computed from scratch and is valid now */
1162 consdata->validminact = TRUE;
1163
1164 /* the activity was just computed from scratch, mark it to be reliable */
1165 consdata->lastminactivity = consdata->minactivity;
1167}
1168
1169/** recompute the maxactivity of a constraint */
1170static
1172 SCIP* scip, /**< SCIP data structure */
1173 SCIP_CONSDATA* consdata /**< linear constraint data */
1174 )
1175{
1176 SCIP_ROUNDMODE prevmode;
1177 SCIP_Real contribution;
1178 int i;
1179
1180 consdata->maxactivity = 0.0;
1181 prevmode = SCIPintervalGetRoundingMode();
1183
1184 for( i = consdata->nvars - 1; i >= 0; --i )
1185 {
1186 if( consdata->valsreal[i].sup < 0.0 )
1187 {
1188 assert(consdata->valsreal[i].inf <= 0.0);
1189
1190 contribution = SCIPvarGetLbLocal(consdata->vars[i]);
1191
1192 if( SCIPisInfinity(scip, -contribution) )
1193 continue;
1194 }
1195 else
1196 {
1197 assert(consdata->valsreal[i].inf >= 0.0);
1198
1199 contribution = SCIPvarGetUbLocal(consdata->vars[i]);
1200
1201 if( SCIPisInfinity(scip, contribution) )
1202 continue;
1203 }
1204
1205 contribution *= contribution < 0.0 ? consdata->valsreal[i].inf : consdata->valsreal[i].sup;
1206
1207 if( SCIPisHugeValue(scip, REALABS(contribution)) )
1208 continue;
1209
1210 consdata->maxactivity += contribution;
1211 }
1212
1213 /* the activity was just computed from scratch and is valid now */
1214 consdata->validmaxact = TRUE;
1215
1216 /* the activity was just computed from scratch, mark it to be reliable */
1217 consdata->lastmaxactivity = consdata->maxactivity;
1218
1220}
1221
1222/** recompute the global minactivity of a constraint */
1223static
1225 SCIP* scip, /**< SCIP data structure */
1226 SCIP_CONSDATA* consdata /**< linear constraint data */
1227 )
1228{
1229 SCIP_ROUNDMODE prevmode;
1230 SCIP_Real contribution;
1231 int i;
1232
1233 consdata->glbminactivity = 0.0;
1234 prevmode = SCIPintervalGetRoundingMode();
1236
1237 for( i = consdata->nvars - 1; i >= 0; --i )
1238 {
1239 if( consdata->valsreal[i].sup < 0.0 )
1240 {
1241 assert(consdata->valsreal[i].inf <= 0.0);
1242
1243 contribution = SCIPvarGetUbGlobal(consdata->vars[i]);
1244
1245 if( SCIPisInfinity(scip, contribution) )
1246 continue;
1247 }
1248 else
1249 {
1250 assert(consdata->valsreal[i].inf >= 0.0);
1251
1252 contribution = SCIPvarGetLbGlobal(consdata->vars[i]);
1253
1254 if( SCIPisInfinity(scip, -contribution) )
1255 continue;
1256 }
1257
1258 contribution *= contribution < 0.0 ? consdata->valsreal[i].sup : consdata->valsreal[i].inf;
1259
1260 if( SCIPisHugeValue(scip, REALABS(contribution)) )
1261 continue;
1262
1263 consdata->glbminactivity += contribution;
1264 }
1265
1266 /* the activity was just computed from scratch and is valid now */
1267 consdata->validglbminact = TRUE;
1268
1269 /* the activity was just computed from scratch, mark it to be reliable */
1270 consdata->lastglbminactivity = consdata->glbminactivity;
1271
1273}
1274
1275/** recompute the global maxactivity of a constraint */
1276static
1278 SCIP* scip, /**< SCIP data structure */
1279 SCIP_CONSDATA* consdata /**< linear constraint data */
1280 )
1281{
1282 SCIP_ROUNDMODE prevmode;
1283 SCIP_Real contribution;
1284 int i;
1285
1286 consdata->glbmaxactivity = 0.0;
1287 prevmode = SCIPintervalGetRoundingMode();
1289
1290 for( i = consdata->nvars - 1; i >= 0; --i )
1291 {
1292 if( consdata->valsreal[i].sup < 0.0 )
1293 {
1294 assert(consdata->valsreal[i].inf <= 0.0);
1295
1296 contribution = SCIPvarGetLbGlobal(consdata->vars[i]);
1297
1298 if( SCIPisInfinity(scip, -contribution) )
1299 continue;
1300 }
1301 else
1302 {
1303 assert(consdata->valsreal[i].inf >= 0.0);
1304
1305 contribution = SCIPvarGetUbGlobal(consdata->vars[i]);
1306
1307 if( SCIPisInfinity(scip, contribution) )
1308 continue;
1309 }
1310
1311 contribution *= contribution < 0.0 ? consdata->valsreal[i].inf : consdata->valsreal[i].sup;
1312
1313 if( SCIPisHugeValue(scip, REALABS(contribution)) )
1314 continue;
1315
1316 consdata->glbmaxactivity += contribution;
1317 }
1318
1319 /* the activity was just computed from scratch and is valid now */
1320 consdata->validglbmaxact = TRUE;
1321
1322 /* the activity was just computed from scratch, mark it to be reliable */
1323 consdata->lastglbmaxactivity = consdata->glbmaxactivity;
1325}
1326
1327/** calculates minimum absolute value of coefficients */
1328static
1330 SCIP_CONSDATA* consdata /**< linear constraint data */
1331 )
1332{
1333 int i;
1334 assert(consdata != NULL);
1335 assert(!consdata->validminabsval);
1336
1337 consdata->validminabsval = TRUE;
1338
1339 if( consdata->nvars > 0 )
1340 {
1341 SCIPrationalAbs(consdata->minabsvalexact, consdata->vals[0]);
1342 assert(!SCIPrationalIsZero(consdata->vals[0]));
1343 }
1344 else
1345 SCIPrationalSetReal(consdata->minabsvalexact, 0.0);
1346
1347 for( i = 1; i < consdata->nvars; ++i )
1348 {
1349 assert(!SCIPrationalIsZero(consdata->vals[i]));
1350
1351 if( SCIPrationalIsAbsGT(consdata->minabsvalexact, consdata->vals[i]) )
1352 SCIPrationalAbs(consdata->minabsvalexact, consdata->vals[i]);
1353 }
1354}
1355
1356/** checks the type of all variables of the constraint and sets hasnonbinvar and hascontvar flags accordingly */
1357static
1359 SCIP_CONSDATA* consdata /**< linear constraint data */
1360 )
1361{
1362 int v;
1363
1364 assert(!consdata->hasnonbinvalid);
1365 consdata->hasnonbinvar = FALSE;
1366 consdata->hascontvar = FALSE;
1367
1368 for( v = consdata->nvars - 1; v >= 0; --v )
1369 {
1370 SCIP_VARTYPE vartype = SCIPvarGetType(consdata->vars[v]);
1371
1372 if( vartype != SCIP_VARTYPE_BINARY )
1373 {
1374 consdata->hasnonbinvar = TRUE;
1375
1376 if( vartype == SCIP_VARTYPE_CONTINUOUS )
1377 {
1378 consdata->hascontvar = TRUE;
1379 break;
1380 }
1381 }
1382 }
1383 assert(consdata->hascontvar || v < 0);
1384
1385 consdata->hasnonbinvalid = TRUE;
1386}
1387
1388#ifdef SCIP_MORE_DEBUG
1389/* checks that the stored maximal activity delta (if not invalid) is correct */
1390static
1392 SCIP* scip, /**< SCIP data structure */
1393 SCIP_CONSDATA* consdata /**< linear constraint data */
1394 )
1395{
1396 if( consdata->maxactdelta != SCIP_INVALID )
1397 {
1398 SCIP_Rational* maxactdelta;
1399 SCIP_Rational* domain;
1400 SCIP_Rational* delta;
1401 SCIP_RATIONAL* lb;
1402 SCIP_RATIONAL* ub;
1403 int v;
1404
1408
1409 for( v = consdata->nvars - 1; v >= 0; --v )
1410 {
1411 lb = SCIPvarGetLbLocalExact(consdata->vars[v]);
1412 ub = SCIPvarGetUbLocalExact(consdata->vars[v]);
1413
1415 {
1416 SCIPrationalSetInfinity(maxactdelta);
1417 break;
1418 }
1419
1420 SCIPrationalDiff(domain, ub, lb);
1421 SCIPrationalAbs(delta, consdata->vals[v]);
1422 SCIPrationalMult(delta, delta, domain);
1423
1424 if( SCIPrationalisGT(delta,maxactdelta) )
1425 {
1426 SCIPrationalSetRational(maxactdelta, delta);
1427 }
1428 }
1429 assert(SCIPrationalIsEQ(maxactdelta, consdata->maxactdelta));
1430
1433 SCIPrationalFreeBuffer(SCIPbuffer(scip), maxactdelta);
1434 }
1435}
1436#else
1437#define checkMaxActivityDelta(scip, consdata) /**/
1438#endif
1439
1440/** recompute maximal activity contribution for a single variable */
1441static
1443 SCIP* scip, /**< SCIP data structure */
1444 SCIP_CONSDATA* consdata /**< linear constraint data */
1445 )
1446{
1447 SCIP_Real delta;
1448 int v;
1449 consdata->maxactdelta = 0.0;
1450
1451 if( !consdata->hasnonbinvalid )
1452 consdataCheckNonbinvar(consdata);
1453
1454 /* easy case, the problem consists only of binary variables */
1455 if( !consdata->hasnonbinvar )
1456 {
1457 for( v = consdata->nvars - 1; v >= 0; --v )
1458 {
1459 if( SCIPvarGetLbLocal(consdata->vars[v]) < 0.5 && SCIPvarGetUbLocal(consdata->vars[v]) > 0.5 )
1460 {
1461 delta = SCIPintervalAbsMax(consdata->valsreal[v]);
1462
1463 if( delta > consdata->maxactdelta )
1464 {
1465 consdata->maxactdelta = delta;
1466 consdata->maxactdeltavar = consdata->vars[v];
1467 }
1468 }
1469 }
1470 return;
1471 }
1472
1473 for( v = consdata->nvars - 1; v >= 0; --v )
1474 {
1475 SCIP_Real domain;
1476 SCIP_Real lb;
1477 SCIP_Real ub;
1478
1479 lb = SCIPvarGetLbLocal(consdata->vars[v]);
1480 ub = SCIPvarGetUbLocal(consdata->vars[v]);
1481
1482 if( SCIPisInfinity(scip, -lb) || SCIPisInfinity(scip, ub) )
1483 {
1484 consdata->maxactdelta = SCIPinfinity(scip);
1485 consdata->maxactdeltavar = consdata->vars[v];
1486 break;
1487 }
1488
1489 domain = ub - lb;
1490 delta = SCIPintervalAbsMax(consdata->valsreal[v]) * domain;
1491
1492 if( delta > consdata->maxactdelta )
1493 {
1494 consdata->maxactdelta = delta;
1495 consdata->maxactdeltavar = consdata->vars[v];
1496 }
1497 }
1498}
1499
1500/** updates activities for a change in a bound */
1501static
1503 SCIP* scip, /**< SCIP data structure */
1504 SCIP_CONSDATA* consdata, /**< linear constraint data */
1505 SCIP_VAR* var, /**< variable that has been changed; can be NULL for global bound changes */
1506 SCIP_Real oldbound, /**< old bound of variable */
1507 SCIP_Real newbound, /**< new bound of variable */
1508 SCIP_INTERVAL valrange, /**< coefficient of constraint entry */
1509 SCIP_BOUNDTYPE boundtype, /**< type of the bound change */
1510 SCIP_Bool global /**< is it a global or a local bound change? */
1511 )
1512{
1513 SCIP_Real* activity;
1514 SCIP_Real* lastactivity;
1515 int* activityposinf;
1516 int* activityneginf;
1517 int* activityposhuge;
1518 int* activityneghuge;
1519 SCIP_Real oldcontribution;
1520 SCIP_Real newcontribution;
1521 SCIP_Real delta;
1522 SCIP_Bool validact;
1523 SCIP_Bool finitenewbound;
1524 SCIP_Bool hugevalnewcont;
1525 SCIP_Real oldval;
1526 SCIP_Real newval;
1527 SCIP_ROUNDMODE prevmode;
1528
1529 prevmode = SCIPintervalGetRoundingMode();
1530
1531 assert(scip != NULL);
1532 assert(consdata != NULL);
1533 assert(global || (var != NULL));
1534 assert(consdata->validactivities);
1535 assert(consdata->minactivity < SCIP_INVALID);
1536 assert(consdata->maxactivity < SCIP_INVALID);
1537 assert(consdata->lastminactivity < SCIP_INVALID);
1538 assert(consdata->lastmaxactivity < SCIP_INVALID);
1539 assert(consdata->minactivityneginf >= 0);
1540 assert(consdata->minactivityposinf >= 0);
1541 assert(consdata->maxactivityneginf >= 0);
1542 assert(consdata->maxactivityposinf >= 0);
1543 assert(consdata->minactivityneghuge >= 0);
1544 assert(consdata->minactivityposhuge >= 0);
1545 assert(consdata->maxactivityneghuge >= 0);
1546 assert(consdata->maxactivityposhuge >= 0);
1547 assert(consdata->glbminactivity < SCIP_INVALID);
1548 assert(consdata->glbmaxactivity < SCIP_INVALID);
1549 assert(consdata->lastglbminactivity < SCIP_INVALID);
1550 assert(consdata->lastglbmaxactivity < SCIP_INVALID);
1551 assert(consdata->glbminactivityneginf >= 0);
1552 assert(consdata->glbminactivityposinf >= 0);
1553 assert(consdata->glbmaxactivityneginf >= 0);
1554 assert(consdata->glbmaxactivityposinf >= 0);
1555 assert(consdata->glbminactivityneghuge >= 0);
1556 assert(consdata->glbminactivityposhuge >= 0);
1557 assert(consdata->glbmaxactivityneghuge >= 0);
1558 assert(consdata->glbmaxactivityposhuge >= 0);
1559
1560 delta = 0.0;
1561
1562 /* we are updating global activities */
1563 if( global )
1564 {
1565 /* depending on the boundtype and the coefficient, we choose the activity to be updated:
1566 * lower bound + pos. coef: update minactivity
1567 * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
1568 * upper bound + pos. coef: update maxactivity
1569 * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
1570 */
1571 if( boundtype == SCIP_BOUNDTYPE_LOWER )
1572 {
1573 if( valrange.sup < 0.0 )
1574 {
1575 assert(valrange.inf <= 0.0);
1576
1577 activity = &(consdata->glbmaxactivity);
1578 lastactivity = &(consdata->lastglbmaxactivity);
1579 activityposinf = &(consdata->glbmaxactivityneginf);
1580 activityneginf = &(consdata->glbmaxactivityposinf);
1581 activityposhuge = &(consdata->glbmaxactivityposhuge);
1582 activityneghuge = &(consdata->glbmaxactivityneghuge);
1583 validact = consdata->validglbmaxact;
1585 oldval = oldbound < 0.0 ? valrange.inf : valrange.sup;
1586 newval = newbound < 0.0 ? valrange.inf : valrange.sup;
1587 }
1588 else
1589 {
1590 assert(valrange.inf >= 0.0);
1591
1592 activity = &(consdata->glbminactivity);
1593 lastactivity = &(consdata->lastglbminactivity);
1594 activityposinf = &(consdata->glbminactivityposinf);
1595 activityneginf = &(consdata->glbminactivityneginf);
1596 activityposhuge = &(consdata->glbminactivityposhuge);
1597 activityneghuge = &(consdata->glbminactivityneghuge);
1598 validact = consdata->validglbminact;
1600 oldval = oldbound < 0.0 ? valrange.sup : valrange.inf;
1601 newval = newbound < 0.0 ? valrange.sup : valrange.inf;
1602 }
1603 }
1604 else
1605 {
1606 if( valrange.sup < 0.0 )
1607 {
1608 assert(valrange.inf <= 0.0);
1609
1610 activity = &(consdata->glbminactivity);
1611 lastactivity = &(consdata->lastglbminactivity);
1612 activityposinf = &(consdata->glbminactivityneginf);
1613 activityneginf = &(consdata->glbminactivityposinf);
1614 activityposhuge = &(consdata->glbminactivityposhuge);
1615 activityneghuge = &(consdata->glbminactivityneghuge);
1616 validact = consdata->validglbminact;
1618 oldval = oldbound < 0.0 ? valrange.sup : valrange.inf;
1619 newval = newbound < 0.0 ? valrange.sup : valrange.inf;
1620 }
1621 else
1622 {
1623 assert(valrange.inf >= 0.0);
1624
1625 activity = &(consdata->glbmaxactivity);
1626 lastactivity = &(consdata->lastglbmaxactivity);
1627 activityposinf = &(consdata->glbmaxactivityposinf);
1628 activityneginf = &(consdata->glbmaxactivityneginf);
1629 activityposhuge = &(consdata->glbmaxactivityposhuge);
1630 activityneghuge = &(consdata->glbmaxactivityneghuge);
1631 validact = consdata->validglbmaxact;
1633 oldval = oldbound < 0.0 ? valrange.inf : valrange.sup;
1634 newval = newbound < 0.0 ? valrange.inf : valrange.sup;
1635 }
1636 }
1637 }
1638 /* we are updating local activities */
1639 else
1640 {
1641 /* depending on the boundtype and the coefficient, we choose the activity to be updated:
1642 * lower bound + pos. coef: update minactivity
1643 * lower bound + neg. coef: update maxactivity, positive and negative infinity counters have to be switched
1644 * upper bound + pos. coef: update maxactivity
1645 * upper bound + neg. coef: update minactivity, positive and negative infinity counters have to be switched
1646 */
1647 if( boundtype == SCIP_BOUNDTYPE_LOWER )
1648 {
1649 if( valrange.sup < 0.0 )
1650 {
1651 assert(valrange.inf <= 0.0);
1652
1653 activity = &(consdata->maxactivity);
1654 lastactivity = &(consdata->lastmaxactivity);
1655 activityposinf = &(consdata->maxactivityneginf);
1656 activityneginf = &(consdata->maxactivityposinf);
1657 activityposhuge = &(consdata->maxactivityposhuge);
1658 activityneghuge = &(consdata->maxactivityneghuge);
1659 validact = consdata->validmaxact;
1661 oldval = oldbound < 0.0 ? valrange.inf : valrange.sup;
1662 newval = newbound < 0.0 ? valrange.inf : valrange.sup;
1663 }
1664 else
1665 {
1666 assert(valrange.inf >= 0.0);
1667
1668 activity = &(consdata->minactivity);
1669 lastactivity = &(consdata->lastminactivity);
1670 activityposinf = &(consdata->minactivityposinf);
1671 activityneginf = &(consdata->minactivityneginf);
1672 activityposhuge = &(consdata->minactivityposhuge);
1673 activityneghuge = &(consdata->minactivityneghuge);
1674 validact = consdata->validminact;
1676 oldval = oldbound < 0.0 ? valrange.sup : valrange.inf;
1677 newval = newbound < 0.0 ? valrange.sup : valrange.inf;
1678 }
1679 }
1680 else
1681 {
1682 if( valrange.sup < 0.0 )
1683 {
1684 assert(valrange.inf <= 0.0);
1685
1686 activity = &(consdata->minactivity);
1687 lastactivity = &(consdata->lastminactivity);
1688 activityposinf = &(consdata->minactivityneginf);
1689 activityneginf = &(consdata->minactivityposinf);
1690 activityposhuge = &(consdata->minactivityposhuge);
1691 activityneghuge = &(consdata->minactivityneghuge);
1692 validact = consdata->validminact;
1694 oldval = oldbound < 0.0 ? valrange.sup : valrange.inf;
1695 newval = newbound < 0.0 ? valrange.sup : valrange.inf;
1696 }
1697 else
1698 {
1699 assert(valrange.inf >= 0.0);
1700
1701 activity = &(consdata->maxactivity);
1702 lastactivity = &(consdata->lastmaxactivity);
1703 activityposinf = &(consdata->maxactivityposinf);
1704 activityneginf = &(consdata->maxactivityneginf);
1705 activityposhuge = &(consdata->maxactivityposhuge);
1706 activityneghuge = &(consdata->maxactivityneghuge);
1707 validact = consdata->validmaxact;
1709 oldval = oldbound < 0.0 ? valrange.inf : valrange.sup;
1710 newval = newbound < 0.0 ? valrange.inf : valrange.sup;
1711 }
1712 }
1713 }
1714
1715 oldcontribution = SCIPintervalNegateReal(oldval) * oldbound;
1716 newcontribution = newval * newbound;
1717 hugevalnewcont = SCIPisHugeValue(scip, REALABS(newcontribution));
1718 finitenewbound = !SCIPisInfinity(scip, REALABS(newbound));
1719
1720 if( SCIPisInfinity(scip, REALABS(oldbound)) )
1721 {
1722 /* old bound was +infinity */
1723 if( oldbound > 0.0 )
1724 {
1725 assert((*activityposinf) >= 1);
1726
1727 /* we only have to do something if the new bound is not again +infinity */
1728 if( finitenewbound || newbound < 0.0 )
1729 {
1730 /* decrease the counter for positive infinite contributions */
1731 (*activityposinf)--;
1732
1733 /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1734 if( !finitenewbound && newbound < 0.0 )
1735 (*activityneginf)++;
1736 else if( hugevalnewcont )
1737 {
1738 /* if the contribution of this variable is too large, increase the counter for huge values */
1739 if( newcontribution > 0.0 )
1740 (*activityposhuge)++;
1741 else
1742 (*activityneghuge)++;
1743 }
1744 /* "normal case": just add the contribution to the activity */
1745 else
1746 delta = newcontribution;
1747 }
1748 }
1749 /* old bound was -infinity */
1750 else
1751 {
1752 assert(oldbound < 0.0);
1753 assert((*activityneginf) >= 1);
1754
1755 /* we only have to do something ig the new bound is not again -infinity */
1756 if( finitenewbound || newbound > 0.0 )
1757 {
1758 /* decrease the counter for negative infinite contributions */
1759 (*activityneginf)--;
1760
1761 /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1762 if( !finitenewbound && newbound > 0.0 )
1763 (*activityposinf)++;
1764 else if( hugevalnewcont )
1765 {
1766 /* if the contribution of this variable is too large, increase the counter for huge values */
1767 if( newcontribution > 0.0 )
1768 (*activityposhuge)++;
1769 else
1770 (*activityneghuge)++;
1771 }
1772 /* "normal case": just add the contribution to the activity */
1773 else
1774 delta = newcontribution;
1775 }
1776 }
1777 }
1778 else if( SCIPisHugeValue(scip, REALABS(oldcontribution)) )
1779 {
1780 /* old contribution was too large and positive */
1781 if( -oldcontribution > 0.0 )
1782 {
1783 assert((*activityposhuge) >= 1);
1784
1785 /* decrease the counter for huge positive contributions; it might be increased again later,
1786 * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
1787 */
1788 (*activityposhuge)--;
1789
1790 if( !finitenewbound )
1791 {
1792 /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1793 if( newbound > 0.0 )
1794 (*activityposinf)++;
1795 /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1796 else
1797 (*activityneginf)++;
1798 }
1799 else if( hugevalnewcont )
1800 {
1801 /* if the contribution of this variable is too large and positive, increase the corresponding counter */
1802 if( newcontribution > 0.0 )
1803 (*activityposhuge)++;
1804 /* if the contribution of this variable is too large and negative, increase the corresponding counter */
1805 else
1806 (*activityneghuge)++;
1807 }
1808 /* "normal case": just add the contribution to the activity */
1809 else
1810 delta = newcontribution;
1811 }
1812 /* old contribution was too large and negative */
1813 else
1814 {
1815 assert(-oldcontribution < 0.0);
1816 assert((*activityneghuge) >= 1);
1817
1818 /* decrease the counter for huge negative contributions; it might be increased again later,
1819 * but checking here that the bound is not huge again would not handle a change from a huge to an infinite bound
1820 */
1821 (*activityneghuge)--;
1822
1823 if( !finitenewbound )
1824 {
1825 /* if the bound changed to +infinity, increase the counter for positive infinite contributions */
1826 if( newbound > 0.0 )
1827 (*activityposinf)++;
1828 /* if the bound changed to -infinity, increase the counter for negative infinite contributions */
1829 else
1830 (*activityneginf)++;
1831 }
1832 else if( hugevalnewcont )
1833 {
1834 /* if the contribution of this variable is too large and positive, increase the corresponding counter */
1835 if( newcontribution > 0.0 )
1836 (*activityposhuge)++;
1837 /* if the contribution of this variable is too large and negative, increase the corresponding counter */
1838 else
1839 (*activityneghuge)++;
1840 }
1841 /* "normal case": just add the contribution to the activity */
1842 else
1843 delta = newcontribution;
1844 }
1845 }
1846 /* old bound was finite and not too large */
1847 else
1848 {
1849 if( !finitenewbound )
1850 {
1851 /* if the new bound is +infinity, the old contribution has to be subtracted
1852 * and the counter for positive infinite contributions has to be increased
1853 */
1854 if( newbound > 0.0 )
1855 {
1856 (*activityposinf)++;
1857 delta = oldcontribution;
1858 }
1859 /* if the new bound is -infinity, the old contribution has to be subtracted
1860 * and the counter for negative infinite contributions has to be increased
1861 */
1862 else
1863 {
1864 assert(newbound < 0.0 );
1865
1866 (*activityneginf)++;
1867 delta = oldcontribution;
1868 }
1869 }
1870 /* if the contribution of this variable is too large, increase the counter for huge values */
1871 else if( hugevalnewcont )
1872 {
1873 if( newcontribution > 0.0 )
1874 {
1875 (*activityposhuge)++;
1876 delta = oldcontribution;
1877 }
1878 else
1879 {
1880 (*activityneghuge)++;
1881 delta = oldcontribution;
1882 }
1883 }
1884 /* "normal case": just update the activity */
1885 else
1886 delta = newcontribution + oldcontribution;
1887 }
1888
1889 /* update the activity, if the current value is valid and there was a change in the finite part */
1890 if( validact && (delta != 0.0) )
1891 {
1892 /* if the absolute value of the activity is increased, this is regarded as reliable,
1893 * otherwise, we check whether we can still trust the updated value
1894 */
1895 (*activity) = (*activity) + delta;
1896 assert(!SCIPisInfinity(scip, -(*activity)) && !SCIPisInfinity(scip, *activity));
1897
1898 if( REALABS((*lastactivity)) < REALABS(*activity) )
1899 {
1900 (*lastactivity) = (*activity);
1901 }
1902 }
1903
1905}
1906/** updates minimum and maximum activity for a change in lower bound */
1907static
1909 SCIP* scip, /**< SCIP data structure */
1910 SCIP_CONSDATA* consdata, /**< linear constraint data */
1911 SCIP_VAR* var, /**< variable that has been changed */
1912 SCIP_Real oldlb, /**< old lower bound of variable */
1913 SCIP_Real newlb, /**< new lower bound of variable */
1914 SCIP_INTERVAL val /**< coefficient of constraint entry */
1915 )
1916{
1917 assert(scip != NULL);
1918 assert(consdata != NULL);
1919 assert(var != NULL);
1920
1921 if( consdata->validactivities )
1922 {
1923 consdataUpdateActivities(scip, consdata, var, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, FALSE);
1924
1925 assert(!SCIPisInfinity(scip, -consdata->minactivity) && !SCIPisInfinity(scip, consdata->minactivity));
1926 assert(!SCIPisInfinity(scip, -consdata->maxactivity) && !SCIPisInfinity(scip, consdata->maxactivity));
1927 }
1928}
1929
1930/** updates minimum and maximum activity for a change in upper bound */
1931static
1933 SCIP* scip, /**< SCIP data structure */
1934 SCIP_CONSDATA* consdata, /**< linear constraint data */
1935 SCIP_VAR* var, /**< variable that has been changed */
1936 SCIP_Real oldub, /**< old upper bound of variable */
1937 SCIP_Real newub, /**< new upper bound of variable */
1938 SCIP_INTERVAL val /**< coefficient of constraint entry */
1939 )
1940{
1941 assert(scip != NULL);
1942 assert(consdata != NULL);
1943 assert(var != NULL);
1944
1945 if( consdata->validactivities )
1946 {
1947 consdataUpdateActivities(scip, consdata, var, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, FALSE);
1948
1949 assert(!SCIPisInfinity(scip, -consdata->minactivity) && !SCIPisInfinity(scip, consdata->minactivity));
1950 assert(!SCIPisInfinity(scip, -consdata->maxactivity) && !SCIPisInfinity(scip, consdata->maxactivity));
1951 }
1952}
1953
1954/** updates minimum and maximum global activity for a change in the global lower bound */
1955static
1957 SCIP* scip, /**< SCIP data structure */
1958 SCIP_CONSDATA* consdata, /**< linear constraint data */
1959 SCIP_Real oldlb, /**< old lower bound of variable */
1960 SCIP_Real newlb, /**< new lower bound of variable */
1961 SCIP_INTERVAL val /**< coefficient of constraint entry */
1962 )
1963{
1964 assert(scip != NULL);
1965 assert(consdata != NULL);
1966
1967 if( consdata->validactivities )
1968 {
1969 consdataUpdateActivities(scip, consdata, NULL, oldlb, newlb, val, SCIP_BOUNDTYPE_LOWER, TRUE);
1970
1971 assert(!SCIPisInfinity(scip, -consdata->glbminactivity) && !SCIPisInfinity(scip, consdata->glbminactivity));
1972 assert(!SCIPisInfinity(scip, -consdata->glbmaxactivity) && !SCIPisInfinity(scip, consdata->glbmaxactivity));
1973 }
1974}
1975
1976/** updates minimum and maximum global activity for a change in global upper bound */
1977static
1979 SCIP* scip, /**< SCIP data structure */
1980 SCIP_CONSDATA* consdata, /**< linear constraint data */
1981 SCIP_Real oldub, /**< old upper bound of variable */
1982 SCIP_Real newub, /**< new upper bound of variable */
1983 SCIP_INTERVAL val /**< coefficient of constraint entry */
1984 )
1985{
1986 assert(scip != NULL);
1987 assert(consdata != NULL);
1988
1989 if( consdata->validactivities )
1990 {
1991 consdataUpdateActivities(scip, consdata, NULL, oldub, newub, val, SCIP_BOUNDTYPE_UPPER, TRUE);
1992
1993 assert(!SCIPisInfinity(scip, -consdata->glbminactivity) && !SCIPisInfinity(scip, consdata->glbminactivity));
1994 assert(!SCIPisInfinity(scip, -consdata->glbmaxactivity) && !SCIPisInfinity(scip, consdata->glbmaxactivity));
1995 }
1996}
1997
1998/** updates minimum and maximum activity and maximum absolute value for coefficient addition */
1999static
2001 SCIP* scip, /**< SCIP data structure */
2002 SCIP_CONSDATA* consdata, /**< linear constraint data */
2003 SCIP_VAR* var, /**< variable of constraint entry */
2004 SCIP_RATIONAL* valExact, /**< coefficient of constraint entry */
2005 SCIP_INTERVAL val /**< coefficient of constraint entry */
2006 )
2007{
2008 assert(scip != NULL);
2009 assert(consdata != NULL);
2010 assert(var != NULL);
2011
2012 /* update maximum absolute value */
2013 if( consdata->validmaxabsval )
2014 {
2015 SCIP_Real absval;
2016
2017 assert(consdata->maxabsval < SCIP_INVALID);
2018
2019 absval = MAX(REALABS(val.inf), REALABS(val.sup)); /*lint !e777 !e666*/
2020 consdata->maxabsval = MAX(consdata->maxabsval, absval);
2021 }
2022
2023 if( consdata->validminabsval )
2024 {
2025 SCIP_Real absval;
2026
2027 assert(consdata->minabsval < SCIP_INVALID);
2028
2029 absval = MAX(REALABS(val.inf), REALABS(val.sup)); /*lint !e777 !e666*/
2030 consdata->minabsval = MIN(consdata->minabsval, absval);
2031 }
2032
2033 /* invalidate maximum absolute value, if this coefficient was the maximum */
2034 if( consdata->validmaxabsval )
2035 {
2036 if( SCIPrationalIsAbsEQ(valExact, consdata->maxabsvalexact) )
2037 {
2038 consdata->validmaxabsval = FALSE;
2039 SCIPrationalSetInfinity(consdata->maxabsvalexact);
2040 }
2041 }
2042
2043 /* invalidate minimum absolute value, if this coefficient was the minimum */
2044 if( consdata->validminabsval )
2045 {
2046 if( SCIPrationalIsAbsEQ(valExact, consdata->minabsvalexact) )
2047 {
2048 consdata->validminabsval = FALSE;
2049 SCIPrationalSetInfinity(consdata->minabsvalexact);
2050 }
2051 }
2052
2053 /* update minimal and maximal activity */
2054 if( consdata->validactivities )
2055 {
2056 assert(consdata->minactivity < SCIP_INVALID);
2057 assert(consdata->maxactivity < SCIP_INVALID);
2058 assert(consdata->glbminactivity < SCIP_INVALID);
2059 assert(consdata->glbmaxactivity < SCIP_INVALID);
2060
2065 }
2066}
2067
2068/** updates minimum and maximum activity for coefficient deletion, invalidates maximum absolute value if necessary */
2069static
2071 SCIP* scip, /**< SCIP data structure */
2072 SCIP_CONSDATA* consdata, /**< linear constraint data */
2073 SCIP_VAR* var, /**< variable of constraint entry */
2074 SCIP_RATIONAL* valExact, /**< exact coefficient of constraint entry */
2075 SCIP_INTERVAL val /**< coefficient of constraint entry */
2076 )
2077{
2078 assert(scip != NULL);
2079 assert(consdata != NULL);
2080 assert(var != NULL);
2081
2082 /* invalidate maximum absolute value, if this coefficient was the maximum */
2083 if( consdata->validmaxabsval )
2084 {
2085 SCIP_Real absval;
2086
2087 absval = SCIPintervalAbsMax(val);
2088
2089 if( SCIPisEQ(scip, absval, consdata->maxabsval) )
2090 {
2091 consdata->validmaxabsval = FALSE;
2092 consdata->maxabsval = SCIP_INVALID;
2093 }
2094 }
2095
2096 /* invalidate minimum absolute value, if this coefficient was the minimum */
2097 if( consdata->validminabsval )
2098 {
2099 SCIP_Real absval;
2100
2101 absval = SCIPintervalAbsMax(val);
2102
2103 if( SCIPisEQ(scip, absval, consdata->minabsval) )
2104 {
2105 consdata->validminabsval = FALSE;
2106 consdata->minabsval = SCIP_INVALID;
2107 }
2108 }
2109
2110 /* invalidate maximum absolute value, if this coefficient was the maximum */
2111 if( consdata->validmaxabsval )
2112 {
2113 if( SCIPrationalIsAbsEQ(valExact, consdata->maxabsvalexact) )
2114 {
2115 consdata->validmaxabsval = FALSE;
2116 SCIPrationalSetInfinity(consdata->maxabsvalexact);
2117 }
2118 }
2119
2120 /* invalidate minimum absolute value, if this coefficient was the minimum */
2121 if( consdata->validminabsval )
2122 {
2123 if( SCIPrationalIsAbsEQ(valExact, consdata->minabsvalexact) )
2124 {
2125 consdata->validminabsval = FALSE;
2126 SCIPrationalSetInfinity(consdata->minabsvalexact);
2127 }
2128 }
2129
2130 /* update minimal and maximal activity */
2131 if( consdata->validactivities )
2132 {
2133 assert(consdata->minactivity < SCIP_INVALID);
2134 assert(consdata->maxactivity < SCIP_INVALID);
2135 assert(consdata->glbminactivity < SCIP_INVALID);
2136 assert(consdata->glbmaxactivity < SCIP_INVALID);
2137
2142 }
2143}
2144
2145/** returns the minimum absolute value of all coefficients in the constraint */
2146static
2148 SCIP* scip, /**< SCIP data structure */
2149 SCIP_CONSDATA* consdata /**< linear constraint data */
2150 )
2151{
2152 assert(scip != NULL);
2153 assert(consdata != NULL);
2154
2155 if( !consdata->validminabsval )
2156 consdataCalcMinAbsvalEx(consdata);
2157 assert(consdata->validminabsval);
2158
2159 return consdata->minabsvalexact;
2160}
2161
2162
2163/** updates minimum and maximum activity for coefficient change, invalidates maximum absolute value if necessary */
2164static
2166 SCIP* scip, /**< SCIP data structure */
2167 SCIP_CONSDATA* consdata, /**< linear constraint data */
2168 SCIP_VAR* var, /**< variable of constraint entry */
2169 SCIP_INTERVAL oldval, /**< old coefficient of constraint entry */
2170 SCIP_RATIONAL* oldvalExact, /**< old exact coefficient of constraint entry */
2171 SCIP_INTERVAL newval, /**< new coefficient of constraint entry */
2172 SCIP_RATIONAL* newvalExact /**< new coefficient of constraint entry */
2173 )
2174{
2175 assert(scip != NULL);
2176 assert(consdata != NULL);
2177 assert(var != NULL);
2178
2179 /* update maximum absolute value */
2180 if( consdata->validmaxabsval )
2181 {
2182 SCIP_Real absval;
2183
2184 absval = SCIPintervalAbsMax(newval);
2185
2186 if( absval >= consdata->maxabsval )
2187 {
2188 consdata->maxabsval = absval;
2189 }
2190 else
2191 {
2192 absval = SCIPintervalAbsMax(oldval);
2193
2194 /* invalidate maximum absolute value */
2195 if( SCIPisEQ(scip, absval, consdata->maxabsval) )
2196 {
2197 consdata->validmaxabsval = FALSE;
2198 consdata->maxabsval = SCIP_INVALID;
2199 }
2200 }
2201 }
2202
2203 /* update minimum absolute value */
2204 if( consdata->validminabsval )
2205 {
2206 SCIP_Real absval;
2207
2208 absval = SCIPintervalAbsMax(newval);
2209
2210 if( absval <= consdata->minabsval )
2211 {
2212 consdata->minabsval = absval;
2213 }
2214 else
2215 {
2216 absval = SCIPintervalAbsMax(oldval);
2217
2218 /* invalidate minimum absolute value */
2219 if( SCIPisEQ(scip, absval, consdata->minabsval) )
2220 {
2221 consdata->validminabsval = FALSE;
2222 consdata->minabsval = SCIP_INVALID;
2223 }
2224 }
2225 }
2226 /* update maximum absolute value */
2227 if( consdata->validmaxabsval )
2228 {
2229 if( SCIPrationalIsAbsGT(newvalExact, consdata->maxabsvalexact) )
2230 {
2231 SCIPrationalAbs(consdata->maxabsvalexact, newvalExact);
2232 }
2233 else
2234 {
2235 /* invalidate maximum absolute value */
2236 if( SCIPrationalIsAbsEQ(oldvalExact, consdata->maxabsvalexact) )
2237 {
2238 consdata->validmaxabsval = FALSE;
2239 SCIPrationalSetInfinity(consdata->maxabsvalexact);
2240 }
2241 }
2242 }
2243 /* update minimum absolute value */
2244 if( consdata->validminabsval )
2245 {
2246 if( SCIPrationalIsAbsGT(consdata->minabsvalexact, newvalExact) )
2247 {
2248 SCIPrationalAbs(consdata->minabsvalexact, newvalExact);
2249 }
2250 else
2251 {
2252 /* invalidate minimum absolute value */
2253 if( SCIPrationalIsAbsEQ(oldvalExact, consdata->minabsvalexact) )
2254 {
2255 consdata->validminabsval = FALSE;
2256 SCIPrationalSetInfinity(consdata->minabsvalexact);
2257 }
2258 }
2259 }
2260
2261 /* update maximum activity delta */
2262 if( !SCIPisInfinity(scip, consdata->maxactdelta ) )
2263 {
2264 SCIP_Real domain;
2265 SCIP_Real delta;
2266
2269
2271 delta = SCIPintervalAbsMax(newval) * domain;
2272
2273 if( delta > consdata->maxactdelta )
2274 {
2275 consdata->maxactdelta = delta;
2276 consdata->maxactdeltavar = var;
2277 }
2278 else
2279 {
2280 /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
2281 if( consdata->maxactdeltavar == var )
2282 consdata->maxactdelta = SCIP_INVALID;
2283 }
2284 }
2285
2286 /* @todo as in cons_linear, do something more clever here, e.g. if oldval * newval >= 0, do the update directly */
2287 consdataUpdateDelCoef(scip, consdata, var, oldvalExact, oldval);
2288 consdataUpdateAddCoef(scip, consdata, var, newvalExact, newval);
2289}
2290
2291/** ensures that every nonzero is a least minval so that we don't get problem with SCIPs 0 in floating point representation */
2292static
2294 SCIP* scip, /**< SCIP data structure */
2295 SCIP_CONSDATA* consdata, /**< linear constraint data */
2296 SCIP_Real minval /**< minmimal value for coefficients in constraint */
2297 )
2298{
2299 int i;
2300 SCIP_RATIONAL* scalingfactor;
2301 SCIP_RATIONAL* minabsval;
2302
2303 assert(scip != NULL);
2304 assert(consdata != NULL);
2305
2306 minabsval = consdataGetMinAbsvalEx(scip, consdata);
2307
2308 assert(!SCIPrationalIsZero(minabsval) || consdata->nvars == 0);
2309
2310 (void) SCIPrationalCreateBuffer(SCIPbuffer(scip), &scalingfactor);
2311
2312 if( SCIPrationalIsLTReal(minabsval, minval) )
2313 {
2314 SCIPrationalSetReal(scalingfactor, minval);
2315 SCIPrationalDiv(scalingfactor, scalingfactor, minabsval);
2316
2317 for( i = 0; i < consdata->nvars; i++ )
2318 {
2319 SCIPrationalMult(consdata->vals[i], consdata->vals[i], scalingfactor);
2320 SCIPintervalSetRational(&(consdata->valsreal[i]), consdata->vals[i]);
2321 }
2322
2323 SCIPrationalMult(consdata->rhs, consdata->rhs, scalingfactor);
2324 consdata->rhsreal = SCIPrationalRoundReal(consdata->rhs, SCIP_R_ROUND_UPWARDS);
2325
2326 SCIPrationalMult(consdata->lhs, consdata->lhs, scalingfactor);
2327 consdata->lhsreal = SCIPrationalRoundReal(consdata->lhs, SCIP_R_ROUND_DOWNWARDS);
2328 }
2329
2331
2332 SCIPrationalFreeBuffer(SCIPbuffer(scip), &scalingfactor);
2333}
2334
2335/** calculates minimum and maximum local and global activity for constraint from scratch;
2336 * additionally recalculates maximum absolute value of coefficients
2337 */
2338static
2340 SCIP* scip, /**< SCIP data structure */
2341 SCIP_CONSDATA* consdata /**< linear constraint data */
2342 )
2343{
2344 int i;
2345 assert(scip != NULL);
2346 assert(consdata != NULL);
2347 assert(!consdata->validactivities);
2348 assert(consdata->minactivity >= SCIP_INVALID || consdata->validminact);
2349 assert(consdata->maxactivity >= SCIP_INVALID || consdata->validmaxact);
2350 assert(consdata->glbminactivity >= SCIP_INVALID || consdata->validglbminact);
2351 assert(consdata->glbmaxactivity >= SCIP_INVALID || consdata->validglbmaxact);
2352
2353 consdata->validmaxabsval = TRUE;
2354 consdata->validminabsval = TRUE;
2355 consdata->validactivities = TRUE;
2356 consdata->validminact = TRUE;
2357 consdata->validmaxact = TRUE;
2358 consdata->validglbminact = TRUE;
2359 consdata->validglbmaxact = TRUE;
2360 consdata->maxabsval = 0.0;
2361 consdata->minabsval = (consdata->nvars == 0 ? 0.0 : SCIPintervalAbsMax(consdata->valsreal[0]));
2362 consdata->minactivity = 0.0;
2363 consdata->maxactivity = 0.0;
2364 consdata->lastminactivity = 0.0;
2365 consdata->lastmaxactivity = 0.0;
2366 consdata->minactivityneginf = 0;
2367 consdata->minactivityposinf = 0;
2368 consdata->maxactivityneginf = 0;
2369 consdata->maxactivityposinf = 0;
2370 consdata->minactivityneghuge = 0;
2371 consdata->minactivityposhuge = 0;
2372 consdata->maxactivityneghuge = 0;
2373 consdata->maxactivityposhuge = 0;
2374 consdata->glbminactivity = 0.0;
2375 consdata->glbmaxactivity = 0.0;
2376 consdata->lastglbminactivity = 0.0;
2377 consdata->lastglbmaxactivity = 0.0;
2378 consdata->glbminactivityneginf = 0;
2379 consdata->glbminactivityposinf = 0;
2380 consdata->glbmaxactivityneginf = 0;
2381 consdata->glbmaxactivityposinf = 0;
2382 consdata->glbminactivityneghuge = 0;
2383 consdata->glbminactivityposhuge = 0;
2384 consdata->glbmaxactivityneghuge = 0;
2385 consdata->glbmaxactivityposhuge = 0;
2386
2387 for( i = 0; i < consdata->nvars; ++i )
2388 consdataUpdateAddCoef(scip, consdata, consdata->vars[i], consdata->vals[i], consdata->valsreal[i]);
2389 consdata->lastminactivity = consdata->minactivity;
2390 consdata->lastmaxactivity = consdata->maxactivity;
2391 consdata->lastglbminactivity = consdata->glbminactivity;
2392 consdata->lastglbmaxactivity = consdata->glbmaxactivity;
2393}
2394
2395/** computes the activity of a row for a given solution plus a bound on the floating-point error using running error analysis */
2396static
2398 SCIP* scip, /**< SCIP data structure */
2399 SCIP_CONSDATA* consdata, /**< linear constraint data */
2400 SCIP_SOL* sol, /**< primal CIP solution */
2401 SCIP_Real* activity, /**< buffer to return floating-point activity */
2402 SCIP_Real* errorbound /**< buffer to return bound on absolute floating-point error */
2403 )
2404{
2405 SCIP_Real solval;
2406 SCIP_Real sum;
2407 SCIP_Real mu;
2408 SCIP_Real inf;
2409 SCIP_Bool success;
2410 int v;
2411
2412 assert(activity != NULL);
2413 assert(errorbound != NULL);
2414
2415 inf = SCIPinfinity(scip);
2416 *activity = SCIP_UNKNOWN;
2417 *errorbound = inf;
2418
2419 sum = 0.0;
2420 mu = 0.0;
2421 /* normally we want to use the row since all fixed/aggregated variables do not appear there */
2422 if( consdata->rowlhs == NULL )
2423 {
2424 for( v = 0; v < consdata->nvars; ++v )
2425 {
2426 if( SCIPvarGetStatus(consdata->vars[v]) == SCIP_VARSTATUS_COLUMN || SCIPvarGetStatus(consdata->vars[v]) == SCIP_VARSTATUS_LOOSE )
2427 solval = SCIPgetSolVal(scip, sol, consdata->vars[v]);
2428 else
2429 return FALSE;
2430
2431 if( solval == SCIP_UNKNOWN ) /*lint !e777*/
2432 return FALSE;
2433
2434 sum += consdata->valsreal[v].inf * solval;
2435 mu += REALABS(sum);
2436 /* the factor 3 + eps is needed to account for rounding errors in valsreal[v]/solval */
2437 mu += (3.0 + SCIP_REAL_UNITROUNDOFF) * REALABS(consdata->valsreal[v].inf * solval);
2438 }
2439 }
2440 else
2441 {
2442 success = SCIPgetRowSolActivityWithErrorboundExact(scip, consdata->rowexact, sol, &sum, &mu);
2443
2444 if( !success )
2445 return FALSE;
2446 }
2447
2448 sum = MAX(sum, -inf);
2449 sum = MIN(sum, +inf);
2450 *activity = sum;
2451
2452 if( SCIPisInfinity(scip, sum) || SCIPisInfinity(scip, -sum) )
2453 *errorbound = inf;
2454 else
2455 *errorbound = mu * 1.1 * SCIP_REAL_UNITROUNDOFF;
2456
2457 return TRUE;
2458}
2459
2460/** gets minimal activity for constraint and given values of counters for infinite and huge contributions
2461 * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
2462 */
2463static
2465 SCIP* scip, /**< SCIP data structure */
2466 SCIP_CONSDATA* consdata, /**< linear constraint */
2467 int posinf, /**< number of coefficients contributing pos. infinite value */
2468 int neginf, /**< number of coefficients contributing neg. infinite value */
2469 int poshuge, /**< number of coefficients contributing huge pos. value */
2470 int neghuge, /**< number of coefficients contributing huge neg. value */
2471 SCIP_Real delta, /**< value to subtract from stored minactivity
2472 * (contribution of the variable set to zero when getting residual activity) */
2473 SCIP_Bool global, /**< should the global or local minimal activity be returned? */
2474 SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
2475 SCIP_Real* minactivity, /**< pointer to store the minimal activity */
2476 SCIP_Bool* isrelax, /**< pointer to store whether the activity is a relaxation,
2477 * i.e. is <= the exact minactivity (in case of huge contributing values) */
2478 SCIP_Bool* issettoinfinity /**< pointer to store whether minactivity was set to infinity or calculated */
2479 )
2480{
2481 assert(scip != NULL);
2482 assert(consdata != NULL);
2483 assert(posinf >= 0);
2484 assert(neginf >= 0);
2485 assert(poshuge >= 0);
2486 assert(neghuge >= 0);
2487 assert(minactivity != NULL);
2488 assert(isrelax != NULL);
2489 assert(issettoinfinity != NULL);
2490
2491 /* if we have pos. infinite contributions, the minactivity is +infty */
2492 if( posinf > 0 )
2493 {
2494 *minactivity = SCIPinfinity(scip);
2495 *issettoinfinity = TRUE;
2496 *isrelax = FALSE;
2497 }
2498 /* if we have neg. (and no pos.) infinite contributions, the minactivity is -infty */
2499 else if( neginf > 0 )
2500 {
2501 *minactivity = -SCIPinfinity(scip);
2502 *issettoinfinity = TRUE;
2503 *isrelax = FALSE;
2504 }
2505 /* if we have neg. huge contributions, we only know that -infty is a relaxation of the minactivity */
2506 else if( neghuge > 0 )
2507 {
2508 *minactivity = -SCIPinfinity(scip);
2509 *issettoinfinity = TRUE;
2510 *isrelax = TRUE;
2511 }
2512 /* we do not need a good relaxation and we have positive huge contributions, so we just return -infty as activity */
2513 else if( !goodrelax && poshuge > 0 )
2514 {
2515 *minactivity = -SCIPinfinity(scip);
2516 *issettoinfinity = TRUE;
2517 *isrelax = TRUE;
2518 }
2519 else
2520 {
2521 SCIP_Real tmpactivity;
2522
2523 /* recompute minactivity if it is not valid */
2524 if( global )
2525 {
2526 if( !consdata->validglbminact )
2528 assert(consdata->validglbminact);
2529
2530 tmpactivity = consdata->glbminactivity;
2531 }
2532 else
2533 {
2534 if( !consdata->validminact )
2536 assert(consdata->validminact);
2537
2538 tmpactivity = consdata->minactivity;
2539 }
2540
2541 /* we have no infinite and no neg. huge contributions, but pos. huge contributions;
2542 * a feasible relaxation of the minactivity is the number of positive huge contributions
2543 * times the minimum value counting as "huge" plus finite (and non-huge) part of minactivity - delta
2544 */
2545 if( poshuge > 0 )
2546 {
2547 *minactivity = 1.0 * poshuge * SCIPgetHugeValue(scip) + (tmpactivity - delta);
2548 *issettoinfinity = FALSE;
2549 *isrelax = TRUE;
2550 }
2551 /* all counters are zero, so the minactivity is just stored and we subtract the delta */
2552 else
2553 {
2554 *minactivity = tmpactivity - delta;
2555 *issettoinfinity = FALSE;
2556 *isrelax = FALSE;
2557 }
2558 }
2559}
2560
2561/** gets maximal activity for constraint and given values of counters for infinite and huge contributions
2562 * and (if needed) delta to subtract from stored finite part of activity in case of a residual activity
2563 */
2564static
2566 SCIP* scip, /**< SCIP data structure */
2567 SCIP_CONSDATA* consdata, /**< linear constraint */
2568 int posinf, /**< number of coefficients contributing pos. infinite value */
2569 int neginf, /**< number of coefficients contributing neg. infinite value */
2570 int poshuge, /**< number of coefficients contributing huge pos. value */
2571 int neghuge, /**< number of coefficients contributing huge neg. value */
2572 SCIP_Real delta, /**< value to subtract from stored maxactivity
2573 * (contribution of the variable set to zero when getting residual activity) */
2574 SCIP_Bool global, /**< should the global or local maximal activity be returned? */
2575 SCIP_Bool goodrelax, /**< should a good relaxation be computed or are relaxed acticities ignored, anyway? */
2576 SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
2577 SCIP_Bool* isrelax, /**< pointer to store whether the activity is a relaxation,
2578 * i.e. is >= the exact maxactivity (in case of huge contributing values) */
2579 SCIP_Bool* issettoinfinity /**< pointer to store whether maxactivity was set to infinity or calculated */
2580 )
2581{
2582 assert(scip != NULL);
2583 assert(consdata != NULL);
2584 assert(posinf >= 0);
2585 assert(neginf >= 0);
2586 assert(poshuge >= 0);
2587 assert(neghuge >= 0);
2588 assert(maxactivity != NULL);
2589 assert(isrelax != NULL);
2590 assert(issettoinfinity != NULL);
2591
2592 /* if we have neg. infinite contributions, the maxactivity is -infty */
2593 if( neginf > 0 )
2594 {
2595 *maxactivity = -SCIPinfinity(scip);
2596 *issettoinfinity = TRUE;
2597 *isrelax = FALSE;
2598 }
2599 /* if we have pos. (and no neg.) infinite contributions, the maxactivity is +infty */
2600 else if( posinf > 0 )
2601 {
2602 *maxactivity = SCIPinfinity(scip);
2603 *issettoinfinity = TRUE;
2604 *isrelax = FALSE;
2605 }
2606 /* if we have pos. huge contributions, we only know that +infty is a relaxation of the maxactivity */
2607 else if( poshuge > 0 )
2608 {
2609 *maxactivity = SCIPinfinity(scip);
2610 *issettoinfinity = TRUE;
2611 *isrelax = TRUE;
2612 }
2613 /* we do not need a good relaxation and we have positve huge contributions, so we just return +infty as activity */
2614 else if( !goodrelax && neghuge > 0 )
2615 {
2616 *maxactivity = SCIPinfinity(scip);
2617 *issettoinfinity = TRUE;
2618 *isrelax = TRUE;
2619 }
2620 else
2621 {
2622 SCIP_Real tmpactivity;
2623
2624 /* recompute maxactivity if it is not valid */
2625 if( global )
2626 {
2627 if( !consdata->validglbmaxact )
2629 assert(consdata->validglbmaxact);
2630
2631 tmpactivity = consdata->glbmaxactivity;
2632 }
2633 else
2634 {
2635 if( !consdata->validmaxact )
2637 assert(consdata->validmaxact);
2638
2639 tmpactivity = consdata->maxactivity;
2640 }
2641
2642 /* we have no infinite, and no pos. huge contributions, but neg. huge contributions;
2643 * a feasible relaxation of the maxactivity is minus the number of negative huge contributions
2644 * times the minimum value counting as "huge" plus the finite (and non-huge) part of maxactivity minus delta
2645 */
2646 if( neghuge > 0 )
2647 {
2648 *maxactivity = -1.0 * neghuge * SCIPgetHugeValue(scip) + tmpactivity - delta;
2649 *issettoinfinity = FALSE;
2650 *isrelax = TRUE;
2651 }
2652 /* all counters are zero, so the maxactivity is just stored and we subtract the delta */
2653 else
2654 {
2655 *maxactivity = tmpactivity - delta;
2656 *issettoinfinity = FALSE;
2657 *isrelax = FALSE;
2658 }
2659 }
2660}
2661
2662/** gets activity bounds for constraint */
2663static
2665 SCIP* scip, /**< SCIP data structure */
2666 SCIP_CONSDATA* consdata, /**< linear constraint */
2667 SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2668 * relaxed activities ignored, anyway? */
2669 SCIP_Real* minactivity, /**< pointer to store the minimal activity */
2670 SCIP_Real* maxactivity, /**< pointer to store the maximal activity */
2671 SCIP_Bool* minisrelax, /**< pointer to store whether the returned minactivity is just a relaxation,
2672 * i.e. <= the exact minactivity (in case of huge contributions),
2673 * or equal to the exact minimal activity */
2674 SCIP_Bool* maxisrelax, /**< pointer to store whether the returned maxactivity is just a relaxation,
2675 * i.e. >= the exact maxactivity (in case of huge contributions),
2676 * or equal to the exact maximal activity */
2677 SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minactivity was set to infinity or calculated */
2678 SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxactivity was set to infinity or calculated */
2679
2680 )
2681{
2682 assert(scip != NULL);
2683 assert(consdata != NULL);
2684 assert(minactivity != NULL);
2685 assert(maxactivity != NULL);
2686 assert(isminsettoinfinity != NULL);
2687 assert(ismaxsettoinfinity != NULL);
2688
2689 if( !consdata->validactivities )
2690 {
2691 consdataCalcActivities(scip, consdata);
2692 assert(consdata->validminact);
2693 assert(consdata->validmaxact);
2694 }
2695 assert(consdata->minactivity < SCIP_INVALID);
2696 assert(consdata->maxactivity < SCIP_INVALID);
2697 assert(consdata->minactivityneginf >= 0);
2698 assert(consdata->minactivityposinf >= 0);
2699 assert(consdata->maxactivityneginf >= 0);
2700 assert(consdata->maxactivityposinf >= 0);
2701
2702 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2703 consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2704 minactivity, minisrelax, isminsettoinfinity);
2705
2706 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2707 consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2708 maxactivity, maxisrelax, ismaxsettoinfinity);
2709}
2710
2711/** gets activity bounds for constraint after setting variable to zero */
2712static
2714 SCIP* scip, /**< SCIP data structure */
2715 SCIP_CONSDATA* consdata, /**< linear constraint */
2716 SCIP_VAR* var, /**< variable to calculate activity residual for */
2717 SCIP_INTERVAL val, /**< coefficient value of variable in linear constraint */
2718 SCIP_Bool goodrelax, /**< if we have huge contributions, do we need a good relaxation or are
2719 * relaxed acticities ignored, anyway? */
2720 SCIP_Real* minresactivity, /**< pointer to store the minimal residual activity */
2721 SCIP_Real* maxresactivity, /**< pointer to store the maximal residual activity */
2722 SCIP_Bool* minisrelax, /**< pointer to store whether the returned residual minactivity is just a
2723 * relaxation, i.e. <= the exact residual minactivity (in case of huge
2724 * contributions), or equal to the exact residual minactivity */
2725 SCIP_Bool* maxisrelax, /**< pointer to store whether the returned residual maxactivity is just a
2726 * relaxation, i.e. <= the exact residual maxactivity (in case of huge
2727 * contributions), or equal to the exact residual minactivity */
2728 SCIP_Bool* isminsettoinfinity, /**< pointer to store whether minresactivity was set to infinity or calculated */
2729 SCIP_Bool* ismaxsettoinfinity /**< pointer to store whether maxresactivity was set to infinity or calculated */
2730 )
2731{
2732 SCIP_Real minactbound;
2733 SCIP_Real maxactbound;
2734 SCIP_Real absval;
2735 SCIP_ROUNDMODE prevmode;
2736 prevmode = SCIPintervalGetRoundingMode();
2737
2738 assert(scip != NULL);
2739 assert(consdata != NULL);
2740 assert(var != NULL);
2741 assert(minresactivity != NULL);
2742 assert(maxresactivity != NULL);
2743 assert(minisrelax != NULL);
2744 assert(maxisrelax != NULL);
2745 assert(isminsettoinfinity != NULL);
2746 assert(ismaxsettoinfinity != NULL);
2747
2748 /* get activity bounds of linear constraint */
2749 if( !consdata->validactivities )
2750 {
2751 consdataCalcActivities(scip, consdata);
2752 assert(consdata->validminact);
2753 assert(consdata->validmaxact);
2754 }
2755 assert(consdata->minactivity < SCIP_INVALID);
2756 assert(consdata->maxactivity < SCIP_INVALID);
2757 assert(consdata->minactivityneginf >= 0);
2758 assert(consdata->minactivityposinf >= 0);
2759 assert(consdata->maxactivityneginf >= 0);
2760 assert(consdata->maxactivityposinf >= 0);
2761 assert(consdata->minactivityneghuge >= 0);
2762 assert(consdata->minactivityposhuge >= 0);
2763 assert(consdata->maxactivityneghuge >= 0);
2764 assert(consdata->maxactivityposhuge >= 0);
2765
2766 if( val.sup < 0.0 )
2767 {
2768 assert(val.inf <= 0.0);
2769
2770 minactbound = -SCIPvarGetUbLocal(var);
2771 maxactbound = -SCIPvarGetLbLocal(var);
2772 absval = -val.inf;
2773 }
2774 else
2775 {
2776 assert(val.inf >= 0.0);
2777
2778 minactbound = SCIPvarGetLbLocal(var);
2779 maxactbound = SCIPvarGetUbLocal(var);
2780 absval = val.sup;
2781 }
2782
2783 /* get/compute minactivity by calling getMinActivity() with updated counters for infinite and huge values
2784 * and contribution of variable set to zero that has to be subtracted from finite part of activity
2785 */
2786 if( SCIPisInfinity(scip, minactbound) )
2787 {
2788 assert(consdata->minactivityposinf >= 1);
2789
2790 getMinActivity(scip, consdata, consdata->minactivityposinf - 1, consdata->minactivityneginf,
2791 consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2792 minresactivity, minisrelax, isminsettoinfinity);
2793 }
2794 else if( SCIPisInfinity(scip, -minactbound) )
2795 {
2796 assert(consdata->minactivityneginf >= 1);
2797
2798 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf - 1,
2799 consdata->minactivityposhuge, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2800 minresactivity, minisrelax, isminsettoinfinity);
2801 }
2802 else if( SCIPisHugeValue(scip, minactbound * absval) )
2803 {
2804 assert(consdata->minactivityposhuge >= 1);
2805
2806 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2807 consdata->minactivityposhuge - 1, consdata->minactivityneghuge, 0.0, FALSE, goodrelax,
2808 minresactivity, minisrelax, isminsettoinfinity);
2809 }
2810 else if( SCIPisHugeValue(scip, -minactbound * absval) )
2811 {
2812 assert(consdata->minactivityneghuge >= 1);
2813
2814 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2815 consdata->minactivityposhuge, consdata->minactivityneghuge - 1, 0.0, FALSE, goodrelax,
2816 minresactivity, minisrelax, isminsettoinfinity);
2817 }
2818 else
2819 {
2820 SCIP_Real delta;
2821 delta = absval * minactbound;
2824 getMinActivity(scip, consdata, consdata->minactivityposinf, consdata->minactivityneginf,
2825 consdata->minactivityposhuge, consdata->minactivityneghuge, delta, FALSE, goodrelax,
2826 minresactivity, minisrelax, isminsettoinfinity);
2827 }
2828
2829 /* get/compute maxactivity by calling getMaxActivity() with updated counters for infinite and huge values
2830 * and contribution of variable set to zero that has to be subtracted from finite part of activity
2831 */
2832 if( SCIPisInfinity(scip, -maxactbound) )
2833 {
2834 assert(consdata->maxactivityneginf >= 1);
2835
2836 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf - 1,
2837 consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2838 maxresactivity, maxisrelax, ismaxsettoinfinity);
2839 }
2840 else if( SCIPisInfinity(scip, maxactbound) )
2841 {
2842 assert(consdata->maxactivityposinf >= 1);
2843
2844 getMaxActivity(scip, consdata, consdata->maxactivityposinf - 1, consdata->maxactivityneginf,
2845 consdata->maxactivityposhuge, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2846 maxresactivity, maxisrelax, ismaxsettoinfinity);
2847 }
2848 else if( SCIPisHugeValue(scip, absval * maxactbound) )
2849 {
2850 assert(consdata->maxactivityposhuge >= 1);
2851
2852 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2853 consdata->maxactivityposhuge - 1, consdata->maxactivityneghuge, 0.0, FALSE, goodrelax,
2854 maxresactivity, maxisrelax, ismaxsettoinfinity);
2855 }
2856 else if( SCIPisHugeValue(scip, -absval * maxactbound) )
2857 {
2858 assert(consdata->maxactivityneghuge >= 1);
2859
2860 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2861 consdata->maxactivityposhuge, consdata->maxactivityneghuge - 1, 0.0, FALSE, goodrelax,
2862 maxresactivity, maxisrelax, ismaxsettoinfinity);
2863 }
2864 else
2865 {
2866 SCIP_Real delta;
2867 delta = absval * maxactbound;
2870 getMaxActivity(scip, consdata, consdata->maxactivityposinf, consdata->maxactivityneginf,
2871 consdata->maxactivityposhuge, consdata->maxactivityneghuge, delta, FALSE, goodrelax,
2872 maxresactivity, maxisrelax, ismaxsettoinfinity);
2873 }
2875}
2876
2877/** calculates the activity of the linear constraint for given solution */
2878static
2880 SCIP* scip, /**< SCIP data structure */
2881 SCIP_CONSDATA* consdata, /**< linear constraint data */
2882 SCIP_SOL* sol, /**< solution to get activity for, NULL to current solution */
2883 SCIP_Bool useexact, /**< should the exact solution be used */
2884 SCIP_RATIONAL* activity /**< pointer to store the activity */
2885 )
2886{
2887 assert(scip != NULL);
2888 assert(consdata != NULL);
2889
2890 if( (sol == NULL) && !SCIPhasCurrentNodeLP(scip) )
2891 consdataComputePseudoActivity(consdata, activity);
2892 else
2893 {
2894 SCIP_RATIONAL* solval;
2895 int nposinf;
2896 int nneginf;
2897 SCIP_Bool negsign;
2898 int v;
2899
2900 (void) SCIPrationalCreateBuffer(SCIPbuffer(scip), &solval);
2901
2902 SCIPrationalSetFraction(activity, 0LL, 1LL);
2903 nposinf = 0;
2904 nneginf = 0;
2905
2906 for( v = 0; v < consdata->nvars; ++v )
2907 {
2908 if( useexact )
2909 SCIPgetSolValExact(scip, sol, consdata->vars[v], solval);
2910 else
2911 SCIPrationalSetReal(solval, SCIPgetSolVal(scip, sol, consdata->vars[v]));
2912
2913 assert(!SCIPrationalIsZero(consdata->vals[v]));
2914 negsign = SCIPrationalIsNegative(consdata->vals[v]);
2915
2916 if( (SCIPrationalIsInfinity(solval) && !negsign) || (SCIPrationalIsNegInfinity(solval) && negsign) )
2917 ++nposinf;
2918 else if( (SCIPrationalIsInfinity(solval) && negsign) || (SCIPrationalIsNegInfinity(solval) && !negsign) )
2919 ++nneginf;
2920 else
2921 {
2922 SCIPrationalAddProd(activity, solval, consdata->vals[v]);
2923 }
2924 }
2925 assert(nneginf >= 0 && nposinf >= 0);
2926
2927 SCIPdebugMsg(scip, "activity of linear constraint: %.15g, %d positive infinity values, %d negative infinity values \n", SCIPrationalGetReal(activity), nposinf, nneginf);
2928
2929 /* set activity to infeasible infinity for contradicting contributions */
2930 if( nneginf > 0 && ( nposinf == 0 || !SCIPrationalIsNegInfinity(consdata->lhs) ) )
2932 else if( nposinf > 0 && ( nneginf == 0 || !SCIPrationalIsInfinity(consdata->rhs) ) )
2933 SCIPrationalSetInfinity(activity);
2934
2935 SCIPrationalDebugMessage("corrected activity of linear constraint: %q\n", activity);
2936
2938 }
2939}
2940
2941/** calculates the feasibility of the linear constraint for given solution */
2942static
2944 SCIP* scip, /**< SCIP data structure */
2945 SCIP_CONSDATA* consdata, /**< linear constraint data */
2946 SCIP_SOL* sol, /**< solution to get feasibility for, NULL to current solution */
2947 SCIP_RATIONAL* ret /**< pointer to store the result */
2948 )
2949{
2950 SCIP_RATIONAL* activity;
2951 SCIP_RATIONAL* op1;
2952 SCIP_RATIONAL* op2;
2953
2954 assert(scip != NULL);
2955 assert(consdata != NULL);
2956
2957 (void) SCIPrationalCreateBuffer(SCIPbuffer(scip), &activity);
2960
2961 consdataGetActivity(scip, consdata, sol, FALSE, activity);
2962 SCIPrationalDiff(op1, consdata->rhs, activity);
2963 SCIPrationalDiff(op2, activity, consdata->lhs);
2964
2965 SCIPrationalMin(ret, op1, op2);
2966
2970}
2971
2972/** creates an LP row in a linear constraint data */
2973static
2975 SCIP* scip, /**< SCIP data structure */
2976 SCIP_CONS* cons /**< linear constraint */
2977 );
2978
2979/** prints the certificate for a given original exact linear constraint */
2981 SCIP* scip, /**< SCIP data structure */
2982 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
2983 SCIP_CONS* cons /**< constraint */
2984 )
2985{
2986 SCIP_CONSDATA* consdata;
2987 int* varsindex;
2988 int i;
2989
2990 /*lint --e{715}*/
2991 assert(scip != NULL);
2992 assert(conshdlr != NULL);
2993 assert(cons != NULL);
2994
2995 /* print constraint into certificate output */
2996 if( SCIPisCertified(scip) )
2997 {
2998 consdata = SCIPconsGetData(cons);
2999
3000 SCIP_CALL( SCIPallocBufferArray(scip, &varsindex, consdata->nvars) );
3001 for( i = 0; i < consdata->nvars; ++i )
3002 varsindex[i] = SCIPvarGetCertificateIndex(consdata->vars[i]);
3003
3004 /* print constraint */
3005 if( SCIPrationalIsEQ(consdata->lhs, consdata->rhs) )
3006 {
3007 assert(!SCIPrationalIsAbsInfinity(consdata->lhs));
3008 SCIP_CALL( SCIPcertifyCons(scip, TRUE, NULL, 'E', consdata->lhs, consdata->nvars, varsindex, consdata->vals) );
3009 }
3010 else
3011 {
3012 if( !SCIPrationalIsNegInfinity(consdata->lhs) )
3013 {
3014 SCIP_CALL( SCIPcertifyCons(scip, TRUE, NULL, 'G', consdata->lhs, consdata->nvars, varsindex, consdata->vals) );
3015 }
3016 if( !SCIPrationalIsInfinity(consdata->rhs) )
3017 {
3018 SCIP_CALL( SCIPcertifyCons(scip, TRUE, NULL, 'L', consdata->rhs, consdata->nvars, varsindex, consdata->vals) );
3019 }
3020 }
3021
3022 SCIPfreeBufferArray(scip, &varsindex);
3023 }
3024
3025 return SCIP_OKAY;
3026}
3027
3028/** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
3029static
3031{ /*lint --e{715}*/
3032 SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
3033
3034 assert(consdata != NULL);
3035 assert(0 <= ind1 && ind1 < consdata->nvars);
3036 assert(0 <= ind2 && ind2 < consdata->nvars);
3037
3038 return SCIPvarCompare(consdata->vars[ind1], consdata->vars[ind2]);
3039}
3040
3041/** index comparison method of linear constraints: compares two indices of the variable set in the linear constraint */
3042static
3043SCIP_DECL_SORTINDCOMP(consdataCompVarProp)
3044{ /*lint --e{715}*/
3045 SCIP_CONSDATA* consdata = (SCIP_CONSDATA*)dataptr;
3046 SCIP_VAR* var1;
3047 SCIP_VAR* var2;
3048
3049 assert(consdata != NULL);
3050 assert(0 <= ind1 && ind1 < consdata->nvars);
3051 assert(0 <= ind2 && ind2 < consdata->nvars);
3052
3053 var1 = consdata->vars[ind1];
3054 var2 = consdata->vars[ind2];
3055
3056 /* exactly one variable is binary */
3057 if( SCIPvarIsBinary(var1) != SCIPvarIsBinary(var2) )
3058 {
3059 return (SCIPvarIsBinary(var1) ? -1 : +1);
3060 }
3061 /* both variables are binary */
3062 else if( SCIPvarIsBinary(var1) )
3063 {
3064 if( SCIPrationalIsAbsEQ(consdata->vals[ind1], consdata->vals[ind2]) ) {
3065 return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
3066 }
3067 if( SCIPrationalIsAbsGT(consdata->vals[ind1], consdata->vals[ind2]) )
3068 return -1;
3069 else
3070 return +1;
3071 }
3072 else
3073 {
3074 SCIP_VARTYPE vartype1 = SCIPvarGetType(var1);
3075 SCIP_VARTYPE vartype2 = SCIPvarGetType(var2);
3076
3077 if( vartype1 < vartype2 )
3078 {
3079 return -1;
3080 }
3081 else if( vartype1 > vartype2 )
3082 {
3083 return +1;
3084 }
3085 else
3086 {
3087 /* both variables are continuous */
3088 if( !SCIPvarIsIntegral(var1) )
3089 {
3090 assert(!SCIPvarIsIntegral(var2));
3091 return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
3092 }
3093 else
3094 {
3095 SCIP_RATIONAL* abscont1;
3096 SCIP_RATIONAL* abscont2;
3097
3098 (void) SCIPrationalCreate(&abscont1);
3099 (void) SCIPrationalCreate(&abscont2);
3100
3102 SCIPrationalMult(abscont1, consdata->vals[ind1], abscont1);
3103
3105 SCIPrationalMult(abscont2, consdata->vals[ind2], abscont2);
3106
3107 if( SCIPrationalIsAbsEQ(abscont1, abscont2) ) {
3108 SCIPrationalFree(&abscont1);
3109 SCIPrationalFree(&abscont2);
3110 return (SCIPvarGetProbindex(var1) - SCIPvarGetProbindex(var2));
3111 }
3112 if( SCIPrationalIsAbsGT(abscont2, abscont1) )
3113 {
3114 SCIPrationalFree(&abscont1);
3115 SCIPrationalFree(&abscont2);
3116 return 1;
3117 }
3118 else
3119 {
3120 SCIPrationalFree(&abscont1);
3121 SCIPrationalFree(&abscont2);
3122 return -1;
3123 }
3124 }
3125 }
3126 }
3127}
3128
3129/** permutes the constraint's variables according to a given permutation. */
3130static
3132 SCIP_CONSDATA* consdata, /**< the constraint data */
3133 int* perm, /**< the target permutation */
3134 int nvars /**< the number of variables */
3135 )
3136{ /*lint --e{715}*/
3137 SCIP_VAR* varv;
3138 SCIP_EVENTDATA* eventdatav;
3139 SCIP_INTERVAL valrealv;
3140 SCIP_RATIONAL* valv;
3141 int v;
3142 int i;
3143 int nexti;
3144
3145 assert(perm != NULL);
3146 assert(consdata != NULL);
3147
3148 /* permute the variables in the linear constraint according to the target permutation */
3149 eventdatav = NULL;
3150 for( v = 0; v < nvars; ++v )
3151 {
3152 if( perm[v] != v )
3153 {
3154 varv = consdata->vars[v];
3155 valv = consdata->vals[v];
3156 valrealv = consdata->valsreal[v];
3157 if( consdata->eventdata != NULL )
3158 eventdatav = consdata->eventdata[v];
3159 i = v;
3160 do
3161 {
3162 assert(0 <= perm[i] && perm[i] < nvars);
3163 assert(perm[i] != i);
3164 consdata->vars[i] = consdata->vars[perm[i]];
3165 consdata->vals[i] = consdata->vals[perm[i]];
3166 consdata->valsreal[i] = consdata->valsreal[perm[i]];
3167 if( consdata->eventdata != NULL )
3168 {
3169 consdata->eventdata[i] = consdata->eventdata[perm[i]];
3170 consdata->eventdata[i]->varpos = i;
3171 }
3172 nexti = perm[i];
3173 perm[i] = i;
3174 i = nexti;
3175 }
3176 while( perm[i] != v );
3177 consdata->vars[i] = varv;
3178 consdata->vals[i] = valv;
3179 consdata->valsreal[i] = valrealv;
3180 if( consdata->eventdata != NULL )
3181 {
3182 consdata->eventdata[i] = eventdatav;
3183 consdata->eventdata[i]->varpos = i;
3184 }
3185 perm[i] = i;
3186 }
3187 }
3188#ifdef SCIP_DEBUG
3189 /* check sorting */
3190 for( v = 0; v < nvars; ++v )
3191 {
3192 assert(perm[v] == v);
3193 assert(consdata->eventdata == NULL || consdata->eventdata[v]->varpos == v);
3194 }
3195#endif
3196}
3197
3198/** sorts linear constraint's variables depending on the stage of the solving process:
3199 * - during PRESOLVING
3200 * sorts variables by binary, integer, implied integral, and continuous variables,
3201 * and the variables of the same type by non-decreasing variable index
3202 *
3203 * - during SOLVING
3204 * sorts variables of the remaining problem by binary, integer, implied integral, and continuous variables,
3205 * and binary and integer variables by their global max activity delta (within each group),
3206 * ties within a group are broken by problem index of the variable.
3207 *
3208 * This fastens the propagation time of the constraint handler.
3209 */
3210static
3212 SCIP* scip, /**< SCIP data structure */
3213 SCIP_CONSDATA* consdata /**< linear constraint data */
3214 )
3215{
3216 assert(scip != NULL);
3217 assert(consdata != NULL);
3218
3219 /* check if there are variables for sorting */
3220 if( consdata->nvars <= 1 )
3221 {
3222 consdata->indexsorted = TRUE;
3223 consdata->coefsorted = TRUE;
3224 consdata->nbinvars = (consdata->nvars == 1 ? (int)SCIPvarIsBinary(consdata->vars[0]) : 0);
3225 }
3226 else if( (!consdata->indexsorted && SCIPgetStage(scip) < SCIP_STAGE_INITSOLVE)
3227 || (!consdata->coefsorted && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE) )
3228 {
3229 int* perm;
3230 int v;
3231
3232 /* get temporary memory to store the sorted permutation */
3233 SCIP_CALL( SCIPallocBufferArray(scip, &perm, consdata->nvars) );
3234
3235 /* call sorting method */
3237 SCIPsort(perm, consdataCompVar, (void*)consdata, consdata->nvars);
3238 else
3239 SCIPsort(perm, consdataCompVarProp, (void*)consdata, consdata->nvars);
3240
3241 permSortConsdata(consdata, perm, consdata->nvars);
3242
3243 /* free temporary memory */
3244 SCIPfreeBufferArray(scip, &perm);
3245
3247 {
3248 consdata->indexsorted = FALSE;
3249 consdata->coefsorted = TRUE;
3250
3251 /* count binary variables in the sorted vars array */
3252 consdata->nbinvars = 0;
3253 for( v = 0; v < consdata->nvars; ++v )
3254 {
3255 if( SCIPvarIsBinary(consdata->vars[v]) )
3256 ++consdata->nbinvars;
3257 else
3258 break;
3259 }
3260 }
3261 else
3262 {
3263 consdata->indexsorted = TRUE;
3264 consdata->coefsorted = FALSE;
3265 }
3266 }
3267
3268 return SCIP_OKAY;
3269}
3270
3271
3272/*
3273 * local linear constraint handler methods
3274 */
3275
3276/** sets left hand side of linear constraint */
3277static
3279 SCIP* scip, /**< SCIP data structure */
3280 SCIP_CONS* cons, /**< linear constraint */
3281 SCIP_RATIONAL* lhs /**< new left hand side */
3282 )
3283{
3284 SCIP_CONSDATA* consdata;
3285 SCIP_Bool locked;
3286 int i;
3287
3288 assert(scip != NULL);
3289 assert(cons != NULL);
3291
3292 consdata = SCIPconsGetData(cons);
3293 assert(consdata != NULL);
3294 assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
3295 assert(!SCIPrationalIsInfinity(consdata->lhs));
3296
3297 /* check whether the side is not changed */
3298 if( SCIPrationalIsEQ(consdata->lhs, lhs) )
3299 return SCIP_OKAY;
3300
3301 /* ensure that rhs >= lhs is satisfied without numerical tolerance */
3302 if( SCIPrationalIsEQ(lhs, consdata->rhs) )
3303 {
3304 SCIPrationalSetRational(consdata->rhs, lhs);
3305 assert(consdata->rowlhs == NULL);
3306 }
3307
3308 locked = FALSE;
3309 for( i = 0; i < NLOCKTYPES && !locked; i++ )
3310 locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
3311
3312 /* if necessary, update the rounding locks of variables */
3313 if( locked )
3314 {
3315 if( SCIPrationalIsNegInfinity(consdata->lhs) && !SCIPrationalIsNegInfinity(lhs) )
3316 {
3317 SCIP_VAR** vars;
3318 SCIP_RATIONAL** vals;
3319 int v;
3320
3321 /* the left hand side switched from -infinity to a non-infinite value -> install rounding locks */
3322 vars = consdata->vars;
3323 vals = consdata->vals;
3324
3325 for( v = 0; v < consdata->nvars; ++v )
3326 {
3327 assert(vars[v] != NULL);
3328 assert(!SCIPrationalIsZero(vals[v]));
3329
3330 if( SCIPrationalIsPositive(vals[v]) )
3331 {
3332 SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3333 }
3334 else
3335 {
3336 SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3337 }
3338 }
3339 }
3340 else if( !SCIPrationalIsNegInfinity(consdata->lhs) && SCIPrationalIsNegInfinity(lhs) )
3341 {
3342 SCIP_VAR** vars;
3343 SCIP_RATIONAL** vals;
3344 int v;
3345
3346 /* the left hand side switched from a non-infinite value to -infinity -> remove rounding locks */
3347 vars = consdata->vars;
3348 vals = consdata->vals;
3349
3350 for( v = 0; v < consdata->nvars; ++v )
3351 {
3352 assert(vars[v] != NULL);
3353 assert(!SCIPrationalIsZero(vals[v]));
3354
3355 if( SCIPrationalIsPositive(vals[v]) )
3356 {
3358 }
3359 else
3360 {
3362 }
3363 }
3364 }
3365 }
3366
3367 /* 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 */
3368 if( !SCIPrationalIsNegInfinity(lhs) && SCIPrationalIsGT(lhs, consdata->lhs) )
3369 {
3370 consdata->boundstightened = 0;
3371 consdata->presolved = FALSE;
3372 consdata->cliquesadded = FALSE;
3373 consdata->implsadded = FALSE;
3374
3375 /* mark the constraint for propagation */
3376 if( SCIPconsIsTransformed(cons) )
3377 {
3379 }
3380 }
3381
3382 /* set new left hand side and update constraint data */
3383 SCIPrationalSetRational(consdata->lhs, lhs);
3384 consdata->lhsreal = SCIPrationalRoundReal(lhs, SCIP_R_ROUND_DOWNWARDS);
3385 consdata->changed = TRUE;
3386 consdata->normalized = FALSE;
3387 consdata->rangedrowpropagated = 0;
3388
3389 /* update the lhs of the LP row */
3390 if( consdata->rowexact != NULL )
3391 {
3392 SCIP_CALL( SCIPchgRowExactLhs(scip, consdata->rowexact, lhs) );
3393 }
3394
3395 return SCIP_OKAY;
3396}
3397
3398/** sets right hand side of linear constraint */
3399static
3401 SCIP* scip, /**< SCIP data structure */
3402 SCIP_CONS* cons, /**< linear constraint */
3403 SCIP_RATIONAL* rhs /**< new right hand side */
3404 )
3405{
3406 SCIP_CONSDATA* consdata;
3407 SCIP_Bool locked;
3408 int i;
3409
3410 assert(scip != NULL);
3411 assert(cons != NULL);
3413
3414 consdata = SCIPconsGetData(cons);
3415 assert(consdata != NULL);
3416 assert(consdata->nvars == 0 || (consdata->vars != NULL && consdata->vals != NULL));
3417 assert(!SCIPrationalIsNegInfinity(consdata->rhs));
3418
3419 /* check whether the side is not changed */
3420 if( SCIPrationalIsEQ(consdata->rhs, rhs) )
3421 return SCIP_OKAY;
3422
3423 /* ensure that rhs >= lhs is satisfied without numerical tolerance */
3424 if( SCIPrationalIsEQ(rhs, consdata->lhs) )
3425 {
3426 SCIPrationalSetRational(consdata->rhs, rhs);
3427 assert(consdata->rowlhs == NULL);
3428 }
3429
3430 locked = FALSE;
3431 for( i = 0; i < NLOCKTYPES && !locked; i++ )
3432 locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
3433
3434 /* if necessary, update the rounding locks of variables */
3435 if( locked )
3436 {
3438
3439 if( SCIPrationalIsInfinity(consdata->rhs) && !SCIPrationalIsInfinity(rhs) )
3440 {
3441 SCIP_VAR** vars;
3442 SCIP_RATIONAL** vals;
3443 int v;
3444
3445 /* the right hand side switched from infinity to a non-infinite value -> install rounding locks */
3446 vars = consdata->vars;
3447 vals = consdata->vals;
3448
3449 for( v = 0; v < consdata->nvars; ++v )
3450 {
3451 assert(vars[v] != NULL);
3452 assert(!SCIPrationalIsZero(vals[v]));
3453
3454 if( SCIPrationalIsPositive(vals[v]) )
3455 {
3456 SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, FALSE, TRUE) );
3457 }
3458 else
3459 {
3460 SCIP_CALL( SCIPlockVarCons(scip, vars[v], cons, TRUE, FALSE) );
3461 }
3462 }
3463 }
3464 else if( !SCIPrationalIsInfinity(consdata->rhs) && SCIPrationalIsInfinity(rhs) )
3465 {
3466 SCIP_VAR** vars;
3467 SCIP_RATIONAL** vals;
3468 int v;
3469
3470 /* the right hand side switched from a non-infinite value to infinity -> remove rounding locks */
3471 vars = consdata->vars;
3472 vals = consdata->vals;
3473
3474 for( v = 0; v < consdata->nvars; ++v )
3475 {
3476 assert(vars[v] != NULL);
3477 assert(!SCIPrationalIsZero(vals[v]));
3478
3479 if( SCIPrationalIsPositive(vals[v]) )
3480 {
3482 }
3483 else
3484 {
3486 }
3487 }
3488 }
3489 }
3490
3491 /* 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 */
3492 if( !SCIPrationalIsInfinity(rhs) && SCIPrationalIsLT(rhs, consdata->rhs) )
3493 {
3494 consdata->boundstightened = 0;
3495 consdata->presolved = FALSE;
3496 consdata->cliquesadded = FALSE;
3497 consdata->implsadded = FALSE;
3498
3499 /* mark the constraint for propagation */
3500 if( SCIPconsIsTransformed(cons) )
3501 {
3503 }
3504 }
3505
3506 /* set new right hand side and update constraint data */
3507 SCIPrationalSetRational(consdata->rhs, rhs);
3508 consdata->rhsreal = SCIPrationalRoundReal(rhs, SCIP_R_ROUND_UPWARDS);
3509 consdata->changed = TRUE;
3510 consdata->normalized = FALSE;
3511 consdata->rangedrowpropagated = 0;
3512
3513 /* update the rhs of the LP row */
3514 if( consdata->rowexact != NULL )
3515 {
3516 SCIP_CALL( SCIPchgRowExactRhs(scip, consdata->rowexact, rhs) );
3517 }
3518
3519 return SCIP_OKAY;
3520}
3521
3522/** adds coefficient in linear constraint */
3523static
3525 SCIP* scip, /**< SCIP data structure */
3526 SCIP_CONS* cons, /**< linear constraint */
3527 SCIP_VAR* var, /**< variable of constraint entry */
3528 SCIP_RATIONAL* val /**< coefficient of constraint entry */
3529 )
3530{
3531 SCIP_CONSDATA* consdata;
3532 SCIP_Bool transformed;
3533
3534 assert(scip != NULL);
3535 assert(cons != NULL);
3536 assert(var != NULL);
3537
3538 /* ignore coefficient if it is nearly zero */
3539 if( SCIPrationalIsZero(val) )
3540 return SCIP_OKAY;
3541
3542 consdata = SCIPconsGetData(cons);
3543 assert(consdata != NULL);
3544
3545 /* are we in the transformed problem? */
3546 transformed = SCIPconsIsTransformed(cons);
3547
3548 /* always use transformed variables in transformed constraints */
3549 if( transformed )
3550 {
3552 }
3553 assert(var != NULL);
3554 assert(transformed == SCIPvarIsTransformed(var));
3555
3556 SCIP_CALL( consdataEnsureVarsSize(scip, consdata, consdata->nvars+1) );
3557 consdata->vars[consdata->nvars] = var;
3558 SCIPrationalSetRational(consdata->vals[consdata->nvars], val);
3559 SCIPintervalSetRational(&(consdata->valsreal[consdata->nvars]), val);
3560 consdata->nvars++;
3561
3562 /* capture variable */
3564
3565 /* if we are in transformed problem, the variable needs an additional event data */
3566 if( transformed )
3567 {
3568 if( consdata->eventdata != NULL )
3569 {
3570 SCIP_CONSHDLR* conshdlr;
3571 SCIP_CONSHDLRDATA* conshdlrdata;
3572
3573 /* check for event handler */
3574 conshdlr = SCIPconsGetHdlr(cons);
3575 conshdlrdata = SCIPconshdlrGetData(conshdlr);
3576 assert(conshdlrdata != NULL);
3577 assert(conshdlrdata->eventhdlr != NULL);
3578
3579 /* initialize eventdata array */
3580 consdata->eventdata[consdata->nvars-1] = NULL;
3581
3582 /* catch bound change events of variable */
3583 SCIP_CALL( consCatchEvent(scip, cons, conshdlrdata->eventhdlr, consdata->nvars-1) );
3584 }
3585
3586 /* update minimum and maximum activities */
3587 consdataUpdateAddCoef(scip, consdata, var, consdata->vals[consdata->nvars - 1], consdata->valsreal[consdata->nvars - 1]);
3588 }
3589
3590 /* install rounding locks for new variable */
3591 SCIP_CALL( lockRounding(scip, cons, var, val) );
3592
3593 /* mark the constraint for propagation */
3594 if( transformed )
3595 {
3597 }
3598
3599 consdata->boundstightened = 0;
3600 consdata->presolved = FALSE;
3601 consdata->removedfixings = consdata->removedfixings && SCIPvarIsActive(var);
3602
3603 consdata->changed = TRUE;
3604 consdata->normalized = FALSE;
3605 consdata->cliquesadded = FALSE;
3606 consdata->implsadded = FALSE;
3607 consdata->rangedrowpropagated = 0;
3608
3609 if( consdata->nvars == 1 )
3610 {
3611 consdata->indexsorted = TRUE;
3612 consdata->coefsorted = TRUE;
3613 consdata->merged = TRUE;
3614 }
3615 else
3616 {
3617 consdata->merged = FALSE;
3618
3620 {
3621 consdata->indexsorted = consdata->indexsorted && (consdataCompVar((void*)consdata, consdata->nvars-2, consdata->nvars-1) <= 0);
3622 consdata->coefsorted = FALSE;
3623 }
3624 else
3625 {
3626 consdata->indexsorted = FALSE;
3627 consdata->coefsorted = consdata->coefsorted && (consdataCompVarProp((void*)consdata, consdata->nvars-2, consdata->nvars-1) <= 0);
3628 }
3629 }
3630
3631 /* update hascontvar and hasnonbinvar flags */
3632 if( consdata->hasnonbinvalid && !consdata->hascontvar )
3633 {
3634 SCIP_VARTYPE vartype = SCIPvarGetType(var);
3635
3636 if( vartype != SCIP_VARTYPE_BINARY )
3637 {
3638 consdata->hasnonbinvar = TRUE;
3639
3640 if( vartype == SCIP_VARTYPE_CONTINUOUS )
3641 consdata->hascontvar = TRUE;
3642 }
3643 }
3644
3645 /* add the new coefficient to the LP row */
3646 if( consdata->rowexact != NULL )
3647 {
3648 SCIP_CALL( SCIPaddVarsToRowExact(scip, consdata->rowexact, 1, &var, &val) );
3649 }
3650
3651 return SCIP_OKAY;
3652}
3653
3654/** deletes coefficient at given position from linear constraint data */
3655static
3657 SCIP* scip, /**< SCIP data structure */
3658 SCIP_CONS* cons, /**< linear constraint */
3659 int pos /**< position of coefficient to delete */
3660 )
3661{
3662 SCIP_CONSDATA* consdata;
3663 SCIP_VAR* var;
3664 SCIP_RATIONAL* val;
3665
3666 assert(scip != NULL);
3667 assert(cons != NULL);
3668
3669 consdata = SCIPconsGetData(cons);
3670 assert(consdata != NULL);
3671 assert(0 <= pos && pos < consdata->nvars);
3672
3673 var = consdata->vars[pos];
3674 val = consdata->vals[pos];
3675 assert(var != NULL);
3676
3677 /* remove rounding locks for deleted variable */
3678 SCIP_CALL( unlockRounding(scip, cons, var, val) );
3679
3680 /* if we are in transformed problem, delete the event data of the variable */
3681 if( SCIPconsIsTransformed(cons) )
3682 {
3683 SCIP_CONSHDLR* conshdlr;
3684 SCIP_CONSHDLRDATA* conshdlrdata;
3685
3686 /* check for event handler */
3687 conshdlr = SCIPconsGetHdlr(cons);
3688 conshdlrdata = SCIPconshdlrGetData(conshdlr);
3689 assert(conshdlrdata != NULL);
3690 assert(conshdlrdata->eventhdlr != NULL);
3691
3692 /* drop bound change events of variable */
3693 if( consdata->eventdata != NULL )
3694 {
3695 SCIP_CALL( consDropEvent(scip, cons, conshdlrdata->eventhdlr, pos) );
3696 assert(consdata->eventdata[pos] == NULL);
3697 }
3698 }
3699
3700 /* move the last variable to the free slot */
3701 if( pos != consdata->nvars - 1 )
3702 {
3703 consdata->vars[pos] = consdata->vars[consdata->nvars-1];
3704 SCIPrationalSetRational(consdata->vals[pos], consdata->vals[consdata->nvars - 1]);
3705 consdata->valsreal[pos] = consdata->valsreal[consdata->nvars -1];
3706
3707 if( consdata->eventdata != NULL )
3708 {
3709 consdata->eventdata[pos] = consdata->eventdata[consdata->nvars-1];
3710 assert(consdata->eventdata[pos] != NULL);
3711 consdata->eventdata[pos]->varpos = pos;
3712 }
3713
3714 consdata->indexsorted = consdata->indexsorted && (pos + 2 >= consdata->nvars);
3715 consdata->coefsorted = consdata->coefsorted && (pos + 2 >= consdata->nvars);
3716 }
3717 consdata->nvars--;
3718
3719 /* mark the constraint for propagation */
3720 if( SCIPconsIsTransformed(cons) )
3721 {
3723 }
3724
3725 consdata->boundstightened = 0;
3726 consdata->presolved = FALSE;
3727 consdata->changed = TRUE;
3728 consdata->normalized = FALSE;
3729 consdata->cliquesadded = FALSE;
3730 consdata->implsadded = FALSE;
3731 consdata->rangedrowpropagated = 0;
3732
3733 /* check if hasnonbinvar flag might be incorrect now */
3734 if( consdata->hasnonbinvar && SCIPvarGetType(var) != SCIP_VARTYPE_BINARY )
3735 {
3736 consdata->hasnonbinvalid = FALSE;
3737 }
3738
3739 /* release variable */
3741
3742 return SCIP_OKAY;
3743}
3744
3745/** changes coefficient value at given position of linear constraint data */
3746static
3748 SCIP* scip, /**< SCIP data structure */
3749 SCIP_CONS* cons, /**< linear constraint */
3750 int pos, /**< position of coefficient to delete */
3751 SCIP_RATIONAL* newval /**< new value of coefficient */
3752 )
3753{
3754 SCIP_CONSDATA* consdata;
3755 SCIP_VAR* var;
3756 SCIP_RATIONAL* val;
3757 SCIP_Bool locked;
3758 SCIP_INTERVAL newvalfp;
3759 int i;
3760
3761 assert(scip != NULL);
3762 assert(cons != NULL);
3763 assert(!SCIPrationalIsZero(newval));
3764
3765 consdata = SCIPconsGetData(cons);
3766 assert(consdata != NULL);
3767 assert(0 <= pos && pos < consdata->nvars);
3768
3769 var = consdata->vars[pos];
3770 val = consdata->vals[pos];
3771 assert(var != NULL);
3773
3774 locked = FALSE;
3775 for( i = 0; i < NLOCKTYPES && !locked; i++ )
3776 locked = SCIPconsIsLockedType(cons, (SCIP_LOCKTYPE) i);
3777
3778 /* if necessary, update the rounding locks of the variable */
3779 if( locked && ((SCIPrationalIsNegative(newval) && SCIPrationalIsPositive(val)) || (SCIPrationalIsNegative(val) && SCIPrationalIsPositive(newval))) )
3780 {
3782
3783 /* remove rounding locks for variable with old coefficient */
3784 SCIP_CALL( unlockRounding(scip, cons, var, val) );
3785
3786 /* install rounding locks for variable with new coefficient */
3787 SCIP_CALL( lockRounding(scip, cons, var, newval) );
3788 }
3789 SCIPintervalSetRational(&newvalfp, newval);
3790 /* update minimum and maximum activities */
3791 if( SCIPconsIsTransformed(cons) )
3792 consdataUpdateChgCoef(scip, consdata, var, consdata->valsreal[pos], val, newvalfp, newval);
3793
3794 /* change the value */
3795 SCIPrationalSetRational(consdata->vals[pos], newval);
3796 consdata->valsreal[pos] = newvalfp;
3797 if( consdata->coefsorted )
3798 {
3799 if( pos > 0 )
3800 consdata->coefsorted = (consdataCompVarProp((void*)consdata, pos - 1, pos) <= 0);
3801 if( consdata->coefsorted && pos < consdata->nvars - 1 )
3802 consdata->coefsorted = (consdataCompVarProp((void*)consdata, pos, pos + 1) <= 0);
3803 }
3804 /* mark the constraint for propagation */
3805 if( SCIPconsIsTransformed(cons) )
3806 {
3808 }
3809
3810 consdata->boundstightened = 0;
3811 consdata->presolved = FALSE;
3812 consdata->changed = TRUE;
3813 consdata->normalized = FALSE;
3814 consdata->cliquesadded = FALSE;
3815 consdata->implsadded = FALSE;
3816 consdata->rangedrowpropagated = 0;
3817
3818 return SCIP_OKAY;
3819}
3820
3821/* perform deletion of variables in all constraints of the constraint handler */
3822static
3824 SCIP* scip, /**< SCIP data structure */
3825 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
3826 SCIP_CONS** conss, /**< array of constraints */
3827 int nconss /**< number of constraints */
3828 )
3829{
3830 SCIP_CONSDATA* consdata;
3831 int i;
3832 int v;
3833
3834 assert(scip != NULL);
3835 assert(conshdlr != NULL);
3836 assert(conss != NULL);
3837 assert(nconss >= 0);
3838
3840
3841 /* iterate over all constraints */
3842 for( i = 0; i < nconss; i++ )
3843 {
3844 consdata = SCIPconsGetData(conss[i]);
3845
3846 /* constraint is marked, that some of its variables were deleted */
3847 if( consdata->varsdeleted )
3848 {
3849 /* iterate over all variables of the constraint and delete them from the constraint */
3850 for( v = consdata->nvars - 1; v >= 0; --v )
3851 {
3852 if( SCIPvarIsDeleted(consdata->vars[v]) )
3853 {
3854 SCIP_CALL( delCoefPos(scip, conss[i], v) );
3855 }
3856 }
3857 consdata->varsdeleted = FALSE;
3858 }
3859 }
3860
3861 return SCIP_OKAY;
3862}
3863
3864/** replaces multiple occurrences of a variable by a single coefficient */
3865static
3867 SCIP* scip, /**< SCIP data structure */
3868 SCIP_CONS* cons /**< linear constraint */
3869 )
3870{
3871 SCIP_CONSDATA* consdata;
3872 SCIP_VAR* var;
3873 SCIP_RATIONAL* valsum;
3874 int v;
3875
3876 assert(scip != NULL);
3877 assert(cons != NULL);
3878
3879 consdata = SCIPconsGetData(cons);
3880 assert(consdata != NULL);
3881
3882 if( consdata->merged )
3883 return SCIP_OKAY;
3884
3886
3887 /* sort the constraint */
3888 SCIP_CALL( consdataSort(scip, consdata) );
3889
3890 /* go backwards through the constraint looking for multiple occurrences of the same variable;
3891 * backward direction is necessary, since delCoefPos() modifies the given position and
3892 * the subsequent ones
3893 */
3894 v = consdata->nvars-1;
3895 while( v >= 1 )
3896 {
3897 var = consdata->vars[v];
3898 if( consdata->vars[v-1] == var )
3899 {
3900 SCIPrationalSetRational(valsum, consdata->vals[v]);
3901 do
3902 {
3903 SCIP_CALL( delCoefPos(scip, cons, v) );
3904 --v;
3905 SCIPrationalAdd(valsum, valsum, consdata->vals[v]);
3906 }
3907 while( v >= 1 && consdata->vars[v-1] == var );
3908
3909 /* modify the last existing occurrence of the variable */
3910 assert(consdata->vars[v] == var);
3911 if( SCIPrationalIsZero(valsum) )
3912 {
3913 SCIP_CALL( delCoefPos(scip, cons, v) );
3914
3915 /* if the variable defining the maximal activity delta was removed from the constraint, the maximal activity
3916 * delta needs to be recalculated on the next real propagation
3917 */
3918 if( consdata->maxactdeltavar == var )
3919 {
3920 consdata->maxactdelta = SCIP_INVALID;
3921 consdata->maxactdeltavar = NULL;
3922 }
3923 }
3924 else
3925 {
3926 SCIP_CALL( chgCoefPos(scip, cons, v, valsum) );
3927 }
3928 }
3929 --v;
3930 }
3931
3933 consdata->merged = TRUE;
3934
3935 return SCIP_OKAY;
3936}
3937
3938/** replaces all fixed and aggregated variables by their non-fixed counterparts */
3939static
3941 SCIP* scip, /**< SCIP data structure */
3942 SCIP_CONS* cons, /**< linear constraint */
3943 SCIP_Bool* infeasible /**< pointer to store if infeasibility is detected; or NULL if this
3944 * information is not needed; in this case, we apply all fixings
3945 * instead of stopping after the first infeasible one */
3946 )
3947{
3948 SCIP_CONSDATA* consdata;
3949 SCIP_VAR* var;
3950 SCIP_VAR** aggrvars;
3951 SCIP_RATIONAL* val;
3952 SCIP_RATIONAL** aggrscalars;
3953 SCIP_RATIONAL* fixedval;
3954 SCIP_RATIONAL* aggrconst;
3955 SCIP_Real negconst;
3956 int v;
3957 int naggrvars;
3958 int i;
3959
3960 assert(scip != NULL);
3961 assert(cons != NULL);
3962
3963 if( infeasible != NULL )
3964 *infeasible = FALSE;
3965
3966 consdata = SCIPconsGetData(cons);
3967 assert(consdata != NULL);
3968
3969 if( consdata->eventdata == NULL )
3970 {
3971 SCIP_CONSHDLR* conshdlr;
3972 SCIP_CONSHDLRDATA* conshdlrdata;
3973
3974 conshdlr = SCIPconsGetHdlr(cons);
3975 assert(conshdlr != NULL);
3976
3977 conshdlrdata = SCIPconshdlrGetData(conshdlr);
3978 assert(conshdlrdata != NULL);
3979
3980 /* catch bound change events of variables */
3981 SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
3982 assert(consdata->eventdata != NULL);
3983 }
3984
3985 if( !consdata->removedfixings )
3986 {
3987 SCIP_RATIONAL* lhssubtrahend;
3988 SCIP_RATIONAL* rhssubtrahend;
3989 SCIP_RATIONAL* tmpval;
3990
3994
3995 SCIPdebugMsg(scip, "applying fixings:\n");
3997
3998 v = 0;
3999 while( v < consdata->nvars )
4000 {
4001 var = consdata->vars[v];
4002 val = consdata->vals[v];
4004
4005 switch( SCIPvarGetStatus(var) )
4006 {
4008 SCIPerrorMessage("original variable in transformed linear constraint\n");
4009 return SCIP_INVALIDDATA;
4010
4013 ++v;
4014 break;
4015
4018 fixedval = SCIPvarGetLbGlobalExact(var);
4019 if( !SCIPrationalIsNegInfinity(consdata->lhs) )
4020 {
4021 if( SCIPrationalIsAbsInfinity(fixedval) )
4022 {
4023 if( SCIPrationalGetSign(val) == SCIPrationalGetSign(fixedval) )
4024 {
4026 SCIP_CALL( chgLhs(scip, cons, tmpval) );
4027 }
4028 else
4029 {
4030 if( infeasible != NULL )
4031 {
4032 /* if lhs gets infinity it means that the problem is infeasible */
4033 *infeasible = TRUE;
4034 return SCIP_OKAY;
4035 }
4036 else
4037 {
4039 SCIP_CALL( chgLhs(scip, cons, tmpval) );
4040 }
4041 }
4042 }
4043 else
4044 SCIPrationalAddProd(lhssubtrahend, val, fixedval);
4045 }
4046 if( !SCIPrationalIsInfinity(consdata->rhs) )
4047 {
4048 if( SCIPrationalIsAbsInfinity(fixedval) )
4049 {
4050 if( SCIPrationalGetSign(val) == SCIPrationalGetSign(fixedval) )
4051 {
4052 if( infeasible != NULL )
4053 {
4054 /* if rhs gets -infinity it means that the problem is infeasible */
4055 *infeasible = TRUE;
4056 return SCIP_OKAY;
4057 }
4058 else
4059 {
4061 SCIP_CALL( chgRhs(scip, cons, tmpval) );
4062 }
4063 }
4064 else
4065 {
4067 SCIP_CALL( chgRhs(scip, cons, tmpval) );
4068 }
4069 }
4070 else
4071 SCIPrationalAddProd(rhssubtrahend, val, fixedval);
4072 }
4073 SCIP_CALL( delCoefPos(scip, cons, v) );
4074 break;
4075
4077 {
4078 SCIP_VAR* activevar = SCIPvarGetAggrVar(var);
4079 SCIP_RATIONAL* activescalar;
4080 SCIP_RATIONAL* activeconstant;
4081
4083 SCIP_CALL( SCIPrationalCreateBuffer(SCIPbuffer(scip), &activeconstant) );
4084
4085 SCIPrationalMult(activescalar, val, SCIPvarGetAggrScalarExact(var));
4086 SCIPrationalMult(activeconstant, val, SCIPvarGetAggrConstantExact(var));
4087
4088 assert(activevar != NULL);
4089 SCIP_CALL( SCIPgetProbvarSumExact(scip, &activevar, activescalar, activeconstant) );
4090 assert(activevar != NULL);
4091
4092 if( !SCIPrationalIsZero(activescalar) )
4093 {
4094 SCIP_CALL( addCoef(scip, cons, activevar, activescalar) );
4095 }
4096
4097 if( !SCIPrationalIsZero(activeconstant) )
4098 {
4099 if( !SCIPrationalIsNegInfinity(consdata->lhs) )
4100 SCIPrationalAdd(lhssubtrahend, lhssubtrahend, activeconstant);
4101 if( !SCIPrationalIsInfinity(consdata->rhs) )
4102 SCIPrationalAdd(rhssubtrahend, rhssubtrahend, activeconstant);
4103 }
4104
4105 SCIP_CALL( delCoefPos(scip, cons, v) );
4106
4107 SCIPrationalFreeBuffer(SCIPbuffer(scip), &activescalar);
4108 SCIPrationalFreeBuffer(SCIPbuffer(scip), &activeconstant);
4109 break;
4110 }
4113 naggrvars = SCIPvarGetMultaggrNVars(var);
4114 aggrvars = SCIPvarGetMultaggrVars(var);
4115 aggrscalars = SCIPvarGetMultaggrScalarsExact(var);
4116 for( i = 0; i < naggrvars; ++i )
4117 {
4118 SCIPrationalMult(tmpval, val, aggrscalars[i]);
4119 SCIP_CALL( addCoef(scip, cons, aggrvars[i], tmpval) );
4120 }
4122
4123 if( !SCIPrationalIsNegInfinity(consdata->lhs) )
4124 {
4125 SCIPrationalMult(tmpval, val, aggrconst);
4126 SCIPrationalAdd(lhssubtrahend, lhssubtrahend, tmpval);
4127 }
4128 if( !SCIPrationalIsInfinity(consdata->rhs) )
4129 {
4130 SCIPrationalMult(tmpval, val, aggrconst);
4131 SCIPrationalAdd(rhssubtrahend, rhssubtrahend, tmpval);
4132 }
4133
4134 SCIP_CALL( delCoefPos(scip, cons, v) );
4135 break;
4136
4138 SCIPrationalNegate(tmpval, val);
4139 SCIP_CALL( addCoef(scip, cons, SCIPvarGetNegationVar(var), tmpval) );
4140 negconst = SCIPvarGetNegationConstant(var);
4141
4142 if( !SCIPrationalIsNegInfinity(consdata->lhs) )
4143 {
4144 SCIPrationalMultReal(tmpval, val, negconst);
4145 SCIPrationalAdd(lhssubtrahend, lhssubtrahend, tmpval);
4146 }
4147 if( !SCIPrationalIsInfinity(consdata->rhs) )
4148 {
4149 SCIPrationalMultReal(tmpval, val, negconst);
4150 SCIPrationalAdd(rhssubtrahend, rhssubtrahend, tmpval);
4151 }
4152
4153 SCIP_CALL( delCoefPos(scip, cons, v) );
4154 break;
4155
4156 default:
4157 SCIPerrorMessage("unknown variable status\n");
4158 SCIPABORT();
4159 return SCIP_INVALIDDATA; /*lint !e527*/
4160 }
4161 }
4162
4163 if( !SCIPrationalIsAbsInfinity(consdata->lhs) )
4164 {
4165 SCIPrationalDiff(tmpval, consdata->lhs, lhssubtrahend);
4166 SCIP_CALL( chgLhs(scip, cons, tmpval) );
4167 }
4168 if( !SCIPrationalIsAbsInfinity(consdata->rhs) )
4169 {
4170 SCIPrationalDiff(tmpval, consdata->rhs, rhssubtrahend);
4171 SCIP_CALL( chgRhs(scip, cons, tmpval) );
4172 }
4173
4174 consdata->removedfixings = TRUE;
4175
4176 SCIPdebugMsg(scip, "after fixings:\n");
4178
4179 /* if aggregated variables have been replaced, multiple entries of the same variable are possible and we have
4180 * to clean up the constraint
4181 */
4182 SCIP_CALL( mergeMultiples(scip, cons) );
4183
4184 SCIPdebugMsg(scip, "after merging:\n");
4186
4188 SCIPrationalFreeBuffer(SCIPbuffer(scip), &rhssubtrahend);
4189 SCIPrationalFreeBuffer(SCIPbuffer(scip), &lhssubtrahend);
4190 }
4191 assert(consdata->removedfixings);
4192
4193#ifndef NDEBUG
4194 /* check, if all fixings are applied */
4195 for( v = 0; v < consdata->nvars; ++v )
4196 assert(SCIPvarIsActive(consdata->vars[v]));
4197#endif
4198
4199 return SCIP_OKAY;
4200}
4201
4202/** prints activity conflict to certificate file */
4203static
4205 SCIP* scip, /**< SCIP data structure */
4206 SCIP_CONS* cons, /**< constraint */
4207 SCIP_CONSDATA* consdata, /**< constraint data */
4208 SCIP_Bool rhs /**< right-hand side */
4209 )
4210{
4211 SCIP_Real side;
4212 SCIP_Real activity;
4213 SCIP_RATIONAL* diff;
4214 int nvals;
4215 SCIP_RATIONAL** vals;
4216
4217 if( !SCIPisCertified(scip) )
4218 return SCIP_OKAY;
4219
4221
4222 if( rhs )
4223 {
4225 side = consdata->rhsreal;
4226 activity = consdata->minactivity;
4227 assert( activity > side );
4228 }
4229 else
4230 {
4232 side = consdata->lhsreal;
4233 activity = consdata->maxactivity;
4234 assert( activity < side );
4235 }
4236
4237 if( consdata->rowexact != NULL )
4238 {
4239 nvals = SCIProwExactGetNNonz(consdata->rowexact);
4240 vals = SCIProwExactGetVals(consdata->rowexact);
4241 }
4242 else
4243 {
4244 nvals = consdata->nvars;
4245 vals = consdata->vals;
4246 }
4247 SCIPrationalSetReal(diff, activity);
4248 SCIPrationalDiffReal(diff, diff, side);
4249
4250 SCIP_CALL( SCIPcertifyActivityConflict(scip, cons, consdata->rowexact, consdata->lhs, consdata->rhs,
4251 nvals, vals, consdata->vars, diff, rhs) );
4252
4254
4255 return SCIP_OKAY;
4256}
4257
4258/** tightens bounds of a single variable due to activity bounds */
4259static
4261 SCIP* scip, /**< SCIP data structure */
4262 SCIP_CONS* cons, /**< linear constraint */
4263 int pos, /**< position of the variable in the vars array */
4264 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
4265 int* nchgbds, /**< pointer to count the total number of tightened bounds */
4266 SCIP_Bool force /**< should a possible bound change be forced even if below bound strengthening tolerance */
4267 )
4268{
4269 SCIP_CONSDATA* consdata;
4270 SCIP_VAR* var;
4271 SCIP_INTERVAL valrange;
4272 SCIP_Real lb;
4273 SCIP_Real ub;
4274 SCIP_Real minresactivity;
4275 SCIP_Real maxresactivity;
4276 SCIP_Real lhs;
4277 SCIP_Real rhs;
4278 SCIP_Bool infeasible;
4279 SCIP_Bool tightened;
4280 SCIP_Bool minisrelax;
4281 SCIP_Bool maxisrelax;
4282 SCIP_Bool isminsettoinfinity;
4283 SCIP_Bool ismaxsettoinfinity;
4284 SCIP_ROUNDMODE prevmode;
4285 SCIP_RATIONAL* tmpbound;
4286 SCIP_CONSHDLR* conshdlr;
4287 SCIP_CONSHDLRDATA* conshdlrdata;
4288
4289 conshdlr = SCIPconsGetHdlr(cons);
4290 assert(conshdlr != NULL);
4291
4292 conshdlrdata = SCIPconshdlrGetData(conshdlr);
4293 assert(conshdlrdata != NULL);
4294
4295 prevmode = SCIPintervalGetRoundingMode();
4296
4297 assert(scip != NULL);
4298 assert(cons != NULL);
4299 assert(cutoff != NULL);
4300 assert(nchgbds != NULL);
4301
4302 /* we cannot tighten variables' bounds, if the constraint may be not complete */
4303 if( SCIPconsIsModifiable(cons) )
4304 goto RETURN_SCIP_OKAY;
4305
4306 consdata = SCIPconsGetData(cons);
4307 assert(consdata != NULL);
4308
4309 *cutoff = FALSE;
4310
4311 var = consdata->vars[pos];
4312
4313 /* we cannot tighten bounds of multi-aggregated variables */
4315 {
4316 return SCIP_OKAY;
4317 }
4318 else
4319 {
4320 SCIP_VAR* tmpVar;
4321 SCIP_Real tmpBound;
4322 SCIP_BOUNDTYPE tmpBoundtype;
4323 tmpVar = var;
4324 SCIP_CALL( SCIPvarGetProbvarBound(&tmpVar, &tmpBound, &tmpBoundtype) );
4326 goto RETURN_SCIP_OKAY;
4327 }
4328 }
4329
4330 if( SCIPvarGetType(var) == SCIP_VARTYPE_CONTINUOUS && !conshdlrdata->propcont )
4331 return SCIP_OKAY;
4332
4333 valrange = consdata->valsreal[pos];
4334 lhs = consdata->lhsreal;
4335 rhs = consdata->rhsreal;
4336 consdataGetActivityResiduals(scip, consdata, var, valrange, FALSE, &minresactivity, &maxresactivity,
4337 &minisrelax, &maxisrelax, &isminsettoinfinity, &ismaxsettoinfinity);
4338 assert(var != NULL);
4339 assert(!SCIPisInfinity(scip, lhs));
4340 assert(!SCIPisInfinity(scip, -rhs));
4341
4342 lb = SCIPvarGetLbLocal(var);
4343 ub = SCIPvarGetUbLocal(var);
4344 assert(SCIPisLE(scip, lb, ub));
4345
4346 if( valrange.sup > 0.0 )
4347 {
4348 /* check, if we can tighten the variable's bounds */
4349 if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && !minisrelax )
4350 {
4351 SCIP_Real newub;
4352 SCIP_INTERVAL ubinterval;
4353
4355
4356 /* newub = (rhs + SCIPintervalNegateReal(minresactivity))/valrange.inf; */
4357 SCIPintervalSet(&ubinterval, rhs);
4358 SCIPintervalSubScalar(SCIPinfinity(scip), &ubinterval, ubinterval, minresactivity);
4359 SCIPintervalDiv(SCIPinfinity(scip), &ubinterval, ubinterval, valrange);
4360 newub = ubinterval.sup;
4361
4362 if( !SCIPisInfinity(scip, newub) &&
4363 ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
4364 {
4365 /* activity is never unreliable in exact solving */
4366
4367 /* tighten upper bound */
4368 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newub=%.15g\n",
4369 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, valrange.inf, minresactivity, maxresactivity, lhs, rhs, newub);
4370
4372 {
4373 SCIP_Longint boundmaxdenom;
4374
4376 SCIPrationalSetReal(tmpbound, newub);
4377
4378 if( conshdlrdata->limitdenom )
4379 {
4380 boundmaxdenom = conshdlrdata->boundmaxdenom;
4381 SCIPrationalComputeApproximation(tmpbound, tmpbound, boundmaxdenom, 1);
4382 }
4383
4386 SCIP_BOUNDTYPE_UPPER, tmpbound, false, cons, var, consdata->rowexact, consdata->vals, consdata->lhs, consdata->rhs, consdata->vars, consdata->nvars) );
4387
4389 &infeasible, &tightened) );
4391 }
4392 else
4393 {
4396 SCIP_BOUNDTYPE_UPPER, newub, false, cons, var, consdata->rowexact, consdata->vals, consdata->lhs, consdata->rhs, consdata->vars, consdata->nvars) );
4397
4398 newub = SCIPadjustedVarUbExactFloat(scip, var, newub);
4399 SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_RHS, pos), force,
4400 &infeasible, &tightened) );
4401 }
4402
4403 if( infeasible )
4404 {
4405 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
4406 SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
4407
4408 /* analyze conflict */
4411 *cutoff = TRUE;
4412 goto RETURN_SCIP_OKAY;
4413 }
4414 if( tightened )
4415 {
4416 ub = SCIPvarGetUbLocal(var); /* get bound again: it may be additionally modified due to integrality */
4417 (*nchgbds)++;
4418
4419 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
4420 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
4421 }
4422 }
4423 }
4424
4425 if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && !maxisrelax )
4426 {
4427 SCIP_Real newlb;
4428 SCIP_INTERVAL lbinterval;
4429
4431 /* newlb = (lhs + SCIPintervalNegateReal(maxresactivity))/valrange.sup; */
4432 SCIPintervalSet(&lbinterval, lhs);
4433 SCIPintervalSubScalar(SCIPinfinity(scip), &lbinterval, lbinterval, maxresactivity);
4434 SCIPintervalDiv(SCIPinfinity(scip), &lbinterval, lbinterval, valrange);
4435 newlb = lbinterval.inf;
4436
4437 if( !SCIPisInfinity(scip, -newlb) &&
4438 ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
4439 {
4440 /* tighten lower bound */
4441 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
4442 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, valrange.inf, minresactivity, maxresactivity, lhs, rhs, newlb);
4443
4445 {
4446 SCIP_Longint boundmaxdenom;
4447
4449 SCIPrationalSetReal(tmpbound, newlb);
4450
4451 if( conshdlrdata->limitdenom )
4452 {
4453 boundmaxdenom = conshdlrdata->boundmaxdenom;
4454 SCIPrationalComputeApproximation(tmpbound, tmpbound, boundmaxdenom, -1);
4455 }
4458 SCIP_BOUNDTYPE_LOWER, tmpbound, true, cons, var, consdata->rowexact, consdata->vals, consdata->lhs, consdata->rhs, consdata->vars, consdata->nvars) );
4459
4461 &infeasible, &tightened) );
4463 }
4464 else
4465 {
4468 SCIP_BOUNDTYPE_LOWER, newlb, true, cons, var, consdata->rowexact, consdata->vals, consdata->lhs, consdata->rhs, consdata->vars, consdata->nvars) );
4469
4470 newlb = SCIPadjustedVarLbExactFloat(scip, var, newlb);
4471 SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_LHS, pos), force,
4472 &infeasible, &tightened) );
4473 }
4474
4475 if( infeasible )
4476 {
4477 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
4478 SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
4479
4482
4483 *cutoff = TRUE;
4484 goto RETURN_SCIP_OKAY;
4485 }
4486 if( tightened )
4487 {
4488 (*nchgbds)++;
4489 SCIPdebug(lb = SCIPvarGetLbLocal(var)); /* get bound again: it may be additionally modified due to integrality */
4490 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
4491 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
4492 }
4493 }
4494 }
4495 }
4496 else
4497 {
4498 /* check, if we can tighten the variable's bounds */
4499 if( !isminsettoinfinity && !SCIPisInfinity(scip, rhs) && !minisrelax )
4500 {
4501 SCIP_Real newlb;
4502 SCIP_INTERVAL lbinterval;
4503
4505
4506 SCIPintervalSet(&lbinterval, rhs);
4507 SCIPintervalSubScalar(SCIPinfinity(scip), &lbinterval, lbinterval, minresactivity);
4508 SCIPintervalDiv(SCIPinfinity(scip), &lbinterval, lbinterval, valrange);
4509 newlb = lbinterval.inf;
4510
4511 assert(newlb <= lbinterval.inf);
4512
4513 if( !SCIPisInfinity(scip, -newlb) &&
4514 ((force && SCIPisGT(scip, newlb, lb)) || (SCIPvarIsIntegral(var) && SCIPisFeasGT(scip, newlb, lb)) || SCIPisLbBetter(scip, newlb, lb, ub)) )
4515 {
4516 /* tighten lower bound */
4517 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g] -> newlb=%.15g\n",
4518 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, valrange.sup, minresactivity, maxresactivity, lhs, rhs, newlb);
4519
4521 {
4522 SCIP_Longint boundmaxdenom;
4523
4525 SCIPrationalSetReal(tmpbound, newlb);
4526
4527 if( conshdlrdata->limitdenom )
4528 {
4529 boundmaxdenom = conshdlrdata->boundmaxdenom;
4530 SCIPrationalComputeApproximation(tmpbound, tmpbound, boundmaxdenom, -1);
4531 }
4534 SCIP_BOUNDTYPE_LOWER, tmpbound, false, cons, var, consdata->rowexact, consdata->vals, consdata->lhs, consdata->rhs, consdata->vars, consdata->nvars) );
4535
4537 &infeasible, &tightened) );
4539 }
4540 else
4541 {
4544 SCIP_BOUNDTYPE_LOWER, newlb, false, cons, var, consdata->rowexact, consdata->vals, consdata->lhs, consdata->rhs, consdata->vars, consdata->nvars) );
4545
4546 newlb = SCIPadjustedVarLbExactFloat(scip, var, newlb);
4547 SCIP_CALL( SCIPinferVarLbCons(scip, var, newlb, cons, getInferInt(PROPRULE_1_RHS, pos), force,
4548 &infeasible, &tightened) );
4549 }
4550
4551 if( infeasible )
4552 {
4553 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
4554 SCIPconsGetName(cons), SCIPvarGetName(var), newlb, ub);
4555
4558
4559 /**@todo analyze conflict detected in exactlinear constraint handler */
4560 *cutoff = TRUE;
4561 goto RETURN_SCIP_OKAY;
4562 }
4563 if( tightened )
4564 {
4565 lb = SCIPvarGetLbLocal(var); /* get bound again: it may be additionally modified due to integrality */
4566 (*nchgbds)++;
4567 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
4568 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
4569 }
4570 }
4571 }
4572
4573 if( !ismaxsettoinfinity && !SCIPisInfinity(scip, -lhs) && !maxisrelax )
4574 {
4575 SCIP_Real newub;
4576 SCIP_INTERVAL ubinterval;
4577
4579
4580 /* newub = (maxresactivity + SCIPintervalNegateReal(lhs))/SCIPintervalNegateReal(valrange.inf); */
4581 SCIPintervalSet(&ubinterval, lhs);
4582 SCIPintervalSubScalar(SCIPinfinity(scip), &ubinterval, ubinterval, maxresactivity);
4583 SCIPintervalDiv(SCIPinfinity(scip), &ubinterval, ubinterval, valrange);
4584 newub = ubinterval.sup;
4585
4586 if( !SCIPisInfinity(scip, newub) &&
4587 ((force && SCIPisLT(scip, newub, ub)) || (SCIPvarIsIntegral(var) && SCIPisFeasLT(scip, newub, ub)) || SCIPisUbBetter(scip, newub, lb, ub)) )
4588 {
4589 /* tighten upper bound */
4590 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, old bds=[%.15g,%.15g], val=%.15g, resactivity=[%.15g,%.15g], sides=[%.15g,%.15g], newub=%.15g\n",
4591 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub, valrange.sup, minresactivity, maxresactivity, lhs, rhs, newub);
4592
4594 {
4595 SCIP_Longint boundmaxdenom;
4596
4598 SCIPrationalSetReal(tmpbound, newub);
4599
4600 if( conshdlrdata->limitdenom )
4601 {
4602 boundmaxdenom = conshdlrdata->boundmaxdenom;
4603 SCIPrationalComputeApproximation(tmpbound, tmpbound, boundmaxdenom, 1);
4604 }
4607 SCIP_BOUNDTYPE_UPPER, tmpbound, true, cons, var, consdata->rowexact, consdata->vals, consdata->lhs, consdata->rhs, consdata->vars, consdata->nvars) );
4608
4610 &infeasible, &tightened) );
4612 }
4613 else
4614 {
4617 SCIP_BOUNDTYPE_UPPER, newub, true, cons, var, consdata->rowexact, consdata->vals, consdata->lhs, consdata->rhs, consdata->vars, consdata->nvars) );
4618
4619 newub = SCIPadjustedVarUbExactFloat(scip, var, newub);
4620 SCIP_CALL( SCIPinferVarUbCons(scip, var, newub, cons, getInferInt(PROPRULE_1_LHS, pos), force,
4621 &infeasible, &tightened) );
4622 }
4623
4624 if( infeasible )
4625 {
4626 SCIPdebugMsg(scip, "linear constraint <%s>: cutoff <%s>, new bds=[%.15g,%.15g]\n",
4627 SCIPconsGetName(cons), SCIPvarGetName(var), lb, newub);
4628
4631
4632 *cutoff = TRUE;
4633 goto RETURN_SCIP_OKAY;
4634 }
4635 if( tightened )
4636 {
4637 (*nchgbds)++;
4638 SCIPdebug(ub = SCIPvarGetUbLocal(var)); /* get bound again: it may be additionally modified due to integrality */
4639 SCIPdebugMsg(scip, "linear constraint <%s>: tighten <%s>, new bds=[%.15g,%.15g]\n",
4640 SCIPconsGetName(cons), SCIPvarGetName(var), lb, ub);
4641 }
4642 }
4643 }
4644 }
4645 RETURN_SCIP_OKAY:
4647 return SCIP_OKAY;
4648}
4649
4650#define MAXTIGHTENROUNDS 10
4651
4652/** tightens bounds of variables in constraint due to activity bounds */
4653static
4655 SCIP* scip, /**< SCIP data structure */
4656 SCIP_CONS* cons, /**< linear constraint */
4657 SCIP_Bool sortvars, /**< should variables be used in sorted order? */
4658 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
4659 int* nchgbds /**< pointer to count the total number of tightened bounds */
4660 )
4661{
4662 SCIP_CONSDATA* consdata;
4663 unsigned int tightenmode;
4664 int nvars;
4665 int nrounds;
4666 int lastchange;
4667 int v;
4668 SCIP_Bool force;
4669
4670 assert(scip != NULL);
4671 assert(cons != NULL);
4672 assert(nchgbds != NULL);
4673 assert(cutoff != NULL);
4674
4675 *cutoff = FALSE;
4676
4677 /* we cannot tighten variables' bounds, if the constraint may be not complete */
4678 if( SCIPconsIsModifiable(cons) )
4679 return SCIP_OKAY;
4680
4681 /* currently, we do not need to call applyFixings() as in cons_linear.c */
4682
4683 consdata = SCIPconsGetData(cons);
4684 assert(consdata != NULL);
4685
4686 nvars = consdata->nvars;
4687 force = (nvars == 1) && !SCIPconsIsModifiable(cons);
4688
4689 /* we are at the root node or during presolving */
4690 if( SCIPgetDepth(scip) < 1 )
4691 tightenmode = 2;
4692 else
4693 tightenmode = 1;
4694
4695 /* stop if we already tightened the constraint and the tightening is not forced */
4696 if( !force && (consdata->boundstightened >= tightenmode) ) /*lint !e574*/
4697 return SCIP_OKAY;
4698
4699 /* ensure that the variables are properly sorted */
4700 if( sortvars && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE && !consdata->coefsorted )
4701 {
4702 SCIP_CALL( consdataSort(scip, consdata) );
4703 assert(consdata->coefsorted);
4704 }
4705
4706 /* update maximal activity delta if necessary */
4707 if( consdata->maxactdelta == SCIP_INVALID ) /*lint !e777*/
4709
4710 assert(consdata->maxactdelta != SCIP_INVALID); /*lint !e777*/
4711 assert(!SCIPisFeasNegative(scip, consdata->maxactdelta));
4712 checkMaxActivityDelta(scip, consdata);
4713
4714 /* this may happen if all variables are fixed */
4715 if( SCIPisFeasZero(scip, consdata->maxactdelta) )
4716 return SCIP_OKAY;
4717
4718 if( !SCIPisInfinity(scip, consdata->maxactdelta) )
4719 {
4720 SCIP_Real slack;
4721 SCIP_Real surplus;
4722 SCIP_Real minactivity;
4723 SCIP_Real maxactivity;
4724 SCIP_Bool minisrelax;
4725 SCIP_Bool maxisrelax;
4726 SCIP_Bool isminsettoinfinity;
4727 SCIP_Bool ismaxsettoinfinity;
4728
4729 /* use maximal activity delta to skip propagation (cannot deduce anything) */
4730 consdataGetActivityBounds(scip, consdata, FALSE, &minactivity, &maxactivity, &minisrelax, &maxisrelax,
4731 &isminsettoinfinity, &ismaxsettoinfinity);
4732
4733 assert(!SCIPisInfinity(scip, minactivity));
4734 assert(!SCIPisInfinity(scip, -maxactivity));
4735
4736 slack = (SCIPisInfinity(scip, consdata->rhsreal) || isminsettoinfinity) ? SCIPinfinity(scip) : (consdata->rhsreal - minactivity);
4737 surplus = (SCIPisInfinity(scip, -consdata->lhsreal) || ismaxsettoinfinity) ? SCIPinfinity(scip) : (maxactivity - consdata->lhsreal);
4738
4739 /* check if the constraint will propagate */
4740 if( consdata->maxactdelta <= MIN(slack, surplus) )
4741 return SCIP_OKAY;
4742 }
4743
4744 /* as long as the bounds might be tightened again, try to tighten them; abort after a maximal number of rounds */
4745 lastchange = -1;
4746
4747 for( nrounds = 0; (force || consdata->boundstightened < tightenmode) && nrounds < MAXTIGHTENROUNDS; ++nrounds ) /*lint !e574*/
4748 {
4749#ifdef SCIP_DEBUG
4750 int oldnchgbdstotal = *nchgbds;
4751#endif
4752
4753 /* ensure that the variables are properly sorted
4754 *
4755 * note: it might happen that integer variables become binary during bound tightening at the root node
4756 */
4757 if( sortvars && SCIPgetStage(scip) >= SCIP_STAGE_INITSOLVE && !consdata->coefsorted )
4758 {
4759 SCIP_CALL( consdataSort(scip, consdata) );
4760 assert(consdata->coefsorted);
4761 }
4762
4763 /* mark the constraint to have the variables' bounds tightened */
4764 consdata->boundstightened = (unsigned int)tightenmode;
4765 /* try to tighten the bounds of each variable in the constraint. During solving process, the binary variable
4766 * sorting enables skipping variables
4767 */
4768 v = 0;
4769 while( v < nvars && v != lastchange && !(*cutoff) )
4770 {
4771 int oldnchgbds = *nchgbds;
4772
4773 SCIP_CALL( tightenVarBounds(scip, cons, v, cutoff, nchgbds, force) );
4774
4775 /* if there was no progress, skip the rest of the binary variables */
4776 if( *cutoff )
4777 {
4778 break;
4779 }
4780 else if( *nchgbds > oldnchgbds )
4781 {
4782 lastchange = v;
4783 ++v;
4784 }
4785 else if( consdata->coefsorted && v < consdata->nbinvars - 1
4786 && !SCIPisFeasEQ(scip, SCIPvarGetUbLocal(consdata->vars[v]), SCIPvarGetLbLocal(consdata->vars[v])) )
4787 v = consdata->nbinvars;
4788 else
4789 ++v;
4790 }
4791
4792#ifdef SCIP_DEBUG
4793 SCIPdebugMsg(scip, "linear constraint <%s> found %d bound changes in round %d\n", SCIPconsGetName(cons),
4794 *nchgbds - oldnchgbdstotal, nrounds);
4795#endif
4796 }
4797
4798 return SCIP_OKAY;
4799}
4800
4801/** checks linear constraint for feasibility of given solution or current solution */
4802static
4804 SCIP* scip, /**< SCIP data structure */
4805 SCIP_CONS* cons, /**< linear constraint */
4806 SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
4807 SCIP_SOL* sol, /**< solution to be checked, or NULL for current solution */
4808 SCIP_Bool useexactsol, /**< should the sol or solex be checked? */
4809 SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
4810 SCIP_Bool* violated /**< pointer to store whether the constraint is violated */
4811 )
4812{
4813 SCIP_CONSDATA* consdata;
4814 SCIP_RATIONAL* activity;
4815 SCIP_Bool success;
4816
4817 assert(scip != NULL);
4818 assert(cons != NULL);
4819 assert(violated != NULL);
4820
4821 SCIPdebugMsg(scip, "checking linear constraint <%s>\n", SCIPconsGetName(cons));
4822 SCIPdebug(consPrintConsSol(scip, cons, sol, useexactsol, NULL));
4823
4824 consdata = SCIPconsGetData(cons);
4825 assert(consdata != NULL);
4826
4827 *violated = FALSE;
4828 activity = consdata->activity;
4829
4830 /* only check exact constraint if fp cons is feasible enough */
4831 if( (consdata->rowexact == NULL || checklprows) && !SCIPrationalIsEQ(consdata->lhs, consdata->rhs) )
4832 {
4833 SCIP_Real activityfp;
4834 SCIP_Real mu;
4835
4836 success = consdataComputeSolActivityWithErrorbound(scip, consdata, sol, &activityfp, &mu);
4837
4838 conshdlrdata->ncheckserrorbound++;
4839
4840 if( !success )
4841 conshdlrdata->nabotserrorbound++;
4842
4843 if( success )
4844 {
4845 if( activityfp - mu > consdata->rhsreal || activityfp + mu < consdata->lhsreal )
4846 {
4847 SCIPdebugMsg(scip, "discarding solution due to fp check: activityfp=%g, lhsreal=%g, rhsreal=%g, mu=%g\n",
4848 activityfp, consdata->lhsreal, consdata->rhsreal, mu);
4849 *violated = TRUE;
4850 conshdlrdata->nsuccesserrorbound++;
4851 return SCIP_OKAY;
4852 }
4853 else if( activityfp + mu < consdata->rhsreal && activityfp - mu >= consdata->lhsreal )
4854 {
4855 SCIPdebugMsg(scip, "skipping exact check due to fp check: activityfp=%g, lhsreal=%g, rhsreal=%g, mu=%g\n",
4856 activityfp, consdata->lhsreal, consdata->rhsreal, mu);
4857 *violated = FALSE;
4858 conshdlrdata->nsuccesserrorbound++;
4859 return SCIP_OKAY;
4860 }
4861 else
4862 {
4863 SCIPdebugMsg(scip, "no decision due to fp check: activityfp=%g, lhsreal=%g, rhsreal=%g, mu=%g\n",
4864 activityfp, consdata->lhsreal, consdata->rhsreal, mu);
4865 }
4866 }
4867 }
4868
4869 if( consdata->rowexact != NULL )
4870 {
4871 if( !checklprows && SCIProwExactIsInLP(consdata->rowexact) && SCIPlpExactIsSolved(scip) )
4872 return SCIP_OKAY;
4873 else if( sol == NULL && !SCIPhasCurrentNodeLP(scip) )
4874 consdataComputePseudoActivity(consdata, activity);
4875 else
4876 {
4877 SCIP_CALL( SCIPgetRowSolActivityExact(scip, consdata->rowexact, sol, useexactsol, activity) );
4878 }
4879 }
4880 else
4881 consdataGetActivity(scip, consdata, sol, useexactsol, activity);
4882
4883 SCIPrationalDebugMessage("consdata activity=%q (lhs=%q, rhs=%q, row=%p, checklprows=%u, rowinlp=%u, sol=%p, hascurrentnodelp=%u)\n",
4884 activity, consdata->lhs, consdata->rhs, (void*)consdata->rowexact, checklprows,
4885 consdata->rowexact == NULL ? 0 : SCIProwExactIsInLP(consdata->rowexact), (void*)sol,
4886 consdata->rowexact == NULL ? FALSE : SCIPhasCurrentNodeLP(scip));
4887
4888 /* the activity of pseudo solutions may be invalid if it comprises positive and negative infinity contributions; we
4889 * return infeasible for safety
4890 */
4891 if( ((!SCIPrationalIsNegInfinity(consdata->lhs) && SCIPrationalIsLT(activity, consdata->lhs)) ||
4892 (!SCIPrationalIsInfinity(consdata->rhs) && SCIPrationalIsGT(activity, consdata->rhs))) )
4893 {
4894 *violated = TRUE;
4895
4896 /* only reset constraint age if we are in enforcement */
4897 if( sol == NULL )
4898 {
4900 }
4901 }
4902 else
4903 {
4904 /* only increase constraint age if we are in enforcement */
4905 if( sol == NULL )
4906 {
4907 SCIP_CALL( SCIPincConsAge(scip, cons) );
4908 }
4909 }
4910
4911 return SCIP_OKAY;
4912}
4913
4914/** creates an LP row in a linear constraint data */
4915static
4917 SCIP* scip, /**< SCIP data structure */
4918 SCIP_CONS* cons /**< linear constraint */
4919 )
4920{
4921 SCIP_CONSDATA* consdata;
4922 SCIP_Bool onerowrelax;
4923 SCIP_Bool hasfprelax;
4924
4925 assert(scip != NULL);
4926 assert(cons != NULL);
4927
4928 consdata = SCIPconsGetData(cons);
4929
4930 assert(consdata != NULL);
4931 assert(consdata->rowexact == NULL);
4932
4933 /* create empty fp-rows */
4936
4939
4940 /* create exact row */
4941 SCIP_CALL( SCIPcreateEmptyRowConsExact(scip, &consdata->rowexact, consdata->rowlhs, consdata->rowrhs,
4942 consdata->lhs, consdata->rhs, consdata->hasfprelax) );
4943
4944 SCIP_CALL( SCIPcaptureRowExact(scip, consdata->rowexact) );
4945
4946 SCIP_CALL( SCIPaddVarsToRowExact(scip, consdata->rowexact, consdata->nvars, consdata->vars, consdata->vals) );
4947
4948 onerowrelax = TRUE;
4949 hasfprelax = TRUE;
4950
4951 SCIP_CALL( SCIPgenerateFpRowsFromRowExact(scip, consdata->rowexact, consdata->rowlhs,
4952 consdata->rowrhs, &onerowrelax, &hasfprelax) );
4953
4954 consdata->onerowrelax = onerowrelax;
4955 consdata->hasfprelax = hasfprelax;
4957 if( !(consdata->hasfprelax) || consdata->onerowrelax )
4958 consdata->rowrhs = NULL;
4959
4960 return SCIP_OKAY;
4961}
4962
4963/** adds linear constraint as cut to the LP */
4964static
4966 SCIP* scip, /**< SCIP data structure */
4967 SCIP_CONS* cons, /**< linear constraint */
4968 SCIP_Bool* cutoff /**< pointer to store whether a cutoff was found */
4969 )
4970{
4971 SCIP_CONSDATA* consdata;
4972
4973 assert(scip != NULL);
4974 assert(cons != NULL);
4975
4976 consdata = SCIPconsGetData(cons);
4977 assert(consdata != NULL);
4978
4979 if( consdata->rowexact == NULL )
4980 {
4981 /* convert consdata object into LP row and exact lp row */
4982 SCIP_CALL( createRows(scip, cons) );
4983 }
4984 assert(consdata->rowlhs != NULL);
4985 assert(consdata->rowexact != NULL);
4986
4987 if( consdata->nvars == 0 )
4988 {
4989 SCIPdebugMsg(scip, "Empty linear constraint enters LP: <%s>\n", SCIPconsGetName(cons));
4990 }
4991
4992 /* insert LP row as cut */
4993 if( !SCIProwIsInLP(consdata->rowlhs) )
4994 {
4995 SCIPdebugMsg(scip, "adding relaxation of linear constraint <%s>: ", SCIPconsGetName(cons));
4996 SCIPdebug( SCIP_CALL( SCIPprintRow(scip, consdata->rowlhs, NULL)) );
4997 SCIPdebug( SCIP_CALL( SCIPprintRowExact(scip, consdata->rowexact, NULL)) );
4998
4999 /* if presolving is turned off, the row might be trivial */
5000 if( !SCIPrationalIsNegInfinity(consdata->lhs) || !SCIPrationalIsInfinity(consdata->rhs) )
5001 {
5002 SCIP_CALL( SCIPaddRow(scip, consdata->rowlhs, FALSE, cutoff) );
5003 SCIP_CALL( SCIPaddRowExact(scip, consdata->rowexact) );
5004 }
5005#ifndef NDEBUG
5006 else
5007 {
5008 int pr;
5009 int cr;
5010 SCIP_CALL( SCIPgetIntParam(scip, "presolving/maxrounds", &pr) );
5011 SCIP_CALL( SCIPgetIntParam(scip, "constraints/linear/maxprerounds", &cr) );
5012 assert( pr == 0 || cr == 0 );
5013 }
5014#endif
5015 }
5016
5017 return SCIP_OKAY;
5018}
5019
5020/** separates linear constraint: adds linear constraint as cut, if violated by given solution */
5021static
5023 SCIP* scip, /**< SCIP data structure */
5024 SCIP_CONS* cons, /**< linear constraint */
5025 SCIP_CONSHDLRDATA* conshdlrdata, /**< constraint handler data */
5026 SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
5027 int* ncuts, /**< pointer to add up the number of found cuts */
5028 SCIP_Bool* cutoff /**< pointer to store whether a cutoff was found */
5029 )
5030{ /*lint --e{715}*/
5031 SCIP_Bool violated;
5032 int oldncuts;
5033
5034 assert(scip != NULL);
5035 assert(conshdlrdata != NULL);
5036 assert(cons != NULL);
5037 assert(cutoff != NULL);
5038
5039 assert(ncuts != NULL);
5040
5041 oldncuts = *ncuts;
5042 *cutoff = FALSE;
5043
5044 SCIP_CALL( checkCons(scip, cons, conshdlrdata, sol, FALSE, (sol != NULL), &violated) );
5045
5046 if( violated )
5047 {
5048 /* insert LP row as cut */
5050 (*ncuts)++;
5051 }
5052
5053 if( *ncuts > oldncuts )
5054 {
5056 }
5057
5058 return SCIP_OKAY;
5059}
5060
5061/** propagation method for linear constraints */
5062static
5064 SCIP* scip, /**< SCIP data structure */
5065 SCIP_CONS* cons, /**< linear constraint */
5066 SCIP_Bool tightenbounds, /**< should the variable's bounds be tightened? */
5067 SCIP_Bool sortvars, /**< should variable sorting for faster propagation be used? */
5068 SCIP_Bool* cutoff, /**< pointer to store whether the node can be cut off */
5069 int* nchgbds /**< pointer to count the total number of tightened bounds */
5070 )
5071{
5072 SCIP_CONSDATA* consdata;
5073 SCIP_Real minactivity;
5074 SCIP_Real maxactivity;
5075 SCIP_Bool minactisrelax;
5076 SCIP_Bool maxactisrelax;
5077 SCIP_Bool isminsettoinfinity;
5078 SCIP_Bool ismaxsettoinfinity;
5079
5080 assert(scip != NULL);
5081 assert(cons != NULL);
5082 assert(cutoff != NULL);
5083 assert(nchgbds != NULL);
5084
5085 /*SCIPdebugMsg(scip, "propagating linear constraint <%s>\n", SCIPconsGetName(cons));*/
5086
5087 consdata = SCIPconsGetData(cons);
5088 assert(consdata != NULL);
5089
5090 if( consdata->eventdata == NULL )
5091 {
5092 SCIP_CONSHDLR* conshdlr;
5093 SCIP_CONSHDLRDATA* conshdlrdata;
5094
5095 conshdlr = SCIPconsGetHdlr(cons);
5096 assert(conshdlr != NULL);
5097
5098 conshdlrdata = SCIPconshdlrGetData(conshdlr);
5099 assert(conshdlrdata != NULL);
5100
5101 /* catch bound change events of variables */
5102 SCIP_CALL( consCatchAllEvents(scip, cons, conshdlrdata->eventhdlr) );
5103 assert(consdata->eventdata != NULL);
5104 }
5105
5106 *cutoff = FALSE;
5107
5108 /* we can only infer activity bounds of the linear constraint, if it is not modifiable */
5109 if( !SCIPconsIsModifiable(cons) )
5110 {
5111 SCIP_CONSHDLR* conshdlr;
5112 SCIP_CONSHDLRDATA* conshdlrdata;
5113
5114 conshdlr = SCIPconsGetHdlr(cons);
5115 assert(conshdlr != NULL);
5116
5117 conshdlrdata = SCIPconshdlrGetData(conshdlr);
5118 assert(conshdlrdata != NULL);
5119
5120 if( !SCIPconsIsInitial(cons) )
5121 {
5122 conshdlrdata->nconspropnoninit++;
5123 conshdlrdata->propnonzerosnoninit += consdata->nvars;
5124 }
5125 else
5126 {
5127 conshdlrdata->nconsprop++;
5128 conshdlrdata->propnonzeros += consdata->nvars;
5129 }
5130
5131 /* increase age of constraint; age is reset to zero, if a conflict or a propagation was found */
5133 {
5134 SCIP_CALL( SCIPincConsAge(scip, cons) );
5135 }
5136
5137 /* tighten the variable's bounds */
5138 if( tightenbounds )
5139 {
5140 int oldnchgbds;
5141
5142 oldnchgbds = *nchgbds;
5143
5144 SCIP_CALL( tightenBounds(scip, cons, sortvars, cutoff, nchgbds) );
5145
5146 if( *nchgbds > oldnchgbds )
5147 {
5149 }
5150 }
5151
5152 /* check constraint for infeasibility and redundancy */
5153 if( !(*cutoff) )
5154 {
5155 consdataGetActivityBounds(scip, consdata, TRUE, &minactivity, &maxactivity, &minactisrelax, &maxactisrelax,
5156 &isminsettoinfinity, &ismaxsettoinfinity);
5157
5158 if( SCIPrationalIsGTReal(consdata->lhs, maxactivity) )
5159 {
5160 SCIPrationalDebugMessage("linear constraint <%s> is infeasible (lhs): activitybounds=[%.15g,%.15g], sides=[%q,%q]\n",
5161 SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
5162
5164
5165 /**@todo analyze conflict detected in exactlinear constraint handler */
5167 *cutoff = TRUE;
5168 }
5169 else if( SCIPrationalIsLTReal(consdata->rhs, minactivity) )
5170 {
5171 SCIPrationalDebugMessage("linear constraint <%s> is infeasible (rhs): activitybounds=[%.15g,%.15g], sides=[%q,%q]\n",
5172 SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
5173
5175
5176 /**@todo analyze conflict detected in exactlinear constraint handler */
5178 *cutoff = TRUE;
5179 }
5180 else if( SCIPrationalIsLEReal(consdata->lhs, minactivity) && SCIPrationalIsGEReal(consdata->rhs, maxactivity) )
5181 {
5182 SCIPrationalDebugMessage("linear constraint <%s> is redundant: activitybounds=[%.15g,%.15g], sides=[%q,%q]\n",
5183 SCIPconsGetName(cons), minactivity, maxactivity, consdata->lhs, consdata->rhs);
5184
5185 /* remove the constraint locally unless it has become empty, in which case it is removed globally */
5186 if( consdata->nvars > 0 )
5188 else
5189 SCIP_CALL( SCIPdelCons(scip, cons) );
5190 }
5191 }
5192 }
5193
5194 return SCIP_OKAY;
5195}
5196
5197
5198/*
5199 * Presolving methods
5200 */
5201
5202/** helper function to enforce constraints */
5203static
5205 SCIP* scip, /**< SCIP data structure */
5206 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
5207 SCIP_CONS** conss, /**< constraints to process */
5208 int nconss, /**< number of constraints */
5209 int nusefulconss, /**< number of useful (non-obsolete) constraints to process */
5210 SCIP_SOL* sol, /**< solution to enforce (NULL for the LP solution) */
5211 SCIP_RESULT* result /**< pointer to store the result of the enforcing call */
5212 )
5213{
5214 SCIP_CONSHDLRDATA* conshdlrdata;
5215 SCIP_Bool violated;
5216 SCIP_Bool checkexact;
5218 int c;
5219
5220 assert(scip != NULL);
5221 assert(conshdlr != NULL);
5222 assert(result != NULL);
5223
5225
5226 conshdlrdata = SCIPconshdlrGetData(conshdlr);
5227 assert(conshdlrdata != NULL);
5228
5229 if( sol == NULL )
5230 checkexact = SCIPlpExactIsSolved(scip);
5231 else
5232 checkexact = SCIPsolIsExact(sol);
5233
5234 SCIPdebugMsg(scip, "Enforcement method of linear constraints for %s solution\n", sol == NULL ? "LP" : "relaxation");
5236
5237 /* check for violated constraints
5238 * LP is processed at current node -> we can add violated linear constraints to the SCIP_LP
5239 */
5241
5242 /* check all useful linear constraints for feasibility */
5243 for( c = 0; c < nusefulconss; ++c )
5244 {
5245 SCIP_CALL( checkCons(scip, conss[c], conshdlrdata, sol, checkexact, FALSE, &violated) );
5246
5247 if( violated )
5248 {
5249 /* insert LP row as cut */
5250 SCIP_CALL( addRelaxation(scip, conss[c], &cutoff) );
5251 if( cutoff )
5253 else
5255 }
5256 }
5257
5258 /* check all obsolete linear constraints for feasibility */
5259 for( c = nusefulconss; c < nconss && *result == SCIP_FEASIBLE; ++c )
5260 {
5261 SCIP_CALL( checkCons(scip, conss[c], conshdlrdata, sol, checkexact, FALSE, &violated) );
5262
5263 if( violated )
5264 {
5265 /* insert LP row as cut */
5266 SCIP_CALL( addRelaxation(scip, conss[c], &cutoff) );
5267 if( cutoff )
5269 else
5271 }
5272 }
5273
5274 SCIPdebugMsg(scip, "-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
5275
5276 return SCIP_OKAY;
5277}
5278
5279/*
5280 * Callback methods of constraint handler
5281 */
5282
5283/** copy method for constraint handler plugins (called when SCIP copies plugins) */
5284static
5285SCIP_DECL_CONSHDLRCOPY(conshdlrCopyExactLinear)
5286{ /*lint --e{715}*/
5287 assert(scip != NULL);
5288 assert(conshdlr != NULL);
5289
5291
5292 /* call inclusion method of constraint handler */
5294
5295 *valid = TRUE;
5296
5297 return SCIP_OKAY;
5298}
5299
5300/** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
5301static
5302SCIP_DECL_CONSFREE(consFreeExactLinear)
5303{ /*lint --e{715}*/
5304 SCIP_CONSHDLRDATA* conshdlrdata;
5305
5306 assert(scip != NULL);
5307 assert(conshdlr != NULL);
5308
5310
5311 /* free constraint handler data */
5312 conshdlrdata = SCIPconshdlrGetData(conshdlr);
5313 assert(conshdlrdata != NULL);
5314
5315 conshdlrdataFree(scip, &conshdlrdata);
5316
5317 SCIPconshdlrSetData(conshdlr, NULL);
5318
5319 return SCIP_OKAY;
5320}
5321
5322
5323/** initialization method of constraint handler (called after problem was transformed) */
5324static
5325SCIP_DECL_CONSINIT(consInitExactLinear)
5326{
5327 SCIP_CONSHDLRDATA* conshdlrdata;
5328 int c;
5329
5330 assert(scip != NULL);
5331 assert(SCIPisExact(scip) || nconss == 0);
5332
5333 /* check for event handler */
5334 conshdlrdata = SCIPconshdlrGetData(conshdlr);
5335 assert(conshdlrdata != NULL);
5336 assert(conshdlrdata->eventhdlr != NULL);
5337 assert(nconss == 0 || conss != NULL);
5338
5339 /* catch events for the constraints */
5340 for( c = 0; c < nconss; ++c )
5341 {
5342 /* catch all events */
5343 SCIP_CALL( consCatchAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
5344 }
5345
5346 return SCIP_OKAY;
5347}
5348
5349
5350/** deinitialization method of constraint handler (called before transformed problem is freed) */
5351static
5352SCIP_DECL_CONSEXIT(consExitExactLinear)
5353{
5354 SCIP_CONSHDLRDATA* conshdlrdata;
5355 int c;
5356
5357 assert(scip != NULL);
5358 assert(SCIPisExact(scip) || nconss == 0);
5359
5360 /* check for event handler */
5361 conshdlrdata = SCIPconshdlrGetData(conshdlr);
5362 assert(conshdlrdata != NULL);
5363 assert(conshdlrdata->eventhdlr != NULL);
5364
5365 /* drop events for the constraints */
5366 for( c = nconss - 1; c >= 0; --c )
5367 {
5368 SCIP_CONSDATA* consdata;
5369
5370 consdata = SCIPconsGetData(conss[c]);
5371 assert(consdata != NULL);
5372
5373 if( consdata->eventdata != NULL )
5374 {
5375 /* drop all events */
5376 SCIP_CALL( consDropAllEvents(scip, conss[c], conshdlrdata->eventhdlr) );
5377 assert(consdata->eventdata == NULL);
5378 }
5379 }
5380
5381 return SCIP_OKAY;
5382}
5383
5384/** presolving deinitialization method of constraint handler (called after presolving has been finished) */
5385static
5386SCIP_DECL_CONSEXITPRE(consExitpreExactLinear)
5387{ /*lint --e{715}*/
5388 int c;
5389
5390 assert(scip != NULL);
5391 assert(SCIPisExact(scip) || nconss == 0);
5392
5393 /* make sure, only active variables remain in the remaining constraints */
5394 for( c = 0; c < nconss; ++c )
5395 {
5396 if( SCIPconsIsDeleted(conss[c]) )
5397 continue;
5398
5399 /* since we are not allowed to detect infeasibility in the exitpre stage, we dont give an infeasible pointer */
5400 SCIP_CALL( applyFixings(scip, conss[c], NULL) );
5401 }
5402
5403 return SCIP_OKAY;
5404}
5405
5406
5407/** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
5408static
5409SCIP_DECL_CONSEXITSOL(consExitsolExactLinear)
5410{ /*lint --e{715}*/
5411 int c;
5412
5413 assert(scip != NULL);
5414 assert(SCIPisExact(scip) || nconss == 0);
5415
5416 if( !SCIPisExact(scip) )
5417 return SCIP_OKAY;
5418
5419 /* release the rows of all constraints */
5420 for( c = 0; c < nconss; ++c )
5421 {
5422 SCIP_CONSDATA* consdata;
5423
5424 consdata = SCIPconsGetData(conss[c]);
5425 assert(consdata != NULL);
5426
5427 if( consdata->rowlhs != NULL )
5428 {
5429 SCIP_CALL( SCIPreleaseRowExact(scip, &consdata->rowexact) );
5430 SCIP_CALL( SCIPreleaseRow(scip, &consdata->rowlhs) );
5431
5432 if( consdata->rowrhs != NULL )
5433 {
5434 assert(!consdata->onerowrelax);
5435 SCIP_CALL( SCIPreleaseRow(scip, &consdata->rowrhs) );
5436 }
5437 }
5438 }
5439
5440 /**@todo when enabling restarts, extend SCIPconvertCutsToConss() in order to convert exact cuts to exactlinear
5441 * constraints and call here
5442 */
5443
5444 return SCIP_OKAY;
5445}
5446
5447
5448/** constraint deactivation notification method of constraint handler */
5449static
5450SCIP_DECL_CONSDEACTIVE(consDeactiveExactLinear)
5451{ /*lint --e{715}*/
5452 assert(scip != NULL);
5454 assert(cons != NULL);
5455
5456 if( SCIPconsIsDeleted(cons) )
5457 {
5458 SCIP_CONSHDLRDATA* conshdlrdata;
5459 SCIP_CONSDATA* consdata;
5460
5461 assert(conshdlr != NULL);
5462
5464
5465 /* get constraint data */
5466 consdata = SCIPconsGetData(cons);
5467 assert(consdata != NULL);
5468
5469 /* check for event handler */
5470 conshdlrdata = SCIPconshdlrGetData(conshdlr);
5471 assert(conshdlrdata != NULL);
5472 assert(conshdlrdata->eventhdlr != NULL);
5473
5474 /* free event data */
5475 if( consdata->eventdata != NULL )
5476 {
5477 /* drop bound change events of variables */
5478 SCIP_CALL( consDropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
5479 }
5480 assert(consdata->eventdata == NULL);
5481 }
5482
5483 return SCIP_OKAY;
5484}
5485
5486
5487/** frees specific constraint data */
5488static
5489SCIP_DECL_CONSDELETE(consDeleteExactLinear)
5490{ /*lint --e{715}*/
5491 assert(scip != NULL);
5493 assert(conshdlr != NULL);
5494
5496
5497 if( (*consdata)->eventdata != NULL )
5498 {
5499 SCIP_CONSHDLRDATA* conshdlrdata;
5500
5501 conshdlrdata = SCIPconshdlrGetData(conshdlr);
5502 assert(conshdlrdata != NULL);
5503
5504 /* drop all events */
5505 SCIP_CALL( consDropAllEvents(scip, cons, conshdlrdata->eventhdlr) );
5506 assert((*consdata)->eventdata == NULL);
5507 }
5508 /* free linear constraint */
5509 SCIP_CALL( consdataFree(scip, consdata) );
5510
5511 return SCIP_OKAY;
5512}
5513
5514
5515/** transforms constraint data into data belonging to the transformed problem */
5516static
5517SCIP_DECL_CONSTRANS(consTransExactLinear)
5518{ /*lint --e{715}*/
5519 SCIP_CONSDATA* sourcedata;
5520 SCIP_CONSDATA* targetdata;
5521
5522 assert(scip != NULL);
5524 assert(conshdlr != NULL);
5526 assert(sourcecons != NULL);
5527 assert(targetcons != NULL);
5528
5530
5531 sourcedata = SCIPconsGetData(sourcecons);
5532 assert(sourcedata != NULL);
5533 assert(sourcedata->rowlhs == NULL && sourcedata->rowexact == NULL); /* in original problem, there cannot be LP rows */
5534
5535 /* create linear constraint data for target constraint */
5536 SCIP_CALL( consdataCreate(scip, &targetdata, sourcedata->nvars, sourcedata->vars, sourcedata->vals, sourcedata->lhs,
5537 sourcedata->rhs) );
5538
5539 if( sourcedata->nvars > 0 )
5540 consdataScaleMinValue(scip, targetdata, 2 * SCIPepsilon(scip));
5541
5542 /* create target constraint */
5543 SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
5544 SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
5545 SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
5546 SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
5547 SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
5548
5549 return SCIP_OKAY;
5550}
5551
5552/** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
5553static
5554SCIP_DECL_CONSINITLP(consInitlpExactLinear)
5555{ /*lint --e{715}*/
5556 int c;
5557
5558 assert(scip != NULL);
5559 assert(SCIPisExact(scip) || nconss == 0);
5560
5562
5563 *infeasible = FALSE;
5564
5565 for( c = 0; c < nconss && !(*infeasible); ++c )
5566 {
5567 assert(SCIPconsIsInitial(conss[c]));
5568 /* add both the relaxation to the fp-lp as well as the correct constraint to the exact lp */
5569 SCIP_CALL( addRelaxation(scip, conss[c], infeasible) );
5570 }
5571
5572 return SCIP_OKAY;
5573}
5574
5575/** separation method of constraint handler for LP solutions */
5576static
5577SCIP_DECL_CONSSEPALP(consSepalpExactLinear)
5578{ /*lint --e{715}*/
5579 SCIP_CONSHDLRDATA* conshdlrdata;
5581 int c;
5582 int depth;
5583 int nrounds;
5584 int maxsepacuts;
5585 int ncuts;
5586
5587 assert(scip != NULL);
5588 assert(SCIPisExact(scip) || nconss == 0);
5589 assert(conshdlr != NULL);
5590 assert(result != NULL);
5591
5593
5594 if( !SCIPisExact(scip) )
5595 return SCIP_OKAY;
5596
5597 conshdlrdata = SCIPconshdlrGetData(conshdlr);
5598 assert(conshdlrdata != NULL);
5600 nrounds = SCIPgetNSepaRounds(scip);
5601
5603
5604 /* only call the separator a given number of times at each node */
5605 if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
5606 || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
5607 return SCIP_OKAY;
5608
5609 /* get the maximal number of cuts allowed in a separation round */
5610 maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
5611
5613 ncuts = 0;
5614 cutoff = FALSE;
5615
5616 /* check all useful linear constraints for feasibility */
5617 for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
5618 {
5619 SCIPdebugMsg(scip, "separating exact linear constraint <%s>\n", SCIPconsGetName(conss[c]));
5620 SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, NULL, &ncuts, &cutoff) );
5621 }
5622
5623 /* adjust return value */
5624 if( cutoff )
5626 else if( ncuts > 0 )
5628
5629 return SCIP_OKAY;
5630}
5631
5632
5633/** separation method of constraint handler for arbitrary primal solutions */
5634static
5635SCIP_DECL_CONSSEPASOL(consSepasolExactLinear)
5636{ /*lint --e{715}*/
5637 SCIP_CONSHDLRDATA* conshdlrdata;
5638 int c;
5639 int depth;
5640 int nrounds;
5641 int maxsepacuts;
5642 int ncuts;
5644
5645 assert(scip != NULL);
5646 assert(SCIPisExact(scip) || nconss == 0);
5647 assert(conshdlr != NULL);
5648 assert(result != NULL);
5649
5651
5652 if( !SCIPisExact(scip) )
5653 return SCIP_OKAY;
5654
5655 conshdlrdata = SCIPconshdlrGetData(conshdlr);
5656 assert(conshdlrdata != NULL);
5658 nrounds = SCIPgetNSepaRounds(scip);
5659
5661
5662 /* only call the separator a given number of times at each node */
5663 if( (depth == 0 && conshdlrdata->maxroundsroot >= 0 && nrounds >= conshdlrdata->maxroundsroot)
5664 || (depth > 0 && conshdlrdata->maxrounds >= 0 && nrounds >= conshdlrdata->maxrounds) )
5665 return SCIP_OKAY;
5666
5667 /* get the maximal number of cuts allowed in a separation round */
5668 maxsepacuts = (depth == 0 ? conshdlrdata->maxsepacutsroot : conshdlrdata->maxsepacuts);
5669
5671 ncuts = 0;
5672 cutoff = FALSE;
5673
5674 /* check all useful linear constraints for feasibility */
5675 for( c = 0; c < nusefulconss && ncuts < maxsepacuts && !cutoff; ++c )
5676 {
5677 SCIPdebugMsg(scip, "separating exact linear constraint <%s>\n", SCIPconsGetName(conss[c]));
5678 SCIP_CALL( separateCons(scip, conss[c], conshdlrdata, sol, &ncuts, &cutoff) );
5679 }
5680
5681 /* adjust return value */
5682 if( cutoff )
5684 else if( ncuts > 0 )
5686
5687 return SCIP_OKAY;
5688}
5689
5690
5691/** constraint enforcing method of constraint handler for LP solutions */
5692static
5693SCIP_DECL_CONSENFOLP(consEnfolpExactLinear)
5694{ /*lint --e{715}*/
5695 assert(scip != NULL);
5696 assert(SCIPisExact(scip) || nconss == 0);
5697
5698 if( !SCIPisExact(scip) )
5699 return SCIP_OKAY;
5700
5701 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, NULL, result) );
5702
5703 return SCIP_OKAY;
5704}
5705
5706/** constraint enforcing method of constraint handler for relaxation solutions */
5707static
5708SCIP_DECL_CONSENFORELAX(consEnforelaxExactLinear)
5709{ /*lint --e{715}*/
5710 assert(scip != NULL);
5711 assert(SCIPisExact(scip) || nconss == 0);
5712
5713 if( !SCIPisExact(scip) )
5714 return SCIP_OKAY;
5715
5716 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, sol, result) );
5717
5718 return SCIP_OKAY;
5719}
5720
5721/** constraint enforcing method of constraint handler for pseudo solutions */
5722static
5723SCIP_DECL_CONSENFOPS(consEnfopsExactLinear)
5724{ /*lint --e{715}*/
5725 SCIP_CONSHDLRDATA* conshdlrdata;
5726 SCIP_Bool violated;
5727 int c;
5728
5729 assert(scip != NULL);
5730 assert(SCIPisExact(scip) || nconss == 0);
5731 assert(conshdlr != NULL);
5732 assert(result != NULL);
5733
5735
5736 conshdlrdata = SCIPconshdlrGetData(conshdlr);
5737 assert(conshdlrdata != NULL);
5738
5739 SCIPdebugMsg(scip, "Enfops method of linear constraints\n");
5740
5741 if( !SCIPisExact(scip) )
5742 {
5744 return SCIP_OKAY;
5745 }
5746
5747 /* if the solution is infeasible anyway due to objective value, skip the enforcement */
5748 if( objinfeasible )
5749 {
5750 SCIPdebugMsg(scip, "-> pseudo solution is objective infeasible, return.\n");
5751
5753 return SCIP_OKAY;
5754 }
5755
5756 /* check all linear constraints for feasibility */
5757 violated = FALSE;
5758 for( c = 0; c < nconss && !violated; ++c )
5759 {
5760 SCIP_CALL( checkCons(scip, conss[c], conshdlrdata, NULL, FALSE, TRUE, &violated) );
5761 }
5762
5763 if( violated )
5765 else
5767
5768 SCIPdebugMsg(scip, "-> constraints checked, %s\n", *result == SCIP_FEASIBLE ? "all constraints feasible" : "infeasibility detected");
5769
5770 return SCIP_OKAY;
5771}
5772
5773
5774/** feasibility check method of constraint handler for integral solutions */
5775static
5776SCIP_DECL_CONSCHECK(consCheckExactLinear)
5777{ /*lint --e{715}*/
5778 SCIP_CONSHDLRDATA* conshdlrdata;
5779 SCIP_Bool checkexact;
5780 int c;
5781
5782 assert(scip != NULL);
5783 assert(SCIPisExact(scip) || nconss == 0);
5784 assert(conshdlr != NULL);
5785 assert(result != NULL);
5786
5788
5790
5791 if( !SCIPisExact(scip) )
5792 return SCIP_OKAY;
5793
5794 conshdlrdata = SCIPconshdlrGetData(conshdlr);
5795 assert(conshdlrdata != NULL);
5796
5797 /* if the fp-solution has a stand-in exact solution we check that instead */
5798 checkexact = SCIPsolIsExact(sol);
5799
5800 /* check all linear constraints for feasibility */
5801 for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
5802 {
5803 SCIP_Bool violated = FALSE;
5804 SCIP_CALL( checkCons(scip, conss[c], conshdlrdata, sol, checkexact, checklprows, &violated) );
5805
5806 if( violated )
5807 {
5809
5810 if( printreason )
5811 {
5812 SCIP_CONSDATA* consdata;
5813 SCIP_RATIONAL* activity;
5814
5816
5817 consdata = SCIPconsGetData(conss[c]);
5818 assert( consdata != NULL);
5819
5820 consdataGetActivity(scip, consdata, sol, checkexact, activity);
5821
5822 SCIP_CALL( consPrintConsSol(scip, conss[c], sol, checkexact, NULL ) );
5823 SCIPinfoMessage(scip, NULL, ";\n");
5824
5825 if( SCIPrationalIsAbsInfinity(activity) )
5826 SCIPinfoMessage(scip, NULL, "activity invalid due to infinity contributions\n");
5827 else if( SCIPrationalIsLT(activity, consdata->lhs) )
5828 {
5829 SCIPrationalDiff(activity, consdata->lhs, activity);
5830 SCIPinfoMessage(scip, NULL, "violation: left hand side is violated by ");
5832 SCIPinfoMessage(scip, NULL, "\n");
5833 }
5834 else if( SCIPrationalIsGT(activity, consdata->rhs) )
5835 {
5836 SCIPrationalDiff(activity, activity, consdata->rhs);
5837 SCIPinfoMessage(scip, NULL, "violation: right hand side is violated by ");
5839 SCIPinfoMessage(scip, NULL, "\n");
5840 }
5841
5843 }
5844 }
5845 }
5846
5847 return SCIP_OKAY;
5848}
5849
5850/** domain propagation method of constraint handler */
5851static
5852SCIP_DECL_CONSPROP(consPropExactLinear)
5853{ /*lint --e{715}*/
5854 SCIP_CONSHDLRDATA* conshdlrdata;
5855 SCIP_Bool tightenbounds;
5857
5858 int nchgbds;
5859 int i;
5860
5861 assert(scip != NULL);
5862 assert(SCIPisExact(scip) || nconss == 0);
5863 assert(conshdlr != NULL);
5864 assert(result != NULL);
5865
5867
5868 if( !SCIPisExact(scip) )
5869 return SCIP_OKAY;
5870
5871 conshdlrdata = SCIPconshdlrGetData(conshdlr);
5872 assert(conshdlrdata != NULL);
5873
5874 /* check, if we want to tighten variable's bounds (in probing, we always want to tighten the bounds) */
5875 if( SCIPinProbing(scip) )
5876 tightenbounds = TRUE;
5877 else
5878 {
5879 int depth;
5880 int propfreq;
5881 int tightenboundsfreq;
5882
5884 propfreq = SCIPconshdlrGetPropFreq(conshdlr);
5885 tightenboundsfreq = propfreq * conshdlrdata->tightenboundsfreq;
5886 tightenbounds = (conshdlrdata->tightenboundsfreq >= 0)
5887 && ((tightenboundsfreq == 0 && depth == 0) || (tightenboundsfreq >= 1 && (depth % tightenboundsfreq == 0)));
5888 }
5889
5890 cutoff = FALSE;
5891 nchgbds = 0;
5892
5893 /* process constraints marked for propagation */
5894 for( i = 0; i < nmarkedconss && !cutoff; i++ )
5895 {
5897 SCIP_CALL( propagateCons(scip, conss[i], tightenbounds,
5898 conshdlrdata->sortvars, &cutoff, &nchgbds) );
5899 }
5900
5901 /* adjust result code */
5902 if( cutoff )
5904 else if( nchgbds > 0 )
5906 else
5908
5909 return SCIP_OKAY;
5910}
5911
5912
5913/** variable rounding lock method of constraint handler */
5914static
5915SCIP_DECL_CONSLOCK(consLockExactLinear)
5916{ /*lint --e{715}*/
5917 SCIP_CONSDATA* consdata;
5918 SCIP_Bool haslhs;
5919 SCIP_Bool hasrhs;
5920 int i;
5921
5922 assert(scip != NULL);
5924 assert(cons != NULL);
5925 consdata = SCIPconsGetData(cons);
5926 assert(consdata != NULL);
5927
5928 haslhs = !SCIPrationalIsNegInfinity(consdata->lhs);
5929 hasrhs = !SCIPrationalIsInfinity(consdata->rhs);
5930
5931 /* update rounding locks of every single variable */
5932 for( i = 0; i < consdata->nvars; ++i )
5933 {
5934 if( SCIPrationalIsPositive(consdata->vals[i]) )
5935 {
5936 if( haslhs )
5937 {
5938 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlockspos, nlocksneg) );
5939 }
5940 if( hasrhs )
5941 {
5942 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlocksneg, nlockspos) );
5943 }
5944 }
5945 else
5946 {
5947 if( haslhs )
5948 {
5949 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlocksneg, nlockspos) );
5950 }
5951 if( hasrhs )
5952 {
5953 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlockspos, nlocksneg) );
5954 }
5955 }
5956 }
5957
5958 return SCIP_OKAY;
5959}
5960
5961
5962/** variable deletion method of constraint handler */
5963static
5964SCIP_DECL_CONSDELVARS(consDelvarsExactLinear)
5965{
5966 assert(scip != NULL);
5967 assert(SCIPisExact(scip) || nconss == 0);
5968 assert(conshdlr != NULL);
5969 assert(conss != NULL || nconss == 0);
5970
5971 if( nconss > 0 )
5972 {
5973 SCIP_CALL( performVarDeletions(scip, conshdlr, conss, nconss) );
5974 }
5975
5976 return SCIP_OKAY;
5977}
5978
5979/** constraint display method of constraint handler */
5980static
5981SCIP_DECL_CONSPRINT(consPrintExactLinear)
5982{ /*lint --e{715}*/
5983 assert(scip != NULL);
5984 assert(conshdlr != NULL);
5985 assert(cons != NULL);
5986
5988
5989 return SCIP_OKAY;
5990}
5991
5992/** constraint copying method of constraint handler */
5993static
5994SCIP_DECL_CONSCOPY(consCopyExactLinear)
5995{ /*lint --e{715}*/
5996 SCIP_VAR** sourcevars;
5997 SCIP_INTERVAL* sourcecoefs;
5998 const char* consname;
5999 int nvars;
6000
6001 assert(scip != NULL);
6002 assert(sourcescip != NULL);
6003 assert(sourcecons != NULL);
6004
6005 /* get variables and coefficients of the source constraint */
6006 sourcevars = SCIPgetVarsExactLinear(sourcescip, sourcecons);
6007 sourcecoefs = SCIPgetValsRealExactLinear(sourcescip, sourcecons);
6008 nvars = SCIPgetNVarsExactLinear(sourcescip, sourcecons);
6009
6010 if( name != NULL )
6011 consname = name;
6012 else
6013 consname = SCIPconsGetName(sourcecons);
6014
6015 SCIP_CALL( SCIPcopyConsExactLinear(scip, cons, sourcescip, consname, nvars, sourcevars, sourcecoefs,
6016 SCIPrationalGetReal(SCIPgetLhsExactLinear(sourcescip, sourcecons)), SCIPrationalGetReal(SCIPgetRhsExactLinear(sourcescip, sourcecons)), varmap, consmap,
6017 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, global, valid) );
6018 assert(cons != NULL || *valid == FALSE);
6019
6020 return SCIP_OKAY;
6021}
6022
6023/* find operators '<=', '==', '>=', [free] in input string and return those places. There should only be one operator,
6024 * except for ranged rows for which exactly two operators '<=' must be present
6025 */
6026static
6028 const char* str, /**< null terminated input string */
6029 char** firstoperator, /**< pointer to store the string starting at the first operator */
6030 char** secondoperator, /**< pointer to store the string starting at the second operator */
6031 SCIP_Bool* success /**< pointer to store if the line contains a valid operator order */
6032 )
6033{
6034 char* curr;
6035
6036 assert(str != NULL);
6037 assert(firstoperator != NULL);
6038 assert(secondoperator != NULL);
6039
6040 *firstoperator = NULL;
6041 *secondoperator = NULL;
6042
6043 curr = (char*)str;
6044 *success = TRUE;
6045
6046 /* loop over the input string to find all operators */
6047 while( *curr && *success )
6048 {
6049 SCIP_Bool found = FALSE;
6050 int increment = 1;
6051
6052 /* try if we found a possible operator */
6053 switch( *curr )
6054 {
6055 case '<':
6056 case '=':
6057 case '>':
6058
6059 /* check if the two characters curr[0,1] form an operator together */
6060 if( curr[1] == '=' )
6061 {
6062 found = TRUE;
6063
6064 /* update increment to continue after this operator */
6065 increment = 2;
6066 }
6067 break;
6068 case '[':
6069 if( strncmp(curr, "[free]", 6) == 0 )
6070 {
6071 found = TRUE;
6072
6073 /* update increment to continue after this operator */
6074 increment = 6;
6075 }
6076 break;
6077 default:
6078 break;
6079 }
6080
6081 /* assign the found operator to the first or second pointer and check for violations of the linear constraint grammar */
6082 if( found )
6083 {
6084 if( *firstoperator == NULL )
6085 {
6086 *firstoperator = curr;
6087 }
6088 else
6089 {
6090 if( *secondoperator != NULL )
6091 {
6092 SCIPerrorMessage("Found more than two operators in line %s\n", str);
6093 *success = FALSE;
6094 }
6095 else if( strncmp(*firstoperator, "<=", 2) != 0 )
6096 {
6097 SCIPerrorMessage("Two operators in line that is not a ranged row: %s", str);
6098 *success = FALSE;
6099 }
6100 else if( strncmp(curr, "<=", 2) != 0 )
6101 {
6102 SCIPerrorMessage("Bad second operator, expected ranged row specification: %s", str);
6103 *success = FALSE;
6104 }
6105
6106 *secondoperator = curr;
6107 }
6108 }
6109
6110 curr += increment;
6111 }
6112
6113 /* check if we did find at least one operator */
6114 if( *success )
6115 {
6116 if( *firstoperator == NULL )
6117 {
6118 SCIPerrorMessage("Could not find any operator in line %s\n", str);
6119 *success = FALSE;
6120 }
6121 }
6122
6123 return SCIP_OKAY;
6124}
6125
6126/** constraint parsing method of constraint handler */
6127static
6128SCIP_DECL_CONSPARSE(consParseExactLinear)
6129{ /*lint --e{715}*/
6130 SCIP_RETCODE retcode = SCIP_OKAY;
6131 SCIP_VAR** vars = NULL;
6132 SCIP_RATIONAL** coefs = NULL;
6133 int nvars;
6134 int coefssize = 100;
6135 int requsize;
6136 SCIP_RATIONAL* lhs;
6137 SCIP_RATIONAL* rhs;
6138 char* endptr;
6139 char* firstop;
6140 char* secondop;
6141 SCIP_Bool operatorsuccess;
6142 char* lhsstrptr = NULL;
6143 char* rhsstrptr = NULL;
6144 char* varstrptr = (char*)str;
6145
6146 assert(scip != NULL);
6147 assert(success != NULL);
6148 assert(str != NULL);
6149 assert(name != NULL);
6150 assert(cons != NULL);
6151
6152 *success = FALSE;
6153
6154 /* return of string empty */
6155 if( !(*str) )
6156 return SCIP_OKAY;
6157
6158 /* set left and right hand side to their default values */
6161
6164
6165 /* ignore whitespace */
6166 SCIP_CALL_TERMINATE( retcode, SCIPskipSpace((char**)&str), TERMINATE );
6167
6168 /* find operators in the line first, all other remaining parsing depends on occurence of the operators '<=', '>=', '==',
6169 * and the special word [free]
6170 */
6171 SCIP_CALL_TERMINATE( retcode, findOperators(str, &firstop, &secondop, &operatorsuccess), TERMINATE );
6172
6173 /* if the grammar is not valid for parsing a linear constraint, return */
6174 if( ! operatorsuccess )
6175 {
6176 retcode = SCIP_OKAY;
6177 goto TERMINATE;
6178 }
6179 assert(firstop != NULL);
6180
6181 /* assign the strings for parsing the left hand side, right hand side, and the linear variable sum */
6182 switch( *firstop )
6183 {
6184 case '<':
6185 assert(firstop[1] == '=');
6186 /* we have ranged row lhs <= a_1 x_1 + ... + a_n x_n <= rhs */
6187 if( secondop != NULL )
6188 {
6189 assert(secondop[0] == '<' && secondop[1] == '=');
6190 lhsstrptr = (char *)str;
6191 varstrptr = firstop + 2;
6192 rhsstrptr = secondop + 2;
6193 }
6194 else
6195 {
6196 /* we have an inequality with infinite left hand side a_1 x_1 + ... + a_n x_n <= rhs */
6197 lhsstrptr = NULL;
6198 varstrptr = (char *)str;
6199 rhsstrptr = firstop + 2;
6200 }
6201 break;
6202 case '>':
6203 assert(firstop[1] == '=');
6204 assert(secondop == NULL);
6205 /* we have a_1 x_1 + ... + a_n x_n >= lhs */
6206 lhsstrptr = firstop + 2;
6207 break;
6208 case '=':
6209 assert(firstop[1] == '=');
6210 assert(secondop == NULL);
6211 /* we have a_1 x_1 + ... + a_n x_n == lhs (rhs) */
6212 rhsstrptr = firstop + 2;
6213 lhsstrptr = firstop + 2;
6214 break;
6215 case '[':
6216 assert(strncmp(firstop, "[free]", 6) == 0);
6217 assert(secondop == NULL);
6218 /* nothing to assign in case of a free a_1 x_1 + ... + a_n x_n [free] */
6219 break;
6220 default:
6221 /* it should not be possible that a different character appears in that position */
6222 SCIPerrorMessage("Parsing has wrong operator character '%c', should be one of <=>[", *firstop);
6223 retcode = SCIP_READERROR;
6224 goto TERMINATE;
6225 }
6226
6227 /* parse left hand side, if necessary */
6228 if( lhsstrptr != NULL )
6229 {
6230 if( ! SCIPparseRational(scip, lhsstrptr, lhs, &endptr) )
6231 {
6232 SCIPerrorMessage("error parsing left hand side number from <%s>\n", lhsstrptr);
6233 retcode = SCIP_OKAY;
6234 goto TERMINATE;
6235 }
6236
6237 /* in case of an equation, assign the left also to the right hand side */
6238 if( rhsstrptr == lhsstrptr )
6239 SCIPrationalSetRational(rhs, lhs);
6240 }
6241
6242 /* parse right hand side, if different from left hand side */
6243 if( rhsstrptr != NULL && rhsstrptr != lhsstrptr )
6244 {
6245 if( ! SCIPparseRational(scip, rhsstrptr, rhs, &endptr) )
6246 {
6247 SCIPerrorMessage("error parsing right hand side number from <%s>\n", lhsstrptr);
6248 retcode = SCIP_OKAY;
6249 goto TERMINATE;
6250 }
6251 }
6252
6253 /* initialize buffers for storing the variables and coefficients */
6254 SCIP_CALL( SCIPallocBufferArray(scip, &vars, coefssize) );
6256
6257 assert(varstrptr != NULL);
6258
6259 /* parse linear sum to get variables and coefficients */
6260 SCIP_CALL_TERMINATE( retcode, SCIPparseVarsLinearsumExact(scip, varstrptr, vars, coefs, &nvars, coefssize, &requsize, &endptr, success), TERMINATE );
6261
6262 if( *success && requsize > coefssize )
6263 {
6264 /* realloc buffers and try again */
6265 SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requsize) );
6266 SCIP_CALL( SCIPrationalReallocBufferArray(SCIPbuffer(scip), &coefs, coefssize, requsize) );
6267
6268 coefssize = requsize;
6269
6270 SCIP_CALL_TERMINATE( retcode, SCIPparseVarsLinearsumExact(scip, varstrptr, vars, coefs, &nvars, coefssize, &requsize, &endptr, success), TERMINATE );
6271 assert(!*success || requsize <= coefssize); /* if successful, then should have had enough space now */
6272 }
6273
6274 if( *success )
6275 {
6276 SCIP_CALL_TERMINATE( retcode, SCIPcreateConsExactLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
6277 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode),
6278 TERMINATE );
6279 }
6280
6281 TERMINATE:
6282 if( !*success )
6283 {
6284 SCIPerrorMessage("no luck in parsing exact linear sum '%s'\n", varstrptr);
6285 }
6286 if( coefs != NULL )
6287 SCIPrationalFreeBufferArray(SCIPbuffer(scip), &coefs, coefssize);
6289
6292
6293 return retcode;
6294}
6295
6296
6297/** constraint method of constraint handler which returns the variables (if possible) */
6298static
6299SCIP_DECL_CONSGETVARS(consGetVarsExactLinear)
6300{ /*lint --e{715}*/
6301 SCIP_CONSDATA* consdata;
6302
6303 consdata = SCIPconsGetData(cons);
6304 assert(consdata != NULL);
6305
6306 if( varssize < consdata->nvars )
6307 (*success) = FALSE;
6308 else
6309 {
6310 assert(vars != NULL);
6311
6312 BMScopyMemoryArray(vars, consdata->vars, consdata->nvars);
6313 (*success) = TRUE;
6314 }
6315
6316 return SCIP_OKAY;
6317}
6318
6319/**! [Callback for the number of variables]*/
6320/** constraint method of constraint handler which returns the number of variables (if possible) */
6321static
6322SCIP_DECL_CONSGETNVARS(consGetNVarsExactLinear)
6323{ /*lint --e{715}*/
6324 SCIP_CONSDATA* consdata;
6325
6326 consdata = SCIPconsGetData(cons);
6327 assert(consdata != NULL);
6328
6329 (*nvars) = consdata->nvars;
6330 (*success) = TRUE;
6331
6332 return SCIP_OKAY;
6333}
6334/**! [Callback for the number of variables]*/
6335
6336/*
6337 * Callback methods of event handler
6338 */
6339
6340static
6341SCIP_DECL_EVENTEXEC(eventExecExactLinear)
6342{ /*lint --e{715}*/
6343 SCIP_CONS* cons;
6344 SCIP_CONSDATA* consdata;
6345 SCIP_VAR* var;
6346 SCIP_EVENTTYPE eventtype;
6348 assert(scip != NULL);
6350 assert(eventhdlr != NULL);
6351 assert(eventdata != NULL);
6352 assert(event != NULL);
6353
6355
6356 cons = eventdata->cons;
6357 assert(cons != NULL);
6358 consdata = SCIPconsGetData(cons);
6359 if( consdata == NULL )
6360 return SCIP_OKAY;
6361 /* we can skip events dropped for deleted constraints */
6362 if( SCIPconsIsDeleted(cons) )
6363 return SCIP_OKAY;
6364
6365 eventtype = SCIPeventGetType(event);
6366 var = SCIPeventGetVar(event);
6367 updateActivities = ((consdata->rowexact != NULL) == eventdata->rowvar) && consdata->validactivities;
6368 assert(!consdata->validactivities || (consdata->validminact && consdata->validmaxact && consdata->validglbminact && consdata->validglbmaxact));
6369
6370 if( ((eventtype & SCIP_EVENTTYPE_BOUNDCHANGED) != 0) )
6371 {
6372 SCIP_Real oldbound;
6373 SCIP_Real newbound;
6374 SCIP_INTERVAL valrange;
6375 int varpos;
6376 varpos = eventdata->varpos;
6377
6378 oldbound = SCIPeventGetOldbound(event);
6379 newbound = SCIPeventGetNewbound(event);
6380 assert(var != NULL);
6381 valrange = consdata->valsreal[varpos];
6382
6383 /* we only need to update the activities if the constraint is active,
6384 * otherwise we mark them to be invalid
6385 */
6386 if( SCIPconsIsActive(cons) )
6387 {
6388 /* update the activity values */
6389 if( (eventtype & SCIP_EVENTTYPE_LBCHANGED) != 0 )
6390 consdataUpdateActivitiesLb(scip, consdata, var, oldbound, newbound, valrange);
6391 else
6392 {
6393 assert((eventtype & SCIP_EVENTTYPE_UBCHANGED) != 0);
6394 consdataUpdateActivitiesUb(scip, consdata, var, oldbound, newbound, valrange);
6395 }
6396 }
6397 else
6399
6400 consdata->presolved = FALSE;
6401
6402 /* in probing do not reset disabled ranged row propagation */
6403 if( !SCIPinProbing(scip) )
6404 consdata->rangedrowpropagated = 0;
6405
6406 /* bound change can turn the constraint infeasible or redundant only if it was a tightening */
6407 if( (eventtype & SCIP_EVENTTYPE_BOUNDTIGHTENED) != 0 )
6408 {
6410
6411 /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
6412 if( consdata->maxactdeltavar == var )
6413 {
6414 consdata->maxactdelta = SCIP_INVALID;
6415 consdata->maxactdeltavar = NULL;
6416 }
6417
6418 /* check whether bound tightening might now be successful */
6419 if( consdata->boundstightened > 0)
6420 {
6421 switch( eventtype )
6422 {
6424 if( (valrange.sup > 0.0 ? !SCIPisInfinity(scip, consdata->rhsreal) : !SCIPisInfinity(scip, -consdata->lhsreal)) )
6425 consdata->boundstightened = 0;
6426 break;
6428 if( (valrange.sup > 0.0 ? !SCIPisInfinity(scip, -consdata->lhsreal) : !SCIPisInfinity(scip, consdata->rhsreal)) )
6429 consdata->boundstightened = 0;
6430 break;
6431 default:
6432 SCIPerrorMessage("invalid event type %" SCIP_EVENTTYPE_FORMAT "\n", eventtype);
6433 return SCIP_INVALIDDATA;
6434 }
6435 }
6436 }
6437 /* update maximal activity delta if a bound was relaxed */
6438 else if( !SCIPisInfinity(scip, consdata->maxactdelta) )
6439 {
6440 SCIP_Real lb;
6441 SCIP_Real ub;
6442 SCIP_Real domain;
6443 SCIP_Real delta;
6444
6445 assert((eventtype & SCIP_EVENTTYPE_BOUNDRELAXED) != 0);
6446
6447 lb = SCIPvarGetLbLocal(var);
6448 ub = SCIPvarGetUbLocal(var);
6449
6450 domain = ub - lb;
6451 delta = SCIPintervalAbsMax(valrange) * domain;
6452
6453 if( delta > consdata->maxactdelta )
6454 {
6455 consdata->maxactdelta = delta;
6456 consdata->maxactdeltavar = var;
6457 }
6458 }
6459 }
6460 else if( (eventtype & SCIP_EVENTTYPE_VARFIXED) != 0 )
6461 {
6462 /* we want to remove the fixed variable */
6463 consdata->presolved = FALSE;
6464 consdata->removedfixings = FALSE;
6465 consdata->rangedrowpropagated = 0;
6466
6467 /* reset maximal activity delta, so that it will be recalculated on the next real propagation */
6468 if( consdata->maxactdeltavar == var )
6469 {
6470 consdata->maxactdelta = SCIP_INVALID;
6471 consdata->maxactdeltavar = NULL;
6472 }
6473 }
6474 else if( (eventtype & SCIP_EVENTTYPE_VARUNLOCKED) != 0 )
6475 {
6476 /* there is only one lock left: we may multi-aggregate the variable as slack of an equation */
6479 consdata->presolved = FALSE;
6480 }
6481 else if( (eventtype & SCIP_EVENTTYPE_GBDCHANGED) != 0 )
6482 {
6483 SCIP_Real oldbound;
6484 SCIP_Real newbound;
6485 SCIP_INTERVAL valrange;
6486 int varpos;
6487
6488 varpos = eventdata->varpos;
6489
6490 if( updateActivities )
6491 {
6492 oldbound = SCIPeventGetOldbound(event);
6493 newbound = SCIPeventGetNewbound(event);
6494 assert(var != NULL);
6495 assert(consdata->vars[varpos] == var);
6496 valrange = consdata->valsreal[varpos];
6497
6498 consdata->rangedrowpropagated = 0;
6499
6500 /* update the activity values */
6501 if( (eventtype & SCIP_EVENTTYPE_GLBCHANGED) != 0 )
6502 consdataUpdateActivitiesGlbLb(scip, consdata, oldbound, newbound, valrange);
6503 else
6504 {
6505 assert((eventtype & SCIP_EVENTTYPE_GUBCHANGED) != 0);
6506 consdataUpdateActivitiesGlbUb(scip, consdata, oldbound, newbound, valrange);
6507 }
6508 }
6509
6510 /* if the variable is binary but not fixed it had to become binary due to this global change */
6512 {
6514 consdata->indexsorted = FALSE;
6515 else
6516 consdata->coefsorted = FALSE;
6517 }
6518 }
6519 else if( ((eventtype & SCIP_EVENTTYPE_TYPECHANGED) != 0) )
6520 {
6522
6523 /* for presolving it only matters if a variable type changed from continuous to some kind of integer */
6524 consdata->presolved = (consdata->presolved && SCIPeventGetOldtype(event) < SCIP_VARTYPE_CONTINUOUS);
6525
6526 /* the ordering is preserved if the type changes from something different to binary to binary but SCIPvarIsBinary() is true */
6527 consdata->indexsorted = (consdata->indexsorted && SCIPeventGetNewtype(event) == SCIP_VARTYPE_BINARY && SCIPvarIsBinary(var));
6528 }
6529 else if( (eventtype & SCIP_EVENTTYPE_VARDELETED) )
6530 {
6531 consdata->varsdeleted = TRUE;
6532 }
6533 return SCIP_OKAY;
6534}
6535
6536
6537/*
6538 * Callback methods of conflict handler
6539 */
6540
6541/*
6542 * constraint specific interface methods
6543 */
6544
6545/** creates the handler for linear constraints and includes it in SCIP */
6547 SCIP* scip /**< SCIP data structure */
6548 )
6549{
6550 SCIP_CONSHDLRDATA* conshdlrdata;
6551 SCIP_CONSHDLR* conshdlr;
6552 SCIP_EVENTHDLR* eventhdlr;
6553
6554 assert(scip != NULL);
6555
6556 /* create event handler for bound change events */
6558 eventExecExactLinear, NULL) );
6559
6560 /* create constraint handler data */
6561 SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
6562
6563 /* include constraint handler */
6566 consEnfolpExactLinear, consEnfopsExactLinear, consCheckExactLinear, consLockExactLinear,
6567 conshdlrdata) );
6568
6569 assert(conshdlr != NULL);
6570
6571 /* mark constraint handler as exact */
6572 SCIPconshdlrMarkExact(conshdlr);
6573
6574 /* set non-fundamental callbacks via specific setter functions */
6575 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyExactLinear, consCopyExactLinear) );
6576 SCIP_CALL( SCIPsetConshdlrDeactive(scip, conshdlr, consDeactiveExactLinear) );
6577 SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteExactLinear) );
6578 SCIP_CALL( SCIPsetConshdlrDelvars(scip, conshdlr, consDelvarsExactLinear) );
6579 SCIP_CALL( SCIPsetConshdlrExit(scip, conshdlr, consExitExactLinear) );
6580 SCIP_CALL( SCIPsetConshdlrExitpre(scip, conshdlr, consExitpreExactLinear) );
6581 SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolExactLinear) );
6582 SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeExactLinear) );
6583 SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsExactLinear) );
6584 SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsExactLinear) );
6585 SCIP_CALL( SCIPsetConshdlrInit(scip, conshdlr, consInitExactLinear) );
6586 SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpExactLinear) );
6587 SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseExactLinear) );
6588 SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintExactLinear) );
6589 SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropExactLinear, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP,
6591 SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpExactLinear, consSepasolExactLinear, CONSHDLR_SEPAFREQ,
6593 SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransExactLinear) );
6594 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxExactLinear) );
6595
6596 /* add constraint handler parameters */
6598 "constraints/" CONSHDLR_NAME "/tightenboundsfreq",
6599 "multiplier on propagation frequency, how often the bounds are tightened (-1: never, 0: only at root)",
6600 &conshdlrdata->tightenboundsfreq, TRUE, DEFAULT_TIGHTENBOUNDSFREQ, -1, SCIP_MAXTREEDEPTH, NULL, NULL) );
6602 "constraints/" CONSHDLR_NAME "/maxrounds",
6603 "maximal number of separation rounds per node (-1: unlimited)",
6604 &conshdlrdata->maxrounds, FALSE, DEFAULT_MAXROUNDS, -1, INT_MAX, NULL, NULL) );
6606 "constraints/" CONSHDLR_NAME "/maxroundsroot",
6607 "maximal number of separation rounds per node in the root node (-1: unlimited)",
6608 &conshdlrdata->maxroundsroot, FALSE, DEFAULT_MAXROUNDSROOT, -1, INT_MAX, NULL, NULL) );
6610 "constraints/" CONSHDLR_NAME "/maxsepacuts",
6611 "maximal number of cuts separated per separation round",
6612 &conshdlrdata->maxsepacuts, FALSE, DEFAULT_MAXSEPACUTS, 0, INT_MAX, NULL, NULL) );
6614 "constraints/" CONSHDLR_NAME "/maxsepacutsroot",
6615 "maximal number of cuts separated per separation round in the root node",
6616 &conshdlrdata->maxsepacutsroot, FALSE, DEFAULT_MAXSEPACUTSROOT, 0, INT_MAX, NULL, NULL) );
6618 "constraints/" CONSHDLR_NAME "/sortvars", "apply binaries sorting in decr. order of coeff abs value?",
6619 &conshdlrdata->sortvars, TRUE, DEFAULT_SORTVARS, NULL, NULL) );
6621 "constraints/" CONSHDLR_NAME "/propcont",
6622 "should bounds on continuous variables be tightened by propagation?",
6623 &conshdlrdata->propcont, TRUE, TRUE, NULL, NULL) );
6625 "constraints/" CONSHDLR_NAME "/limitdenom",
6626 "should denominators of rational bounds on continuous variables be controlled?",
6627 &conshdlrdata->limitdenom, TRUE, DEFAULT_LIMITDENOM, NULL, NULL) );
6629 "constraints/" CONSHDLR_NAME "/boundmaxdenom",
6630 "maximal denominator for rational bounds on continuous variables after propagation",
6631 &conshdlrdata->boundmaxdenom, TRUE, DEFAULT_BOUNDMAXDENOM, 1L, SCIP_LONGINT_MAX, NULL, NULL) );
6632
6633 return SCIP_OKAY;
6634}
6635
6636/** creates and captures a linear constraint
6637 *
6638 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
6639 */
6641 SCIP* scip, /**< SCIP data structure */
6642 SCIP_CONS** cons, /**< pointer to hold the created constraint */
6643 const char* name, /**< name of constraint */
6644 int nvars, /**< number of nonzeros in the constraint */
6645 SCIP_VAR** vars, /**< array with variables of constraint entries */
6646 SCIP_RATIONAL** vals, /**< array with coefficients of constraint entries */
6647 SCIP_RATIONAL* lhs, /**< left hand side of constraint */
6648 SCIP_RATIONAL* rhs, /**< right hand side of constraint */
6649 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
6650 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
6651 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
6652 * Usually set to TRUE. */
6653 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
6654 * TRUE for model constraints, FALSE for additional, redundant constraints. */
6655 SCIP_Bool check, /**< should the constraint be checked for feasibility?
6656 * TRUE for model constraints, FALSE for additional, redundant constraints. */
6657 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
6658 * Usually set to TRUE. */
6659 SCIP_Bool local, /**< is constraint only valid locally?
6660 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
6661 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
6662 * Usually set to FALSE. In column generation applications, set to TRUE if pricing
6663 * adds coefficients to this constraint. */
6664 SCIP_Bool dynamic, /**< is constraint subject to aging?
6665 * Usually set to FALSE. Set to TRUE for own cuts which
6666 * are separated as constraints. */
6667 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
6668 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
6669 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
6670 * if it may be moved to a more global node?
6671 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
6672 )
6673{
6674 SCIP_CONSHDLR* conshdlr;
6675 SCIP_CONSDATA* consdata;
6676 int i;
6677
6678 assert(scip != NULL);
6679 assert(cons != NULL);
6680
6681 /* find the linear constraint handler */
6682 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
6683 if( conshdlr == NULL )
6684 {
6685 SCIPerrorMessage("linear constraint handler not found\n");
6686 return SCIP_PLUGINNOTFOUND;
6687 }
6688
6689 /* terminate if a coefficient is infinite */
6690 for( i = 0; i < nvars; ++i )
6691 {
6692 if( SCIPrationalIsAbsInfinity(vals[i]) )
6693 {
6694 SCIPerrorMessage("coefficient of variable <%s> in constraint <%s> is infinite,"
6695 " consider adjusting the infinity threshold\n", SCIPvarGetName(vars[i]), name);
6696 SCIPABORT();
6697 return SCIP_INVALIDDATA;
6698 }
6699 }
6700
6701 /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
6702 * constraint after presolving we have to ensure that it holds active variables
6703 */
6705 {
6706 SCIP_VAR** consvars;
6707 SCIP_RATIONAL** consvals;
6708 SCIP_RATIONAL* constant;
6709 int nconsvars;
6710 int requiredsize;
6711
6713
6714 nconsvars = nvars;
6715 SCIP_CALL( SCIPduplicateBufferArray(scip, &consvars, vars, nconsvars) );
6716 SCIP_CALL( SCIPduplicateBufferArray(scip, &consvals, vals, nconsvars) );
6717
6718 /* get active variables for new constraint */
6719 SCIP_CALL( SCIPgetProbvarLinearSumExact(scip, consvars, consvals, &nconsvars, nconsvars, constant, &requiredsize, TRUE) );
6720
6721 /* if space was not enough we need to resize the buffers */
6722 if( requiredsize > nconsvars )
6723 {
6724 SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
6725 SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
6726
6727 SCIP_CALL( SCIPgetProbvarLinearSumExact(scip, consvars, consvals, &nconsvars, requiredsize, constant, &requiredsize, TRUE) );
6728 assert(requiredsize <= nconsvars);
6729 }
6730
6731 /* adjust sides and check that we do not subtract infinity values */
6732 if( SCIPrationalIsAbsInfinity(constant) )
6733 {
6734 SCIPfreeBufferArray(scip, &consvals);
6735 SCIPfreeBufferArray(scip, &consvars);
6737 SCIPerrorMessage("while creating constraint <%s> inactive variables lead to an infinite constant\n", name);
6738 SCIPABORT();
6739 return SCIP_INVALIDDATA;
6740 }
6741 else
6742 {
6743 if( !SCIPrationalIsAbsInfinity(lhs) )
6744 SCIPrationalDiff(lhs, lhs, constant);
6745 if( !SCIPrationalIsAbsInfinity(rhs) )
6746 SCIPrationalDiff(rhs, rhs, constant);
6747 }
6748
6749 /* create constraint data */
6750 SCIP_CALL( consdataCreate(scip, &consdata, nconsvars, consvars, consvals, lhs, rhs) );
6751
6752 SCIPfreeBufferArray(scip, &consvals);
6753 SCIPfreeBufferArray(scip, &consvars);
6755 }
6756 else
6757 {
6758 /* create constraint data */
6759 SCIP_CALL( consdataCreate(scip, &consdata, nvars, vars, vals, lhs, rhs) );
6760 }
6761 assert(consdata != NULL);
6762
6763 /* create constraint */
6764 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
6765 local, modifiable, dynamic, removable, stickingatnode) );
6766
6767 return SCIP_OKAY;
6768}
6769
6770/** creates and captures a linear constraint
6771 * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
6772 * method SCIPcreateConsLinear(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
6773 *
6774 * @see SCIPcreateConsLinear() for information about the basic constraint flag configuration
6775 *
6776 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
6777 */
6779 SCIP* scip, /**< SCIP data structure */
6780 SCIP_CONS** cons, /**< pointer to hold the created constraint */
6781 const char* name, /**< name of constraint */
6782 int nvars, /**< number of nonzeros in the constraint */
6783 SCIP_VAR** vars, /**< array with variables of constraint entries */
6784 SCIP_RATIONAL** vals, /**< array with coefficients of constraint entries */
6785 SCIP_RATIONAL* lhs, /**< left hand side of constraint */
6786 SCIP_RATIONAL* rhs /**< right hand side of constraint */
6787 )
6788{
6789 assert(scip != NULL);
6790
6791 SCIP_CALL( SCIPcreateConsExactLinear(scip, cons, name, nvars, vars, vals, lhs, rhs,
6793
6794 return SCIP_OKAY;
6795}
6796
6797/** creates a linear constraint from an exact linear constraint by rounding values to floating-point and captures it */
6799 SCIP* scip, /**< target SCIP data structure */
6800 SCIP_CONS** cons, /**< pointer to store the created target constraint */
6801 SCIP* sourcescip, /**< source SCIP data structure */
6802 const char* name, /**< name of constraint */
6803 int nvars, /**< number of variables in source variable array */
6804 SCIP_VAR** sourcevars, /**< source variables of the linear constraints */
6805 SCIP_INTERVAL* sourcecoefs, /**< coefficient array of the linear constraint, or NULL if all coefficients are one */
6806 SCIP_Real lhs, /**< left hand side of the linear constraint */
6807 SCIP_Real rhs, /**< right hand side of the linear constraint */
6808 SCIP_HASHMAP* varmap, /**< a SCIP_HASHMAP mapping variables of the source SCIP to corresponding
6809 * variables of the target SCIP */
6810 SCIP_HASHMAP* consmap, /**< a hashmap to store the mapping of source constraints to the corresponding
6811 * target constraints */
6812 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP? */
6813 SCIP_Bool separate, /**< should the constraint be separated during LP processing? */
6814 SCIP_Bool enforce, /**< should the constraint be enforced during node processing? */
6815 SCIP_Bool check, /**< should the constraint be checked for feasibility? */
6816 SCIP_Bool propagate, /**< should the constraint be propagated during node processing? */
6817 SCIP_Bool local, /**< is constraint only valid locally? */
6818 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)? */
6819 SCIP_Bool dynamic, /**< is constraint subject to aging? */
6820 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup? */
6821 SCIP_Bool stickingatnode, /**< should the constraint always be kept at the node where it was added, even
6822 * if it may be moved to a more global node? */
6823 SCIP_Bool global, /**< create a global or a local copy? */
6824 SCIP_Bool* valid /**< pointer to store if the copying was valid */
6825 )
6826{
6827 SCIP_VAR** vars;
6828 SCIP_Real* coefs;
6829
6830 SCIP_Real constant;
6831 int requiredsize;
6832 int v;
6833 SCIP_Bool success;
6834
6835 /**@todo This method is currently only used for subSCIPs in floating-point heuristics, but should be extended to be
6836 * able to perform an exact copy in the future. This would allow application of the cons_components presolver,
6837 * for example. In this case, whether an exact or an fp copy is created, could probably be decided by checking
6838 * SCIPisExact() for the target SCIP.
6839 */
6841 (*valid) = FALSE;
6842
6843 if( SCIPisGT(scip, lhs, rhs) )
6844 {
6845 return SCIP_OKAY;
6846 }
6847
6848 if( nvars == 0 )
6849 {
6850 SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, 0, NULL, NULL, lhs, rhs,
6851 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
6852 return SCIP_OKAY;
6853 }
6854
6855 /* duplicate variable array */
6857
6858 /* duplicate coefficient array */
6859 if( sourcecoefs != NULL )
6860 {
6862 for( int i = 0; i < nvars; i++ )
6863 {
6864 coefs[i] = SCIPintervalGetSup(sourcecoefs[i]);
6865 assert(!SCIPisInfinity(scip, coefs[i]) && !SCIPisInfinity(scip, -coefs[i]));
6866 }
6867 }
6868 else
6869 {
6871 for( v = 0; v < nvars; ++v )
6872 coefs[v] = 1.0;
6873 }
6874
6875 constant = 0.0;
6876
6877 /* transform source variable to active variables of the source SCIP since only these can be mapped to variables of
6878 * the target SCIP
6879 */
6880 if( !SCIPvarIsOriginal(vars[0]) )
6881 {
6882 SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, nvars, &constant, &requiredsize) );
6883
6884 if( requiredsize > nvars )
6885 {
6886 SCIP_CALL( SCIPreallocBufferArray(scip, &vars, requiredsize) );
6887 SCIP_CALL( SCIPreallocBufferArray(scip, &coefs, requiredsize) );
6888
6889 SCIP_CALL( SCIPgetProbvarLinearSum(sourcescip, vars, coefs, &nvars, requiredsize, &constant, &requiredsize) );
6890 assert(requiredsize <= nvars);
6891 }
6892 }
6893 else
6894 {
6895 for( v = 0; v < nvars; ++v )
6896 {
6898 SCIP_CALL( SCIPvarGetOrigvarSum(&vars[v], &coefs[v], &constant) );
6899 assert(vars[v] != NULL);
6900 }
6901 }
6902
6903 success = TRUE;
6904 /* map variables of the source constraint to variables of the target SCIP */
6905 for( v = 0; v < nvars && success; ++v )
6906 {
6907 SCIP_VAR* var;
6908 var = vars[v];
6909
6910 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, var, &vars[v], varmap, consmap, global, &success) );
6911 assert(!(success) || vars[v] != NULL);
6912 }
6913
6914 /* only create the target constraint, if all variables could be copied */
6915 if( success )
6916 {
6917 if( !SCIPisInfinity(scip, -lhs) )
6918 lhs -= constant;
6919
6920 if( !SCIPisInfinity(scip, rhs) )
6921 rhs -= constant;
6922
6923 SCIP_CALL( SCIPcreateConsLinear(scip, cons, name, nvars, vars, coefs, lhs, rhs,
6924 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
6925 }
6926
6927 /* free buffer array */
6928 SCIPfreeBufferArray(scip, &coefs);
6930
6931 return SCIP_OKAY;
6932}
6933
6934/** adds coefficient to linear constraint (if it is not zero) */
6936 SCIP* scip, /**< SCIP data structure */
6937 SCIP_CONS* cons, /**< constraint data */
6938 SCIP_VAR* var, /**< variable of constraint entry */
6939 SCIP_RATIONAL* val /**< coefficient of constraint entry */
6940 )
6941{
6942 assert(scip != NULL);
6943 assert(cons != NULL);
6944 assert(var != NULL);
6945
6947
6948 /* terminate if coefficient is infinite */
6949 if( SCIPrationalIsAbsInfinity(val) )
6950 {
6951 SCIPerrorMessage("coefficient of variable <%s> in constraint <%s> is infinite,"
6952 " consider adjusting the infinity threshold\n", SCIPvarGetName(var), SCIPconsGetName(cons));
6953 SCIPABORT();
6954 return SCIP_INVALIDDATA;
6955 }
6956
6957 /* for the solving process we need linear rows, containing only active variables; therefore when creating a linear
6958 * constraint after presolving we have to ensure that it holds active variables
6959 */
6961 {
6962 SCIP_CONSDATA* consdata;
6963 SCIP_VAR** consvars;
6964 SCIP_RATIONAL** consvals;
6965 SCIP_RATIONAL* constant;
6966 SCIP_RATIONAL* rhs;
6967 SCIP_RATIONAL* lhs;
6968 int nconsvars;
6969 int requiredsize;
6970 int v;
6971
6972 SCIPerrorMessage("adding coefficients after presolving not supported yet in exact solving mode \n");
6973 SCIPABORT();
6974
6975 nconsvars = 1;
6976 SCIP_CALL( SCIPallocBufferArray(scip, &consvars, nconsvars) );
6977 SCIP_CALL( SCIPallocBufferArray(scip, &consvals, nconsvars) );
6978 consvars[0] = var;
6979 SCIP_CALL( SCIPrationalCopyBlock(SCIPblkmem(scip), &consvals[0], val) );
6981
6982 /* get active variables for new constraint */
6983 SCIP_CALL( SCIPgetProbvarLinearSumExact(scip, consvars, consvals, &nconsvars, nconsvars, constant, &requiredsize, TRUE) );
6984
6985 /* if space was not enough we need to resize the buffers */
6986 if( requiredsize > nconsvars )
6987 {
6988 SCIP_CALL( SCIPreallocBufferArray(scip, &consvars, requiredsize) );
6989 SCIP_CALL( SCIPreallocBufferArray(scip, &consvals, requiredsize) );
6990
6991 SCIP_CALL( SCIPgetProbvarLinearSumExact(scip, consvars, consvals, &nconsvars, requiredsize, constant, &requiredsize, TRUE) );
6992 assert(requiredsize <= nconsvars);
6993 }
6994
6995 consdata = SCIPconsGetData(cons);
6996 assert(consdata != NULL);
6997
6998 SCIP_CALL( SCIPrationalCopyBlock(SCIPblkmem(scip), &lhs, consdata->lhs) );
6999 SCIP_CALL( SCIPrationalCopyBlock(SCIPblkmem(scip), &rhs, consdata->rhs) );
7000
7001 /* adjust sides and check that we do not subtract infinity values */
7002 if( SCIPrationalIsAbsInfinity(constant) )
7003 {
7004 SCIPfreeBufferArray(scip, &consvals);
7005 SCIPfreeBufferArray(scip, &consvars);
7006
7007 SCIPerrorMessage("adding variable <%s> to constraint <%s> leads to infinite constant and cannot be handled safely\n",
7009
7010 SCIPABORT();
7011 return SCIP_INVALIDDATA; /*lint !e527*/
7012 }
7013 /* constant is not infinite */
7014 else
7015 {
7016 if( !SCIPrationalIsAbsInfinity(lhs) )
7017 SCIPrationalDiff(lhs, lhs, constant);
7018 if( !SCIPrationalIsAbsInfinity(rhs) )
7019 SCIPrationalDiff(rhs, rhs, constant);
7020 }
7021
7022 /* add all active variables to constraint */
7023 for( v = nconsvars - 1; v >= 0; --v )
7024 {
7025 SCIP_CALL( addCoef(scip, cons, consvars[v], consvals[v]) );
7026 }
7027
7028 /* update left and right hand sides */
7029 SCIP_CALL( chgLhs(scip, cons, lhs) );
7030 SCIP_CALL( chgRhs(scip, cons, rhs) );
7031
7033 SCIPfreeBufferArray(scip, &consvals);
7034 SCIPfreeBufferArray(scip, &consvars);
7035 }
7036 else
7037 {
7038 SCIP_CALL( addCoef(scip, cons, var, val) );
7039 }
7040
7041 return SCIP_OKAY;
7042}
7043
7044/** changes coefficient of variable in linear constraint; deletes the variable if coefficient is zero; adds variable if
7045 * not yet contained in the constraint
7046 *
7047 * @note This method may only be called during problem creation stage for an original constraint and variable.
7048 *
7049 * @note This method requires linear time to search for occurences of the variable in the constraint data.
7050 */
7052 SCIP* scip, /**< SCIP data structure */
7053 SCIP_CONS* cons, /**< constraint data */
7054 SCIP_VAR* var, /**< variable of constraint entry */
7055 SCIP_RATIONAL* val /**< new coefficient of constraint entry */
7056 )
7057{
7058 SCIP_CONSDATA* consdata;
7059 SCIP_VAR** vars;
7060 SCIP_Bool found;
7061 int i;
7062
7063 assert(scip != NULL);
7064 assert(cons != NULL);
7065 assert(var != NULL);
7066
7068
7070 {
7071 SCIPerrorMessage("method may only be called during problem creation stage for original constraints and variables\n");
7072 return SCIP_INVALIDDATA;
7073 }
7074
7075 consdata = SCIPconsGetData(cons);
7076 assert(consdata != NULL);
7077
7078 vars = consdata->vars;
7079 found = FALSE;
7080 i = 0;
7081 while( i < consdata->nvars )
7082 {
7083 if( vars[i] == var )
7084 {
7085 if( found || SCIPrationalIsZero(val) )
7086 {
7087 SCIP_CALL( delCoefPos(scip, cons, i) );
7088
7089 /* decrease i by one since otherwise we would skip the coefficient which has been switched to position i */
7090 i--;
7091 }
7092 else
7093 {
7094 SCIP_CALL( chgCoefPos(scip, cons, i, val) );
7095 }
7096 found = TRUE;
7097 }
7098 i++;
7099 }
7100
7101 if( !found && !SCIPrationalIsZero(val) )
7102 {
7103 SCIP_CALL( SCIPaddCoefExactLinear(scip, cons, var, val) );
7104 }
7105
7106 return SCIP_OKAY;
7107}
7108
7109/** deletes variable from linear constraint
7110 *
7111 * @note This method may only be called during problem creation stage for an original constraint and variable.
7112 *
7113 * @note This method requires linear time to search for occurences of the variable in the constraint data.
7114 */
7116 SCIP* scip, /**< SCIP data structure */
7117 SCIP_CONS* cons, /**< constraint data */
7118 SCIP_VAR* var /**< variable of constraint entry */
7119 )
7120{
7121 SCIP_RATIONAL* temp;
7122
7123 assert(scip != NULL);
7124 assert(cons != NULL);
7125 assert(var != NULL);
7126
7128
7129 SCIP_CALL( SCIPchgCoefExactLinear(scip, cons, var, temp) );
7130
7132
7133 return SCIP_OKAY;
7134}
7135
7136/** gets left hand side of linear constraint */
7138 SCIP* scip, /**< SCIP data structure */
7139 SCIP_CONS* cons /**< constraint data */
7140 )
7141{
7142 SCIP_CONSDATA* consdata;
7143
7144 assert(scip != NULL);
7145 assert(cons != NULL);
7146
7148
7149 consdata = SCIPconsGetData(cons);
7150 assert(consdata != NULL);
7151
7152 return consdata->lhs;
7153}
7154
7155/** gets right hand side of linear constraint */
7157 SCIP* scip, /**< SCIP data structure */
7158 SCIP_CONS* cons /**< constraint data */
7159 )
7160{
7161 SCIP_CONSDATA* consdata;
7162
7163 assert(scip != NULL);
7164 assert(cons != NULL);
7165
7167
7168 consdata = SCIPconsGetData(cons);
7169 assert(consdata != NULL);
7170
7171 return consdata->rhs;
7172}
7173
7174/** changes left hand side of linear constraint */
7176 SCIP* scip, /**< SCIP data structure */
7177 SCIP_CONS* cons, /**< constraint data */
7178 SCIP_RATIONAL* lhs /**< new left hand side */
7179 )
7180{
7181 assert(scip != NULL);
7182 assert(cons != NULL);
7183 assert(lhs != NULL);
7184
7186
7187 SCIP_CALL( chgLhs(scip, cons, lhs) );
7188
7189 return SCIP_OKAY;
7190}
7191
7192/** changes right hand side of linear constraint */
7194 SCIP* scip, /**< SCIP data structure */
7195 SCIP_CONS* cons, /**< constraint data */
7196 SCIP_RATIONAL* rhs /**< new right hand side */
7197 )
7198{
7199 assert(scip != NULL);
7200 assert(cons != NULL);
7201 assert(rhs != NULL);
7202
7204
7205 SCIP_CALL( chgRhs(scip, cons, rhs) );
7206
7207 return SCIP_OKAY;
7208}
7209
7210/** gets the number of variables in the linear constraint */
7212 SCIP* scip, /**< SCIP data structure */
7213 SCIP_CONS* cons /**< constraint data */
7214 )
7215{
7216 SCIP_CONSDATA* consdata;
7217
7218 assert(scip != NULL);
7219 assert(cons != NULL);
7220
7222
7223 consdata = SCIPconsGetData(cons);
7224 assert(consdata != NULL);
7225
7226 return consdata->nvars;
7227}
7228
7229/** gets the array of variables in the linear constraint; the user must not modify this array! */
7231 SCIP* scip, /**< SCIP data structure */
7232 SCIP_CONS* cons /**< constraint data */
7233 )
7234{
7235 SCIP_CONSDATA* consdata;
7236
7237 assert(scip != NULL);
7238 assert(cons != NULL);
7239
7241
7242 consdata = SCIPconsGetData(cons);
7243 assert(consdata != NULL);
7244
7245 return consdata->vars;
7246}
7247
7248/** gets the array of coefficient values in the linear constraint; the user must not modify this array! */
7250 SCIP* scip, /**< SCIP data structure */
7251 SCIP_CONS* cons /**< constraint data */
7252 )
7253{
7254 SCIP_CONSDATA* consdata;
7255
7256 assert(scip != NULL);
7257 assert(cons != NULL);
7258
7260
7261 consdata = SCIPconsGetData(cons);
7262 assert(consdata != NULL);
7263
7264 return consdata->valsreal;
7265}
7266
7267/** gets the array of coefficient values in the linear constraint; the user must not modify this array! */
7269 SCIP* scip, /**< SCIP data structure */
7270 SCIP_CONS* cons /**< constraint data */
7271 )
7272{
7273 SCIP_CONSDATA* consdata;
7274
7275 assert(scip != NULL);
7276 assert(cons != NULL);
7277
7279
7280 consdata = SCIPconsGetData(cons);
7281 assert(consdata != NULL);
7282
7283 return consdata->vals;
7284}
7285
7286/** gets the activity of the linear constraint in the given solution
7287 *
7288 * @note if the activity comprises positive and negative infinity contributions, the result is currently undefined
7289 */
7291 SCIP* scip, /**< SCIP data structure */
7292 SCIP_CONS* cons, /**< constraint data */
7293 SCIP_SOL* sol, /**< solution, or NULL to use current node's solution */
7294 SCIP_RATIONAL* ret
7295 )
7296{
7297 SCIP_CONSDATA* consdata;
7298
7299 assert(scip != NULL);
7300 assert(cons != NULL);
7301
7303
7304 consdata = SCIPconsGetData(cons);
7305 assert(consdata != NULL);
7306
7307 if( consdata->rowexact != NULL )
7308 {
7309 SCIP_CALL( SCIPgetRowSolActivityExact(scip, consdata->rowexact, sol, FALSE, ret) );
7310 }
7311 else
7312 consdataGetActivity(scip, consdata, sol, TRUE, ret);
7313
7314 return SCIP_OKAY;
7315}
7316
7317/** gets the feasibility of the linear constraint in the given solution */
7319 SCIP* scip, /**< SCIP data structure */
7320 SCIP_CONS* cons, /**< constraint data */
7321 SCIP_SOL* sol, /**< solution, or NULL to use current node's solution */
7322 SCIP_RATIONAL* ret /**< pointer to store the result */
7323 )
7324{
7325 SCIP_CONSDATA* consdata;
7326
7327 assert(scip != NULL);
7328 assert(cons != NULL);
7329
7331
7332 consdata = SCIPconsGetData(cons);
7333 assert(consdata != NULL);
7334
7335 if( consdata->rowexact != NULL )
7336 SCIP_CALL( SCIPgetRowSolFeasibilityExact(scip, consdata->rowexact, sol, ret) );
7337 else
7338 consdataGetFeasibility(scip, consdata, sol, ret);
7339
7340 return SCIP_OKAY;
7341}
7342
7343/** gets the dual solution of the linear constraint in the current LP
7344 *
7345 * @note this method currently returns the value from the floating-point LP
7346 */
7348 SCIP* scip, /**< SCIP data structure */
7349 SCIP_CONS* cons, /**< constraint data */
7350 SCIP_RATIONAL* ret /**< result pointer */
7351 )
7352{
7353 SCIP_CONSDATA* consdata;
7354
7355 assert(scip != NULL);
7356 assert(cons != NULL);
7357 assert(!SCIPconsIsOriginal(cons)); /* original constraints would always return 0 */
7358
7359 SCIP_STRINGEQ( SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME, /**@todo return SCIP_INVALIDCALL type */ );
7360
7361 consdata = SCIPconsGetData(cons);
7362 assert(consdata != NULL);
7363
7364 if( consdata->rowlhs != NULL )
7365 SCIPrationalSetReal(ret, SCIProwGetDualsol(consdata->rowlhs));
7366 else
7367 SCIPrationalSetReal(ret, 0.0);
7368}
7369
7370/** gets the dual Farkas value of the linear constraint in the current infeasible LP
7371 *
7372 * @note this method currently returns an approximate value from the floating-point LP
7373 */
7375 SCIP* scip, /**< SCIP data structure */
7376 SCIP_CONS* cons, /**< constraint data */
7377 SCIP_RATIONAL* ret /**< result pointer */
7378 )
7379{
7380 SCIP_CONSDATA* consdata;
7381
7382 assert(scip != NULL);
7383 assert(cons != NULL);
7384 assert(!SCIPconsIsOriginal(cons)); /* original constraints would always return 0 */
7385
7386 SCIP_STRINGEQ( SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME, /**@todo return SCIP_INVALIDCALL type */ );
7387
7388 consdata = SCIPconsGetData(cons);
7389 assert(consdata != NULL);
7390
7391 if( consdata->rowlhs != NULL )
7392 SCIPrationalSetReal(ret, SCIProwGetDualfarkas(consdata->rowlhs));
7393 else
7394 SCIPrationalSetReal(ret, 0.0);
7395}
7396
7397/** returns the linear relaxation of the given linear constraint; may return NULL if no LP row was yet created;
7398 * the user must not modify the row!
7399 */
7401 SCIP* scip, /**< SCIP data structure */
7402 SCIP_CONS* cons /**< constraint data */
7403 )
7404{
7405 SCIP_CONSDATA* consdata;
7406
7407 assert(scip != NULL);
7408 assert(cons != NULL);
7409
7411
7412 consdata = SCIPconsGetData(cons);
7413 assert(consdata != NULL);
7414
7415 return consdata->rowlhs;
7416}
7417
7418/** returns the exact linear relaxation of the given linear constraint; may return NULL if no LP row was yet created;
7419 * the user must not modify the row!
7420 */
7422 SCIP* scip, /**< SCIP data structure */
7423 SCIP_CONS* cons /**< constraint data */
7424 )
7425{
7426 SCIP_CONSDATA* consdata;
7427
7428 assert(scip != NULL);
7429 assert(cons != NULL);
7430
7432
7433 consdata = SCIPconsGetData(cons);
7434 assert(consdata != NULL);
7435
7436 return consdata->rowexact;
7437}
static long bound
#define EVENTHDLR_NAME
internal methods for clocks and timing issues
#define EVENTHDLR_DESC
enum Proprule PROPRULE
Definition cons_and.c:172
#define CONSHDLR_NEEDSCONS
Definition cons_and.c:96
#define CONSHDLR_SEPAFREQ
Definition cons_and.c:89
#define CONSHDLR_CHECKPRIORITY
Definition cons_and.c:88
#define CONSHDLR_DESC
Definition cons_and.c:85
#define CONSHDLR_PROP_TIMING
Definition cons_and.c:99
#define CONSHDLR_SEPAPRIORITY
Definition cons_and.c:86
Proprule
Definition cons_and.c:165
@ PROPRULE_INVALID
Definition cons_and.c:166
#define CONSHDLR_PROPFREQ
Definition cons_and.c:90
#define CONSHDLR_EAGERFREQ
Definition cons_and.c:91
#define CONSHDLR_ENFOPRIORITY
Definition cons_and.c:87
#define CONSHDLR_DELAYSEPA
Definition cons_and.c:94
#define CONSHDLR_NAME
Definition cons_and.c:84
#define CONSHDLR_DELAYPROP
Definition cons_and.c:95
struct InferInfo INFERINFO
static SCIP_RETCODE consdataPrint(SCIP *scip, SCIP_CONSDATA *consdata, FILE *file)
static void permSortConsdata(SCIP_CONSDATA *consdata, int *perm, int nvars)
static void consdataRecomputeMaxActivityDelta(SCIP *scip, SCIP_CONSDATA *consdata)
static SCIP_RETCODE addRelaxation(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff)
static void consdataUpdateActivitiesLb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real oldlb, SCIP_Real newlb, SCIP_INTERVAL val)
static void consdataUpdateAddCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_RATIONAL *valExact, SCIP_INTERVAL val)
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)
static SCIP_RATIONAL * consdataGetMinAbsvalEx(SCIP *scip, SCIP_CONSDATA *consdata)
static void consdataCalcMinAbsvalEx(SCIP_CONSDATA *consdata)
static void consdataRecomputeMinactivity(SCIP *scip, SCIP_CONSDATA *consdata)
static SCIP_RETCODE chgCoefPos(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_RATIONAL *newval)
static SCIP_RETCODE unlockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_RATIONAL *val)
static SCIP_Bool consdataComputeSolActivityWithErrorbound(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol, SCIP_Real *activity, SCIP_Real *errorbound)
static void conshdlrdataFree(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata)
static void consdataRecomputeGlbMinactivity(SCIP *scip, SCIP_CONSDATA *consdata)
static SCIP_RETCODE printActivityConflictToCertificate(SCIP *scip, SCIP_CONS *cons, SCIP_CONSDATA *consdata, SCIP_Bool rhs)
static void consdataUpdateDelCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_RATIONAL *valExact, SCIP_INTERVAL val)
static void consdataRecomputeMaxactivity(SCIP *scip, SCIP_CONSDATA *consdata)
static SCIP_RETCODE chgRhs(SCIP *scip, SCIP_CONS *cons, SCIP_RATIONAL *rhs)
static SCIP_RETCODE performVarDeletions(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss)
#define checkMaxActivityDelta(scip, consdata)
#define DEFAULT_LIMITDENOM
#define DEFAULT_MAXROUNDSROOT
static void consdataGetActivityResiduals(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_INTERVAL val, SCIP_Bool goodrelax, SCIP_Real *minresactivity, SCIP_Real *maxresactivity, SCIP_Bool *minisrelax, SCIP_Bool *maxisrelax, SCIP_Bool *isminsettoinfinity, SCIP_Bool *ismaxsettoinfinity)
static SCIP_RETCODE separateCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_SOL *sol, int *ncuts, SCIP_Bool *cutoff)
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)
static SCIP_RETCODE propagateCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool tightenbounds, SCIP_Bool sortvars, SCIP_Bool *cutoff, int *nchgbds)
static SCIP_RETCODE consPrintConsSol(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool useexactsol, FILE *file)
static SCIP_RETCODE mergeMultiples(SCIP *scip, SCIP_CONS *cons)
static void consdataCheckNonbinvar(SCIP_CONSDATA *consdata)
#define DEFAULT_SORTVARS
static SCIP_RETCODE tightenBounds(SCIP *scip, SCIP_CONS *cons, SCIP_Bool sortvars, SCIP_Bool *cutoff, int *nchgbds)
#define DEFAULT_BOUNDMAXDENOM
static SCIP_RETCODE consCatchEvent(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
static SCIP_RETCODE consdataEnsureVarsSize(SCIP *scip, SCIP_CONSDATA *consdata, int num)
static void consdataUpdateActivitiesGlbUb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real oldub, SCIP_Real newub, SCIP_INTERVAL val)
static SCIP_RETCODE consdataCreate(SCIP *scip, SCIP_CONSDATA **consdata, int nvars, SCIP_VAR **vars, SCIP_RATIONAL **vals, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs)
#define DEFAULT_MAXSEPACUTSROOT
@ PROPRULE_1_RANGEDROW
@ PROPRULE_1_LHS
@ PROPRULE_1_RHS
static SCIP_RETCODE consDropAllEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
static void consdataUpdateActivitiesGlbLb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real oldlb, SCIP_Real newlb, SCIP_INTERVAL val)
static SCIP_RETCODE findOperators(const char *str, char **firstoperator, char **secondoperator, SCIP_Bool *success)
static SCIP_RETCODE checkCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONSHDLRDATA *conshdlrdata, SCIP_SOL *sol, SCIP_Bool useexactsol, SCIP_Bool checklprows, SCIP_Bool *violated)
static SCIP_RETCODE chgLhs(SCIP *scip, SCIP_CONS *cons, SCIP_RATIONAL *lhs)
static SCIP_RETCODE delCoefPos(SCIP *scip, SCIP_CONS *cons, int pos)
static void consdataUpdateActivitiesUb(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real oldub, SCIP_Real newub, SCIP_INTERVAL val)
static void consdataComputePseudoActivity(SCIP_CONSDATA *consdata, SCIP_RATIONAL *pseudoactivity)
static SCIP_RETCODE createRows(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE enforceConstraint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss, int nusefulconss, SCIP_SOL *sol, SCIP_RESULT *result)
static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata)
#define DEFAULT_MAXSEPACUTS
static void consdataGetActivity(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol, SCIP_Bool useexact, SCIP_RATIONAL *activity)
static void consdataScaleMinValue(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_Real minval)
#define DEFAULT_TIGHTENBOUNDSFREQ
static SCIP_RETCODE conshdlrdataCreate(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata, SCIP_EVENTHDLR *eventhdlr)
static void consdataRecomputeGlbMaxactivity(SCIP *scip, SCIP_CONSDATA *consdata)
static SCIP_RETCODE applyFixings(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible)
static void consdataCalcActivities(SCIP *scip, SCIP_CONSDATA *consdata)
#define DEFAULT_MAXROUNDS
static int getInferInt(PROPRULE proprule, int pos)
static SCIP_RETCODE lockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_RATIONAL *val)
static void consdataInvalidateActivities(SCIP_CONSDATA *consdata)
static SCIP_RETCODE consDropEvent(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
static SCIP_RETCODE tightenVarBounds(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool force)
static void consdataGetFeasibility(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol, SCIP_RATIONAL *ret)
static int inferInfoToInt(INFERINFO inferinfo)
static SCIP_RETCODE consdataSort(SCIP *scip, SCIP_CONSDATA *consdata)
static void consdataUpdateChgCoef(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_INTERVAL oldval, SCIP_RATIONAL *oldvalExact, SCIP_INTERVAL newval, SCIP_RATIONAL *newvalExact)
static SCIP_RETCODE consCatchAllEvents(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
static SCIP_RETCODE addCoef(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_RATIONAL *val)
static void consdataUpdateActivities(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_VAR *var, SCIP_Real oldbound, SCIP_Real newbound, SCIP_INTERVAL valrange, SCIP_BOUNDTYPE boundtype, SCIP_Bool global)
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)
static INFERINFO getInferInfo(PROPRULE proprule, int pos)
#define MAXTIGHTENROUNDS
Constraint handler for linear constraints in their most general form, .
Constraint handler for knapsack constraints of the form , x binary and .
Constraint handler for linear constraints in their most general form, .
constraint handler for nonlinear constraints specified by algebraic expressions
methods for debugging
common defines and data types used in all packages of SCIP
#define NULL
Definition def.h:257
#define SCIP_Longint
Definition def.h:150
#define SCIP_MAXTREEDEPTH
Definition def.h:306
#define SCIP_REAL_UNITROUNDOFF
Definition def.h:169
#define SCIP_INVALID
Definition def.h:187
#define SCIP_Bool
Definition def.h:100
#define MIN(x, y)
Definition def.h:233
#define SCIP_STRINGEQ(name, reference, retcode)
Definition def.h:454
#define SCIP_Real
Definition def.h:165
#define SCIP_UNKNOWN
Definition def.h:188
#define TRUE
Definition def.h:102
#define FALSE
Definition def.h:103
#define MAX(x, y)
Definition def.h:229
#define SCIP_CALL_TERMINATE(retcode, x, TERM)
Definition def.h:385
#define SCIPABORT()
Definition def.h:336
#define REALABS(x)
Definition def.h:191
#define SCIP_LONGINT_MAX
Definition def.h:151
#define SCIP_CALL(x)
Definition def.h:364
SCIP_RETCODE SCIPchgLhsExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_RATIONAL *lhs)
SCIP_RATIONAL * SCIPgetLhsExactLinear(SCIP *scip, SCIP_CONS *cons)
void SCIPgetFpDualsolExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_RATIONAL *ret)
SCIP_RATIONAL * SCIPgetRhsExactLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPchgRhsExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_RATIONAL *rhs)
SCIP_RETCODE SCIPcreateConsExactLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_RATIONAL **vals, SCIP_RATIONAL *lhs, SCIP_RATIONAL *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_VAR ** SCIPgetVarsExactLinear(SCIP *scip, SCIP_CONS *cons)
void SCIPgetFpDualfarkasExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_RATIONAL *ret)
SCIP_RETCODE SCIPcopyConsExactLinear(SCIP *scip, SCIP_CONS **cons, SCIP *sourcescip, const char *name, int nvars, SCIP_VAR **sourcevars, SCIP_INTERVAL *sourcecoefs, SCIP_Real lhs, SCIP_Real rhs, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode, SCIP_Bool global, SCIP_Bool *valid)
int SCIPgetNVarsExactLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPaddCoefExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_RATIONAL *val)
SCIP_RETCODE SCIPcertifyConsOrigExactLinear(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS *cons)
SCIP_RETCODE SCIPgetActivityExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_RATIONAL *ret)
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 SCIPcreateConsBasicExactLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_RATIONAL **vals, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs)
SCIP_ROWEXACT * SCIPgetRowExactExactLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_INTERVAL * SCIPgetValsRealExactLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RATIONAL ** SCIPgetValsExactLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPdelCoefExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
SCIP_ROW * SCIPgetRowExactLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPgetFeasibilityExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_RATIONAL *ret)
SCIP_RETCODE SCIPchgCoefExactLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_RATIONAL *val)
SCIP_RETCODE SCIPincludeConshdlrExactLinear(SCIP *scip)
SCIP_Bool SCIPisConsCompressionEnabled(SCIP *scip)
Definition scip_copy.c:662
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:713
SCIP_Bool SCIPisTransformed(SCIP *scip)
SCIP_STAGE SCIPgetStage(SCIP *scip)
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition scip_prob.c:3420
SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
Definition scip_prob.c:4067
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
SCIP_MESSAGEHDLR * SCIPgetMessagehdlr(SCIP *scip)
#define SCIPdebugMsg
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
SCIP_RETCODE SCIPaddLongintParam(SCIP *scip, const char *name, const char *desc, SCIP_Longint *valueptr, SCIP_Bool isadvanced, SCIP_Longint defaultvalue, SCIP_Longint minvalue, SCIP_Longint maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:111
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
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
SCIP_RETCODE SCIPgetIntParam(SCIP *scip, const char *name, int *value)
Definition scip_param.c:269
SCIP_RETCODE SCIPcertifyCons(SCIP *scip, SCIP_Bool isorigfile, const char *consname, const char sense, SCIP_RATIONAL *side, int len, int *ind, SCIP_RATIONAL **val)
SCIP_RETCODE SCIPcertifyActivityVarBound(SCIP *scip, const char *linename, SCIP_BOUNDTYPE boundtype, SCIP_Real newbound, SCIP_Bool ismaxactivity, SCIP_CONS *constraint, SCIP_VAR *variable, SCIP_ROWEXACT *row, SCIP_RATIONAL **vals, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, SCIP_VAR **vars, int nvars)
SCIP_RETCODE SCIPcertifyActivityConflict(SCIP *scip, SCIP_CONS *cons, SCIP_ROWEXACT *row, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, int nvals, SCIP_RATIONAL **vals, SCIP_VAR **vars, SCIP_RATIONAL *diff, SCIP_Bool userhs)
SCIP_Bool SCIPisCertified(SCIP *scip)
SCIP_RETCODE SCIPcertifyActivityVarBoundExact(SCIP *scip, const char *linename, SCIP_BOUNDTYPE boundtype, SCIP_RATIONAL *newbound, SCIP_Bool ismaxactivity, SCIP_CONS *constraint, SCIP_VAR *variable, SCIP_ROWEXACT *row, SCIP_RATIONAL **vals, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, SCIP_VAR **vars, int nvars)
SCIP_Bool SCIPshouldCertificateTrackBounds(SCIP *scip)
void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
Definition cons.c:4350
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:372
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:235
SCIP_RETCODE SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
Definition scip_cons.c:281
SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:323
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:181
void SCIPconshdlrMarkExact(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4374
SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:808
SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:831
SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:785
int SCIPconshdlrGetPropFreq(SCIP_CONSHDLR *conshdlr)
Definition cons.c:5286
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4320
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)),)
Definition scip_cons.c:347
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition scip_cons.c:940
SCIP_RETCODE SCIPsetConshdlrInit(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:396
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:578
SCIP_RETCODE SCIPsetConshdlrDeactive(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:693
SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4340
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:601
SCIP_RETCODE SCIPsetConshdlrExitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:516
SCIP_RETCODE SCIPsetConshdlrExitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:468
SCIP_RETCODE SCIPsetConshdlrDelvars(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:762
SCIP_RETCODE SCIPsetConshdlrExit(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:420
SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:624
SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:854
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition cons.c:8423
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition cons.c:8652
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition cons.c:8413
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition cons.c:8562
SCIP_Bool SCIPconsIsOriginal(SCIP_CONS *cons)
Definition cons.c:8692
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition cons.c:8592
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition cons.c:8522
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition cons.c:8702
SCIP_Bool SCIPconsIsLockedType(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition cons.c:8786
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition cons.c:8582
SCIP_RETCODE SCIPunmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
Definition scip_cons.c:2042
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition cons.c:8454
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:997
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition cons.c:8612
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition cons.c:8632
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition cons.c:8393
SCIP_RETCODE SCIPresetConsAge(SCIP *scip, SCIP_CONS *cons)
Definition scip_cons.c:1812
SCIP_RETCODE SCIPmarkConsPropagate(SCIP *scip, SCIP_CONS *cons)
Definition scip_cons.c:2014
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition cons.c:8642
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition cons.c:8672
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition cons.c:8572
SCIP_RETCODE SCIPincConsAge(SCIP *scip, SCIP_CONS *cons)
Definition scip_cons.c:1784
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition cons.c:8662
SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
Definition scip_cut.c:225
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:111
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition event.c:396
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition event.c:1194
SCIP_VARTYPE SCIPeventGetNewtype(SCIP_EVENT *event)
Definition event.c:1479
SCIP_RETCODE SCIPcatchVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition scip_event.c:367
SCIP_RETCODE SCIPdropVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition scip_event.c:413
SCIP_Real SCIPeventGetOldbound(SCIP_EVENT *event)
Definition event.c:1391
SCIP_VAR * SCIPeventGetVar(SCIP_EVENT *event)
Definition event.c:1217
SCIP_Real SCIPeventGetNewbound(SCIP_EVENT *event)
Definition event.c:1415
SCIP_VARTYPE SCIPeventGetOldtype(SCIP_EVENT *event)
Definition event.c:1462
SCIP_Bool SCIPisExact(SCIP *scip)
Definition scip_exact.c:193
SCIP_RETCODE SCIPaddRowExact(SCIP *scip, SCIP_ROWEXACT *rowexact)
Definition scip_exact.c:257
void SCIPintervalSetRoundingModeUpwards(void)
void SCIPintervalSetRoundingModeDownwards(void)
SCIP_ROUNDMODE SCIPintervalGetRoundingMode(void)
void SCIPintervalSetRoundingMode(SCIP_ROUNDMODE roundmode)
SCIP_Real SCIPintervalAbsMax(SCIP_INTERVAL interval)
void SCIPintervalSubScalar(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_Real operand2)
int SCIP_ROUNDMODE
void SCIPintervalSet(SCIP_INTERVAL *resultant, SCIP_Real value)
struct SCIP_Interval SCIP_INTERVAL
void SCIPintervalDiv(SCIP_Real infinity, SCIP_INTERVAL *resultant, SCIP_INTERVAL operand1, SCIP_INTERVAL operand2)
SCIP_Real SCIPintervalGetSup(SCIP_INTERVAL interval)
SCIP_Real SCIPintervalNegateReal(SCIP_Real x)
void SCIPintervalSetRational(SCIP_INTERVAL *resultant, SCIP_RATIONAL *value)
SCIP_RETCODE SCIPreleaseRowExact(SCIP *scip, SCIP_ROWEXACT **row)
SCIP_Bool SCIPgetRowSolActivityWithErrorboundExact(SCIP *scip, SCIP_ROWEXACT *row, SCIP_SOL *sol, SCIP_Real *activity, SCIP_Real *errorbound)
SCIP_RETCODE SCIPprintRowExact(SCIP *scip, SCIP_ROWEXACT *row, FILE *file)
SCIP_RETCODE SCIPgenerateFpRowsFromRowExact(SCIP *scip, SCIP_ROWEXACT *row, SCIP_ROW *rowlhs, SCIP_ROW *rowrhs, SCIP_Bool *onerowrelax, SCIP_Bool *hasfprelax)
SCIP_RETCODE SCIPgetRowSolActivityExact(SCIP *scip, SCIP_ROWEXACT *row, SCIP_SOL *sol, SCIP_Bool useexact, SCIP_RATIONAL *result)
SCIP_RETCODE SCIPgetRowSolFeasibilityExact(SCIP *scip, SCIP_ROWEXACT *row, SCIP_SOL *sol, SCIP_RATIONAL *result)
SCIP_RETCODE SCIPchgRowExactLhs(SCIP *scip, SCIP_ROWEXACT *row, SCIP_RATIONAL *lhs)
SCIP_RETCODE SCIPcreateEmptyRowConsExact(SCIP *scip, SCIP_ROWEXACT **rowexact, SCIP_ROW *fprow, SCIP_ROW *fprowrhs, SCIP_RATIONAL *lhs, SCIP_RATIONAL *rhs, SCIP_Bool isfprelaxable)
SCIP_RETCODE SCIPchgRowExactRhs(SCIP *scip, SCIP_ROWEXACT *row, SCIP_RATIONAL *rhs)
SCIP_RETCODE SCIPaddVarsToRowExact(SCIP *scip, SCIP_ROWEXACT *row, int nvars, SCIP_VAR **vars, SCIP_RATIONAL **vals)
SCIP_Bool SCIPlpExactIsSolved(SCIP *scip)
SCIP_RETCODE SCIPcaptureRowExact(SCIP *scip, SCIP_ROWEXACT *row)
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition scip_lp.c:87
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:110
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition scip_mem.c:57
BMS_BUFMEM * SCIPbuffer(SCIP *scip)
Definition scip_mem.c:72
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition scip_mem.c:139
#define SCIPallocBufferArray(scip, ptr, num)
Definition scip_mem.h:124
#define SCIPreallocBufferArray(scip, ptr, num)
Definition scip_mem.h:128
#define SCIPfreeBufferArray(scip, ptr)
Definition scip_mem.h:136
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition scip_mem.h:132
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:93
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition scip_mem.h:99
#define SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition scip_mem.h:111
#define SCIPfreeBufferArrayNull(scip, ptr)
Definition scip_mem.h:137
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition scip_mem.h:105
SCIP_Bool SCIPinProbing(SCIP *scip)
SCIP_Bool SCIPrationalIsLTReal(SCIP_RATIONAL *rat, SCIP_Real real)
void SCIPrationalMin(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
SCIP_RETCODE SCIPrationalCreateBlock(BMS_BLKMEM *blkmem, SCIP_RATIONAL **rational)
Definition rational.cpp:109
SCIP_RETCODE SCIPrationalCreate(SCIP_RATIONAL **rational)
Definition rational.cpp:95
void SCIPrationalMult(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
SCIP_Bool SCIPrationalIsAbsEQ(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
void SCIPrationalSetInfinity(SCIP_RATIONAL *res)
Definition rational.cpp:619
void SCIPrationalAdd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
Definition rational.cpp:936
SCIP_Real SCIPrationalGetReal(SCIP_RATIONAL *rational)
SCIP_RETCODE SCIPrationalCreateString(BMS_BLKMEM *mem, SCIP_RATIONAL **rational, const char *desc)
Definition rational.cpp:797
void SCIPrationalFreeBlock(BMS_BLKMEM *mem, SCIP_RATIONAL **rational)
Definition rational.cpp:462
#define SCIPrationalDebugMessage
Definition rational.h:641
void SCIPrationalAbs(SCIP_RATIONAL *res, SCIP_RATIONAL *op)
void SCIPrationalDiv(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
SCIP_Bool SCIPrationalIsAbsInfinity(SCIP_RATIONAL *rational)
SCIP_Bool SCIPrationalIsLT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
void SCIPrationalSetReal(SCIP_RATIONAL *res, SCIP_Real real)
Definition rational.cpp:604
SCIP_Bool SCIPrationalIsGT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
SCIP_RETCODE SCIPrationalCopyBlock(BMS_BLKMEM *mem, SCIP_RATIONAL **result, SCIP_RATIONAL *src)
Definition rational.cpp:152
void SCIPrationalFreeBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
Definition rational.cpp:474
SCIP_RETCODE SCIPrationalCopyBlockArray(BMS_BLKMEM *mem, SCIP_RATIONAL ***target, SCIP_RATIONAL **src, int len)
Definition rational.cpp:250
void SCIPrationalDiff(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
Definition rational.cpp:984
SCIP_Bool SCIPrationalIsLEReal(SCIP_RATIONAL *rat, SCIP_Real real)
SCIP_Bool SCIPrationalIsPositive(SCIP_RATIONAL *rational)
int SCIPrationalGetSign(const SCIP_RATIONAL *rational)
SCIP_RETCODE SCIPrationalCreateBuffer(BMS_BUFMEM *bufmem, SCIP_RATIONAL **rational)
Definition rational.cpp:124
void SCIPrationalAddProd(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_RATIONAL *op2)
SCIP_Bool SCIPrationalIsZero(SCIP_RATIONAL *rational)
void SCIPrationalSetRational(SCIP_RATIONAL *res, SCIP_RATIONAL *src)
Definition rational.cpp:570
SCIP_Bool SCIPrationalIsGEReal(SCIP_RATIONAL *rat, SCIP_Real real)
void SCIPrationalMessage(SCIP_MESSAGEHDLR *msg, FILE *file, SCIP_RATIONAL *rational)
void SCIPrationalSetNegInfinity(SCIP_RATIONAL *res)
Definition rational.cpp:631
void SCIPrationalSetFraction(SCIP_RATIONAL *res, SCIP_Longint nom, SCIP_Longint denom)
Definition rational.cpp:583
void SCIPrationalNegate(SCIP_RATIONAL *res, SCIP_RATIONAL *op)
SCIP_Bool SCIPrationalIsNegative(SCIP_RATIONAL *rational)
void SCIPrationalDiffReal(SCIP_RATIONAL *res, SCIP_RATIONAL *rat, SCIP_Real real)
SCIP_Bool SCIPrationalIsInfinity(SCIP_RATIONAL *rational)
void SCIPrationalFreeBlockArray(BMS_BLKMEM *mem, SCIP_RATIONAL ***ratblockarray, int size)
Definition rational.cpp:502
SCIP_Real SCIPrationalRoundReal(SCIP_RATIONAL *rational, SCIP_ROUNDMODE_RAT roundmode)
SCIP_Bool SCIPrationalIsEQReal(SCIP_RATIONAL *rat, SCIP_Real real)
SCIP_RETCODE SCIPrationalCreateBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***rational, int size)
Definition rational.cpp:215
SCIP_Bool SCIPrationalIsNegInfinity(SCIP_RATIONAL *rational)
void SCIPrationalFree(SCIP_RATIONAL **rational)
Definition rational.cpp:451
SCIP_Bool SCIPrationalIsGTReal(SCIP_RATIONAL *rat, SCIP_Real real)
SCIP_Bool SCIPrationalIsEQ(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
SCIP_RETCODE SCIPrationalReallocBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***result, int oldlen, int newlen)
Definition rational.cpp:315
void SCIPrationalMultReal(SCIP_RATIONAL *res, SCIP_RATIONAL *op1, SCIP_Real op2)
void SCIPrationalComputeApproximation(SCIP_RATIONAL *res, SCIP_RATIONAL *src, SCIP_Longint maxdenom, int forcegreater)
void SCIPrationalFreeBufferArray(BMS_BUFMEM *mem, SCIP_RATIONAL ***ratbufarray, int size)
Definition rational.cpp:519
SCIP_Bool SCIPrationalIsAbsGT(SCIP_RATIONAL *rat1, SCIP_RATIONAL *rat2)
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:1398
SCIP_RETCODE SCIPprintRow(SCIP *scip, SCIP_ROW *row, FILE *file)
Definition scip_lp.c:2176
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition scip_lp.c:1508
SCIP_Real SCIProwGetDualfarkas(SCIP_ROW *row)
Definition lp.c:17719
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition lp.c:17917
SCIP_Real SCIProwGetDualsol(SCIP_ROW *row)
Definition lp.c:17706
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
Definition scip_sol.c:2351
void SCIPgetSolValExact(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var, SCIP_RATIONAL *res)
Definition scip_sol.c:1801
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition scip_sol.c:1763
SCIP_Bool SCIPsolIsExact(SCIP_SOL *sol)
Definition sol.c:4165
int SCIPgetNSepaRounds(SCIP *scip)
SCIP_Bool SCIPisUbBetter(SCIP *scip, SCIP_Real newub, SCIP_Real oldlb, SCIP_Real oldub)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPparseRational(SCIP *scip, const char *str, SCIP_RATIONAL *value, char **endptr)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisLbBetter(SCIP *scip, SCIP_Real newlb, SCIP_Real oldlb, SCIP_Real oldub)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisHugeValue(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPgetHugeValue(SCIP *scip)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Real SCIPepsilon(SCIP *scip)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPinRepropagation(SCIP *scip)
Definition scip_tree.c:146
int SCIPgetDepth(SCIP *scip)
Definition scip_tree.c:672
SCIP_RETCODE SCIPvarGetOrigvarSum(SCIP_VAR **var, SCIP_Real *scalar, SCIP_Real *constant)
Definition var.c:18365
SCIP_RETCODE SCIPvarGetProbvarBound(SCIP_VAR **var, SCIP_Real *bound, SCIP_BOUNDTYPE *boundtype)
Definition var.c:17846
SCIP_Bool SCIPvarIsDeleted(SCIP_VAR *var)
Definition var.c:23566
SCIP_Real SCIPvarGetNegationConstant(SCIP_VAR *var)
Definition var.c:23921
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition scip_var.c:5210
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition var.c:23674
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition var.c:23510
SCIP_RATIONAL * SCIPvarGetAggrScalarExact(SCIP_VAR *var)
Definition var.c:23792
SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition scip_var.c:2119
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition var.c:23418
int SCIPvarGetNLocksUpType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition var.c:4380
SCIP_Real SCIPadjustedVarLbExactFloat(SCIP *scip, SCIP_VAR *var, SCIP_Real lb)
Definition scip_var.c:5602
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition var.c:24300
SCIP_RATIONAL * SCIPvarGetAggrConstantExact(SCIP_VAR *var)
Definition var.c:23815
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition var.c:23462
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:7069
int SCIPvarGetCertificateIndex(SCIP_VAR *var)
Definition var.c:25130
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition var.c:23485
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition var.c:24174
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition scip_var.c:5118
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition scip_var.c:5296
SCIP_RETCODE SCIPinferVarLbConsExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition scip_var.c:7296
int SCIPvarGetProbindex(SCIP_VAR *var)
Definition var.c:23694
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:23299
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition scip_var.c:1887
SCIP_RATIONAL * SCIPvarGetMultaggrConstantExact(SCIP_VAR *var)
Definition var.c:23887
SCIP_RETCODE SCIPgetProbvarLinearSumExact(SCIP *scip, SCIP_VAR **vars, SCIP_RATIONAL **scalars, int *nvars, int varssize, SCIP_RATIONAL *constant, int *requiredsize, SCIP_Bool mergemultiples)
Definition scip_var.c:2443
SCIP_RATIONAL * SCIPvarGetUbLocalExact(SCIP_VAR *var)
Definition var.c:24310
SCIP_RETCODE SCIPgetProbvarLinearSum(SCIP *scip, SCIP_VAR **vars, SCIP_Real *scalars, int *nvars, int varssize, SCIP_Real *constant, int *requiredsize)
Definition scip_var.c:2378
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition var.c:23522
SCIP_RETCODE SCIPparseVarsLinearsumExact(SCIP *scip, char *str, SCIP_VAR **vars, SCIP_RATIONAL **vals, int *nvars, int varssize, int *requiredsize, char **endptr, SCIP_Bool *success)
Definition scip_var.c:1007
SCIP_RETCODE SCIPflattenVarAggregationGraph(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:2332
SCIP_VAR ** SCIPvarGetMultaggrVars(SCIP_VAR *var)
Definition var.c:23838
SCIP_RETCODE SCIPinferVarUbConsExact(SCIP *scip, SCIP_VAR *var, SCIP_RATIONAL *newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition scip_var.c:7174
int SCIPvarGetMultaggrNVars(SCIP_VAR *var)
Definition var.c:23826
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition var.c:24266
SCIP_RATIONAL * SCIPvarGetBestBoundLocalExact(SCIP_VAR *var)
Definition var.c:24357
SCIP_RATIONAL * SCIPvarGetLbGlobalExact(SCIP_VAR *var)
Definition var.c:24162
SCIP_VAR * SCIPvarGetNegationVar(SCIP_VAR *var)
Definition var.c:23910
SCIP_RATIONAL ** SCIPvarGetMultaggrScalarsExact(SCIP_VAR *var)
Definition var.c:23862
SCIP_Real SCIPadjustedVarUbExactFloat(SCIP *scip, SCIP_VAR *var, SCIP_Real ub)
Definition scip_var.c:5666
SCIP_Bool SCIPvarIsOriginal(SCIP_VAR *var)
Definition var.c:23449
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition var.c:24152
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:6964
SCIP_RATIONAL * SCIPvarGetLbLocalExact(SCIP_VAR *var)
Definition var.c:24276
int SCIPvarCompare(SCIP_VAR *var1, SCIP_VAR *var2)
Definition var.c:17319
SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
Definition scip_var.c:361
SCIP_RETCODE SCIPgetProbvarSumExact(SCIP *scip, SCIP_VAR **var, SCIP_RATIONAL *scalar, SCIP_RATIONAL *constant)
Definition scip_var.c:2538
int SCIPvarGetNLocksDownType(SCIP_VAR *var, SCIP_LOCKTYPE locktype)
Definition var.c:4322
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition scip_var.c:2078
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition scip_var.c:1853
SCIP_RETCODE SCIPwriteVarsLinearsumExact(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_RATIONAL **vals, int nvars, SCIP_Bool type)
Definition scip_var.c:533
SCIP_RATIONAL * SCIPvarGetUbGlobalExact(SCIP_VAR *var)
Definition var.c:24184
SCIP_VAR * SCIPvarGetAggrVar(SCIP_VAR *var)
Definition var.c:23768
void SCIPsort(int *perm, SCIP_DECL_SORTINDCOMP((*indcomp)), void *dataptr, int len)
Definition misc.c:5581
SCIP_RETCODE SCIPskipSpace(char **s)
Definition misc.c:10816
return SCIP_OKAY
int c
int depth
SCIP_Bool cutoff
static SCIP_RETCODE updateActivities(SCIP *scip, SCIP_Real *minactivities, SCIP_Real *maxactivities, SCIP_ROW **violrows, int *violrowpos, int *nviolrows, int *nviolfracrows, int *nfracsinrow, int nlprows, SCIP_VAR *var, SCIP_Real oldsolval, SCIP_Real newsolval)
static SCIP_SOL * sol
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
SCIP_VAR * var
static SCIP_Bool propagate
static SCIP_VAR ** vars
interval arithmetics for provable bounds
SCIP_Bool SCIProwExactIsInLP(SCIP_ROWEXACT *row)
Definition lpexact.c:5036
SCIP_RATIONAL ** SCIProwExactGetVals(SCIP_ROWEXACT *row)
Definition lpexact.c:5016
int SCIProwExactGetNNonz(SCIP_ROWEXACT *row)
Definition lpexact.c:5006
memory allocation routines
#define BMScopyMemoryArray(ptr, source, num)
Definition memory.h:134
#define BMSclearMemoryArray(ptr, num)
Definition memory.h:130
void SCIPmessageFPrintInfo(SCIP_MESSAGEHDLR *messagehdlr, FILE *file, const char *formatstr,...)
Definition message.c:618
public methods for conflict analysis handlers
public methods for managing constraints
public methods for managing events
public methods for LP management
public methods for LP management
public methods for message output
#define SCIPerrorMessage
Definition pub_message.h:64
#define SCIPdebug(x)
Definition pub_message.h:93
#define SCIPdebugPrintCons(x, y, z)
public data structures and miscellaneous methods
methods for sorting joint arrays of various types
public methods for problem variables
wrapper for rational number arithmetic
public methods for branching rule plugins and branching
public methods for certified solving
public methods for conflict handler plugins and conflict analysis
public methods for constraint handler plugins and constraints
public methods for problem copies
public methods for cuts and aggregation rows
public methods for event handler plugins and event handlers
public methods for exact solving
general public methods
public methods for the LP relaxation, rows and columns
public methods for the LP relaxation, rows and columns
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for global and local (sub)problems
public methods for the probing mode
public methods for querying solving statistics
public methods for the branch-and-bound tree
public methods for SCIP variables
static SCIP_RETCODE separate(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
Main separation function.
internal methods for storing separated exact cuts
SCIP_Real sup
SCIP_Real inf
datastructures for problem statistics
#define SCIP_DECL_CONSENFOLP(x)
Definition type_cons.h:363
#define SCIP_DECL_CONSDELETE(x)
Definition type_cons.h:229
struct SCIP_Cons SCIP_CONS
Definition type_cons.h:63
#define SCIP_DECL_CONSEXIT(x)
Definition type_cons.h:136
#define SCIP_DECL_CONSGETVARS(x)
Definition type_cons.h:867
#define SCIP_DECL_CONSPRINT(x)
Definition type_cons.h:769
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition type_cons.h:64
#define SCIP_DECL_CONSSEPALP(x)
Definition type_cons.h:288
#define SCIP_DECL_CONSENFORELAX(x)
Definition type_cons.h:388
#define SCIP_DECL_CONSPROP(x)
Definition type_cons.h:506
#define SCIP_DECL_CONSGETNVARS(x)
Definition type_cons.h:885
#define SCIP_DECL_CONSENFOPS(x)
Definition type_cons.h:431
#define SCIP_DECL_CONSPARSE(x)
Definition type_cons.h:845
#define SCIP_DECL_CONSTRANS(x)
Definition type_cons.h:239
#define SCIP_DECL_CONSDEACTIVE(x)
Definition type_cons.h:706
#define SCIP_DECL_CONSINITLP(x)
Definition type_cons.h:259
#define SCIP_DECL_CONSEXITPRE(x)
Definition type_cons.h:180
#define SCIP_DECL_CONSLOCK(x)
Definition type_cons.h:676
struct SCIP_Conshdlr SCIP_CONSHDLR
Definition type_cons.h:62
#define SCIP_DECL_CONSCOPY(x)
Definition type_cons.h:810
#define SCIP_DECL_CONSINIT(x)
Definition type_cons.h:126
struct SCIP_ConsData SCIP_CONSDATA
Definition type_cons.h:65
#define SCIP_DECL_CONSCHECK(x)
Definition type_cons.h:474
#define SCIP_DECL_CONSHDLRCOPY(x)
Definition type_cons.h:108
#define SCIP_DECL_CONSEXITSOL(x)
Definition type_cons.h:216
#define SCIP_DECL_CONSFREE(x)
Definition type_cons.h:116
#define SCIP_DECL_CONSSEPASOL(x)
Definition type_cons.h:320
#define SCIP_DECL_CONSDELVARS(x)
Definition type_cons.h:753
struct SCIP_Eventhdlr SCIP_EVENTHDLR
Definition type_event.h:159
#define SCIP_EVENTTYPE_BOUNDCHANGED
Definition type_event.h:127
#define SCIP_EVENTTYPE_VARUNLOCKED
Definition type_event.h:73
#define SCIP_EVENTTYPE_TYPECHANGED
Definition type_event.h:86
#define SCIP_EVENTTYPE_GUBCHANGED
Definition type_event.h:76
#define SCIP_EVENTTYPE_GBDCHANGED
Definition type_event.h:122
struct SCIP_EventData SCIP_EVENTDATA
Definition type_event.h:179
#define SCIP_EVENTTYPE_UBTIGHTENED
Definition type_event.h:79
#define SCIP_EVENTTYPE_VARFIXED
Definition type_event.h:72
#define SCIP_EVENTTYPE_VARDELETED
Definition type_event.h:71
#define SCIP_DECL_EVENTEXEC(x)
Definition type_event.h:259
#define SCIP_EVENTTYPE_FORMAT
Definition type_event.h:157
#define SCIP_EVENTTYPE_GLBCHANGED
Definition type_event.h:75
#define SCIP_EVENTTYPE_BOUNDRELAXED
Definition type_event.h:126
#define SCIP_EVENTTYPE_LBCHANGED
Definition type_event.h:123
#define SCIP_EVENTTYPE_UBCHANGED
Definition type_event.h:124
uint64_t SCIP_EVENTTYPE
Definition type_event.h:156
#define SCIP_EVENTTYPE_BOUNDTIGHTENED
Definition type_event.h:125
#define SCIP_EVENTTYPE_LBTIGHTENED
Definition type_event.h:77
struct SCIP_Row SCIP_ROW
Definition type_lp.h:105
@ SCIP_BOUNDTYPE_UPPER
Definition type_lp.h:58
@ SCIP_BOUNDTYPE_LOWER
Definition type_lp.h:57
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition type_lp.h:60
struct SCIP_RowExact SCIP_ROWEXACT
struct SCIP_HashMap SCIP_HASHMAP
Definition type_misc.h:106
#define SCIP_DECL_SORTINDCOMP(x)
Definition type_misc.h:181
struct SCIP_Rational SCIP_RATIONAL
@ SCIP_R_ROUND_UPWARDS
@ SCIP_R_ROUND_DOWNWARDS
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_CUTOFF
Definition type_result.h:48
@ SCIP_FEASIBLE
Definition type_result.h:45
@ SCIP_REDUCEDDOM
Definition type_result.h:51
@ SCIP_DIDNOTFIND
Definition type_result.h:44
@ SCIP_SEPARATED
Definition type_result.h:49
@ SCIP_INFEASIBLE
Definition type_result.h:46
enum SCIP_Result SCIP_RESULT
Definition type_result.h:61
type definitions for return codes for SCIP methods
@ SCIP_READERROR
@ SCIP_INVALIDDATA
@ SCIP_PLUGINNOTFOUND
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
@ SCIP_STAGE_PROBLEM
Definition type_set.h:45
@ SCIP_STAGE_INITSOLVE
Definition type_set.h:52
@ SCIP_STAGE_EXITPRESOLVE
Definition type_set.h:50
@ SCIP_STAGE_TRANSFORMING
Definition type_set.h:46
@ SCIP_STAGE_PRESOLVED
Definition type_set.h:51
struct SCIP_Sol SCIP_SOL
Definition type_sol.h:57
struct SCIP_Var SCIP_VAR
Definition type_var.h:166
#define NLOCKTYPES
Definition type_var.h:138
@ SCIP_VARTYPE_CONTINUOUS
Definition type_var.h:71
@ SCIP_VARTYPE_BINARY
Definition type_var.h:64
@ SCIP_VARSTATUS_ORIGINAL
Definition type_var.h:51
@ SCIP_VARSTATUS_FIXED
Definition type_var.h:54
@ SCIP_VARSTATUS_COLUMN
Definition type_var.h:53
@ SCIP_VARSTATUS_MULTAGGR
Definition type_var.h:56
@ SCIP_VARSTATUS_NEGATED
Definition type_var.h:57
@ SCIP_VARSTATUS_AGGREGATED
Definition type_var.h:55
@ SCIP_VARSTATUS_LOOSE
Definition type_var.h:52
enum SCIP_LockType SCIP_LOCKTYPE
Definition type_var.h:144
@ SCIP_LOCKTYPE_MODEL
Definition type_var.h:141
enum SCIP_Vartype SCIP_VARTYPE
Definition type_var.h:73
internal methods for problem variables