Scippy

SCIP

Solving Constraint Integer Programs

cons_bounddisjunction.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-2017 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file cons_bounddisjunction.c
17  * @brief constraint handler for bound disjunction constraints \f$(x_1 \{\leq,\geq\} b_1) \vee \ldots \vee (x_n \{\leq,\geq\} b_n)\f$
18  * @author Tobias Achterberg
19  * @author Marc Pfetsch
20  */
21 
22 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
23 
24 #include <assert.h>
25 #include <string.h>
26 #include <limits.h>
27 #include <ctype.h>
28 
30 #include "scip/cons_quadratic.h"
31 #include "scip/cons_linear.h"
32 #include "scip/cons_logicor.h"
33 #include "scip/cons_setppc.h"
34 #include "scip/pub_misc.h"
35 
36 /**@name Constraint handler properties
37  *
38  * @{
39  */
40 
41 #define CONSHDLR_NAME "bounddisjunction"
42 #define CONSHDLR_DESC "bound disjunction constraints"
43 #define CONSHDLR_ENFOPRIORITY -3000000 /**< priority of the constraint handler for constraint enforcing */
44 #define CONSHDLR_CHECKPRIORITY -3000000 /**< priority of the constraint handler for checking feasibility */
45 #define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
46 #define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
47  * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
48 #define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
49 #define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
50 #define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
51 
52 #define CONSHDLR_PRESOLTIMING SCIP_PRESOLTIMING_FAST
53 #define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP
54 
55 #define QUADCONSUPGD_PRIORITY 500000 /**< priority of the constraint handler for upgrading of quadratic constraints */
56 
57 /**@} */
58 
59 /**@name Event handler properties
60  *
61  * @{
62  */
63 
64 #define EVENTHDLR_NAME "bounddisjunction"
65 #define EVENTHDLR_DESC "event handler for bound disjunction constraints"
66 
67 /**@} */
68 
69 /**@name Conflict handler properties
70  *
71  * @{
72  */
73 
74 #define CONFLICTHDLR_NAME "bounddisjunction"
75 #define CONFLICTHDLR_DESC "conflict handler creating bound disjunction constraints"
76 #define CONFLICTHDLR_PRIORITY -3000000
77 
78 /**@} */
79 
80 /**@name Default parameter values
81  *
82  * @{
83  */
84 
85 #define DEFAULT_CONTINUOUSFRAC 0.4 /**< maximal percantage of continuous variables within a conflict */
86 
87 /**@} */
88 
89 /**@name Age increase defines
90  *
91  * @{
92  */
93 
94 /* @todo make this a parameter setting */
95 #if 1 /* @todo test which AGEINCREASE formula is better! */
96 #define AGEINCREASE(n) (1.0 + 0.2*n)
97 #else
98 #define AGEINCREASE(n) (0.1*n)
99 #endif
100 
101 /**@} */
102 
103 
104 /**@name Comparison for two values
105  *
106  * @{
107  */
108 
109 #ifdef SCIP_DISABLED_CODE /* These only work if one also passes integral values in case of integral variables. This is not always the case and not even asserted. */
110 /** use defines for numeric compare methods to be slightly faster for integral values */
111 #define isFeasLT(scip, var, val1, val2) (SCIPvarIsIntegral(var) ? (val2) - (val1) > 0.5 : SCIPisFeasLT(scip, val1, val2))
112 #define isFeasLE(scip, var, val1, val2) (SCIPvarIsIntegral(var) ? (val2) - (val1) > -0.5 : SCIPisFeasLE(scip, val1, val2))
113 #define isFeasGT(scip, var, val1, val2) (SCIPvarIsIntegral(var) ? (val1) - (val2) > 0.5 : SCIPisFeasGT(scip, val1, val2))
114 #define isFeasGE(scip, var, val1, val2) (SCIPvarIsIntegral(var) ? (val1) - (val2) > -0.5 : SCIPisFeasGE(scip, val1, val2))
115 #else
116 #define isFeasLT(scip, var, val1, val2) SCIPisFeasLT(scip, val1, val2)
117 #define isFeasLE(scip, var, val1, val2) SCIPisFeasLE(scip, val1, val2)
118 #define isFeasGT(scip, var, val1, val2) SCIPisFeasGT(scip, val1, val2)
119 #define isFeasGE(scip, var, val1, val2) SCIPisFeasGE(scip, val1, val2)
120 #endif
121 /**@} */
122 
123 
124 /** constraint handler data */
125 struct SCIP_ConshdlrData
126 {
127  SCIP_EVENTHDLR* eventhdlr; /**< event handler for events on watched variables */
128 };
129 
130 /** bound disjunction constraint data */
131 struct SCIP_ConsData
132 {
133  SCIP_VAR** vars; /**< variables of the literals in the constraint */
134  SCIP_BOUNDTYPE* boundtypes; /**< types of bounds of the literals (lower or upper bounds) */
135  SCIP_Real* bounds; /**< bounds of the literals */
136  int varssize; /**< size of vars, boundtypes, and bounds arrays */
137  int nvars; /**< number of variables in the constraint */
138  int watchedvar1; /**< position of the first watched variable */
139  int watchedvar2; /**< position of the second watched variable */
140  int filterpos1; /**< event filter position of first watched variable */
141  int filterpos2; /**< event filter position of second watched variable */
142 };
143 
144 /**@name Local methods
145  *
146  */
147 
148 /** adds rounding locks for the given variable in the given bound disjunction constraint */
149 static
151  SCIP* scip, /**< SCIP data structure */
152  SCIP_CONS* cons, /**< bound disjunction constraint */
153  SCIP_CONSDATA* consdata, /**< bound disjunction constraint data */
154  int pos /**< position of the variable in the constraint */
155  )
156 {
157  assert(consdata != NULL);
158  assert(0 <= pos && pos < consdata->nvars);
159 
160  if( consdata->boundtypes[pos] == SCIP_BOUNDTYPE_LOWER )
161  {
162  /* rounding down may violate the constraint */
163  SCIP_CALL( SCIPlockVarCons(scip, consdata->vars[pos], cons, TRUE, FALSE) );
164  }
165  else
166  {
167  /* rounding up may violate the constraint */
168  SCIP_CALL( SCIPlockVarCons(scip, consdata->vars[pos], cons, FALSE, TRUE) );
169  }
170 
171  return SCIP_OKAY;
172 }
173 
174 /** removes rounding locks for the given variable in the given bound disjunction constraint */
175 static
177  SCIP* scip, /**< SCIP data structure */
178  SCIP_CONS* cons, /**< bound disjunction constraint */
179  SCIP_CONSDATA* consdata, /**< bound disjunction constraint data */
180  int pos /**< position of the variable in the constraint */
181  )
182 {
183  assert(consdata != NULL);
184  assert(0 <= pos && pos < consdata->nvars);
185 
186  if( consdata->boundtypes[pos] == SCIP_BOUNDTYPE_LOWER )
187  {
188  /* rounding down may violate the constraint */
189  SCIP_CALL( SCIPunlockVarCons(scip, consdata->vars[pos], cons, TRUE, FALSE) );
190  }
191  else
192  {
193  /* rounding up may violate the constraint */
194  SCIP_CALL( SCIPunlockVarCons(scip, consdata->vars[pos], cons, FALSE, TRUE) );
195  }
196 
197  return SCIP_OKAY;
198 }
199 
200 /** catches the events on a single variable of the bound disjunction constraint */
201 static
203  SCIP* scip, /**< SCIP data structure */
204  SCIP_CONS* cons, /**< bound disjunction constraint */
205  SCIP_CONSDATA* consdata, /**< bound disjunction constraint data */
206  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
207  int pos, /**< position of the variable in the constraint */
208  int* filterpos /**< pointer to store position of event filter entry, or NULL */
209  )
210 {
211  assert(consdata != NULL);
212  assert(0 <= pos && pos < consdata->nvars);
213 
214  if( consdata->boundtypes[pos] == SCIP_BOUNDTYPE_LOWER )
215  {
217  eventhdlr, (SCIP_EVENTDATA*)cons, filterpos) );
218  }
219  else
220  {
222  eventhdlr, (SCIP_EVENTDATA*)cons, filterpos) );
223  }
224 
225  return SCIP_OKAY;
226 }
227 
228 /** drops the events on a single variable of the bound disjunction constraint */
229 static
231  SCIP* scip, /**< SCIP data structure */
232  SCIP_CONS* cons, /**< bound disjunction constraint */
233  SCIP_CONSDATA* consdata, /**< bound disjunction constraint data */
234  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
235  int pos, /**< position of the variable in the constraint */
236  int filterpos /**< position of event filter entry returned by SCIPcatchVarEvent(), or -1 */
237  )
238 {
239  assert(consdata != NULL);
240  assert(0 <= pos && pos < consdata->nvars);
241 
242  if( consdata->boundtypes[pos] == SCIP_BOUNDTYPE_LOWER )
243  {
245  eventhdlr, (SCIP_EVENTDATA*)cons, filterpos) );
246  }
247  else
248  {
250  eventhdlr, (SCIP_EVENTDATA*)cons, filterpos) );
251  }
252 
253  return SCIP_OKAY;
254 }
255 
256 /** creates constraint handler data for bound disjunction constraint handler */
257 static
259  SCIP* scip, /**< SCIP data structure */
260  SCIP_CONSHDLRDATA** conshdlrdata, /**< pointer to store the constraint handler data */
261  SCIP_EVENTHDLR* eventhdlr /**< event handler */
262  )
263 {
264  assert(scip != NULL);
265  assert(conshdlrdata != NULL);
266  assert(eventhdlr != NULL);
267 
268  SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
269 
270  /* set event handler for catching events on watched variables */
271  (*conshdlrdata)->eventhdlr = eventhdlr;
272 
273  return SCIP_OKAY;
274 }
275 
276 /** frees constraint handler data for bound disjunction constraint handler */
277 static
279  SCIP* scip, /**< SCIP data structure */
280  SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to the constraint handler data */
281  )
282 {
283  assert(conshdlrdata != NULL);
284  assert(*conshdlrdata != NULL);
285 
286  SCIPfreeBlockMemory(scip, conshdlrdata);
287 
288  return SCIP_OKAY;
289 }
290 
291 /** creates a bound disjunction constraint data object */
292 static
294  SCIP* scip, /**< SCIP data structure */
295  SCIP_CONSDATA** consdata, /**< pointer to store the bound disjunction constraint data */
296  int nvars, /**< number of variables in the constraint */
297  SCIP_VAR** vars, /**< variables of the literals in the constraint */
298  SCIP_BOUNDTYPE* boundtypes, /**< types of bounds of the literals (lower or upper bounds) */
299  SCIP_Real* bounds /**< bounds of the literals */
300  )
301 {
302  assert(consdata != NULL);
303  assert(nvars == 0 || vars != NULL);
304  assert(nvars == 0 || boundtypes != NULL);
305  assert(nvars == 0 || bounds != NULL);
306 
307  SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
308 
309  if( nvars > 0 )
310  {
311  if( SCIPisConsCompressionEnabled(scip) )
312  {
313  int k;
314  int v;
315  int nviolations;
316  SCIP_Bool redundant;
317  SCIP_VAR** varsbuffer;
318  SCIP_BOUNDTYPE* boundtypesbuffer;
319  SCIP_Real* boundsbuffer;
320 
321  SCIP_CALL( SCIPallocBufferArray(scip, &varsbuffer, nvars) );
322  SCIP_CALL( SCIPallocBufferArray(scip, &boundtypesbuffer, nvars) );
323  SCIP_CALL( SCIPallocBufferArray(scip, &boundsbuffer, nvars) );
324 
325  nviolations = 0;
326  k = 0;
327  redundant = FALSE;
328  /* loop over variables, compare fixed ones against its bound disjunction */
329  for( v = 0; v < nvars && !redundant; ++v )
330  {
331  SCIP_VAR* var = vars[v];
332  SCIP_BOUNDTYPE boundtype = boundtypes[v];
333  SCIP_Real bound = bounds[v];
334 
335  /* is the variable fixed? */
336  if( SCIPisEQ(scip, SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var)) )
337  {
338  if( (boundtype == SCIP_BOUNDTYPE_LOWER && isFeasGE(scip, var, SCIPvarGetLbLocal(var), bound))
339  || (boundtype == SCIP_BOUNDTYPE_UPPER && isFeasLE(scip, var, SCIPvarGetUbLocal(var), bound)) )
340  {
341  /* safe this feasible assignment at the first position */
342  varsbuffer[0] = var;
343  boundtypesbuffer[0] = boundtype;
344  boundsbuffer[0] = bound;
345  k = 1;
346  redundant = TRUE;
347  }
348  else
349  ++nviolations;
350  }
351  else
352  {
353  /* append unfixed variable to buffer */
354  varsbuffer[k] = var;
355  boundtypesbuffer[k] = boundtype;
356  boundsbuffer[k] = bound;
357  ++k;
358  }
359  }
360 
361  /* duplicate a single, infeasible assignment, wlog the first one */
362  if( k == 0 )
363  {
364  assert(nviolations == nvars);
365  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, vars, 1) );
366  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->boundtypes, boundtypes, 1) );
367  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->bounds, bounds, 1) );
368  (*consdata)->varssize = 1;
369  (*consdata)->nvars = 1;
370  }
371  else
372  {
373  /* if the bound disjunction is already trivially satisfied, we keep only a single feasible assignment */
374  assert(!redundant || k == 1);
375 
376  /* we only copy the buffered variables required to represent the constraint */
377  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, varsbuffer, k) );
378  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->boundtypes, boundtypesbuffer, k) );
379  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->bounds, boundsbuffer, k) );
380  (*consdata)->varssize = k;
381  (*consdata)->nvars = k;
382  }
383 
384  /* free buffer storage */
385  SCIPfreeBufferArray(scip, &boundsbuffer);
386  SCIPfreeBufferArray(scip, &boundtypesbuffer);
387  SCIPfreeBufferArray(scip, &varsbuffer);
388  }
389  else
390  {
391  /* without problem compression, the entire vars array is copied */
392  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, vars, nvars) );
393  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->boundtypes, boundtypes, nvars) );
394  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->bounds, bounds, nvars) );
395  (*consdata)->varssize = nvars;
396  (*consdata)->nvars = nvars;
397  }
398  }
399  else
400  {
401  (*consdata)->vars = NULL;
402  (*consdata)->boundtypes = NULL;
403  (*consdata)->bounds = NULL;
404  (*consdata)->varssize = 0;
405  (*consdata)->nvars = 0;
406  }
407  (*consdata)->watchedvar1 = -1;
408  (*consdata)->watchedvar2 = -1;
409  (*consdata)->filterpos1 = -1;
410  (*consdata)->filterpos2 = -1;
411 
412  /* get transformed variables, if we are in the transformed problem */
413  if( SCIPisTransformed(scip) )
414  {
415  SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
416  }
417 
418  return SCIP_OKAY;
419 }
420 
421 /** frees a bound disjunction constraint data */
422 static
424  SCIP* scip, /**< SCIP data structure */
425  SCIP_CONSDATA** consdata /**< pointer to the bound disjunction constraint */
426  )
427 {
428  assert(consdata != NULL);
429  assert(*consdata != NULL);
430 
431  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->vars, (*consdata)->varssize);
432  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->boundtypes, (*consdata)->varssize);
433  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->bounds, (*consdata)->varssize);
434  SCIPfreeBlockMemory(scip, consdata);
435 
436  return SCIP_OKAY;
437 }
438 
439 /** prints bound disjunction constraint to file stream */
440 static
441 void consdataPrint(
442  SCIP* scip, /**< SCIP data structure */
443  SCIP_CONSDATA* consdata, /**< bound disjunction constraint data */
444  FILE* file, /**< output file (or NULL for standard output) */
445  SCIP_Bool endline /**< should an endline be set? */
446  )
447 {
448  int v;
449 
450  assert(consdata != NULL);
451 
452  /* print coefficients */
453  SCIPinfoMessage(scip, file, "bounddisjunction(");
454  for( v = 0; v < consdata->nvars; ++v )
455  {
456  assert(consdata->vars[v] != NULL);
457  if( v > 0 )
458  SCIPinfoMessage(scip, file, ", ");
459  SCIPinfoMessage(scip, file, "<%s> %s %.15g", SCIPvarGetName(consdata->vars[v]),
460  consdata->boundtypes[v] == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", consdata->bounds[v]);
461  }
462  SCIPinfoMessage(scip, file, ")");
463 
464  if( endline )
465  SCIPinfoMessage(scip, file, "\n");
466 }
467 
468 /** stores the given variable numbers as watched variables, and updates the event processing */
469 static
471  SCIP* scip, /**< SCIP data structure */
472  SCIP_CONS* cons, /**< bound disjunction constraint */
473  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
474  int watchedvar1, /**< new first watched variable */
475  int watchedvar2 /**< new second watched variable */
476  )
477 {
478  SCIP_CONSDATA* consdata;
479 
480  consdata = SCIPconsGetData(cons);
481  assert(consdata != NULL);
482  assert(watchedvar1 == -1 || watchedvar1 != watchedvar2);
483  assert(watchedvar1 != -1 || watchedvar2 == -1);
484  assert(watchedvar1 == -1 || (0 <= watchedvar1 && watchedvar1 < consdata->nvars));
485  assert(watchedvar2 == -1 || (0 <= watchedvar2 && watchedvar2 < consdata->nvars));
486 
487  /* don't watch variables for non active constraints */
488  if( !SCIPconsIsActive(cons) )
489  return SCIP_OKAY;
490 
491  /* if one watched variable is equal to the old other watched variable, just switch positions */
492  if( watchedvar1 == consdata->watchedvar2 || watchedvar2 == consdata->watchedvar1 )
493  {
494  int tmp;
495 
496  tmp = consdata->watchedvar1;
497  consdata->watchedvar1 = consdata->watchedvar2;
498  consdata->watchedvar2 = tmp;
499  tmp = consdata->filterpos1;
500  consdata->filterpos1 = consdata->filterpos2;
501  consdata->filterpos2 = tmp;
502  }
503  assert(watchedvar1 == -1 || watchedvar1 != consdata->watchedvar2);
504  assert(watchedvar2 == -1 || watchedvar2 != consdata->watchedvar1);
505 
506  /* drop events on old watched variables */
507  if( consdata->watchedvar1 != -1 && consdata->watchedvar1 != watchedvar1 )
508  {
509  assert(consdata->filterpos1 != -1);
510  SCIP_CALL( dropEvents(scip, cons, consdata, eventhdlr, consdata->watchedvar1, consdata->filterpos1) );
511  consdata->watchedvar1 = -1;
512  }
513  if( consdata->watchedvar2 != -1 && consdata->watchedvar2 != watchedvar2 )
514  {
515  assert(consdata->filterpos2 != -1);
516  SCIP_CALL( dropEvents(scip, cons, consdata, eventhdlr, consdata->watchedvar2, consdata->filterpos2) );
517  consdata->watchedvar2 = -1;
518  }
519 
520  /* catch events on new watched variables */
521  if( watchedvar1 != -1 && watchedvar1 != consdata->watchedvar1 )
522  {
523  SCIP_CALL( catchEvents(scip, cons, consdata, eventhdlr, watchedvar1, &consdata->filterpos1) );
524  }
525  if( watchedvar2 != -1 && watchedvar2 != consdata->watchedvar2 )
526  {
527  SCIP_CALL( catchEvents(scip, cons, consdata, eventhdlr, watchedvar2, &consdata->filterpos2) );
528  }
529 
530  /* set the new watched variables */
531  consdata->watchedvar1 = watchedvar1;
532  consdata->watchedvar2 = watchedvar2;
533 
534  return SCIP_OKAY;
535 }
536 
537 /** deletes coefficient at given position from bound disjunction constraint data */
538 static
540  SCIP* scip, /**< SCIP data structure */
541  SCIP_CONS* cons, /**< bound disjunction constraint */
542  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
543  int pos /**< position of coefficient to delete */
544  )
545 {
546  SCIP_CONSDATA* consdata;
547 
548  assert(eventhdlr != NULL);
549 
550  consdata = SCIPconsGetData(cons);
551  assert(consdata != NULL);
552  assert(0 <= pos && pos < consdata->nvars);
553  assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(consdata->vars[pos]));
554 
555  /* remove the rounding locks of variable */
556  SCIP_CALL( unlockRounding(scip, cons, consdata, pos) );
557 
558  if( SCIPconsIsTransformed(cons) )
559  {
560  /* if the position is watched, stop watching the position */
561  if( consdata->watchedvar1 == pos )
562  {
563  SCIP_CALL( switchWatchedvars(scip, cons, eventhdlr, consdata->watchedvar2, -1) );
564  }
565  if( consdata->watchedvar2 == pos )
566  {
567  SCIP_CALL( switchWatchedvars(scip, cons, eventhdlr, consdata->watchedvar1, -1) );
568  }
569  }
570  assert(pos != consdata->watchedvar1);
571  assert(pos != consdata->watchedvar2);
572 
573  /* move the last variable to the free slot */
574  consdata->vars[pos] = consdata->vars[consdata->nvars-1];
575  consdata->boundtypes[pos] = consdata->boundtypes[consdata->nvars-1];
576  consdata->bounds[pos] = consdata->bounds[consdata->nvars-1];
577  consdata->nvars--;
578 
579  /* if the last variable (that moved) was watched, update the watched position */
580  if( consdata->watchedvar1 == consdata->nvars )
581  consdata->watchedvar1 = pos;
582  if( consdata->watchedvar2 == consdata->nvars )
583  consdata->watchedvar2 = pos;
584 
585  SCIP_CALL( SCIPenableConsPropagation(scip, cons) );
586 
587  return SCIP_OKAY;
588 }
589 
590 /** adds literal to bound disjunction constraint data */
591 static
593  SCIP* scip, /**< SCIP data structure */
594  SCIP_CONS* cons, /**< bound disjunction constraint */
595  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
596  SCIP_VAR* var, /**< variable in literal */
597  SCIP_BOUNDTYPE boundtype, /**< boundtype of literal */
598  SCIP_Real bound /**< bound of literal */
599  )
600 {
601  SCIP_CONSDATA* consdata;
602 
603  assert(eventhdlr != NULL);
604 
605  consdata = SCIPconsGetData(cons);
606  assert(consdata != NULL);
607  assert(var != NULL);
608  assert(!SCIPisInfinity(scip, REALABS(bound)));
609  assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(var));
610 
611  /* ensure enough memory in consdata arrays */
612  if( consdata->varssize == consdata->nvars )
613  {
614  int newsize;
615 
616  newsize = SCIPcalcMemGrowSize(scip, consdata->nvars + 1);
617  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vars, consdata->varssize, newsize) );
618  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->boundtypes, consdata->varssize, newsize) );
619  SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->bounds, consdata->varssize, newsize) );
620  consdata->varssize = newsize;
621  }
622  assert(consdata->varssize > consdata->nvars);
623 
624  /* add the variable to the end of the array */
625  consdata->vars[consdata->nvars] = var;
626  consdata->boundtypes[consdata->nvars] = boundtype;
627  consdata->bounds[consdata->nvars] = bound;
628  consdata->nvars++;
629 
630  if( SCIPconsIsTransformed(cons) )
631  {
632  /* add rounding lock of variable */
633  SCIP_CALL( lockRounding(scip, cons, consdata, consdata->nvars-1) );
634 
635  /* if less than 2 variables are watched, add the new one to the watched variables */
636  if( consdata->watchedvar1 == -1 )
637  {
638  assert(consdata->watchedvar2 == -1);
639  SCIP_CALL( switchWatchedvars(scip, cons, eventhdlr, consdata->nvars-1, -1) );
640  }
641  else if( consdata->watchedvar2 == -1 )
642  {
643  SCIP_CALL( switchWatchedvars(scip, cons, eventhdlr, consdata->watchedvar1, consdata->nvars-1) );
644  }
645  }
646 
647  SCIP_CALL( SCIPenableConsPropagation(scip, cons) );
648 
649  return SCIP_OKAY;
650 }
651 
652 /** deletes all variables with global bounds violating the literal, checks for global bounds satisfying the literal */
653 static
655  SCIP* scip, /**< SCIP data structure */
656  SCIP_CONS* cons, /**< bound disjunction constraint */
657  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
658  SCIP_Bool* redundant /**< returns whether a variable fixed to one exists in the constraint */
659  )
660 {
661  SCIP_CONSDATA* consdata;
662  int v;
663  SCIP_Real bnd;
664 
665  assert(eventhdlr != NULL);
666  assert(redundant != NULL);
667 
668  consdata = SCIPconsGetData(cons);
669  assert(consdata != NULL);
670  assert(consdata->nvars == 0 || consdata->vars != NULL);
671 
672  *redundant = FALSE;
673  v = 0;
674  while( v < consdata->nvars )
675  {
676  SCIP_VAR* var;
677 
678  var = consdata->vars[v];
679 
680  if( consdata->boundtypes[v] == SCIP_BOUNDTYPE_LOWER )
681  {
682  bnd = SCIPcomputeVarLbGlobal(scip, var);
683  if( isFeasGE(scip, var, bnd, consdata->bounds[v]) )
684  {
685  *redundant = TRUE;
686  return SCIP_OKAY;
687  }
688  else
689  {
690  bnd = SCIPcomputeVarUbGlobal(scip, var);
691  if( isFeasLT(scip, var, bnd, consdata->bounds[v]) )
692  {
693  SCIP_CALL( delCoefPos(scip, cons, eventhdlr, v) );
694  }
695  else
696  ++v;
697  }
698  }
699  else
700  {
701  assert(consdata->boundtypes[v] == SCIP_BOUNDTYPE_UPPER);
702  bnd = SCIPcomputeVarUbGlobal(scip, var);
703  if( isFeasLE(scip, var, bnd, consdata->bounds[v]) )
704  {
705  *redundant = TRUE;
706  return SCIP_OKAY;
707  }
708  else
709  {
710  bnd = SCIPcomputeVarLbGlobal(scip, var);
711  if( isFeasGT(scip, var, bnd, consdata->bounds[v]) )
712  {
713  SCIP_CALL( delCoefPos(scip, cons, eventhdlr, v) );
714  }
715  else
716  ++v;
717  }
718  }
719  }
720 
721  SCIPdebugMsg(scip, "after global bounds: ");
722  SCIPdebug(consdataPrint(scip, consdata, NULL, TRUE));
723 
724  return SCIP_OKAY;
725 }
726 
727 /** returns whether literal at the given position is satisfied in the local bounds */
728 static
730  SCIP* scip, /**< SCIP data structure */
731  SCIP_CONSDATA* consdata, /**< bound disjunction constraint data */
732  int pos /**< position of the literal */
733  )
734 {
735  SCIP_Real bnd;
736 
737  assert(consdata != NULL);
738  assert(0 <= pos && pos < consdata->nvars);
739 
740  if( consdata->boundtypes[pos] == SCIP_BOUNDTYPE_LOWER )
741  {
742  bnd = SCIPcomputeVarLbLocal(scip, consdata->vars[pos]);
743  return isFeasGE(scip, consdata->vars[pos], bnd, consdata->bounds[pos]);
744  }
745  else
746  {
747  bnd = SCIPcomputeVarUbLocal(scip, consdata->vars[pos]);
748  return isFeasLE(scip, consdata->vars[pos], bnd, consdata->bounds[pos]);
749  }
750 }
751 
752 /** returns whether literal at the given position is violated in the local bounds */
753 static
755  SCIP* scip, /**< SCIP data structure */
756  SCIP_CONSDATA* consdata, /**< bound disjunction constraint data */
757  int pos /**< position of the literal */
758  )
759 {
760  SCIP_Real bnd;
761 
762  assert(consdata != NULL);
763  assert(0 <= pos && pos < consdata->nvars);
764 
765  if( consdata->boundtypes[pos] == SCIP_BOUNDTYPE_LOWER )
766  {
767  bnd = SCIPcomputeVarUbLocal(scip, consdata->vars[pos]);
768  return isFeasLT(scip, consdata->vars[pos], bnd, consdata->bounds[pos]);
769  }
770  else
771  {
772  bnd = SCIPcomputeVarLbLocal(scip, consdata->vars[pos]);
773  return isFeasGT(scip, consdata->vars[pos], bnd, consdata->bounds[pos]);
774  }
775 }
776 
777 /** replace variables by their representative active (or multi-aggregated) variables */
778 static
780  SCIP* scip, /**< SCIP data structure */
781  SCIP_CONS* cons, /**< bound disjunction constraint */
782  SCIP_EVENTHDLR* eventhdlr, /**< event handler */
783  SCIP_Bool* redundant /**< flag to indicate whether constraint has been bound redundant */
784  )
785 {
786  SCIP_CONSDATA* consdata;
787  SCIP_VAR* var;
788  SCIP_BOUNDTYPE boundtype;
790  int v;
791 
792  assert(scip != NULL);
793  assert(cons != NULL);
794  assert(eventhdlr != NULL);
795 
796  consdata = SCIPconsGetData(cons);
797  assert(consdata != NULL);
798 
799  v = 0;
800  while( v < consdata->nvars )
801  {
802 #ifndef NDEBUG
803  SCIP_VAR* oldvar;
804 #endif
805  var = consdata->vars[v];
806  assert(var != NULL);
807 
808 #ifndef NDEBUG
809  oldvar = var;
810 #endif
811 
813  {
814  /* check whether the literal is satisfied and the constraint is thus redundant */
815  if( isLiteralSatisfied(scip, consdata, v) )
816  {
817  *redundant = TRUE;
818  break;
819  }
820 
821  ++v;
822  continue;
823  }
824 
825  /* get active/fixed/multiaggr equivalent of v'th literal */
826  bound = consdata->bounds[v];
827  boundtype = consdata->boundtypes[v];
828  SCIP_CALL( SCIPvarGetProbvarBound(&var, &bound, &boundtype) );
829  assert(SCIPvarGetStatus(var) == SCIP_VARSTATUS_FIXED || oldvar != var);
830 
831  SCIPdebugMsg(scip, "in <%s>, replace <%s>[%g,%g] %c= %g by <%s>[%g,%g] %c= %g\n", SCIPconsGetName(cons),
832  SCIPvarGetName(consdata->vars[v]), SCIPvarGetLbGlobal(consdata->vars[v]), SCIPvarGetUbGlobal(consdata->vars[v]), (consdata->boundtypes[v] == SCIP_BOUNDTYPE_LOWER ? '>' : '<'), consdata->bounds[v],
833  SCIPvarGetName(var), SCIPvarGetLbGlobal(var), SCIPvarGetUbGlobal(var), (boundtype == SCIP_BOUNDTYPE_LOWER ? '>' : '<'), bound);
834 
835  /* if literal is satisfied, then constraint is redundant and we can stop */
836  if( (boundtype == SCIP_BOUNDTYPE_LOWER && isFeasLE(scip, var, bound, SCIPvarGetLbGlobal(var))) || /*lint !e666*/
837  (boundtype == SCIP_BOUNDTYPE_UPPER && isFeasGE(scip, var, bound, SCIPvarGetUbGlobal(var))) ) /*lint !e666*/
838  {
839  *redundant = TRUE;
840  break;
841  }
842 
843  /* if literal is not fixed, replace it */
845  {
846  /* add new literal */
847  SCIP_CALL( addCoef(scip, cons, eventhdlr, var, boundtype, bound) );
848  }
849 
850  /* remove old literal */
851  SCIP_CALL( delCoefPos(scip, cons, eventhdlr, v) );
852  }
853 
854  return SCIP_OKAY;
855 }
856 
857 /** try to upgrade the bounddisjunction constraint
858  *
859  * if only binary variables are left, we can upgrade a bounddisjunction to a logicor constraint(, if only two variables
860  * are left, this logicor constraint can be formulated as set-packing constraint as well)
861  *
862  * e.g.: bounddisjunction( x1 >= 1, x2 <= 0; x3 >= 1; x4 <= 0 ) => x1 + ~x2 + x3 + ~x4 >= 1
863  */
864 static
866  SCIP* scip, /**< SCIP data structure */
867  SCIP_CONS* cons, /**< bound disjunction constraint that detected the conflict */
868  int* ndelconss, /**< pointer to store the number of delete constraint */
869  int* naddconss /**< pointer to store the number of added constraint */
870  )
871 {
872  SCIP_CONSDATA* consdata;
873  SCIP_VAR** newvars;
874  SCIP_Bool allbinary;
875  int nvars;
876  int v;
877 
878  assert(scip != NULL);
879  assert(cons != NULL);
880  assert(ndelconss != NULL);
881  assert(naddconss != NULL);
882  assert(naddconss != NULL);
883  assert(!SCIPconsIsModifiable(cons));
884 
885  consdata = SCIPconsGetData(cons);
886  assert(consdata != NULL);
887 
888  nvars = consdata->nvars;
889  assert(nvars >= 2);
890  assert(consdata->vars != NULL);
891 
892  allbinary = TRUE;
893 
894  SCIP_CALL( SCIPallocBufferArray(scip, &newvars, nvars) );
895 
896  for( v = nvars - 1; v >= 0; --v )
897  {
898  if( !SCIPvarIsBinary(consdata->vars[v]) )
899  {
900  allbinary = FALSE;
901  break;
902  }
903  else
904  {
905  if( consdata->boundtypes[v] == SCIP_BOUNDTYPE_LOWER )
906  {
907  assert(SCIPisFeasGT(scip, consdata->bounds[v], 0.0));
908 
909  if( nvars == 2 )
910  {
911  SCIP_CALL( SCIPgetNegatedVar(scip, consdata->vars[v], &(newvars[v])) );
912  }
913  else
914  newvars[v] = consdata->vars[v];
915  }
916  else
917  {
918  assert(consdata->boundtypes[v] == SCIP_BOUNDTYPE_UPPER);
919  assert(SCIPisFeasLT(scip, consdata->bounds[v], 1.0));
920 
921  if( nvars > 2 )
922  {
923  SCIP_CALL( SCIPgetNegatedVar(scip, consdata->vars[v], &(newvars[v])) );
924  }
925  else
926  newvars[v] = consdata->vars[v];
927  }
928  }
929  }
930 
931  if( allbinary )
932  {
933  SCIP_CONS* newcons;
934 
935  if( nvars == 2 )
936  {
937  SCIP_CALL( SCIPcreateConsSetpack(scip, &newcons, SCIPconsGetName(cons), nvars, newvars,
942  }
943  else
944  {
945  SCIP_CALL( SCIPcreateConsLogicor(scip, &newcons, SCIPconsGetName(cons), nvars, newvars,
950  }
951 
952  SCIPdebugMsg(scip, "updated constraint <%s> to the following %s constraint\n", SCIPconsGetName(cons), (nvars == 2 ? "setppc" : "logicor"));
953  SCIPdebugPrintCons(scip, newcons, NULL);
954  SCIP_CALL( SCIPaddCons(scip, newcons) );
955  SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
956  ++(*naddconss);
957 
958  SCIP_CALL( SCIPdelCons(scip, cons) );
959  ++(*ndelconss);
960  }
961 
962  SCIPfreeBufferArray(scip, &newvars);
963 
964  return SCIP_OKAY;
965 }
966 
967 /** analyzes conflicting assignment on given constraint, and adds conflict constraint to problem */
968 static
970  SCIP* scip, /**< SCIP data structure */
971  SCIP_CONS* cons /**< bound disjunction constraint that detected the conflict */
972  )
973 {
974  SCIP_CONSDATA* consdata;
975  int v;
976 
977  /* conflict analysis can only be applied in solving stage and if it is turned on */
979  return SCIP_OKAY;
980 
981  consdata = SCIPconsGetData(cons);
982  assert(consdata != NULL);
983 
984  /* initialize conflict analysis, and add all bounds of infeasible constraint to conflict candidate queue */
986 
987  for( v = 0; v < consdata->nvars; ++v )
988  {
989  /* the opposite bound is in conflict with this literal */
990  SCIP_CALL( SCIPaddConflictBd(scip, consdata->vars[v], SCIPboundtypeOpposite(consdata->boundtypes[v]), NULL) );
991  }
992 
993  /* analyze the conflict */
994  SCIP_CALL( SCIPanalyzeConflictCons(scip, cons, NULL) );
995 
996  return SCIP_OKAY;
997 }
998 
999 /** disables or deletes the given constraint, depending on the current depth */
1000 static
1002  SCIP* scip, /**< SCIP data structure */
1003  SCIP_CONS* cons /**< bound disjunction constraint to be disabled */
1004  )
1005 {
1006  assert(SCIPconsGetValidDepth(cons) <= SCIPgetDepth(scip));
1007 
1008  if( SCIPgetDepth(scip) == SCIPconsGetValidDepth(cons) )
1009  {
1010  SCIP_CALL( SCIPdelCons(scip, cons) );
1011  }
1012  else
1013  {
1014  SCIP_CALL( SCIPdisableCons(scip, cons) );
1015  }
1016 
1017  return SCIP_OKAY;
1018 }
1019 
1020 /** checks constraint for violation only looking at the watched variables, applies bound changes if possible */
1021 static
1023  SCIP* scip, /**< SCIP data structure */
1024  SCIP_CONS* cons, /**< bound disjunction constraint to be processed */
1025  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
1026  SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
1027  SCIP_Bool* infeasible, /**< pointer to store TRUE, if the constraint is infeasible in current bounds */
1028  SCIP_Bool* reduceddom, /**< pointer to store TRUE, if a domain reduction was found */
1029  SCIP_Bool* mustcheck /**< pointer to store whether this constraint must be checked for feasibility */
1030  )
1031 {
1032  SCIP_CONSDATA* consdata;
1033  SCIP_VAR** vars;
1034  SCIP_BOUNDTYPE* boundtypes;
1035  SCIP_Real* bounds;
1036  SCIP_Longint nbranchings1;
1037  SCIP_Longint nbranchings2;
1038  int nvars;
1039  int watchedvar1;
1040  int watchedvar2;
1041 
1042  assert(cons != NULL);
1043  assert(SCIPconsGetHdlr(cons) != NULL);
1044  assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
1045  assert(cutoff != NULL);
1046  assert(reduceddom != NULL);
1047  assert(mustcheck != NULL);
1048 
1049  consdata = SCIPconsGetData(cons);
1050  assert(consdata != NULL);
1051  assert(consdata->watchedvar1 == -1 || consdata->watchedvar1 != consdata->watchedvar2);
1052 
1053  /* init bools */
1054  *cutoff = FALSE;
1055  *infeasible = FALSE;
1056  *reduceddom = FALSE;
1057  *mustcheck = FALSE;
1058 
1059  SCIPdebugMsg(scip, "processing watched variables of constraint <%s>\n", SCIPconsGetName(cons));
1060 
1061  nvars = consdata->nvars;
1062  vars = consdata->vars;
1063  boundtypes = consdata->boundtypes;
1064  bounds = consdata->bounds;
1065  assert(nvars == 0 || vars != NULL);
1066  assert(nvars == 0 || boundtypes != NULL);
1067  assert(nvars == 0 || bounds != NULL);
1068 
1069  /* check watched variables if they are satisfying the literal */
1070  if( consdata->watchedvar1 >= 0 && isLiteralSatisfied(scip, consdata, consdata->watchedvar1) )
1071  {
1072  /* the literal is satisfied, making the constraint redundant */
1073  SCIPdebugMsg(scip, " -> disabling constraint <%s> (watchedvar1 satisfied)\n", SCIPconsGetName(cons));
1074  SCIP_CALL( disableCons(scip, cons) );
1075  return SCIP_OKAY;
1076  }
1077  if( consdata->watchedvar2 >= 0 && isLiteralSatisfied(scip, consdata, consdata->watchedvar2) )
1078  {
1079  /* the literal is satisfied, making the constraint redundant */
1080  SCIPdebugMsg(scip, " -> disabling constraint <%s> (watchedvar2 satisfied)\n", SCIPconsGetName(cons));
1081  SCIP_CALL( disableCons(scip, cons) );
1082  return SCIP_OKAY;
1083  }
1084 
1085  /* check if watched variables are still undecided */
1086  watchedvar1 = -1;
1087  watchedvar2 = -1;
1088  nbranchings1 = SCIP_LONGINT_MAX;
1089  nbranchings2 = SCIP_LONGINT_MAX;
1090  if( consdata->watchedvar1 >= 0 && !isLiteralViolated(scip, consdata, consdata->watchedvar1) )
1091  {
1092  watchedvar1 = consdata->watchedvar1;
1093  nbranchings1 = -1; /* prefer keeping the watched variable */
1094  }
1095  if( consdata->watchedvar2 >= 0 && !isLiteralViolated(scip, consdata, consdata->watchedvar2) )
1096  {
1097  if( watchedvar1 == -1 )
1098  {
1099  watchedvar1 = consdata->watchedvar2;
1100  nbranchings1 = -1; /* prefer keeping the watched variable */
1101  }
1102  else
1103  {
1104  watchedvar2 = consdata->watchedvar2;
1105  nbranchings2 = -1; /* prefer keeping the watched variable */
1106  }
1107  }
1108  assert(watchedvar1 >= 0 || watchedvar2 == -1);
1109  assert(nbranchings1 <= nbranchings2);
1110  assert(watchedvar1 != -1 || nbranchings1 == SCIP_LONGINT_MAX);
1111  assert(watchedvar2 != -1 || nbranchings2 == SCIP_LONGINT_MAX);
1112 
1113  /* search for new watched variables */
1114  if( watchedvar2 == -1 )
1115  {
1116  int v;
1117 
1118  for( v = 0; v < nvars; ++v )
1119  {
1120  SCIP_Longint nbranchings;
1121 
1122  /* don't process the watched variables again */
1123  if( v == consdata->watchedvar1 || v == consdata->watchedvar2 )
1124  continue;
1125 
1126  /* check, if the literal is violated */
1127  if( isLiteralViolated(scip, consdata, v) )
1128  continue;
1129 
1130  /* check, if the literal is satisfied */
1131  if( isLiteralSatisfied(scip, consdata, v) )
1132  {
1133  assert(v != consdata->watchedvar1);
1134  assert(v != consdata->watchedvar2);
1135 
1136  /* the literal is satisfied, making the constraint redundant;
1137  * make sure, the feasible variable is watched and disable the constraint
1138  */
1139  SCIPdebugMsg(scip, " -> disabling constraint <%s> (variable <%s> fixed to 1.0)\n",
1140  SCIPconsGetName(cons), SCIPvarGetName(vars[v]));
1141  if( consdata->watchedvar1 != -1 )
1142  {
1143  SCIP_CALL( switchWatchedvars(scip, cons, eventhdlr, consdata->watchedvar1, v) );
1144  }
1145  else
1146  {
1147  SCIP_CALL( switchWatchedvars(scip, cons, eventhdlr, v, consdata->watchedvar2) );
1148  }
1149  SCIP_CALL( disableCons(scip, cons) );
1150  return SCIP_OKAY;
1151  }
1152 
1153  /* the literal is still undecided and can be used as watched variable */
1154  nbranchings = SCIPvarGetNBranchingsCurrentRun(vars[v],
1156  if( nbranchings < nbranchings2 )
1157  {
1158  if( nbranchings < nbranchings1 )
1159  {
1160  watchedvar2 = watchedvar1;
1161  nbranchings2 = nbranchings1;
1162  watchedvar1 = v;
1163  nbranchings1 = nbranchings;
1164  }
1165  else
1166  {
1167  watchedvar2 = v;
1168  nbranchings2 = nbranchings;
1169  }
1170  }
1171  }
1172  }
1173  assert(nbranchings1 <= nbranchings2);
1174  assert(watchedvar1 >= 0 || watchedvar2 == -1);
1175 
1176  if( watchedvar1 == -1 )
1177  {
1178  /* there is no undecided literal left -> the constraint is infeasible
1179  * - a modifiable constraint is infeasible
1180  * - an unmodifiable constraint is infeasible and the node can be cut off
1181  */
1182  assert(watchedvar2 == -1);
1183 
1184  SCIPdebugMsg(scip, " -> constraint <%s> is infeasible\n", SCIPconsGetName(cons));
1185  *infeasible = TRUE;
1186 
1187  SCIP_CALL( SCIPresetConsAge(scip, cons) );
1188  if( !SCIPconsIsModifiable(cons) )
1189  {
1190  /* use conflict analysis to get a conflict constraint out of the conflicting assignment */
1191  SCIP_CALL( analyzeConflict(scip, cons) );
1192 
1193  /* mark the node to be cut off */
1194  *cutoff = TRUE;
1195  }
1196  }
1197  else if( watchedvar2 == -1 )
1198  {
1199  /* there is only one undecided literal:
1200  * - a modifiable constraint must be checked manually
1201  * - we cannot change bounds of multi-aggregated variables and have to check manually
1202  * - an unmodifiable constraint is feasible and can be disabled after the remaining literal is satisfied
1203  */
1204  assert(0 <= watchedvar1 && watchedvar1 < nvars);
1205  assert(!isLiteralViolated(scip, consdata, watchedvar1));
1206  assert(!isLiteralSatisfied(scip, consdata, watchedvar1));
1207  if( SCIPconsIsModifiable(cons)
1208  || SCIPvarGetStatus(SCIPvarGetProbvar(vars[watchedvar1])) == SCIP_VARSTATUS_MULTAGGR )
1209  *mustcheck = TRUE;
1210  else
1211  {
1212  SCIP_Bool infbdchg;
1213 
1214 #ifndef NDEBUG
1215  int v;
1216 
1217  /* check whether all other literals are violated */
1218  for (v = 0; v < nvars; ++v)
1219  {
1220  if ( v != watchedvar1 )
1221  {
1222  assert( isLiteralViolated(scip, consdata, v) );
1223  }
1224  }
1225 #endif
1226 
1227  /* satisfy remaining literal and disable constraint; make sure, the fixed-to-one variable is watched */
1228  SCIPdebugMsg(scip, " -> single-literal constraint <%s> (change bound <%s> %s %g) at depth %d\n",
1229  SCIPconsGetName(cons), SCIPvarGetName(vars[watchedvar1]),
1230  boundtypes[watchedvar1] == SCIP_BOUNDTYPE_LOWER ? ">=" : "<=", bounds[watchedvar1], SCIPgetDepth(scip));
1231 
1232  if( boundtypes[watchedvar1] == SCIP_BOUNDTYPE_LOWER )
1233  {
1234  SCIP_CALL( SCIPinferVarLbCons(scip, vars[watchedvar1], bounds[watchedvar1], cons, watchedvar1, TRUE,
1235  &infbdchg, NULL) );
1236  }
1237  else
1238  {
1239  SCIP_CALL( SCIPinferVarUbCons(scip, vars[watchedvar1], bounds[watchedvar1], cons, watchedvar1, TRUE,
1240  &infbdchg, NULL) );
1241  }
1242  assert(!infbdchg);
1243  SCIP_CALL( SCIPresetConsAge(scip, cons) );
1244  if( watchedvar1 != consdata->watchedvar1 ) /* keep one of the watched variables */
1245  {
1246  SCIP_CALL( switchWatchedvars(scip, cons, eventhdlr, watchedvar1, consdata->watchedvar1) );
1247  }
1248  SCIP_CALL( disableCons(scip, cons) );
1249  *reduceddom = TRUE;
1250  }
1251  }
1252  else
1253  {
1254  SCIPdebugMsg(scip, " -> new watched variables <%s> and <%s> of constraint <%s> are still undecided\n",
1255  SCIPvarGetName(vars[watchedvar1]), SCIPvarGetName(vars[watchedvar2]), SCIPconsGetName(cons));
1256 
1257  /* switch to the new watched variables */
1258  SCIP_CALL( switchWatchedvars(scip, cons, eventhdlr, watchedvar1, watchedvar2) );
1259 
1260  /* there are at least two undecided variables -> the constraint must be checked manually */
1261  *mustcheck = TRUE;
1262 
1263  /* disable propagation of constraint until the corresponding bound of a watched variable changed */
1264  SCIP_CALL( SCIPdisableConsPropagation(scip, cons) );
1265 
1266  /* increase aging counter */
1267  SCIP_CALL( SCIPaddConsAge(scip, cons, AGEINCREASE(consdata->nvars)) );
1268  }
1269 
1270  return SCIP_OKAY;
1271 }
1272 
1273 /** checks constraint for violation, returns TRUE iff constraint is feasible */
1274 static
1276  SCIP* scip, /**< SCIP data structure */
1277  SCIP_CONS* cons, /**< bound disjunction constraint to be checked */
1278  SCIP_SOL* sol, /**< primal CIP solution */
1279  SCIP_Bool* violated /**< pointer to store whether the given solution violates the constraint */
1280  )
1281 {
1282  SCIP_CONSDATA* consdata;
1283  SCIP_VAR** vars;
1284  SCIP_BOUNDTYPE* boundtypes;
1285  SCIP_Real* bounds;
1286  SCIP_Real solval;
1287  int nvars;
1288  int v;
1289 
1290  assert(violated != NULL);
1291 
1292  *violated = FALSE;
1293  consdata = SCIPconsGetData(cons);
1294  assert(consdata != NULL);
1295 
1296  nvars = consdata->nvars;
1297  vars = consdata->vars;
1298  boundtypes = consdata->boundtypes;
1299  bounds = consdata->bounds;
1300  assert(nvars == 0 || vars != NULL);
1301  assert(nvars == 0 || boundtypes != NULL);
1302  assert(nvars == 0 || bounds != NULL);
1303 
1304  /* check the given solution */
1305  *violated = TRUE;
1306  for( v = 0; v < nvars; ++v )
1307  {
1308  solval = SCIPgetSolVal(scip, sol, vars[v]);
1309  if( (boundtypes[v] == SCIP_BOUNDTYPE_LOWER && isFeasGE(scip, vars[v], solval, bounds[v]))
1310  || (boundtypes[v] == SCIP_BOUNDTYPE_UPPER && isFeasLE(scip, vars[v], solval, bounds[v])) )
1311  {
1312  *violated = FALSE;
1313  break;
1314  }
1315  }
1316  return SCIP_OKAY;
1317 }
1318 
1319 /* registers variables of a constraint as branching candidates
1320  * indicates whether an n-ary branch is necessary to enforce this constraint,
1321  * because all active literals are w.r.t. continuous variables which bound (in the literal) is at the variable's bound
1322  */
1323 static
1325  SCIP* scip, /**< SCIP data structure */
1326  SCIP_CONS* cons, /**< bound disjunction constraint which variables should be registered for branching */
1327  SCIP_SOL* sol, /**< solution (NULL for LP solution) */
1328  SCIP_Bool* neednarybranch /**< pointer to store TRUE, if n-ary branching is necessary to enforce this constraint */
1329  )
1330 {
1331  SCIP_CONSDATA* consdata;
1332  SCIP_VAR** vars;
1333  SCIP_BOUNDTYPE* boundtypes;
1334  SCIP_Real* bounds;
1335  SCIP_Real violation;
1336  SCIP_Real varlb;
1337  SCIP_Real varub;
1338  int nvars;
1339  int v;
1340 
1341  assert(cons != NULL);
1342  assert(SCIPconsGetHdlr(cons) != NULL);
1343  assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
1344  assert(neednarybranch != NULL);
1345 
1346  consdata = SCIPconsGetData(cons);
1347  assert(consdata != NULL);
1348  nvars = consdata->nvars;
1349  vars = consdata->vars;
1350  boundtypes = consdata->boundtypes;
1351  bounds = consdata->bounds;
1352  assert(nvars == 0 || vars != NULL);
1353  assert(nvars == 0 || boundtypes != NULL);
1354  assert(nvars == 0 || bounds != NULL);
1355 
1356  *neednarybranch = TRUE;
1357 
1358  for( v = 0; v < nvars; ++v )
1359  {
1360  SCIP_VAR* var;
1361 
1362  var = vars[v];
1363  assert(var != NULL);
1364 
1365  /* constraint should be violated, so all bounds in the constraint have to be violated */
1366  assert( !(boundtypes[v] == SCIP_BOUNDTYPE_LOWER && SCIPisFeasGE(scip, SCIPgetSolVal(scip, sol, var), bounds[v])) &&
1367  !(boundtypes[v] == SCIP_BOUNDTYPE_UPPER && SCIPisFeasLE(scip, SCIPgetSolVal(scip, sol, var), bounds[v])) );
1368 
1369  varlb = SCIPcomputeVarLbLocal(scip, var);
1370  varub = SCIPcomputeVarUbLocal(scip, var);
1371 
1372  /* if literal is x >= varlb, but upper bound on x is < varlb, then this literal can never be satisfied,
1373  * thus there is no use for branching
1374  */
1375  if( boundtypes[v] == SCIP_BOUNDTYPE_LOWER && isFeasLT(scip, var, varub, bounds[v]) )
1376  continue;
1377 
1378  /* if literal is x <= varub, but lower bound on x is > varub, then this literal can never be satisfied,
1379  * thus there is no use for branching
1380  */
1381  if( boundtypes[v] == SCIP_BOUNDTYPE_UPPER && isFeasGT(scip, var, varlb, bounds[v]) )
1382  continue;
1383 
1384  /* if literal is always satisfied, then no need to branch on it may happen if propagation is disabled for some
1385  * reason and due to numerics current solution does not satisfy literal, but variable bounds do
1386  */
1387  if( isLiteralSatisfied(scip, consdata, v) )
1388  continue;
1389 
1390  violation = SCIPgetSolVal(scip, sol, var) - bounds[v];
1391 
1392  /* if variable is continuous, then we cannot branch on one of the variable bounds */
1393  if( SCIPvarGetType(vars[v]) != SCIP_VARTYPE_CONTINUOUS ||
1394  ((SCIPisInfinity(scip, -varlb) || !SCIPisFeasEQ(scip, bounds[v], varlb)) &&
1395  (SCIPisInfinity(scip, varub) || !SCIPisFeasEQ(scip, bounds[v], varub))) )
1396  {
1397  SCIP_CALL( SCIPaddExternBranchCand(scip, var, REALABS(violation), bounds[v]) );
1398  *neednarybranch = FALSE;
1399  }
1400  }
1401 
1402  return SCIP_OKAY;
1403 }
1404 
1405 /** enforces the pseudo or LP solution on the given constraint */
1406 static
1408  SCIP* scip, /**< SCIP data structure */
1409  SCIP_CONS* cons, /**< bound disjunction constraint to be separated */
1410  SCIP_SOL* sol, /**< solution which should be enforced (NULL for LP solution) */
1411  SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
1412  SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
1413  SCIP_Bool* infeasible, /**< pointer to store TRUE, if the constraint was infeasible */
1414  SCIP_Bool* reduceddom, /**< pointer to store TRUE, if a domain reduction was found */
1415  SCIP_Bool* registeredbrcand /**< pointer to store TRUE, if branching variable candidates were registered or was already true */
1416  )
1417 {
1418  SCIP_Bool mustcheck;
1419  SCIP_Bool neednarybranch;
1420 
1421  assert(cons != NULL);
1422  assert(SCIPconsGetHdlr(cons) != NULL);
1423  assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
1424  assert(cutoff != NULL);
1425  assert(infeasible != NULL);
1426  assert(reduceddom != NULL);
1427  assert(registeredbrcand != NULL);
1428 
1429  SCIPdebugMsg(scip, "enforce bound disjunction constraint <%s>\n", SCIPconsGetName(cons));
1430 
1431  /* update and check the watched variables, if they were changed since last processing */
1432  if( SCIPconsIsPropagationEnabled(cons) )
1433  {
1434  SCIP_CALL( processWatchedVars(scip, cons, eventhdlr, cutoff, infeasible, reduceddom, &mustcheck) );
1435  }
1436  else
1437  mustcheck = TRUE;
1438 
1439  if( mustcheck )
1440  {
1441  SCIP_Bool violated;
1442 
1443  SCIP_CALL( checkCons(scip, cons, sol, &violated) );
1444  if( violated )
1445  {
1446  /* constraint was infeasible -> reset age */
1447  SCIP_CALL( SCIPresetConsAge(scip, cons) );
1448  *infeasible = TRUE;
1449 
1450  /* register branching candidates */
1451  SCIP_CALL( registerBranchingCandidates(scip, cons, sol, &neednarybranch) );
1452 
1453  if( !neednarybranch )
1454  *registeredbrcand = TRUE;
1455  }
1456  }
1457 
1458  return SCIP_OKAY;
1459 }
1460 
1461 /** enforces a constraint by creating an n-ary branch consisting of a set of child nodes, each enforcing one literal
1462  */
1463 static
1465  SCIP* scip, /**< SCIP data structure */
1466  SCIP_CONS* cons, /**< bound disjunction constraint to branch on */
1467  SCIP_SOL* sol /**< solution which should be enforced (NULL for LP solution) */
1468  )
1469 {
1470  SCIP_CONSDATA* consdata;
1471  SCIP_VAR** vars;
1472  SCIP_BOUNDTYPE* boundtypes;
1473  SCIP_Real* bounds;
1474  SCIP_Real varlb;
1475  SCIP_Real varub;
1476  int nvars;
1477  int v;
1478 
1479  SCIP_Real priority;
1480  SCIP_Real estimate;
1481  SCIP_NODE* node;
1482 
1483  assert(cons != NULL);
1484  assert(SCIPconsGetHdlr(cons) != NULL);
1485  assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
1486 
1487  consdata = SCIPconsGetData(cons);
1488  assert(consdata != NULL);
1489  nvars = consdata->nvars;
1490  vars = consdata->vars;
1491  boundtypes = consdata->boundtypes;
1492  bounds = consdata->bounds;
1493  assert(nvars == 0 || vars != NULL);
1494  assert(nvars == 0 || boundtypes != NULL);
1495  assert(nvars == 0 || bounds != NULL);
1496 
1497  for( v = 0; v < nvars; ++v )
1498  {
1499  SCIP_VAR* var;
1500 
1501  var = vars[v];
1502  assert(var != NULL);
1503 
1504  /* constraint should be violated, so all bounds in the constraint have to be violated */
1505  assert( !(boundtypes[v] == SCIP_BOUNDTYPE_LOWER && isFeasGE(scip, var, SCIPgetSolVal(scip, sol, var), bounds[v])) && /*lint !e666*/
1506  !(boundtypes[v] == SCIP_BOUNDTYPE_UPPER && isFeasLE(scip, var, SCIPgetSolVal(scip, sol, var), bounds[v])) ); /*lint !e666*/
1507 
1508  varlb = SCIPcomputeVarLbLocal(scip, var);
1509  varub = SCIPcomputeVarUbLocal(scip, var);
1510 
1511  /* if literal is x >= varlb, but upper bound on x is < varlb, then this literal can never be satisfied,
1512  * thus there is no use in creating an extra child for it
1513  */
1514  if( boundtypes[v] == SCIP_BOUNDTYPE_LOWER && isFeasLT(scip, var, varub, bounds[v]) )
1515  continue;
1516  /* if literal is x <= varub, but lower bound on x is > varub, then this literal can never be satisfied,
1517  * thus there is no use in creating an extra child for it
1518  */
1519  if( boundtypes[v] == SCIP_BOUNDTYPE_UPPER && isFeasGT(scip, var, varlb, bounds[v]) )
1520  continue;
1521  /* if literal is always satisfied, then no need to branch on it */
1522  if( isLiteralSatisfied(scip, consdata, v) )
1523  continue;
1524 
1525  /* create a child that enforces the current literal */
1526  priority = SCIPcalcNodeselPriority(scip, var, boundtypes[v] == SCIP_BOUNDTYPE_LOWER ?
1528  estimate = SCIPcalcChildEstimate (scip, var, bounds[v]);
1529 
1530  SCIPdebugMsg(scip, " -> creating child to enforce: <%s> %c= %g (priority: %g, estimate: %g)\n",
1531  SCIPvarGetName(vars[v]), boundtypes[v] == SCIP_BOUNDTYPE_LOWER ? '>' : '<', bounds[v], priority, estimate);
1532 
1533  SCIP_CALL( SCIPcreateChild(scip, &node, priority, estimate) );
1534 
1535  /* enforce current literal */
1537  {
1538  SCIP_CONS* brcons;
1539  SCIP_Real one;
1540 
1541  one = 1.0;
1542 
1543  if( boundtypes[v] == SCIP_BOUNDTYPE_LOWER )
1544  {
1545  SCIP_CALL( SCIPcreateConsLinear(scip, &brcons, "bounddisjbranch", 1, &var, &one, bounds[v], SCIPinfinity(scip),
1549  SCIPconsIsStickingAtNode(cons)) );
1550  }
1551  else
1552  {
1553  SCIP_CALL( SCIPcreateConsLinear(scip, &brcons, "bounddisjbranch", 1, &var, &one, -SCIPinfinity(scip), bounds[v],
1557  SCIPconsIsStickingAtNode(cons)) );
1558  }
1559  SCIP_CALL( SCIPaddConsNode(scip, node, brcons, NULL) );
1560  SCIP_CALL( SCIPreleaseCons(scip, &brcons) );
1561  }
1562  else
1563  {
1564  assert(SCIPvarIsActive(var));
1565  if( boundtypes[v] == SCIP_BOUNDTYPE_LOWER )
1566  {
1567  SCIP_CALL( SCIPchgVarLbNode(scip, node, var, bounds[v]) );
1568  }
1569  else
1570  {
1571  SCIP_CALL( SCIPchgVarUbNode(scip, node, var, bounds[v]) );
1572  }
1573  }
1574 
1575  /* delete bound disjunction constraint from child node */
1576  SCIP_CALL( SCIPdelConsNode(scip, node, cons) );
1577  }
1578 
1579  return SCIP_OKAY;
1580 }
1581 
1582 /** helper function to enforce constraints */
1583 static
1585  SCIP* scip, /**< SCIP data structure */
1586  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1587  SCIP_CONS** conss, /**< constraints to process */
1588  int nconss, /**< number of constraints */
1589  SCIP_SOL* sol, /**< solution to enforce (NULL for the LP solution) */
1590  SCIP_RESULT* result /**< pointer to store the result of the enforcing call */
1591  )
1592 {
1593  SCIP_CONSHDLRDATA* conshdlrdata;
1594  SCIP_Bool cutoff;
1595  SCIP_Bool infeasible;
1596  SCIP_Bool reduceddom;
1597  SCIP_Bool registeredbrcand;
1598  SCIP_Bool infeasiblecons;
1599  int c;
1600  int nnarybranchconsvars;
1601  SCIP_CONS* narybranchcons; /* constraint that is a candidate for an n-ary branch */
1602 
1603  assert(conshdlr != NULL);
1604  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
1605  assert(nconss == 0 || conss != NULL);
1606  assert(result != NULL);
1607 
1608  SCIPdebugMsg(scip, "Enforcing %d bound disjunction constraints for %s solution\n", nconss, sol == NULL ? "LP" : "relaxation");
1609 
1610  *result = SCIP_FEASIBLE;
1611 
1612  conshdlrdata = SCIPconshdlrGetData(conshdlr);
1613  assert(conshdlrdata != NULL);
1614 
1615  cutoff = FALSE;
1616  infeasible = FALSE;
1617  reduceddom = FALSE;
1618  registeredbrcand = FALSE;
1619  narybranchcons = NULL;
1620  nnarybranchconsvars = INT_MAX;
1621 
1622  /* check all bound disjunction constraints for feasibility */
1623  for( c = 0; c < nconss && !cutoff && !reduceddom; ++c )
1624  {
1625  infeasiblecons = FALSE;
1626  SCIP_CALL( enforceCurrentSol(scip, conss[c], sol, conshdlrdata->eventhdlr, &cutoff, &infeasiblecons, &reduceddom,
1627  &registeredbrcand) );
1628  infeasible |= infeasiblecons;
1629  if( infeasiblecons && !registeredbrcand )
1630  {
1631  /* if cons. c has less literals than the previous candidate for an n-ary branch, then keep cons. c as candidate for n-ary branch */
1632  if( narybranchcons == NULL || SCIPconsGetData(conss[c])->nvars < nnarybranchconsvars )
1633  {
1634  narybranchcons = conss[c];
1635  nnarybranchconsvars = SCIPconsGetData(narybranchcons)->nvars;
1636  assert(nnarybranchconsvars > 0);
1637  }
1638  }
1639  }
1640 
1641  if( cutoff )
1642  *result = SCIP_CUTOFF;
1643  else if( reduceddom )
1644  *result = SCIP_REDUCEDDOM;
1645  else if( infeasible )
1646  {
1647  if( registeredbrcand )
1648  {
1649  *result = SCIP_INFEASIBLE;
1650  }
1651  else
1652  {
1653  SCIP_CALL( createNAryBranch(scip, narybranchcons, sol) );
1654  *result = SCIP_BRANCHED;
1655  }
1656  }
1657 
1658  return SCIP_OKAY;
1659 }
1660 
1661 /**@} */
1662 
1663 /**@name Upgrading methods for special quadratic constraint
1664  *
1665  */
1666 
1667 /** upgrades quadratic complementarity constraints into a bounddisjunction constraint
1668  * If constraint is of form (x - a) * (y - b) = 0 with x >= a and y >= b for some a and b,
1669  * then upgrade to bounddisjunction constraint "x <= a or y <= b".
1670  * If constraint is of form (x - a) * (y - b) >= 0,
1671  * then upgrade to bounddisjunction constraints "x >= a or y <= b" and "x <= a or y >= b".
1672  */
1673 static
1674 SCIP_DECL_QUADCONSUPGD(upgradeConsQuadratic)
1675 { /*lint --e{715}*/
1676  char name[SCIP_MAXSTRLEN];
1677  SCIP_BOUNDTYPE boundtypes[2];
1678  SCIP_Real bounds[2];
1679  SCIP_VAR* xy[2];
1680  SCIP_QUADVARTERM* quadvarterms;
1681  SCIP_Real coefxy;
1682  SCIP_Real coefx;
1683  SCIP_Real coefy;
1684  SCIP_Real lhs;
1685  SCIP_Real rhs;
1686  SCIP_Real a;
1687  SCIP_Real b;
1688  SCIP_VAR* x;
1689  SCIP_VAR* y;
1690 
1691  assert(scip != NULL);
1692  assert(cons != NULL);
1693  assert(nupgdconss != NULL);
1694  assert(upgdconss != NULL);
1695 
1696  *nupgdconss = 0;
1697 
1698  SCIPdebugMsg(scip, "upgradeConsQuadratic called for constraint <%s>\n", SCIPconsGetName(cons));
1699  SCIPdebugPrintCons(scip, cons, NULL);
1700 
1701  if( SCIPgetNLinearVarsQuadratic(scip, cons) != 0 )
1702  return SCIP_OKAY;
1703  if( SCIPgetNQuadVarTermsQuadratic(scip, cons) != 2 )
1704  return SCIP_OKAY;
1705  if( SCIPgetNBilinTermsQuadratic(scip, cons) != 1 )
1706  return SCIP_OKAY;
1707  /* do not upgrade x*y <=/== rhs with x (or y) binary
1708  * the reformulation for such terms in cons_quadratic should handle this better
1709  */
1710  if( nbinquad > 0 )
1711  return SCIP_OKAY;
1712 
1713  lhs = SCIPgetLhsQuadratic(scip, cons);
1714  rhs = SCIPgetRhsQuadratic(scip, cons);
1715 
1716  /* we don't want a free constraint */
1717  if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
1718  return SCIP_OKAY;
1719 
1720  /* we currently don't want a ranged constraint (could upgrade at most one side) */
1721  if( !SCIPisInfinity(scip, -lhs) && !SCIPisInfinity(scip, rhs) && !SCIPisEQ(scip, lhs, rhs) )
1722  return SCIP_OKAY;
1723 
1724  quadvarterms = SCIPgetQuadVarTermsQuadratic(scip, cons);
1725 
1726  /* we don't want square terms */
1727  if( !SCIPisZero(scip, quadvarterms[0].sqrcoef) || !SCIPisZero(scip, quadvarterms[1].sqrcoef) )
1728  return SCIP_OKAY;
1729 
1730  x = quadvarterms[0].var;
1731  y = quadvarterms[1].var;
1732  assert(x != y);
1733 
1734  coefx = quadvarterms[0].lincoef;
1735  coefy = quadvarterms[1].lincoef;
1736 
1737  coefxy = SCIPgetBilinTermsQuadratic(scip, cons)[0].coef;
1738  assert(SCIPgetBilinTermsQuadratic(scip, cons)[0].var1 == x || SCIPgetBilinTermsQuadratic(scip, cons)[0].var1 == y);
1739  assert(SCIPgetBilinTermsQuadratic(scip, cons)[0].var2 == x || SCIPgetBilinTermsQuadratic(scip, cons)[0].var2 == y);
1740  assert(!SCIPisZero(scip, coefxy));
1741 
1742  /* divide by coefxy */
1743  coefx /= coefxy;
1744  coefy /= coefxy;
1745  if( coefxy > 0.0 )
1746  {
1747  if( !SCIPisInfinity(scip, -lhs) )
1748  lhs /= coefxy;
1749  if( !SCIPisInfinity(scip, rhs) )
1750  rhs /= coefxy;
1751  }
1752  else
1753  {
1754  SCIP_Real tmp;
1755 
1756  if( !SCIPisInfinity(scip, rhs) )
1757  tmp = rhs / coefxy;
1758  else
1759  tmp = -SCIPinfinity(scip);
1760  if( !SCIPisInfinity(scip, -lhs) )
1761  rhs = lhs / coefxy;
1762  else
1763  rhs = SCIPinfinity(scip);
1764  lhs = tmp;
1765  }
1766 
1767  /* now have form lhs <= x*y + coefx x + coefy y <= rhs
1768  * <-> lhs + coefx * coefy <= (x + coefy) * (y + coefx) <= rhs + coefx * coefy
1769  */
1770 
1771  /* handle case (x + coefy) * (y + coefx) == rhs + coefx * coefy */
1772  if( SCIPisEQ(scip, lhs, rhs) )
1773  {
1774  /* check whether rhs + coefx * coefy == 0 */
1775  if( !SCIPisZero(scip, rhs + coefx * coefy) )
1776  return SCIP_OKAY;
1777 
1778  a = -coefy;
1779  b = -coefx;
1780 
1781  /* now have complementarity form x = a or y = b */
1782 
1783  /* we can write this as up to four bounddisjunction constraint:
1784  * (x >= a or y >= b) and (x <= a or y >= b) and (x >= a or y <= b) and (x <= a or y <= b)
1785  *
1786  * count whether we need to create 1, 2, or 4 constraints
1787  */
1788  if( !SCIPisGE(scip, SCIPvarGetLbGlobal(x), a) && !SCIPisLE(scip, SCIPvarGetUbGlobal(x), a) )
1789  *nupgdconss = 2;
1790  else
1791  *nupgdconss = 1;
1792 
1793  if( !SCIPisGE(scip, SCIPvarGetLbGlobal(y), b) && !SCIPisLE(scip, SCIPvarGetUbGlobal(y), b) )
1794  *nupgdconss *= 2;
1795 
1796  if( upgdconsssize < *nupgdconss )
1797  {
1798  /* signal that we need more memory */
1799  *nupgdconss = -*nupgdconss;
1800  return SCIP_OKAY;
1801  }
1802 
1803  xy[0] = x;
1804  xy[1] = y;
1805  bounds[0] = a;
1806  bounds[1] = b;
1807  if( *nupgdconss == 1 )
1808  {
1809  boundtypes[0] = SCIPisGE(scip, SCIPvarGetLbGlobal(x), a) ? SCIP_BOUNDTYPE_UPPER : SCIP_BOUNDTYPE_LOWER;
1810  boundtypes[1] = SCIPisGE(scip, SCIPvarGetLbGlobal(y), b) ? SCIP_BOUNDTYPE_UPPER : SCIP_BOUNDTYPE_LOWER;
1811  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &upgdconss[0], SCIPconsGetName(cons),
1812  2, xy, boundtypes, bounds,
1816  SCIPconsIsStickingAtNode(cons)) );
1817 
1818  SCIPdebugMsg(scip, "created bounddisjunction constraint:\n");
1819  SCIPdebugPrintCons(scip, upgdconss[0], NULL);
1820 
1821  return SCIP_OKAY;
1822  }
1823  else if( SCIPisGE(scip, SCIPvarGetLbGlobal(x), a) || SCIPisLE(scip, SCIPvarGetUbGlobal(x), a) )
1824  {
1825  assert(!SCIPisGE(scip, SCIPvarGetLbGlobal(y), b) && !SCIPisLE(scip, SCIPvarGetUbGlobal(y), b));
1826  assert(*nupgdconss == 2);
1827 
1828  boundtypes[0] = SCIPisGE(scip, SCIPvarGetLbGlobal(x), a) ? SCIP_BOUNDTYPE_UPPER : SCIP_BOUNDTYPE_LOWER;
1829 
1830  /* create constraint with y >= b */
1831  boundtypes[1] = SCIP_BOUNDTYPE_LOWER;
1832  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_lower", SCIPconsGetName(cons));
1833  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &upgdconss[0], name,
1834  2, xy, boundtypes, bounds,
1838  SCIPconsIsStickingAtNode(cons)) );
1839 
1840  /* create constraint with y <= b */
1841  boundtypes[1] = SCIP_BOUNDTYPE_UPPER;
1842  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_upper", SCIPconsGetName(cons));
1843  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &upgdconss[1], name,
1844  2, xy, boundtypes, bounds,
1848  SCIPconsIsStickingAtNode(cons)) );
1849 
1850  SCIPdebugMsg(scip, "created bounddisjunction constraints:\n");
1851  SCIPdebugPrintCons(scip, upgdconss[0], NULL);
1852  SCIPdebugPrintCons(scip, upgdconss[1], NULL);
1853  }
1854  else if( SCIPisGE(scip, SCIPvarGetLbGlobal(y), b) || SCIPisLE(scip, SCIPvarGetUbGlobal(y), b) )
1855  {
1856  assert(!SCIPisEQ(scip, SCIPvarGetLbGlobal(x), a) && !SCIPisEQ(scip, SCIPvarGetUbGlobal(x), a));
1857  assert(*nupgdconss == 2);
1858 
1859  boundtypes[1] = SCIPisGE(scip, SCIPvarGetLbGlobal(y), b) ? SCIP_BOUNDTYPE_UPPER : SCIP_BOUNDTYPE_LOWER;
1860 
1861  /* create constraint with x >= a */
1862  boundtypes[0] = SCIP_BOUNDTYPE_LOWER;
1863  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_lower", SCIPconsGetName(cons));
1864  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &upgdconss[0], name,
1865  2, xy, boundtypes, bounds,
1869  SCIPconsIsStickingAtNode(cons)) );
1870 
1871  /* create constraint with x <= a */
1872  boundtypes[0] = SCIP_BOUNDTYPE_UPPER;
1873  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_lower", SCIPconsGetName(cons));
1874  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &upgdconss[1], name,
1875  2, xy, boundtypes, bounds,
1879  SCIPconsIsStickingAtNode(cons)) );
1880 
1881  SCIPdebugMsg(scip, "created bounddisjunction constraints:\n");
1882  SCIPdebugPrintCons(scip, upgdconss[0], NULL);
1883  SCIPdebugPrintCons(scip, upgdconss[1], NULL);
1884  }
1885  else
1886  {
1887  assert(!SCIPisGE(scip, SCIPvarGetLbGlobal(x), a) && !SCIPisLE(scip, SCIPvarGetUbGlobal(x), a));
1888  assert(!SCIPisGE(scip, SCIPvarGetLbGlobal(y), b) && !SCIPisLE(scip, SCIPvarGetUbGlobal(y), b));
1889  assert(*nupgdconss == 4);
1890 
1891  /* create constraint x >= a or y >= a */
1892  boundtypes[0] = SCIP_BOUNDTYPE_LOWER;
1893  boundtypes[1] = SCIP_BOUNDTYPE_LOWER;
1894  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_lower_lower", SCIPconsGetName(cons));
1895  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &upgdconss[0], name,
1896  2, xy, boundtypes, bounds,
1900  SCIPconsIsStickingAtNode(cons)) );
1901 
1902  /* create constraint x >= a or y <= a */
1903  boundtypes[0] = SCIP_BOUNDTYPE_LOWER;
1904  boundtypes[1] = SCIP_BOUNDTYPE_UPPER;
1905  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_lower_upper", SCIPconsGetName(cons));
1906  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &upgdconss[1], name,
1907  2, xy, boundtypes, bounds,
1911  SCIPconsIsStickingAtNode(cons)) );
1912 
1913  /* create constraint x <= a or y >= a */
1914  boundtypes[0] = SCIP_BOUNDTYPE_UPPER;
1915  boundtypes[1] = SCIP_BOUNDTYPE_LOWER;
1916  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_upper_lower", SCIPconsGetName(cons));
1917  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &upgdconss[2], name,
1918  2, xy, boundtypes, bounds,
1922  SCIPconsIsStickingAtNode(cons)) );
1923 
1924  /* create constraint x <= a or y <= a */
1925  boundtypes[0] = SCIP_BOUNDTYPE_UPPER;
1926  boundtypes[1] = SCIP_BOUNDTYPE_UPPER;
1927  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_upper_upper", SCIPconsGetName(cons));
1928  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &upgdconss[3], name,
1929  2, xy, boundtypes, bounds,
1933  SCIPconsIsStickingAtNode(cons)) );
1934 
1935  SCIPdebugMsg(scip, "created bounddisjunction constraints:\n");
1936  SCIPdebugPrintCons(scip, upgdconss[0], NULL);
1937  SCIPdebugPrintCons(scip, upgdconss[1], NULL);
1938  SCIPdebugPrintCons(scip, upgdconss[2], NULL);
1939  SCIPdebugPrintCons(scip, upgdconss[3], NULL);
1940  }
1941 
1942  return SCIP_OKAY;
1943  }
1944 
1945  /* handle case (x + coefy) * (y + coefx) <= rhs + coefx * coefy */
1946  if( !SCIPisInfinity(scip, rhs) )
1947  {
1948  assert(SCIPisInfinity(scip, -lhs));
1949 
1950  /* check whether rhs + coefx * coefy == 0 */
1951  if( !SCIPisZero(scip, rhs + coefx * coefy) )
1952  return SCIP_OKAY;
1953 
1954  a = -coefy;
1955  b = -coefx;
1956 
1957  /* now have form (x >= a and y <= b) or (x <= a and y >= b)
1958  * which is equivalent to (x >= a or y >= b) and (x <= a or y <= b)
1959  * the latter can be represented as two bound disjunction constraints
1960  */
1961 
1962  if( upgdconsssize < 2 )
1963  {
1964  /* signal that we need more memory */
1965  *nupgdconss = -2;
1966  return SCIP_OKAY;
1967  }
1968 
1969  xy[0] = x;
1970  xy[1] = y;
1971  bounds[0] = a;
1972  bounds[1] = b;
1973 
1974  /* create constraint x >= a or y >= b */
1975  boundtypes[0] = SCIP_BOUNDTYPE_LOWER;
1976  boundtypes[1] = SCIP_BOUNDTYPE_LOWER;
1977  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_lower", SCIPconsGetName(cons));
1978  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &upgdconss[0], name,
1979  2, xy, boundtypes, bounds,
1983  SCIPconsIsStickingAtNode(cons)) );
1984 
1985  /* create constraint x <= a or y <= b */
1986  boundtypes[0] = SCIP_BOUNDTYPE_UPPER;
1987  boundtypes[1] = SCIP_BOUNDTYPE_UPPER;
1988  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_upper", SCIPconsGetName(cons));
1989  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &upgdconss[1], name,
1990  2, xy, boundtypes, bounds,
1994  SCIPconsIsStickingAtNode(cons)) );
1995 
1996  SCIPdebugMsg(scip, "created bounddisjunction constraints:\n");
1997  SCIPdebugPrintCons(scip, upgdconss[0], NULL);
1998  SCIPdebugPrintCons(scip, upgdconss[1], NULL);
1999 
2000  *nupgdconss = 2;
2001 
2002  return SCIP_OKAY;
2003  }
2004 
2005  /* handle remaining case (x + coefy) * (y + coefx) >= lhs + coefx * coefy */
2006  {
2007  assert(!SCIPisInfinity(scip, -lhs));
2008  assert( SCIPisInfinity(scip, rhs));
2009 
2010  /* check whether lhs + coefx * coefy == 0 */
2011  if( !SCIPisZero(scip, lhs + coefx * coefy) )
2012  return SCIP_OKAY;
2013 
2014  a = -coefy;
2015  b = -coefx;
2016 
2017  /* now have form (x >= a and y >= b) or (x <= a and y <= b)
2018  * which is equivalent to (x >= a or y <= b) and (x <= a or y >= b)
2019  * the latter can be represented as two bound disjunction constraints
2020  */
2021 
2022  if( upgdconsssize < 2 )
2023  {
2024  /* signal that we need more memory */
2025  *nupgdconss = -2;
2026  return SCIP_OKAY;
2027  }
2028 
2029  xy[0] = x;
2030  xy[1] = y;
2031  bounds[0] = a;
2032  bounds[1] = b;
2033 
2034  /* create constraint x >= a or y <= b */
2035  boundtypes[0] = SCIP_BOUNDTYPE_LOWER;
2036  boundtypes[1] = SCIP_BOUNDTYPE_UPPER;
2037  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_lower", SCIPconsGetName(cons));
2038  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &upgdconss[0], name,
2039  2, xy, boundtypes, bounds,
2043  SCIPconsIsStickingAtNode(cons)) );
2044 
2045  /* create constraint x <= a or y >= b */
2046  boundtypes[0] = SCIP_BOUNDTYPE_UPPER;
2047  boundtypes[1] = SCIP_BOUNDTYPE_LOWER;
2048  (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_upper", SCIPconsGetName(cons));
2049  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &upgdconss[1], name,
2050  2, xy, boundtypes, bounds,
2054  SCIPconsIsStickingAtNode(cons)) );
2055 
2056  SCIPdebugMsg(scip, "created bounddisjunction constraints:\n");
2057  SCIPdebugPrintCons(scip, upgdconss[0], NULL);
2058  SCIPdebugPrintCons(scip, upgdconss[1], NULL);
2059 
2060  *nupgdconss = 2;
2061  }
2062 
2063  return SCIP_OKAY;
2064 }
2065 
2066 /**@} */
2067 
2068 /**@name Callback methods of constraint handler
2069  *
2070  * @{
2071  */
2072 
2073 /** copy method for constraint handler plugins (called when SCIP copies plugins) */
2074 static
2075 SCIP_DECL_CONSHDLRCOPY(conshdlrCopyBounddisjunction)
2076 { /*lint --e{715}*/
2077  assert(scip != NULL);
2078  assert(conshdlr != NULL);
2079  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2080 
2081  /* call inclusion method of constraint handler */
2083 
2084  *valid = TRUE;
2085 
2086  return SCIP_OKAY;
2087 }
2088 
2089 /** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
2090 static
2091 SCIP_DECL_CONSFREE(consFreeBounddisjunction)
2092 { /*lint --e{715}*/
2093  SCIP_CONSHDLRDATA* conshdlrdata;
2094 
2095  assert(conshdlr != NULL);
2096  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2097  assert(scip != NULL);
2098 
2099  /* free constraint handler data */
2100  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2101  assert(conshdlrdata != NULL);
2102 
2103  SCIP_CALL( conshdlrdataFree(scip, &conshdlrdata) );
2104 
2105  SCIPconshdlrSetData(conshdlr, NULL);
2106 
2107  return SCIP_OKAY;
2108 }
2109 
2110 
2111 /** presolving deinitialization method of constraint handler (called after presolving has been finished) */
2112 static
2113 SCIP_DECL_CONSEXITPRE(consExitpreBounddisjunction)
2114 { /*lint --e{715}*/
2115  SCIP_CONSHDLRDATA* conshdlrdata;
2116  SCIP_CONS* cons;
2117  SCIP_Bool redundant;
2118  int c;
2119 
2120  assert(conshdlr != NULL);
2121  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2122  assert(scip != NULL);
2123 
2124  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2125  assert(conshdlrdata != NULL);
2126 
2127  /* fast processing of constraints, apply global bounds and remove fixed variables */
2128  for( c = 0; c < nconss; ++c )
2129  {
2130  cons = conss[c];
2131  assert(cons != NULL);
2132 
2133  SCIPdebugMsg(scip, "exit-presolving bound disjunction constraint <%s>\n", SCIPconsGetName(cons));
2134 
2135  if( SCIPconsIsDeleted(cons) )
2136  continue;
2137 
2138  /* remove all literals that are violated in global bounds, check redundancy due to global bounds */
2139  SCIP_CALL( applyGlobalBounds(scip, cons, conshdlrdata->eventhdlr, &redundant) );
2140 
2141  if( !redundant )
2142  {
2143  /* replace variables by their representative active (or multi-aggregated) variables */
2144  SCIP_CALL( removeFixedVariables(scip, cons, conshdlrdata->eventhdlr, &redundant) );
2145  }
2146 
2147  if( redundant && SCIPconsIsAdded(cons) )
2148  {
2149  SCIPdebugMsg(scip, "bound disjunction constraint <%s> is redundant\n", SCIPconsGetName(cons));
2150  SCIP_CALL( SCIPdelCons(scip, cons) );
2151  }
2152  }
2153 
2154  return SCIP_OKAY;
2155 }
2156 
2157 
2158 /** frees specific constraint data */
2159 static
2160 SCIP_DECL_CONSDELETE(consDeleteBounddisjunction)
2161 { /*lint --e{715}*/
2162  assert(conshdlr != NULL);
2163  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2164  assert(consdata != NULL);
2165  assert(*consdata != NULL);
2166 
2167  /* free LP row and bound disjunction constraint */
2168  SCIP_CALL( consdataFree(scip, consdata) );
2169 
2170  return SCIP_OKAY;
2171 }
2172 
2173 
2174 /** transforms constraint data into data belonging to the transformed problem */
2175 static
2176 SCIP_DECL_CONSTRANS(consTransBounddisjunction)
2177 { /*lint --e{715}*/
2178  SCIP_CONSDATA* sourcedata;
2179  SCIP_CONSDATA* targetdata;
2180 
2181  /*debugMsg(scip, "Trans method of bound disjunction constraints\n");*/
2182 
2183  assert(conshdlr != NULL);
2184  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2185  assert(SCIPgetStage(scip) == SCIP_STAGE_TRANSFORMING);
2186  assert(sourcecons != NULL);
2187  assert(targetcons != NULL);
2188 
2189  sourcedata = SCIPconsGetData(sourcecons);
2190  assert(sourcedata != NULL);
2191 
2192  /* create constraint data for target constraint */
2193  SCIP_CALL( consdataCreate(scip, &targetdata, sourcedata->nvars, sourcedata->vars,
2194  sourcedata->boundtypes, sourcedata->bounds) );
2195 
2196  /* create target constraint */
2197  SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
2198  SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
2199  SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
2200  SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
2201  SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
2202 
2203  return SCIP_OKAY;
2204 }
2205 
2206 
2207 /** constraint enforcing method of constraint handler for LP solutions */
2208 static
2209 SCIP_DECL_CONSENFOLP(consEnfolpBounddisjunction)
2210 { /*lint --e{715}*/
2211  SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, NULL, result) );
2212 
2213  return SCIP_OKAY;
2214 }
2215 
2216 
2217 /** constraint enforcing method of constraint handler for relaxation solutions */
2218 static
2219 SCIP_DECL_CONSENFORELAX(consEnforelaxBounddisjunction)
2220 { /*lint --e{715}*/
2221  SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, sol, result) );
2222 
2223  return SCIP_OKAY;
2224 }
2225 
2226 
2227 /** constraint enforcing method of constraint handler for pseudo solutions */
2228 static
2229 SCIP_DECL_CONSENFOPS(consEnfopsBounddisjunction)
2230 { /*lint --e{715}*/
2231  SCIP_CONSHDLRDATA* conshdlrdata;
2232  SCIP_Bool cutoff;
2233  SCIP_Bool infeasible;
2234  SCIP_Bool reduceddom;
2235  SCIP_Bool registeredbrcand;
2236  int c;
2237  SCIP_CONS* narybranchcons; /* constraint that is a candidate for an n-ary branch */
2238 
2239  assert(conshdlr != NULL);
2240  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2241  assert(nconss == 0 || conss != NULL);
2242  assert(result != NULL);
2243 
2244  SCIPdebugMsg(scip, "pseudo enforcing %d bound disjunction constraints\n", nconss);
2245 
2246  *result = SCIP_FEASIBLE;
2247 
2248  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2249  assert(conshdlrdata != NULL);
2250 
2251  cutoff = FALSE;
2252  infeasible = FALSE;
2253  reduceddom = FALSE;
2254  registeredbrcand = FALSE;
2255  narybranchcons = NULL;
2256 
2257  /* check all bound disjunction constraints for feasibility */
2258  for( c = 0; c < nconss && !cutoff && !reduceddom; ++c )
2259  {
2260  SCIP_CALL( enforceCurrentSol(scip, conss[c], NULL, conshdlrdata->eventhdlr, &cutoff, &infeasible, &reduceddom,
2261  &registeredbrcand) );
2262  if( infeasible && !registeredbrcand )
2263  {
2264  /* if cons. c has less literals than the previous candidate for an n-ary branch, then keep cons. c as candidate for n-ary branch */
2265  if( !narybranchcons || SCIPconsGetData(conss[c])->nvars < SCIPconsGetData(narybranchcons)->nvars )
2266  narybranchcons = conss[c];
2267  }
2268  }
2269 
2270  if( cutoff )
2271  *result = SCIP_CUTOFF;
2272  else if( reduceddom )
2273  *result = SCIP_REDUCEDDOM;
2274  else if( infeasible )
2275  {
2276  if( registeredbrcand )
2277  {
2278  *result = SCIP_INFEASIBLE;
2279  }
2280  else
2281  {
2282  SCIP_CALL( createNAryBranch(scip, narybranchcons, NULL) );
2283  *result = SCIP_BRANCHED;
2284  }
2285  }
2286 
2287  return SCIP_OKAY;
2288 }
2289 
2290 
2291 /** feasibility check method of constraint handler for integral solutions */
2292 static
2293 SCIP_DECL_CONSCHECK(consCheckBounddisjunction)
2294 { /*lint --e{715}*/
2295  SCIP_CONS* cons;
2296  SCIP_CONSDATA* consdata;
2297  int c;
2298 
2299  assert(conshdlr != NULL);
2300  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2301  assert(nconss == 0 || conss != NULL);
2302  assert(result != NULL);
2303 
2304  *result = SCIP_FEASIBLE;
2305 
2306  /* check all bound disjunction constraints for feasibility */
2307  for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
2308  {
2309  SCIP_Bool violated;
2310 
2311  cons = conss[c];
2312  consdata = SCIPconsGetData(cons);
2313  assert(consdata != NULL);
2314 
2315  SCIP_CALL( checkCons(scip, cons, sol, &violated) );
2316  if( violated )
2317  {
2318  if( printreason )
2319  {
2320  int v;
2321 
2322  SCIP_CALL( SCIPprintCons(scip, cons, NULL) );
2323  SCIPinfoMessage(scip, NULL, ";\nviolation: ");
2324  for( v = 0; v < consdata->nvars; ++v )
2325  {
2326  assert(consdata->vars[v] != NULL);
2327  if( v > 0 )
2328  SCIPinfoMessage(scip, NULL, ", ");
2329  SCIPinfoMessage(scip, NULL, "<%s> = %.15g",
2330  SCIPvarGetName(consdata->vars[v]), SCIPgetSolVal(scip, sol, consdata->vars[v]));
2331  }
2332  SCIPinfoMessage(scip, NULL, ")\n");
2333  }
2334 
2335  /* constraint is violated */
2336  *result = SCIP_INFEASIBLE;
2337  }
2338  }
2339 
2340  return SCIP_OKAY;
2341 }
2342 
2343 
2344 /** domain propagation method of constraint handler */
2345 static
2346 SCIP_DECL_CONSPROP(consPropBounddisjunction)
2347 { /*lint --e{715}*/
2348  SCIP_CONSHDLRDATA* conshdlrdata;
2349  SCIP_Bool cutoff;
2350  SCIP_Bool infeasible;
2351  SCIP_Bool reduceddom;
2352  SCIP_Bool mustcheck;
2353  SCIP_Bool consreduceddom;
2354  int c;
2355 
2356  assert(conshdlr != NULL);
2357  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2358  assert(nconss == 0 || conss != NULL);
2359  assert(result != NULL);
2360 
2361  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2362  assert(conshdlrdata != NULL);
2363 
2364  cutoff = FALSE;
2365  infeasible = FALSE;
2366  reduceddom = FALSE;
2367 
2368  /* propagate all useful bound disjunction constraints */
2369  for( c = 0; c < nusefulconss && !cutoff; ++c )
2370  {
2371  SCIP_CALL( processWatchedVars(scip, conss[c], conshdlrdata->eventhdlr,
2372  &cutoff, &infeasible, &consreduceddom, &mustcheck) );
2373  reduceddom = reduceddom || consreduceddom;
2374  }
2375 
2376  /* return the correct result */
2377  if( cutoff )
2378  *result = SCIP_CUTOFF;
2379  else if( reduceddom )
2380  *result = SCIP_REDUCEDDOM;
2381  else
2382  *result = SCIP_DIDNOTFIND;
2383 
2384  return SCIP_OKAY;
2385 }
2386 
2387 
2388 /** presolving method of constraint handler */
2389 static
2390 SCIP_DECL_CONSPRESOL(consPresolBounddisjunction)
2391 { /*lint --e{715}*/
2392  SCIP_CONSHDLRDATA* conshdlrdata;
2393  SCIP_CONS* cons;
2394  SCIP_CONSDATA* consdata;
2395  SCIP_Bool infeasible;
2396  SCIP_Bool redundant;
2397  SCIP_Bool tightened;
2398  int c;
2399 
2400  assert(conshdlr != NULL);
2401  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2402  assert(scip != NULL);
2403  assert(result != NULL);
2404 
2405  *result = SCIP_DIDNOTFIND;
2406 
2407  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2408  assert(conshdlrdata != NULL);
2409 
2410  /* process constraints */
2411  for( c = 0; c < nconss && *result != SCIP_CUTOFF && !SCIPisStopped(scip); ++c )
2412  {
2413  cons = conss[c];
2414  assert(cons != NULL);
2415  consdata = SCIPconsGetData(cons);
2416  assert(consdata != NULL);
2417 
2418  SCIPdebugMsg(scip, "presolving bound disjunction constraint <%s>\n", SCIPconsGetName(cons));
2419 
2420  /* force presolving the constraint in the initial round */
2421  if( nrounds == 0 )
2422  {
2423  SCIP_CALL( SCIPenableConsPropagation(scip, cons) );
2424  }
2425 
2426  /* remove all literals that are violated in global bounds, check redundancy due to global bounds */
2427  SCIP_CALL( applyGlobalBounds(scip, cons, conshdlrdata->eventhdlr, &redundant) );
2428 
2429  if( !redundant )
2430  {
2431  /* replace variables by their representative active (or multi-aggregated) variables */
2432  SCIP_CALL( removeFixedVariables(scip, cons, conshdlrdata->eventhdlr, &redundant) );
2433  }
2434 
2435  /**@todo find pairs of negated variables in constraint: constraint is redundant */
2436  /**@todo find sets of equal variables in constraint: multiple entries of variable can be replaced by single entry */
2437 
2438  if( redundant )
2439  {
2440  SCIPdebugMsg(scip, "bound disjunction constraint <%s> is redundant\n", SCIPconsGetName(cons));
2441  SCIP_CALL( SCIPdelCons(scip, cons) );
2442  (*ndelconss)++;
2443  *result = SCIP_SUCCESS;
2444  continue;
2445  }
2446  else if( !SCIPconsIsModifiable(cons) )
2447  {
2448  /* if unmodifiable constraint has no variables, it is infeasible,
2449  * if unmodifiable constraint has only one variable, the literal can be satisfied and the constraint deleted
2450  */
2451  if( consdata->nvars == 0 )
2452  {
2453  SCIPdebugMsg(scip, "bound disjunction constraint <%s> is infeasible\n", SCIPconsGetName(cons));
2454  *result = SCIP_CUTOFF;
2455  return SCIP_OKAY;
2456  }
2457  else if( consdata->nvars == 1 )
2458  {
2459  SCIPdebugMsg(scip, "bound disjunction constraint <%s> has only one undecided literal\n",
2460  SCIPconsGetName(cons));
2461 
2462  assert(consdata->vars != NULL);
2463  assert(!isLiteralSatisfied(scip, consdata, 0));
2464  assert(!isLiteralViolated(scip, consdata, 0));
2465 
2466  if( SCIPvarIsActive(consdata->vars[0]) )
2467  {
2468  if( consdata->boundtypes[0] == SCIP_BOUNDTYPE_LOWER )
2469  {
2470  SCIP_CALL( SCIPtightenVarLb(scip, consdata->vars[0], consdata->bounds[0], TRUE, &infeasible, &tightened) );
2471  }
2472  else
2473  {
2474  SCIP_CALL( SCIPtightenVarUb(scip, consdata->vars[0], consdata->bounds[0], TRUE, &infeasible, &tightened) );
2475  }
2476  if( infeasible )
2477  {
2478  SCIPdebugMsg(scip, " -> infeasible fixing\n");
2479  *result = SCIP_CUTOFF;
2480  return SCIP_OKAY;
2481  }
2482  assert(tightened);
2483  (*nchgbds)++;
2484  }
2485  else
2486  {
2487  /* upgrade to a linear constraint, if vars[0] is multi-aggregated */
2488  SCIP_CONS* lincons;
2489  SCIP_Real one;
2490 
2491  assert(SCIPvarGetStatus(consdata->vars[0]) == SCIP_VARSTATUS_MULTAGGR);
2492 
2493  one = 1.0;
2494  if( consdata->boundtypes[0] == SCIP_BOUNDTYPE_LOWER )
2495  {
2496  SCIP_CALL( SCIPcreateConsLinear(scip, &lincons, SCIPconsGetName(cons),
2497  1, &consdata->vars[0], &one, consdata->bounds[0], SCIPinfinity(scip),
2501  SCIPconsIsStickingAtNode(cons)) );
2502  }
2503  else
2504  {
2505  SCIP_CALL( SCIPcreateConsLinear(scip, &lincons, SCIPconsGetName(cons),
2506  1, &consdata->vars[0], &one, -SCIPinfinity(scip), consdata->bounds[0],
2510  SCIPconsIsStickingAtNode(cons)) );
2511  }
2512  SCIP_CALL( SCIPaddCons(scip, lincons) );
2513  SCIP_CALL( SCIPreleaseCons(scip, &lincons) );
2514  (*nupgdconss)++;
2515  }
2516 
2517  SCIP_CALL( SCIPdelCons(scip, cons) );
2518  (*ndelconss)++;
2519  *result = SCIP_SUCCESS;
2520  continue;
2521  }
2522  else
2523  {
2524  /* try to upgrade the bounddisjunction constraint */
2525  SCIP_CALL( upgradeCons(scip, cons, ndelconss, naddconss) );
2526  }
2527  }
2528  }
2529 
2530  /**@todo preprocess pairs of bound disjunction constraints */
2531 
2532  return SCIP_OKAY;
2533 }
2534 
2535 
2536 /** propagation conflict resolving method of constraint handler */
2537 static
2538 SCIP_DECL_CONSRESPROP(consRespropBounddisjunction)
2539 { /*lint --e{715}*/
2540  SCIP_CONSDATA* consdata;
2541  SCIP_VAR** vars;
2542  SCIP_BOUNDTYPE* boundtypes;
2543 #ifndef NDEBUG
2544  SCIP_Real* bounds;
2545 #endif
2546  int v;
2547 
2548  assert(conshdlr != NULL);
2549  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2550  assert(cons != NULL);
2551  assert(infervar != NULL);
2552  assert(result != NULL);
2553 
2554  consdata = SCIPconsGetData(cons);
2555  assert(consdata != NULL);
2556  assert(consdata->vars != NULL);
2557  assert(consdata->nvars > 0);
2558  assert(0 <= inferinfo && inferinfo < consdata->nvars);
2559  assert(consdata->vars[inferinfo] == infervar);
2560 
2561  vars = consdata->vars;
2562  boundtypes = consdata->boundtypes;
2563 #ifndef NDEBUG
2564  bounds = consdata->bounds;
2565  assert(bounds != NULL);
2566 #endif
2567  assert(boundtypes != NULL);
2568 
2569  SCIPdebugMsg(scip, "conflict resolving method of bound disjunction constraint handler\n");
2570 
2571  /* the only deductions are bounds tightened to a literal's bound on bound disjunction constraints where all other
2572  * literals are violated
2573  */
2574  assert((boundtypes[inferinfo] == SCIP_BOUNDTYPE_LOWER
2575  && SCIPisFeasGE(scip, SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE), bounds[inferinfo]))
2576  || (boundtypes[inferinfo] == SCIP_BOUNDTYPE_UPPER
2577  && SCIPisFeasLE(scip, SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE), bounds[inferinfo])));
2578 
2579  for( v = 0; v < consdata->nvars; ++v )
2580  {
2581  if( v != inferinfo )
2582  {
2583  assert(consdata->vars[v] != infervar || consdata->boundtypes[v] != consdata->boundtypes[inferinfo]);
2584 
2585  /* the reason literal must have been violated
2586  * we do not check for multi-aggregated variables, since SCIPvarGetXbAtIndex is not implemented for them */
2587  /* Use a weaker comparison to SCIPvarGetXbAtIndex here (i.e., SCIPisXT instead of SCIPisFeasXT),
2588  * because SCIPvarGetXbAtIndex might differ from the local bound at time bdchgidx by epsilon. */
2589  assert(SCIPvarGetStatus(vars[v]) == SCIP_VARSTATUS_MULTAGGR
2590  || (boundtypes[v] == SCIP_BOUNDTYPE_LOWER
2591  && SCIPisLT(scip, SCIPgetVarUbAtIndex(scip, vars[v], bdchgidx, TRUE), bounds[v]))
2592  || (boundtypes[v] == SCIP_BOUNDTYPE_UPPER
2593  && SCIPisGT(scip, SCIPgetVarLbAtIndex(scip, vars[v], bdchgidx, TRUE), bounds[v])));
2594  SCIP_CALL( SCIPaddConflictBd(scip, vars[v], SCIPboundtypeOpposite(boundtypes[v]), bdchgidx) );
2595  }
2596  }
2597 
2598  *result = SCIP_SUCCESS;
2599 
2600  return SCIP_OKAY;
2601 }
2602 
2603 
2604 /** variable rounding lock method of constraint handler */
2605 static
2606 SCIP_DECL_CONSLOCK(consLockBounddisjunction)
2607 { /*lint --e{715}*/
2608  SCIP_CONSDATA* consdata;
2609  int i;
2610 
2611  consdata = SCIPconsGetData(cons);
2612  assert(consdata != NULL);
2613 
2614  /* lock every single coefficient */
2615  for( i = 0; i < consdata->nvars; ++i )
2616  {
2617  if( consdata->boundtypes[i] == SCIP_BOUNDTYPE_LOWER )
2618  {
2619  SCIP_CALL( SCIPaddVarLocks(scip, consdata->vars[i], nlockspos, nlocksneg) );
2620  }
2621  else
2622  {
2623  SCIP_CALL( SCIPaddVarLocks(scip, consdata->vars[i], nlocksneg, nlockspos) );
2624  }
2625  }
2626 
2627  return SCIP_OKAY;
2628 }
2629 
2630 
2631 /** constraint activation notification method of constraint handler */
2632 static
2633 SCIP_DECL_CONSACTIVE(consActiveBounddisjunction)
2634 { /*lint --e{715}*/
2635  SCIP_CONSHDLRDATA* conshdlrdata;
2636  SCIP_CONSDATA* consdata;
2637 
2638  assert(conshdlr != NULL);
2639  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2640  assert(cons != NULL);
2641  assert(SCIPconsIsTransformed(cons));
2642 
2643  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2644  assert(conshdlrdata != NULL);
2645  consdata = SCIPconsGetData(cons);
2646  assert(consdata != NULL);
2647  assert(consdata->watchedvar1 == -1 || consdata->watchedvar1 != consdata->watchedvar2);
2648 
2649  SCIPdebugMsg(scip, "activating information for bound disjunction constraint <%s>\n", SCIPconsGetName(cons));
2650  SCIPdebug(consdataPrint(scip, consdata, NULL, TRUE));
2651 
2652  /* catch events on watched variables */
2653  if( consdata->watchedvar1 != -1 )
2654  {
2655  SCIP_CALL( catchEvents(scip, cons, consdata, conshdlrdata->eventhdlr, consdata->watchedvar1,
2656  &consdata->filterpos1) );
2657  }
2658  if( consdata->watchedvar2 != -1 )
2659  {
2660  SCIP_CALL( catchEvents(scip, cons, consdata, conshdlrdata->eventhdlr, consdata->watchedvar2,
2661  &consdata->filterpos2) );
2662  }
2663 
2664  return SCIP_OKAY;
2665 }
2666 
2667 
2668 /** constraint deactivation notification method of constraint handler */
2669 static
2670 SCIP_DECL_CONSDEACTIVE(consDeactiveBounddisjunction)
2671 { /*lint --e{715}*/
2672  SCIP_CONSHDLRDATA* conshdlrdata;
2673  SCIP_CONSDATA* consdata;
2674 
2675  assert(conshdlr != NULL);
2676  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2677  assert(cons != NULL);
2678  assert(SCIPconsIsTransformed(cons));
2679 
2680  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2681  assert(conshdlrdata != NULL);
2682  consdata = SCIPconsGetData(cons);
2683  assert(consdata != NULL);
2684  assert(consdata->watchedvar1 == -1 || consdata->watchedvar1 != consdata->watchedvar2);
2685 
2686  SCIPdebugMsg(scip, "deactivating information for bound disjunction constraint <%s>\n", SCIPconsGetName(cons));
2687  SCIPdebug(consdataPrint(scip, consdata, NULL, TRUE));
2688 
2689  /* drop events on watched variables */
2690  if( consdata->watchedvar1 != -1 )
2691  {
2692  assert(consdata->filterpos1 != -1);
2693  SCIP_CALL( dropEvents(scip, cons, consdata, conshdlrdata->eventhdlr, consdata->watchedvar1, consdata->filterpos1) );
2694  consdata->watchedvar1 = -1;
2695  }
2696  if( consdata->watchedvar2 != -1 )
2697  {
2698  assert(consdata->filterpos2 != -1);
2699  SCIP_CALL( dropEvents(scip, cons, consdata, conshdlrdata->eventhdlr, consdata->watchedvar2, consdata->filterpos2) );
2700  consdata->watchedvar2 = -1;
2701  }
2702 
2703  return SCIP_OKAY;
2704 }
2705 
2706 
2707 /** constraint display method of constraint handler */
2708 static
2709 SCIP_DECL_CONSPRINT(consPrintBounddisjunction)
2710 { /*lint --e{715}*/
2711 
2712  assert( scip != NULL );
2713  assert( conshdlr != NULL );
2714  assert( cons != NULL );
2715 
2716  consdataPrint(scip, SCIPconsGetData(cons), file, FALSE);
2717 
2718  return SCIP_OKAY;
2719 }
2720 
2721 /** constraint copying method of constraint handler */
2722 static
2723 SCIP_DECL_CONSCOPY(consCopyBounddisjunction)
2724 { /*lint --e{715}*/
2725  SCIP_VAR** sourcevars;
2726  SCIP_VAR** targetvars;
2727  SCIP_BOUNDTYPE* boundtypes;
2728  SCIP_Real* bounds;
2729  int nvars;
2730  int v;
2731 
2732  assert(valid != NULL);
2733 
2734  *valid = TRUE;
2735 
2736  /* get source data */
2737  sourcevars = SCIPgetVarsBounddisjunction(sourcescip, sourcecons);
2738  nvars = SCIPgetNVarsBounddisjunction(sourcescip, sourcecons);
2739  boundtypes = SCIPgetBoundtypesBounddisjunction(sourcescip, sourcecons);
2740  bounds = SCIPgetBoundsBounddisjunction(sourcescip, sourcecons);
2741 
2742  SCIP_CALL( SCIPallocBufferArray(scip, &targetvars, nvars) );
2743 
2744  /* map source variables to active variables of the target SCIP */
2745  for( v = 0; v < nvars && *valid; ++v )
2746  {
2747  SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, sourcevars[v], &targetvars[v], varmap, consmap, global, valid) );
2748  assert(!(*valid) || targetvars[v] != NULL);
2749  }
2750 
2751  /* only create the target constraint, if all variables could be copied */
2752  if( *valid )
2753  {
2754  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, cons, name ? name : SCIPconsGetName(sourcecons), nvars, targetvars, boundtypes,
2755  bounds, initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
2756  }
2757 
2758  SCIPfreeBufferArray(scip, &targetvars);
2759 
2760  return SCIP_OKAY;
2761 }
2762 
2763 /** constraint parsing method of constraint handler */
2764 static
2765 SCIP_DECL_CONSPARSE(consParseBounddisjunction)
2766 { /*lint --e{715}*/
2767  SCIP_BOUNDTYPE* boundtypes;
2768  SCIP_Real* bounds;
2769  SCIP_VAR** vars;
2770  char* endptr;
2771  int varssize;
2772  int nvars;
2773 
2774  assert( success != NULL );
2775  *success = TRUE;
2776 
2777  SCIPdebugMsg(scip, "parse <%s> as bounddisjunction constraint\n", str);
2778 
2779  /* skip white space */
2780  while( *str != '\0' && isspace((unsigned char)*str) )
2781  ++str;
2782 
2783  /* check for string "bounddisjunction" */
2784  if( strncmp(str, "bounddisjunction(", 16) != 0 )
2785  {
2786  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "error during parsing: expected \"bounddisjunction(\" in <%s>.\n", str);
2787  *success = FALSE;
2788  return SCIP_OKAY;
2789  }
2790 
2791  /* skip "bounddisjunction(" */
2792  str += 17;
2793 
2794  varssize = 100;
2795  nvars = 0;
2796 
2797  /* allocate buffer array for variables */
2798  SCIP_CALL( SCIPallocBufferArray(scip, &vars, varssize) );
2799  SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, varssize) );
2800  SCIP_CALL( SCIPallocBufferArray(scip, &bounds, varssize) );
2801 
2802  /* parse string until ")" */
2803  while( *str != '\0' && *str != ')' )
2804  {
2805  SCIP_VAR* var;
2806 
2807  /* parse variable name */
2808  SCIP_CALL( SCIPparseVarName(scip, str, &var, &endptr) );
2809  str = endptr;
2810 
2811  if( var == NULL )
2812  {
2813  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Error while parsing variable.\n");
2814  *success = FALSE;
2815  goto TERMINATE;
2816  }
2817 
2818  /* skip white space */
2819  while( *str != '\0' && isspace((unsigned char)*str) && *str != '>' && *str != '<' )
2820  ++str;
2821 
2822  /* parse bound type */
2823  switch( *str )
2824  {
2825  case '<':
2826  boundtypes[nvars] = SCIP_BOUNDTYPE_UPPER;
2827  break;
2828  case '>':
2829  boundtypes[nvars] = SCIP_BOUNDTYPE_LOWER;
2830  break;
2831  default:
2832  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "variable with name <%s> does not exist\n", SCIPvarGetName(var));
2833  *success = FALSE;
2834  goto TERMINATE;
2835  }
2836 
2837  ++str;
2838  if( *str != '=' )
2839  {
2840  SCIPdebugMsg(scip, "expected '=': %s\n", str);
2841  *success = FALSE;
2842  goto TERMINATE;
2843  }
2844 
2845  /* skip '=' */
2846  ++str;
2847 
2848  /* skip white space */
2849  while( *str != '\0' && isspace((unsigned char)*str) )
2850  ++str;
2851 
2852  /* parse bound value */
2853  if( !SCIPstrToRealValue(str, &bounds[nvars], &endptr) )
2854  {
2855  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error during parsing of the weight: %s\n", str);
2856  *success = FALSE;
2857  goto TERMINATE;
2858  }
2859 
2860  /* skip white space */
2861  str = endptr;
2862  while( (*str != '\0' && isspace((unsigned char)*str)) || *str == ',' )
2863  ++str;
2864 
2865  /* set variable */
2866  vars[nvars++] = var;
2867 
2868  /* check if the size of the variable array was big enough */
2869  if( nvars > varssize )
2870  {
2871  /* reallocate memory */
2872  varssize *= 2;
2873  SCIP_CALL( SCIPreallocBufferArray(scip, &vars, varssize) );
2874  SCIP_CALL( SCIPreallocBufferArray(scip, &boundtypes, varssize) );
2875  SCIP_CALL( SCIPreallocBufferArray(scip, &bounds, varssize) );
2876  }
2877  }
2878  /* ignore if the string ended without ")" */
2879 
2880  /* add bounddisjunction */
2881  if( *success && nvars > 0 )
2882  {
2883  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, cons, name, nvars, vars, boundtypes, bounds,
2884  initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
2885  }
2886 
2887  TERMINATE:
2888  /* free variable buffer */
2889  SCIPfreeBufferArray(scip, &bounds);
2890  SCIPfreeBufferArray(scip, &boundtypes);
2891  SCIPfreeBufferArray(scip, &vars);
2892 
2893  return SCIP_OKAY;
2894 }
2895 
2896 /** constraint method of constraint handler which returns the variables (if possible) */
2897 static
2898 SCIP_DECL_CONSGETVARS(consGetVarsBounddisjunction)
2899 { /*lint --e{715}*/
2900  SCIP_CONSDATA* consdata;
2901 
2902  assert(cons != NULL);
2903 
2904  consdata = SCIPconsGetData(cons);
2905  assert(consdata != NULL);
2906 
2907  if( varssize < consdata->nvars )
2908  (*success) = FALSE;
2909  else
2910  {
2911  assert(vars != NULL);
2912 
2913  BMScopyMemoryArray(vars, consdata->vars, consdata->nvars);
2914  (*success) = TRUE;
2915  }
2916 
2917  return SCIP_OKAY;
2918 }
2919 
2920 /** constraint method of constraint handler which returns the number of variables (if possible) */
2921 static
2922 SCIP_DECL_CONSGETNVARS(consGetNVarsBounddisjunction)
2923 { /*lint --e{715}*/
2924  SCIP_CONSDATA* consdata;
2925 
2926  assert(cons != NULL);
2927 
2928  consdata = SCIPconsGetData(cons);
2929  assert(consdata != NULL);
2930 
2931  (*nvars) = consdata->nvars;
2932  (*success) = TRUE;
2933 
2934  return SCIP_OKAY;
2935 }
2936 
2937 /**@} */
2938 
2939 /**@name Callback methods of event handler
2940  *
2941  */
2942 
2943 static
2944 SCIP_DECL_EVENTEXEC(eventExecBounddisjunction)
2945 { /*lint --e{715}*/
2946  assert(eventhdlr != NULL);
2947  assert(eventdata != NULL);
2948  assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
2949  assert(event != NULL);
2950 
2951  /*SCIPdebugMsg(scip, "exec method of event handler for bound disjunction constraints\n");*/
2952 
2953  assert(SCIPconsGetData((SCIP_CONS*)eventdata) != NULL);
2954  assert(SCIPconsIsActive((SCIP_CONS*)eventdata) || SCIPconsIsUpdatedeactivate((SCIP_CONS*)eventdata));
2955 
2956  if( (SCIPeventGetType(event) & SCIP_EVENTTYPE_BOUNDRELAXED) != 0 )
2957  {
2958  SCIP_CALL( SCIPenableCons(scip, (SCIP_CONS*)eventdata) );
2959  }
2960  else
2961  assert((SCIPeventGetType(event) & SCIP_EVENTTYPE_BOUNDTIGHTENED) != 0);
2962 
2963  SCIP_CALL( SCIPenableConsPropagation(scip, (SCIP_CONS*)eventdata) );
2964 
2965  return SCIP_OKAY;
2966 }
2967 
2968 /**@} */
2969 
2970 /**@name Callback methods of conflict handler
2971  *
2972  * @{
2973  */
2974 
2975 /** conflict handler data struct */
2976 struct SCIP_ConflicthdlrData
2977 {
2978  SCIP_Real continuousfrac; /**< maximal percantage of continuous variables within a conflict */
2979 };
2980 
2981 /** conflict processing method of conflict handler (called when conflict was found) */
2982 static
2983 SCIP_DECL_CONFLICTEXEC(conflictExecBounddisjunction)
2984 { /*lint --e{715}*/
2985  SCIP_VAR** vars;
2986  SCIP_CONFLICTHDLRDATA* conflicthdlrdata;
2987  SCIP_BOUNDTYPE* boundtypes;
2988  SCIP_Real* bounds;
2989  SCIP_CONS* cons;
2990  char consname[SCIP_MAXSTRLEN];
2991  int ncontinuous;
2992  int i;
2993 
2994  assert(conflicthdlr != NULL);
2995  assert(strcmp(SCIPconflicthdlrGetName(conflicthdlr), CONFLICTHDLR_NAME) == 0);
2996  assert(bdchginfos != NULL || nbdchginfos == 0);
2997  assert(result != NULL);
2998 
2999  /* don't process already resolved conflicts */
3000  if( resolved )
3001  {
3002  *result = SCIP_DIDNOTRUN;
3003  return SCIP_OKAY;
3004  }
3005 
3006  conflicthdlrdata = SCIPconflicthdlrGetData(conflicthdlr);
3007  assert(conflicthdlrdata != NULL);
3008 
3009  *result = SCIP_DIDNOTFIND;
3010  ncontinuous = 0;
3011 
3012  /* create array of variables, boundtypes, and bound values in conflict constraint */
3013  SCIP_CALL( SCIPallocBufferArray(scip, &vars, nbdchginfos) );
3014  SCIP_CALL( SCIPallocBufferArray(scip, &boundtypes, nbdchginfos) );
3015  SCIP_CALL( SCIPallocBufferArray(scip, &bounds, nbdchginfos) );
3016 
3017  for( i = 0; i < nbdchginfos; ++i )
3018  {
3019  assert(bdchginfos != NULL);
3020 
3021  vars[i] = SCIPbdchginfoGetVar(bdchginfos[i]);
3022  boundtypes[i] = SCIPboundtypeOpposite(SCIPbdchginfoGetBoundtype(bdchginfos[i]));
3023  bounds[i] = relaxedbds[i];
3024 
3025  /* check if the relaxed bound is really a relaxed bound */
3026  assert(SCIPbdchginfoGetBoundtype(bdchginfos[i]) == SCIP_BOUNDTYPE_LOWER || SCIPisGE(scip, relaxedbds[i], SCIPbdchginfoGetNewbound(bdchginfos[i])));
3027  assert(SCIPbdchginfoGetBoundtype(bdchginfos[i]) == SCIP_BOUNDTYPE_UPPER || SCIPisLE(scip, relaxedbds[i], SCIPbdchginfoGetNewbound(bdchginfos[i])));
3028 
3029  /* for continuous variables, we can only use the relaxed version of the bounds negation: !(x <= u) -> x >= u */
3030  if( SCIPvarIsIntegral(vars[i]) )
3031  {
3032  assert(SCIPisIntegral(scip, bounds[i]));
3033  bounds[i] += (boundtypes[i] == SCIP_BOUNDTYPE_LOWER ? +1.0 : -1.0);
3034  }
3035  else if( (boundtypes[i] == SCIP_BOUNDTYPE_LOWER && SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(vars[i]), bounds[i]))
3036  || (boundtypes[i] == SCIP_BOUNDTYPE_UPPER && SCIPisFeasEQ(scip, SCIPvarGetUbGlobal(vars[i]), bounds[i])) )
3037  {
3038  /* the literal is satisfied in global bounds (may happen due to weak "negation" of continuous variables)
3039  * -> discard the conflict constraint
3040  */
3041  break;
3042  }
3043  else
3044  ncontinuous++;
3045  }
3046 
3047  /* create a constraint out of the conflict set */
3048  if( i == nbdchginfos && ncontinuous < conflicthdlrdata->continuousfrac * nbdchginfos + 0.5 )
3049  {
3050  (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "cf%d_%" SCIP_LONGINT_FORMAT, SCIPgetNRuns(scip), SCIPgetNConflictConssApplied(scip));
3051  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, &cons, consname, nbdchginfos, vars, boundtypes, bounds,
3052  FALSE, FALSE, FALSE, FALSE, TRUE, local, FALSE, dynamic, removable, FALSE) );
3053 
3054  /* add conflict to SCIP */
3055  SCIP_CALL( SCIPaddConflict(scip, node, cons, validnode, conftype, cutoffinvolved) );
3056 
3057  *result = SCIP_CONSADDED;
3058  }
3059 
3060  /* free temporary memory */
3061  SCIPfreeBufferArray(scip, &bounds);
3062  SCIPfreeBufferArray(scip, &boundtypes);
3063  SCIPfreeBufferArray(scip, &vars);
3064 
3065  return SCIP_OKAY;
3066 }
3067 
3068 /** free method of conflict handler */
3069 static
3070 SCIP_DECL_CONFLICTFREE(conflictFreeBounddisjunction)
3072  SCIP_CONFLICTHDLRDATA* conflicthdlrdata;
3073 
3074  assert(conflicthdlr != NULL);
3075 
3076  /* get conflict handler data */
3077  conflicthdlrdata = SCIPconflicthdlrGetData(conflicthdlr);
3078  assert(conflicthdlrdata != NULL);
3079 
3080  /* free conflict handler structure */
3081  SCIPfreeBlockMemory(scip, &conflicthdlrdata);
3082 
3083  return SCIP_OKAY;
3084 }
3085 
3086 /**@} */
3087 
3088 /**@name Interface methods
3089  *
3090  * @{
3091  */
3092 
3093 /** creates the handler for bound disjunction constraints and includes it in SCIP */
3095  SCIP* scip /**< SCIP data structure */
3096  )
3097 {
3098  SCIP_CONSHDLRDATA* conshdlrdata;
3099  SCIP_CONFLICTHDLRDATA* conflicthdlrdata;
3100  SCIP_CONFLICTHDLR* conflicthdlr;
3101  SCIP_CONSHDLR* conshdlr;
3102  SCIP_EVENTHDLR* eventhdlr;
3103 
3104  /* create event handler for events on watched variables */
3106  eventExecBounddisjunction, NULL) );
3107 
3108  /* allocate memory for conflict handler data */
3109  SCIP_CALL( SCIPallocBlockMemory(scip, &conflicthdlrdata) );
3110 
3111  /* create conflict handler parameter */
3113  "conflict/" CONSHDLR_NAME "/continuousfrac", "maximal percantage of continuous variables within a conflict",
3114  &conflicthdlrdata->continuousfrac, FALSE, DEFAULT_CONTINUOUSFRAC, 0.0, 1.0, NULL, NULL) );
3115 
3116  /* create conflict handler for bound disjunction constraints */
3118  conflictExecBounddisjunction, conflicthdlrdata) );
3119 
3120  SCIP_CALL( SCIPsetConflicthdlrFree(scip, conflicthdlr, conflictFreeBounddisjunction) );
3121 
3122  /* create constraint handler data */
3123  SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
3124 
3125  /* include constraint handler */
3128  consEnfolpBounddisjunction, consEnfopsBounddisjunction, consCheckBounddisjunction, consLockBounddisjunction,
3129  conshdlrdata) );
3130 
3131  assert(conshdlr != NULL);
3132 
3133  /* set non-fundamental callbacks via specific setter functions */
3134  SCIP_CALL( SCIPsetConshdlrActive(scip, conshdlr, consActiveBounddisjunction) );
3135  SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyBounddisjunction, consCopyBounddisjunction) );
3136  SCIP_CALL( SCIPsetConshdlrDeactive(scip, conshdlr, consDeactiveBounddisjunction) );
3137  SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteBounddisjunction) );
3138  SCIP_CALL( SCIPsetConshdlrExitpre(scip, conshdlr, consExitpreBounddisjunction) );
3139  SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeBounddisjunction) );
3140  SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsBounddisjunction) );
3141  SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsBounddisjunction) );
3142  SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseBounddisjunction) );
3143  SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolBounddisjunction, CONSHDLR_MAXPREROUNDS,
3145  SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintBounddisjunction) );
3146  SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropBounddisjunction, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP,
3148  SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropBounddisjunction) );
3149  SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransBounddisjunction) );
3150  SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxBounddisjunction) );
3151 
3152  /* register upgrade of quadratic complementarity constraints in cons_quadratic */
3153  if( SCIPfindConshdlr(scip, "quadratic") )
3154  {
3156  }
3157 
3158  return SCIP_OKAY;
3159 }
3160 
3161 
3162 /** creates and captures a bound disjunction constraint
3163  *
3164  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
3165  */
3167  SCIP* scip, /**< SCIP data structure */
3168  SCIP_CONS** cons, /**< pointer to hold the created constraint */
3169  const char* name, /**< name of constraint */
3170  int nvars, /**< number of variables in the constraint */
3171  SCIP_VAR** vars, /**< variables of the literals in the constraint */
3172  SCIP_BOUNDTYPE* boundtypes, /**< types of bounds of the literals (lower or upper bounds) */
3173  SCIP_Real* bounds, /**< bounds of the literals */
3174  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
3175  * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
3176  SCIP_Bool separate, /**< should the constraint be separated during LP processing?
3177  * Usually set to TRUE. */
3178  SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
3179  * TRUE for model constraints, FALSE for additional, redundant constraints. */
3180  SCIP_Bool check, /**< should the constraint be checked for feasibility?
3181  * TRUE for model constraints, FALSE for additional, redundant constraints. */
3182  SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
3183  * Usually set to TRUE. */
3184  SCIP_Bool local, /**< is constraint only valid locally?
3185  * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
3186  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
3187  * Usually set to FALSE. In column generation applications, set to TRUE if pricing
3188  * adds coefficients to this constraint. */
3189  SCIP_Bool dynamic, /**< is constraint subject to aging?
3190  * Usually set to FALSE. Set to TRUE for own cuts which
3191  * are separated as constraints. */
3192  SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
3193  * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
3194  SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
3195  * if it may be moved to a more global node?
3196  * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
3197  )
3198 {
3199  SCIP_CONSHDLR* conshdlr;
3200  SCIP_CONSDATA* consdata;
3201 
3202  assert(scip != NULL);
3203 
3204  /* find the bounddisjunction constraint handler */
3205  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
3206  if( conshdlr == NULL )
3207  {
3208  SCIPerrorMessage("bound disjunction constraint handler not found\n");
3209  return SCIP_PLUGINNOTFOUND;
3210  }
3211 
3212  /* create the constraint specific data */
3213  SCIP_CALL( consdataCreate(scip, &consdata, nvars, vars, boundtypes, bounds) );
3214 
3215  /* create constraint */
3216  SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
3217  local, modifiable, dynamic, removable, stickingatnode) );
3218 
3219  return SCIP_OKAY;
3220 }
3221 
3222 /** creates and captures a bound disjunction constraint
3223  * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
3224  * method SCIPcreateConsBounddisjunction(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
3225  *
3226  * @see SCIPcreateConsBounddisjunction() for information about the basic constraint flag configuration
3227  *
3228  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
3229  */
3231  SCIP* scip, /**< SCIP data structure */
3232  SCIP_CONS** cons, /**< pointer to hold the created constraint */
3233  const char* name, /**< name of constraint */
3234  int nvars, /**< number of variables in the constraint */
3235  SCIP_VAR** vars, /**< variables of the literals in the constraint */
3236  SCIP_BOUNDTYPE* boundtypes, /**< types of bounds of the literals (lower or upper bounds) */
3237  SCIP_Real* bounds /**< bounds of the literals */
3238  )
3239 {
3240  assert(scip != NULL);
3241 
3242  SCIP_CALL( SCIPcreateConsBounddisjunction(scip, cons, name, nvars, vars, boundtypes, bounds,
3243  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE) );
3244 
3245  return SCIP_OKAY;
3246 }
3247 
3248 /** gets number of variables in bound disjunction constraint */
3250  SCIP* scip, /**< SCIP data structure */
3251  SCIP_CONS* cons /**< constraint data */
3252  )
3253 {
3254  SCIP_CONSDATA* consdata;
3255 
3256  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
3257  {
3258  SCIPerrorMessage("constraint is not a bound disjunction constraint\n");
3259  SCIPABORT();
3260  return 0; /*lint !e527*/
3261  }
3262 
3263  consdata = SCIPconsGetData(cons);
3264  assert(consdata != NULL);
3265 
3266  return consdata->nvars;
3267 }
3268 
3269 /** gets array of variables in bound disjunction constraint */
3271  SCIP* scip, /**< SCIP data structure */
3272  SCIP_CONS* cons /**< constraint data */
3273  )
3274 {
3275  SCIP_CONSDATA* consdata;
3276 
3277  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
3278  {
3279  SCIPerrorMessage("constraint is not a bound disjunction constraint\n");
3280  SCIPABORT();
3281  return NULL; /*lint !e527*/
3282  }
3283 
3284  consdata = SCIPconsGetData(cons);
3285  assert(consdata != NULL);
3286 
3287  return consdata->vars;
3288 }
3289 
3290 /** gets array of bound types in bound disjunction constraint */
3292  SCIP* scip, /**< SCIP data structure */
3293  SCIP_CONS* cons /**< constraint data */
3294  )
3295 {
3296  SCIP_CONSDATA* consdata;
3297 
3298  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
3299  {
3300  SCIPerrorMessage("constraint is not a bound disjunction constraint\n");
3301  SCIPABORT();
3302  return NULL; /*lint !e527*/
3303  }
3304 
3305  consdata = SCIPconsGetData(cons);
3306  assert(consdata != NULL);
3307 
3308  return consdata->boundtypes;
3309 }
3310 
3311 /** gets array of bounds in bound disjunction constraint */
3313  SCIP* scip, /**< SCIP data structure */
3314  SCIP_CONS* cons /**< constraint data */
3315  )
3316 {
3317  SCIP_CONSDATA* consdata;
3318 
3319  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
3320  {
3321  SCIPerrorMessage("constraint is not a bound disjunction constraint\n");
3322  SCIPABORT();
3323  return NULL; /*lint !e527*/
3324  }
3325 
3326  consdata = SCIPconsGetData(cons);
3327  assert(consdata != NULL);
3328 
3329  return consdata->bounds;
3330 }
3331 
3332 /**@} */
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
static SCIP_DECL_CONSCHECK(consCheckBounddisjunction)
enum SCIP_BoundType SCIP_BOUNDTYPE
Definition: type_lp.h:50
void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
Definition: cons.c:4143
static SCIP_RETCODE dropEvents(SCIP *scip, SCIP_CONS *cons, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr, int pos, int filterpos)
SCIP_RETCODE SCIPaddConsAge(SCIP *scip, SCIP_CONS *cons, SCIP_Real deltaage)
Definition: scip.c:27905
#define SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition: scip.h:21898
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
Definition: scip.c:6228
static SCIP_RETCODE lockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_CONSDATA *consdata, int pos)
static SCIP_RETCODE conshdlrdataFree(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata)
SCIP_RETCODE SCIPtightenVarLb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip.c:22118
SCIP_RETCODE SCIPincludeConshdlrBounddisjunction(SCIP *scip)
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip.c:19263
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46086
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip.c:814
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:8140
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
Definition: scip.c:6251
SCIP_Bool SCIPisFeasLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46099
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip.c:19123
int SCIPconsGetValidDepth(SCIP_CONS *cons)
Definition: cons.c:7964
static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata)
SCIP_RETCODE SCIPcatchVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition: scip.c:40275
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip.c:6541
SCIP_VAR * SCIPbdchginfoGetVar(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17788
static SCIP_DECL_CONSDELETE(consDeleteBounddisjunction)
#define CONSHDLR_PROPFREQ
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17166
SCIP_RETCODE SCIPincludeQuadconsUpgrade(SCIP *scip, SCIP_DECL_QUADCONSUPGD((*quadconsupgd)), int priority, SCIP_Bool active, const char *conshdlrname)
SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETVARS((*consgetvars)))
Definition: scip.c:6481
#define SCIP_MAXSTRLEN
Definition: def.h:215
#define CONSHDLR_NEEDSCONS
SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
Definition: scip.c:5973
SCIP_RETCODE SCIPresetConsAge(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:27962
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:12481
SCIP_Real * SCIPgetBoundsBounddisjunction(SCIP *scip, SCIP_CONS *cons)
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip.c:45601
static long bound
static SCIP_RETCODE applyGlobalBounds(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, SCIP_Bool *redundant)
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17222
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:45803
SCIP_RETCODE SCIPdisableConsPropagation(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:28131
SCIP_RETCODE SCIPsetConshdlrDeactive(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDEACTIVE((*consdeactive)))
Definition: scip.c:6343
SCIP_RETCODE SCIPchgVarLbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip.c:21781
SCIP_Bool SCIPconsIsAdded(SCIP_CONS *cons)
Definition: cons.c:8250
SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition: scip.c:8526
SCIP_RETCODE SCIPdelConsNode(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons)
Definition: scip.c:13061
int SCIPgetNVarsBounddisjunction(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE disableCons(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPparseVarName(SCIP *scip, const char *str, SCIP_VAR **var, char **endptr)
Definition: scip.c:17656
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:16732
static SCIP_RETCODE registerBranchingCandidates(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool *neednarybranch)
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46138
#define isFeasGT(scip, var, val1, val2)
static SCIP_DECL_CONSGETVARS(consGetVarsBounddisjunction)
#define FALSE
Definition: def.h:64
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:278
#define isFeasGE(scip, var, val1, val2)
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.c:5831
static SCIP_RETCODE delCoefPos(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
#define CONFLICTHDLR_DESC
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:45816
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:9340
#define TRUE
Definition: def.h:63
#define SCIPdebug(x)
Definition: pub_message.h:74
static SCIP_RETCODE catchEvents(SCIP *scip, SCIP_CONS *cons, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr, int pos, int *filterpos)
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
#define CONSHDLR_PROP_TIMING
SCIP_RETCODE SCIPaddVarLocks(SCIP *scip, SCIP_VAR *var, int nlocksdown, int nlocksup)
Definition: scip.c:21255
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition: cons.c:8160
#define CONFLICTHDLR_PRIORITY
static SCIP_DECL_CONSENFORELAX(consEnforelaxBounddisjunction)
static SCIP_RETCODE analyzeConflict(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:8190
SCIP_RETCODE SCIPinitConflictAnalysis(SCIP *scip, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
Definition: scip.c:26717
SCIP_RETCODE SCIPtightenVarUb(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip.c:22234
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip.h:21907
SCIP_RETCODE SCIPenableConsPropagation(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:28101
static SCIP_DECL_CONSTRANS(consTransBounddisjunction)
SCIP_RETCODE SCIPchgVarUbNode(SCIP *scip, SCIP_NODE *node, SCIP_VAR *var, SCIP_Real newbound)
Definition: scip.c:21825
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:45751
#define SCIP_LONGINT_MAX
Definition: def.h:121
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:21937
SCIP_Longint SCIPvarGetNBranchingsCurrentRun(SCIP_VAR *var, SCIP_BRANCHDIR dir)
Definition: var.c:15046
Constraint handler for the set partitioning / packing / covering constraints .
static SCIP_DECL_CONSFREE(consFreeBounddisjunction)
SCIP_RETCODE SCIPincludeConflicthdlrBasic(SCIP *scip, SCIP_CONFLICTHDLR **conflicthdlrptr, const char *name, const char *desc, int priority, SCIP_DECL_CONFLICTEXEC((*conflictexec)), SCIP_CONFLICTHDLRDATA *conflicthdlrdata)
Definition: scip.c:6625
#define CONSHDLR_ENFOPRIORITY
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip.h:21890
#define SCIPdebugPrintCons(x, y, z)
Definition: pub_message.h:83
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip.c:1010
static SCIP_RETCODE addCoef(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_Real bound)
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:8150
#define SCIPdebugMsg
Definition: scip.h:451
SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip.c:18616
SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
Definition: scip.c:6458
SCIP_Real SCIPgetLhsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition: cons.c:7942
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip.c:1336
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.c:27146
#define CONSHDLR_DELAYPROP
SCIP_Real SCIPcomputeVarUbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:23391
SCIP_Real SCIPcomputeVarLbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:23412
int SCIPgetNQuadVarTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
static SCIP_Bool isLiteralSatisfied(SCIP *scip, SCIP_CONSDATA *consdata, int pos)
#define SCIP_EVENTTYPE_LBRELAXED
Definition: type_event.h:64
int SCIPgetNBilinTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisConflictAnalysisApplicable(SCIP *scip)
Definition: scip.c:26695
SCIP_RETCODE SCIPcreateConsBasicBounddisjunction(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_BOUNDTYPE *boundtypes, SCIP_Real *bounds)
#define CONSHDLR_EAGERFREQ
SCIP_RETCODE SCIPenableCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:27987
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17176
SCIP_VAR * SCIPvarGetProbvar(SCIP_VAR *var)
Definition: var.c:11524
static SCIP_RETCODE enforceCurrentSol(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_EVENTHDLR *eventhdlr, SCIP_Bool *cutoff, SCIP_Bool *infeasible, SCIP_Bool *reduceddom, SCIP_Bool *registeredbrcand)
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip.h:21904
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
Definition: scip.c:5997
static SCIP_DECL_QUADCONSUPGD(upgradeConsQuadratic)
SCIP_VAR ** SCIPgetVarsBounddisjunction(SCIP *scip, SCIP_CONS *cons)
SCIP_BOUNDTYPE SCIPboundtypeOpposite(SCIP_BOUNDTYPE boundtype)
Definition: lp.c:16222
#define SCIPerrorMessage
Definition: pub_message.h:45
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4113
static SCIP_RETCODE enforceConstraint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss, SCIP_SOL *sol, SCIP_RESULT *result)
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:12410
#define CONSHDLR_NAME
static SCIP_DECL_CONSGETNVARS(consGetNVarsBounddisjunction)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:45764
#define QUADCONSUPGD_PRIORITY
Constraint handler for logicor constraints (equivalent to set covering, but algorithms are suited fo...
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip.c:21383
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:7881
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:8100
struct SCIP_EventData SCIP_EVENTDATA
Definition: type_event.h:155
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16552
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
Definition: scip.c:6022
constraint handler for quadratic constraints
SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4133
static SCIP_DECL_CONSENFOLP(consEnfolpBounddisjunction)
#define CONSHDLR_CHECKPRIORITY
#define NULL
Definition: lpi_spx1.cpp:137
#define REALABS(x)
Definition: def.h:159
#define SCIP_EVENTTYPE_UBRELAXED
Definition: type_event.h:66
SCIP_RETCODE SCIPcreateChild(SCIP *scip, SCIP_NODE **node, SCIP_Real nodeselprio, SCIP_Real estimate)
Definition: scip.c:36704
SCIP_RETCODE SCIPsetConflicthdlrFree(SCIP *scip, SCIP_CONFLICTHDLR *conflicthdlr, SCIP_DECL_CONFLICTFREE((*conflictfree)))
Definition: scip.c:6673
struct SCIP_ConflicthdlrData SCIP_CONFLICTHDLRDATA
Definition: type_conflict.h:40
#define SCIP_CALL(x)
Definition: def.h:306
#define SCIP_EVENTTYPE_LBTIGHTENED
Definition: type_event.h:63
SCIP_Bool SCIPisFeasGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46125
SCIP_Real SCIPcomputeVarUbLocal(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:23433
static SCIP_DECL_CONSPARSE(consParseBounddisjunction)
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46112
SCIP_RETCODE SCIPanalyzeConflictCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
Definition: scip.c:27097
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip.c:1353
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8120
SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
Definition: scip.c:6297
struct SCIP_ConsData SCIP_CONSDATA
Definition: type_cons.h:50
SCIP_RETCODE SCIPdisableCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:28021
SCIP_BILINTERM * SCIPgetBilinTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
#define SCIP_EVENTTYPE_BOUNDTIGHTENED
Definition: type_event.h:106
SCIP_BOUNDTYPE * SCIPgetBoundtypesBounddisjunction(SCIP *scip, SCIP_CONS *cons)
#define AGEINCREASE(n)
SCIP_RETCODE SCIPaddConsNode(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons, SCIP_NODE *validnode)
Definition: scip.c:12960
SCIP_Real SCIPgetRhsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPcreateConsSetpack(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, 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: cons_setppc.c:9034
static SCIP_RETCODE processWatchedVars(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, SCIP_Bool *cutoff, SCIP_Bool *infeasible, SCIP_Bool *reduceddom, SCIP_Bool *mustcheck)
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:21925
public data structures and miscellaneous methods
static SCIP_RETCODE conshdlrdataCreate(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata, SCIP_EVENTHDLR *eventhdlr)
#define SCIP_Bool
Definition: def.h:61
SCIP_Bool SCIPconsIsUpdatedeactivate(SCIP_CONS *cons)
Definition: cons.c:7952
#define isFeasLT(scip, var, val1, val2)
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition: event.c:959
SCIP_Bool SCIPconsIsPropagationEnabled(SCIP_CONS *cons)
Definition: cons.c:7999
static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyBounddisjunction)
int SCIPgetDepth(SCIP *scip)
Definition: scip.c:42094
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip.c:28652
static SCIP_DECL_CONSACTIVE(consActiveBounddisjunction)
SCIP_Bool SCIPstrToRealValue(const char *str, SCIP_Real *value, char **endptr)
Definition: misc.c:9411
static SCIP_RETCODE removeFixedVariables(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, SCIP_Bool *redundant)
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:7901
SCIP_RETCODE SCIPaddConflictBd(SCIP *scip, SCIP_VAR *var, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx)
Definition: scip.c:26881
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition: cons.c:8010
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8080
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:8050
SCIP_Real SCIPcomputeVarLbGlobal(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:23370
SCIP_RETCODE SCIPdropVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition: scip.c:40321
SCIP_Real SCIPbdchginfoGetNewbound(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17778
SCIP_Real SCIPcalcNodeselPriority(SCIP *scip, SCIP_VAR *var, SCIP_BRANCHDIR branchdir, SCIP_Real targetvalue)
Definition: scip.c:36654
SCIP_RETCODE SCIPaddExternBranchCand(SCIP *scip, SCIP_VAR *var, SCIP_Real score, SCIP_Real solval)
Definition: scip.c:36399
static SCIP_DECL_CONSRESPROP(consRespropBounddisjunction)
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:89
int SCIPgetNRuns(SCIP *scip)
Definition: scip.c:41099
static SCIP_RETCODE checkCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool *violated)
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip.c:21309
SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
Definition: scip.c:6435
static SCIP_DECL_CONSPRESOL(consPresolBounddisjunction)
#define SCIP_EVENTTYPE_UBTIGHTENED
Definition: type_event.h:65
Constraint handler for linear constraints in their most general form, .
SCIP_Longint SCIPgetNConflictConssApplied(SCIP *scip)
Definition: scip.c:42068
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
Definition: scip.c:45827
SCIP_RETCODE SCIPcreateConsLogicor(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, 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 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.c:22414
SCIP_Real SCIPcalcChildEstimate(SCIP *scip, SCIP_VAR *var, SCIP_Real targetvalue)
Definition: scip.c:36681
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip.c:35033
SCIP_RETCODE SCIPvarGetProbvarBound(SCIP_VAR **var, SCIP_Real *bound, SCIP_BOUNDTYPE *boundtype)
Definition: var.c:11775
static SCIP_Bool isLiteralViolated(SCIP *scip, SCIP_CONSDATA *consdata, int pos)
#define isFeasLE(scip, var, val1, val2)
static SCIP_DECL_CONSENFOPS(consEnfopsBounddisjunction)
SCIP_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPsetConshdlrExitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITPRE((*consexitpre)))
Definition: scip.c:6166
int SCIPgetNLinearVarsQuadratic(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE createNAryBranch(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:45790
static SCIP_RETCODE upgradeCons(SCIP *scip, SCIP_CONS *cons, int *ndelconss, int *naddconss)
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
Definition: scip.c:45900
#define EVENTHDLR_DESC
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.c:1911
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition: cons.c:7911
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.c:22527
static SCIP_RETCODE unlockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_CONSDATA *consdata, int pos)
SCIP_Bool SCIPisConsCompressionEnabled(SCIP *scip)
Definition: scip.c:1861
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip.c:27323
const char * SCIPconflicthdlrGetName(SCIP_CONFLICTHDLR *conflicthdlr)
Definition: conflict.c:714
SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
Definition: scip.c:6190
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16671
#define SCIP_Real
Definition: def.h:135
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8130
static SCIP_DECL_CONSPROP(consPropBounddisjunction)
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip.c:1138
SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETNVARS((*consgetnvars)))
Definition: scip.c:6504
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:8070
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8060
#define SCIP_Longint
Definition: def.h:120
static void consdataPrint(SCIP *scip, SCIP_CONSDATA *consdata, FILE *file, SCIP_Bool endline)
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:16717
SCIP_RETCODE SCIPcreateConsBounddisjunction(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_BOUNDTYPE *boundtypes, SCIP_Real *bounds, 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)
static SCIP_RETCODE consdataCreate(SCIP *scip, SCIP_CONSDATA **consdata, int nvars, SCIP_VAR **vars, SCIP_BOUNDTYPE *boundtypes, SCIP_Real *bounds)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
Definition: scip.c:45864
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:45777
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition: type_cons.h:49
#define EVENTHDLR_NAME
static SCIP_DECL_CONSCOPY(consCopyBounddisjunction)
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:17232
static SCIP_DECL_CONSEXITPRE(consExitpreBounddisjunction)
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip.h:21910
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:16694
SCIP_BOUNDTYPE SCIPbdchginfoGetBoundtype(SCIP_BDCHGINFO *bdchginfo)
Definition: var.c:17808
#define CONSHDLR_DESC
SCIP_RETCODE SCIPsetConshdlrActive(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSACTIVE((*consactive)))
Definition: scip.c:6320
SCIP_QUADVARTERM * SCIPgetQuadVarTermsQuadratic(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPaddConflict(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons, SCIP_NODE *validnode, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
Definition: scip.c:12866
static SCIP_DECL_CONFLICTFREE(conflictFreeBounddisjunction)
static SCIP_DECL_CONFLICTEXEC(conflictExecBounddisjunction)
SCIP_CONFLICTHDLRDATA * SCIPconflicthdlrGetData(SCIP_CONFLICTHDLR *conflicthdlr)
Definition: conflict.c:627
constraint handler for bound disjunction constraints
#define CONFLICTHDLR_NAME
static SCIP_DECL_CONSPRINT(consPrintBounddisjunction)
static SCIP_DECL_EVENTEXEC(eventExecBounddisjunction)
#define CONSHDLR_MAXPREROUNDS
#define SCIPABORT()
Definition: def.h:278
SCIP_Bool SCIPvarIsIntegral(SCIP_VAR *var)
Definition: var.c:16743
#define CONSHDLR_PRESOLTIMING
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip.c:38007
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip.c:4258
#define DEFAULT_CONTINUOUSFRAC
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip.c:18663
static SCIP_DECL_CONSDEACTIVE(consDeactiveBounddisjunction)
static SCIP_RETCODE switchWatchedvars(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int watchedvar1, int watchedvar2)
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:16839
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip.h:21929
SCIP_RETCODE SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
Definition: scip.c:5931
static SCIP_DECL_CONSLOCK(consLockBounddisjunction)
#define SCIP_EVENTTYPE_BOUNDRELAXED
Definition: type_event.h:107