Scippy

SCIP

Solving Constraint Integer Programs

cons_disjunction.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-2018 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_disjunction.c
17  * @brief constraint handler for disjunction constraints
18  * @author Stefan Heinz
19  * @author Michael Winkler
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 
28 #include "scip/cons_disjunction.h"
29 
30 
31 /* constraint handler properties */
32 #define CONSHDLR_NAME "disjunction"
33 #define CONSHDLR_DESC "disjunction of constraints (or(cons1, cons2, ..., consn))"
34 #define CONSHDLR_ENFOPRIORITY -950000 /**< priority of the constraint handler for constraint enforcing */
35 #define CONSHDLR_CHECKPRIORITY -900000 /**< priority of the constraint handler for checking feasibility */
36 #define CONSHDLR_PROPFREQ -1 /**< frequency for propagating domains; zero means only preprocessing propagation */
37 #define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
38  * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
39 #define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in
40  * (-1: no limit) */
41 #define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
42 #define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
43 
44 #define CONSHDLR_PRESOLTIMING SCIP_PRESOLTIMING_FAST
45 #define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP
46 
47 
48 #define DEFAULT_ALWAYSBRANCH TRUE /**< alawys perform branching if one of the constraints is violated, otherwise only if all integers are fixed */
49 
50 /*
51  * Data structures
52  */
53 
54 /** constraint data for disjunction constraints */
55 struct SCIP_ConsData
56 {
57  SCIP_CONS** conss; /**< constraints in disjunction */
58  SCIP_CONS* relaxcons; /**< a conjunction constraint containing the linear relaxation of the
59  * disjunction constraint, or NULL
60  */
61  int consssize; /**< size of conss array */
62  int nconss; /**< number of constraints in disjunction */
63 };
64 
65 /** constraint handler data */
66 struct SCIP_ConshdlrData
67 {
68  SCIP_Bool alwaysbranch; /**< alawys perform branching if one of the constraints is violated, otherwise only if all integers are fixed */
69 };
70 
71 /*
72  * Local methods
73  */
74 
75 /** creates disjunction constraint data, captures initial constraints of disjunction */
76 static
78  SCIP* scip, /**< SCIP data structure */
79  SCIP_CONSDATA** consdata, /**< pointer to constraint data */
80  SCIP_CONS** conss, /**< initial constraint in disjunction */
81  int nconss, /**< number of initial constraints in disjunction */
82  SCIP_CONS* relaxcons /**< a conjuction constraint containing the liner relaxation of the disjunction constraint, or NULL */
83  )
84 {
85  assert(scip != NULL);
86  assert(consdata != NULL);
87 
88  SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
89  if( nconss > 0 )
90  {
91  assert(conss != NULL);
92 
93  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->conss, conss, nconss) );
94 
95  (*consdata)->consssize = nconss;
96  (*consdata)->nconss = nconss;
97  (*consdata)->relaxcons = relaxcons;
98 
99  /* we need to capture the constraints to avoid that SCIP deletes them since they are not (yet) added to the
100  * problem
101  */
102  if( SCIPisTransformed(scip) )
103  {
104  SCIP_CALL( SCIPtransformConss(scip, nconss, (*consdata)->conss, (*consdata)->conss) );
105 
106  if( (*consdata)->relaxcons != NULL )
107  {
108  SCIP_CALL( SCIPtransformCons(scip, (*consdata)->relaxcons, &(*consdata)->relaxcons) );
109  }
110  }
111  else
112  {
113  int c;
114 
115  for( c = 0; c < nconss; ++c )
116  {
117  assert(conss[c] != NULL);
118  SCIP_CALL( SCIPcaptureCons(scip, conss[c]) );
119  }
120 
121  if( (*consdata)->relaxcons != NULL )
122  {
123  SCIP_CALL( SCIPcaptureCons(scip, relaxcons) );
124  }
125  }
126  }
127  else
128  {
129  (*consdata)->conss = NULL;
130  (*consdata)->consssize = 0;
131  (*consdata)->nconss = 0;
132  (*consdata)->relaxcons = NULL;
133  }
134 
135  return SCIP_OKAY;
136 }
137 
138 /** frees constraint data and releases all constraints in disjunction */
139 static
141  SCIP* scip, /**< SCIP data structure */
142  SCIP_CONSDATA** consdata /**< pointer to constraint data */
143  )
144 {
145  int c;
146 
147  assert(scip != NULL);
148  assert(consdata != NULL);
149  assert(*consdata != NULL);
150 
151  /* release constraints */
152  for( c = 0; c < (*consdata)->nconss; ++c )
153  {
154  SCIP_CALL( SCIPreleaseCons(scip, &(*consdata)->conss[c]) );
155  }
156 
157  /* release relaxation constraint */
158  if( (*consdata)->relaxcons != NULL )
159  {
160  SCIP_CALL( SCIPreleaseCons(scip, &(*consdata)->relaxcons) );
161  }
162 
163  /* free memory */
164  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->conss, (*consdata)->consssize);
165  SCIPfreeBlockMemory(scip, consdata);
166 
167  return SCIP_OKAY;
168 }
169 
170 /** adds constraint to disjunction */
171 static
173  SCIP* scip, /**< SCIP data structure */
174  SCIP_CONSDATA* consdata, /**< constraint data */
175  SCIP_CONS* cons /**< constraint to add to the disjunction */
176  )
177 {
178  assert(scip != NULL);
179  assert(consdata != NULL);
180  assert(cons != NULL);
181 
182  /* get memory for additional constraint */
183  SCIP_CALL( SCIPensureBlockMemoryArray(scip, &consdata->conss, &consdata->consssize, consdata->nconss+1) );
184  assert(consdata->conss != NULL);
185  assert(consdata->nconss < consdata->consssize);
186 
187  /* insert constraint in array */
188  consdata->conss[consdata->nconss] = cons;
189  consdata->nconss++;
190 
191  if( SCIPisTransformed(scip) )
192  {
193  SCIP_CALL( SCIPtransformCons(scip, consdata->conss[consdata->nconss - 1], &(consdata->conss[consdata->nconss - 1])));
194  }
195  else
196  {
197  /* capture constraint */
198  SCIP_CALL( SCIPcaptureCons(scip, cons) );
199  }
200 
201  return SCIP_OKAY;
202 }
203 
204 /** branches on disjunctive constraint */
205 static
207  SCIP* scip, /**< SCIP data structure */
208  SCIP_CONS* cons, /**< active disjunction constraint */
209  SCIP_RESULT* result /**< pointer to store the result */
210  )
211 {
212  SCIP_CONSDATA* consdata;
213  SCIP_CONS** conss;
214  SCIP_NODE* child;
215  SCIP_Real estimate;
216  int nconss;
217  int i;
218 
219  assert(result != NULL);
220 
221  /* cannot branch on modifiable constraint */
222  if( SCIPconsIsModifiable(cons) )
223  return SCIP_OKAY;
224 
225  consdata = SCIPconsGetData(cons);
226  assert(consdata != NULL);
227 
228  conss = consdata->conss;
229  assert(conss != NULL);
230 
231  nconss = consdata->nconss;
232  assert(nconss > 0);
233 
234  estimate = SCIPgetLocalTransEstimate(scip);
235 
236  /* add all inactive constraints to local subproblem */
237  for( i = 0; i < nconss; ++i )
238  {
239  /* create the branch-and-bound tree child nodes of the current node */
240  SCIP_CALL( SCIPcreateChild(scip, &child, 0.0, estimate) );
241 
242  /* if disjunctive constraint needs to be checked, the upgraded constraint also needs to be checked */
243  if( SCIPconsIsChecked(cons) )
244  {
245  SCIP_CALL( SCIPsetConsChecked(scip, conss[i], TRUE) );
246  }
247 
248  /* add constraints to nodes */
249  SCIP_CALL( SCIPaddConsNode(scip, child, conss[i], NULL) );
250 
251  /* remove disjunction constraint, from child node */
252  SCIP_CALL( SCIPdelConsNode(scip, child, cons) );
253  }
254 
255  SCIPdebugMsg(scip, "disjunction constraint <%s> branched %d childs\n", SCIPconsGetName(cons), nconss);
256 
257  /* reset constraint age */
258  SCIP_CALL( SCIPresetConsAge(scip, cons) );
259 
260  *result = SCIP_BRANCHED;
261 
262  return SCIP_OKAY;
263 }
264 
265 /** checks disjunction constraints if at least one is feasible */
266 static
268  SCIP* scip, /**< SCIP data structure */
269  SCIP_CONS* cons, /**< active disjunction constraint */
270  SCIP_SOL* sol, /**< solution to check */
271  SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
272  SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
273  SCIP_Bool printreason, /**< Should the reason for the violation be printed? */
274  SCIP_RESULT* result /**< pointer to store the result */
275  )
276 {
277  SCIP_CONSDATA* consdata;
278  SCIP_CONS** conss;
279  int nconss;
280  int i;
281 
282  assert(result != NULL);
283 
284  consdata = SCIPconsGetData(cons);
285  assert(consdata != NULL);
286 
287  conss = consdata->conss;
288  assert(conss != NULL);
289 
290  nconss = consdata->nconss;
291  assert(nconss > 0);
292 
293  *result = SCIP_INFEASIBLE;
294 
296 
297  /* check all constraints */
298  for( i = 0; i < nconss && *result != SCIP_FEASIBLE; ++i )
299  {
300  SCIP_CALL( SCIPcheckCons(scip, conss[i], sol, checkintegrality, checklprows, FALSE, result) );
301  assert(*result == SCIP_FEASIBLE || *result == SCIP_INFEASIBLE);
302  }
303 
305 
306  if( *result == SCIP_INFEASIBLE )
307  {
308  if( sol != NULL )
309  SCIPupdateSolConsViolation(scip, sol, 1.0, 1.0);
310 
311  if( printreason )
312  {
313  SCIPinfoMessage(scip, NULL, "constraint %s is violated, all sub-constraints in this disjunction are violated by this given solution\n", SCIPconsGetName(cons));
314  SCIPdebug( SCIP_CALL( SCIPprintCons(scip, cons, NULL) ) );
315  }
316  }
317 
318  return SCIP_OKAY;
319 }
320 
321 /** propagation method for disjunction constraint */
322 static
324  SCIP* scip, /**< SCIP data structure */
325  SCIP_CONS* cons, /**< disjunctive constraint */
326  int* ndelconss /**< pointer to count number of deleted constraints */
327  )
328 {
329  SCIP_CONSDATA* consdata;
330  SCIP_CONS** conss;
331  int nconss;
332  int c;
333 
334  assert(scip != NULL);
335  assert(cons != NULL);
336  assert(ndelconss != NULL);
337 
338  consdata = SCIPconsGetData(cons);
339  assert(consdata != NULL);
340 
341  conss = consdata->conss;
342  assert(conss != NULL);
343 
344  nconss = consdata->nconss;
345  assert(nconss >= 1);
346 
347  for( c = 0; c < nconss; ++c )
348  {
349  /* if a constraint of the disjunction is already active, the disjunction is enforce by this constraint and
350  * therefore redundant and can be locally deleted
351  */
352  if( SCIPconsIsActive(conss[c]) )
353  {
354  /* if we can globally delete the whole disjunctive constraint, because one constraint is already active, we
355  * might need to update the check stage
356  */
357  if( SCIPgetStage(scip) == SCIP_STAGE_PRESOLVING || SCIPgetNNodes(scip) == 0 )
358  {
359  /* if disjunctive constraint needs to be checked, the upgraded constraint also needs to be checked */
360  if( SCIPconsIsChecked(cons) )
361  {
362  SCIP_CALL( SCIPsetConsChecked(scip, conss[c], TRUE) );
363  }
364  }
365 
366  (*ndelconss)++;
367  SCIP_CALL( SCIPdelConsLocal(scip, cons) );
368  break;
369  }
370  /* if a sub-constraint is globally deleted, it means that this constraint is redundant and always fulfilled and
371  * this makes also this disjunction redundant
372  */
373  else if( SCIPconsIsDeleted(conss[c]) )
374  {
375  (*ndelconss)++;
376  SCIP_CALL( SCIPdelCons(scip, cons) );
377  break;
378  }
379  }
380 
381  return SCIP_OKAY;
382 }
383 
384 /** helper function to enforce constraints */
385 static
387  SCIP* scip, /**< SCIP data structure */
388  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
389  SCIP_CONS** conss, /**< constraints to process */
390  int nconss, /**< number of constraints */
391  SCIP_RESULT* result /**< pointer to store the result of the enforcing call */
392  )
393 {
394  SCIP_CONSHDLRDATA* conshdlrdata;
396  int c;
397 
398  *result = SCIP_FEASIBLE;
399 
400  conshdlrdata = SCIPconshdlrGetData(conshdlr);
401  assert(conshdlrdata != NULL);
402 
403  branch = SCIPgetNPseudoBranchCands(scip) == 0 || conshdlrdata->alwaysbranch;
404 
405  for( c = 0; c < nconss && *result != SCIP_BRANCHED; ++c )
406  {
407  /* check the disjunction */
408  SCIP_CALL( checkCons(scip, conss[c], NULL, FALSE, FALSE, FALSE, result) );
409 
410  if( *result == SCIP_INFEASIBLE && branch )
411  {
412  SCIP_CALL( branchCons(scip, conss[c], result) );
413  }
414  }
415 
416  return SCIP_OKAY;
417 }
418 
419 /*
420  * Callback methods of constraint handler
421  */
422 
423 /** copy method for constraint handler plugins (called when SCIP copies plugins) */
424 static
425 SCIP_DECL_CONSHDLRCOPY(conshdlrCopyDisjunction)
426 { /*lint --e{715}*/
427  assert(scip != NULL);
428  assert(conshdlr != NULL);
429  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
430 
431  /* call inclusion method of constraint handler */
433 
434  *valid = TRUE;
435 
436  return SCIP_OKAY;
437 }
438 
439 /** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
440 static
441 SCIP_DECL_CONSFREE(consFreeDisjunction)
442 {
443  SCIP_CONSHDLRDATA* conshdlrdata;
444 
445  assert(scip != NULL);
446  assert(conshdlr != NULL);
447  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
448 
449  /* free constraint handler data */
450  conshdlrdata = SCIPconshdlrGetData(conshdlr);
451  assert(conshdlrdata != NULL);
452 
453  SCIPfreeBlockMemory(scip, &conshdlrdata);
454 
455  SCIPconshdlrSetData(conshdlr, NULL);
456 
457  return SCIP_OKAY;
458 }
459 
460 /** frees specific constraint data */
461 static
462 SCIP_DECL_CONSDELETE(consDeleteDisjunction)
463 { /*lint --e{715}*/
464  SCIP_CALL( consdataFree(scip, consdata) );
465 
466  return SCIP_OKAY;
467 }
468 
469 
470 /** transforms constraint data into data belonging to the transformed problem */
471 static
472 SCIP_DECL_CONSTRANS(consTransDisjunction)
473 { /*lint --e{715}*/
474  SCIP_CONSDATA* sourcedata;
475  SCIP_CONSDATA* targetdata;
476 
477  /* get constraint data of source constraint */
478  sourcedata = SCIPconsGetData(sourcecons);
479  assert(sourcedata != NULL);
480 
481  SCIP_CALL( consdataCreate(scip, &targetdata, sourcedata->conss, sourcedata->nconss, sourcedata->relaxcons) );
482 
483  /* create target constraint */
484  SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
485  SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
486  SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
487  SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
488  SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
489 
490  return SCIP_OKAY;
491 }
492 
493 /** LP initialization method of constraint handler */
494 static
495 SCIP_DECL_CONSINITLP(consInitlpDisjunction)
496 { /*lint --e{715}*/
497  SCIP_CONSDATA* consdata;
498  int c;
499 
500  *infeasible = FALSE;
501 
502  for( c = 0; c < nconss; ++c )
503  {
504  consdata = SCIPconsGetData(conss[c]);
505  assert(consdata != NULL);
506 
507  /* if we have a relaxation constraint and it is not active, then we add it locally */
508  if( consdata->relaxcons != NULL && !SCIPconsIsActive(consdata->relaxcons) )
509  {
510  SCIP_CALL( SCIPaddConsLocal(scip, consdata->relaxcons, NULL) );
511  }
512  }
513 
514  return SCIP_OKAY;
515 }
516 
517 
518 /** constraint enforcing method of constraint handler for LP solutions */
519 static
520 SCIP_DECL_CONSENFOLP(consEnfolpDisjunction)
521 { /*lint --e{715}*/
522  SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, result) );
523 
524  return SCIP_OKAY;
525 }
526 
527 
528 /** constraint enforcing method of constraint handler for relaxation solutions */
529 static
530 SCIP_DECL_CONSENFORELAX(consEnforelaxDisjunction)
531 { /*lint --e{715}*/
532  SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, result) );
533 
534  return SCIP_OKAY;
535 }
536 
537 
538 /** constraint enforcing method of constraint handler for pseudo solutions */
539 static
540 SCIP_DECL_CONSENFOPS(consEnfopsDisjunction)
541 { /*lint --e{715}*/
542  SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, result) );
543 
544  return SCIP_OKAY;
545 }
546 
547 
548 /** feasibility check method of constraint handler for integral solutions */
549 static
550 SCIP_DECL_CONSCHECK(consCheckDisjunction)
551 { /*lint --e{715}*/
552  int c;
553 
554  *result = SCIP_FEASIBLE;
555 
556  for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
557  {
558  SCIP_RESULT tmpres;
559 
560  /* check the disjunction */
561  SCIP_CALL( checkCons(scip, conss[c], sol, checkintegrality, checklprows, printreason, &tmpres) );
562  assert(tmpres == SCIP_FEASIBLE || tmpres == SCIP_INFEASIBLE);
563 
564  if( tmpres == SCIP_INFEASIBLE )
565  *result = SCIP_INFEASIBLE;
566  }
567 
568  return SCIP_OKAY;
569 }
570 
571 
572 /** domain propagation method of constraint handler */
573 static
574 SCIP_DECL_CONSPROP(consPropDisjunction)
575 { /*lint --e{715}*/
576  int ndelconss;
577  int c;
578 
579  ndelconss = 0;
580 
581  /* in probing mode we do not for deletable constraints */
582  if( !SCIPinProbing(scip) )
583  {
584  for( c = 0; c < nconss; ++c )
585  {
586  /* propagate constraint */
587  SCIP_CALL( propagateCons(scip, conss[c], &ndelconss) );
588  }
589  }
590 
591  /* adjust result code */
592  if( ndelconss > 0 )
593  *result = SCIP_REDUCEDDOM;
594  else
595  *result = SCIP_DIDNOTFIND;
596 
597  return SCIP_OKAY;
598 }
599 
600 
601 /** presolving method of constraint handler */
602 static
603 SCIP_DECL_CONSPRESOL(consPresolDisjunction)
604 { /*lint --e{715}*/
605  SCIP_CONSDATA* consdata;
606  int oldndelconss;
607  int c;
608 
609  assert(result != NULL);
610 
611  *result = SCIP_DIDNOTFIND;
612  oldndelconss = *ndelconss;
613 
614  /* all disjunction constraints with one constraint can be replaced with that corresponding constraint */
615  for( c = 0; c < nconss; ++c )
616  {
617  consdata = SCIPconsGetData(conss[c]);
618  assert(consdata != NULL);
619 
620  if( !SCIPconsIsModifiable(conss[c]) && consdata->nconss == 1 )
621  {
622  /* add constraint to the problem */
623  if( !SCIPconsIsActive(consdata->conss[0]) )
624  {
625  SCIP_CONS* subcons = consdata->conss[0];
626 
627  /* if disjunctive constraint needs to be checked, the upgraded constraint also needs to be checked */
628  if( SCIPconsIsChecked(conss[c]) )
629  {
630  SCIP_CALL( SCIPsetConsChecked(scip, subcons, TRUE) );
631  }
632 
633  SCIP_CALL( SCIPaddCons(scip, subcons) );
634  }
635 
636  /* remove disjunction constraint */
637  SCIP_CALL( SCIPdelCons(scip, conss[c]) );
638 
639  *result = SCIP_SUCCESS;
640 
641  continue;
642  }
643 
644  /* propagate constraint */
645  SCIP_CALL( propagateCons(scip, conss[c], ndelconss) );
646  }
647 
648  if( *ndelconss > oldndelconss )
649  *result = SCIP_SUCCESS;
650 
651  return SCIP_OKAY;
652 }
653 
654 
655 /** variable rounding lock method of constraint handler */
656 static
657 SCIP_DECL_CONSLOCK(consLockDisjunction)
658 { /*lint --e{715}*/
659  SCIP_CONSDATA* consdata;
660  int c;
661 
662  consdata = SCIPconsGetData(cons);
663  assert(consdata != NULL);
664 
665  /* lock sub constraints */
666  for( c = 0; c < consdata->nconss; ++c )
667  {
668  SCIP_CALL( SCIPaddConsLocks(scip, consdata->conss[c], nlockspos, nlocksneg) );
669  }
670 
671  return SCIP_OKAY;
672 }
673 
674 
675 /** constraint display method of constraint handler */
676 static
677 SCIP_DECL_CONSPRINT(consPrintDisjunction)
678 { /*lint --e{715}*/
679  SCIP_CONSDATA* consdata;
680  int i;
681 
682  assert(scip != NULL);
683  assert(conshdlr != NULL);
684  assert(cons != NULL);
685 
686  consdata = SCIPconsGetData(cons);
687  assert(consdata != NULL);
688 
689  SCIPinfoMessage(scip, file, "disjunction(");
690 
691  for( i = 0; i < consdata->nconss; ++i )
692  {
693  if( i > 0 )
694  SCIPinfoMessage(scip, file, ", ");
695  SCIP_CALL( SCIPprintCons(scip, consdata->conss[i], file) );
696  }
697 
698  /* print relaxation */
699  if( consdata->relaxcons != NULL )
700  {
701  SCIPinfoMessage(scip, file, ",, ");
702  SCIP_CALL( SCIPprintCons(scip, consdata->relaxcons, file) );
703  }
704 
705  SCIPinfoMessage(scip, file, ")");
706 
707  return SCIP_OKAY;
708 }
709 
710 /** constraint parsing method of constraint handler */
711 static
712 SCIP_DECL_CONSPARSE(consParseDisjunction)
713 { /*lint --e{715}*/
714  SCIP_CONS** conss;
715  SCIP_Bool relaxed = FALSE;
716  int nconss;
717  int sconss;
718  char* token;
719  char* saveptr;
720  char* nexttokenstart;
721  char* copystr;
722 
723  assert(scip != NULL);
724  assert(conshdlr != NULL);
725  assert(cons != NULL);
726  assert(success != NULL);
727  assert(str != NULL);
728  assert(name != NULL);
729 
730  SCIPdebugMsg(scip, "parsing disjunction <%s>\n", name);
731 
732  *success = TRUE;
733 
734  /* allocate memory for constraint in disjunction, initial size is set to 10 */
735  nconss = 0;
736  sconss = 10;
737  SCIP_CALL( SCIPallocBufferArray(scip, &conss, sconss) );
738  SCIP_CALL( SCIPduplicateBufferArray(scip, &copystr, str, (int)strlen(str)+1) );
739 
740  /* find '(' at the beginning, string should start with 'disjunction(' */
741  saveptr = strpbrk(copystr, "("); /*lint !e158*/
742 
743  if( saveptr == NULL )
744  {
745  SCIPdebugMsg(scip, "error parsing disjunctive constraint: \"%s\"\n", str);
746  *success = FALSE;
747  goto TERMINATE;
748  }
749 
750  /* skip '(' */
751  ++saveptr;
752  /* remember token start position */
753  nexttokenstart = saveptr;
754 
755  /* brackets '(' and ')' can exist co we check for them and the constraint delimeter */
756  saveptr = strpbrk(saveptr, "(,");
757 
758  /* brackets '(' and ')' can exist in the rest of the string so we need to skip them to find the end of the first
759  * sub-constraint marked by a ','
760  */
761  if( saveptr != NULL )
762  {
763  do
764  {
765  int bracketcounter = 0;
766 
767  if( *saveptr == '(' )
768  {
769  do
770  {
771  ++bracketcounter;
772  ++saveptr;
773 
774  /* find last ending bracket */
775  while( bracketcounter > 0 )
776  {
777  saveptr = strpbrk(saveptr, "()");
778 
779  if( saveptr != NULL )
780  {
781  if( *saveptr == '(' )
782  ++bracketcounter;
783  else
784  --bracketcounter;
785 
786  ++saveptr;
787  }
788  else
789  {
790  SCIPdebugMsg(scip, "error parsing disjunctive constraint: \"%s\"\n", str);
791  *success = FALSE;
792  goto TERMINATE;
793  }
794  }
795 
796  saveptr = strpbrk(saveptr, "(,");
797  }
798  while( saveptr != NULL && *saveptr == '(' );
799  }
800 
801  /* we found a ',' so the end of the first sub-constraint is determined */
802  if( saveptr != NULL )
803  {
804  assert(*saveptr == ',');
805 
806  /* resize constraint array if necessary */
807  if( nconss == sconss )
808  {
809  sconss = SCIPcalcMemGrowSize(scip, nconss+1);
810  assert(nconss < sconss);
811 
812  SCIP_CALL( SCIPreallocBufferArray(scip, &conss, sconss) );
813  }
814 
815  assert(saveptr > nexttokenstart);
816 
817  /* extract token for parsing */
818  SCIP_CALL( SCIPduplicateBufferArray(scip, &token, nexttokenstart, saveptr - nexttokenstart + 1) );
819  token[saveptr - nexttokenstart] = '\0';
820 
821  SCIPdebugMsg(scip, "disjunctive parsing token(constraint): %s\n", token);
822 
823  /* parsing a constraint, part of the disjunction */
824  SCIP_CALL( SCIPparseCons(scip, &(conss[nconss]), token, initial, separate, enforce, FALSE, propagate, TRUE, modifiable, dynamic, removable, stickingatnode, success) );
825 
826  SCIPfreeBufferArray(scip, &token);
827 
828  if( *success )
829  ++nconss;
830  else
831  {
832  SCIPdebugMsg(scip, "error parsing disjunctive constraint: \"%s\"\n", str);
833  goto TERMINATE;
834  }
835  /* skip ',' delimeter */
836  ++saveptr;
837  /* remember token start position */
838  nexttokenstart = saveptr;
839 
840  /* check if we found the last constraint, which is a conjunctive relaxation of the disjunction, and in the
841  * CIP format marked by two consecutive ','
842  */
843  if( *nexttokenstart == ',' )
844  {
845  /* remember token start position */
846  nexttokenstart = saveptr+1;
847 
848  relaxed = TRUE;
849  break;
850  }
851 
852  saveptr = strpbrk(saveptr, "(,");
853  }
854  }
855  while( saveptr != NULL );
856  }
857 
858  /* find end of disjunction constraint */
859  saveptr = strrchr(nexttokenstart, ')');
860 
861  if( saveptr == NULL )
862  {
863  SCIPdebugMsg(scip, "error parsing disjunctive constraint: \"%s\"\n", str);
864  *success = FALSE;
865  goto TERMINATE;
866  }
867  /* parse last sub-constraint */
868  else
869  {
870  /* resize constraint array if necessary */
871  if( nconss == sconss )
872  {
873  ++sconss;
874  SCIP_CALL( SCIPreallocBufferArray(scip, &conss, sconss) );
875  }
876 
877  assert(saveptr > nexttokenstart);
878 
879  /* extract token for parsing */
880  SCIP_CALL( SCIPduplicateBufferArray(scip, &token, nexttokenstart, saveptr - nexttokenstart + 1) );
881  token[saveptr - nexttokenstart] = '\0';
882 
883  SCIPdebugMsg(scip, "disjunctive parsing token(constraint): %s\n", token);
884 
885  /* parsing a constraint, part of the disjunction */
886  SCIP_CALL( SCIPparseCons(scip, &(conss[nconss]), token, initial, separate, enforce, FALSE, propagate, TRUE, modifiable, dynamic, removable, stickingatnode, success) );
887 
888  if( *success )
889  ++nconss;
890 
891  SCIPfreeBufferArray(scip, &token);
892  }
893  assert(nconss > 0 || !(*success));
894 
895  /* if parsing sub-constraints was fine, create the disjunctive constraint */
896  if( *success )
897  {
898  /* create disjunctive constraint */
899  SCIP_CALL( SCIPcreateConsDisjunction(scip, cons, name, relaxed ? nconss - 1: nconss, conss, relaxed ? conss[nconss - 1] : NULL,
900  initial, enforce, check, local, modifiable, dynamic) );
901  }
902 
903  /* free parsed constraints */
904  for( --nconss; nconss >= 0; --nconss )
905  {
906  SCIP_CALL( SCIPreleaseCons(scip, &conss[nconss]) );
907  }
908 
909  TERMINATE:
910  /* free temporary memory */
911  SCIPfreeBufferArray(scip, &copystr);
912  SCIPfreeBufferArray(scip, &conss);
913 
914  return SCIP_OKAY;
915 }
916 
917 
918 /** constraint copying method of constraint handler */
919 static
920 SCIP_DECL_CONSCOPY(consCopyDisjunction)
921 { /*lint --e{715}*/
922  SCIP_CONSDATA* sourcedata;
923  SCIP_CONS** sourceconss;
924  SCIP_CONS** conss;
925  int nconss;
926  int c;
927 
928  *valid = TRUE;
929 
930  sourcedata = SCIPconsGetData(sourcecons);
931  assert(sourcedata != NULL);
932 
933  nconss = sourcedata->nconss;
934 
935  SCIP_CALL( SCIPallocBufferArray(scip, &conss, nconss) );
936  sourceconss = sourcedata->conss;
937 
938  /* copy each constraint one by one */
939  for( c = 0; c < nconss && (*valid); ++c )
940  {
941  SCIP_CALL( SCIPgetConsCopy(sourcescip, scip, sourceconss[c], &conss[c], SCIPconsGetHdlr(sourceconss[c]),
942  varmap, consmap, SCIPconsGetName(sourceconss[c]),
943  SCIPconsIsInitial(sourceconss[c]), SCIPconsIsSeparated(sourceconss[c]), SCIPconsIsEnforced(sourceconss[c]),
944  SCIPconsIsChecked(sourceconss[c]), SCIPconsIsPropagated(sourceconss[c]),
945  SCIPconsIsLocal(sourceconss[c]), SCIPconsIsModifiable(sourceconss[c]),
946  SCIPconsIsDynamic(sourceconss[c]), SCIPconsIsRemovable(sourceconss[c]), SCIPconsIsStickingAtNode(sourceconss[c]),
947  global, valid) );
948  assert(!(*valid) || conss[c] != NULL);
949  }
950 
951  if( *valid )
952  {
953  SCIP_CONS* sourcerelaxcons;
954  SCIP_CONS* targetrelaxcons;
955 
956  sourcerelaxcons = sourcedata->relaxcons;
957  targetrelaxcons = NULL;
958 
959  if( sourcerelaxcons != NULL )
960  {
961  SCIP_CALL( SCIPgetConsCopy(sourcescip, scip, sourcerelaxcons, &targetrelaxcons, SCIPconsGetHdlr(sourcerelaxcons),
962  varmap, consmap, SCIPconsGetName(sourcerelaxcons),
963  SCIPconsIsInitial(sourcerelaxcons), SCIPconsIsSeparated(sourcerelaxcons), SCIPconsIsEnforced(sourcerelaxcons),
964  SCIPconsIsChecked(sourcerelaxcons), SCIPconsIsPropagated(sourcerelaxcons),
965  SCIPconsIsLocal(sourcerelaxcons), SCIPconsIsModifiable(sourcerelaxcons),
966  SCIPconsIsDynamic(sourcerelaxcons), SCIPconsIsRemovable(sourcerelaxcons),
967  SCIPconsIsStickingAtNode(sourcerelaxcons),
968  global, valid) );
969  }
970 
971  if( *valid )
972  {
973  if( name == NULL )
974  {
975  SCIP_CALL( SCIPcreateConsDisjunction(scip, cons, SCIPconsGetName(sourcecons), nconss, conss, targetrelaxcons,
976  initial, enforce, check, local, modifiable, dynamic) );
977  }
978  else
979  {
980  SCIP_CALL( SCIPcreateConsDisjunction(scip, cons, name, nconss, conss, targetrelaxcons,
981  initial, enforce, check, local, modifiable, dynamic) );
982  }
983 
984  if( targetrelaxcons != NULL )
985  {
986  SCIP_CALL( SCIPreleaseCons(scip, &targetrelaxcons) );
987  }
988  }
989  }
990 
991  /* release the copied constraints */
992  for( c = (*valid ? c - 1 : c - 2); c >= 0; --c )
993  {
994  assert(conss[c] != NULL);
995  SCIP_CALL( SCIPreleaseCons(scip, &conss[c]) );
996  }
997 
998  SCIPfreeBufferArray(scip, &conss);
999 
1000  return SCIP_OKAY;
1001 }
1002 
1003 
1004 /*
1005  * constraint specific interface methods
1006  */
1007 
1008 /** creates the handler for disjunction constraints and includes it in SCIP */
1010  SCIP* scip /**< SCIP data structure */
1011  )
1012 {
1013  SCIP_CONSHDLRDATA* conshdlrdata;
1014  SCIP_CONSHDLR* conshdlr;
1015 
1016  /* create disjunction constraint handler data */
1017  SCIP_CALL( SCIPallocBlockMemory(scip, &conshdlrdata) );
1018 
1019  /* include constraint handler */
1022  consEnfolpDisjunction, consEnfopsDisjunction, consCheckDisjunction, consLockDisjunction,
1023  conshdlrdata) );
1024 
1025  assert(conshdlr != NULL);
1026 
1027  /* set non-fundamental callbacks via specific setter functions */
1028  SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyDisjunction, consCopyDisjunction) );
1029  SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeDisjunction) );
1030  SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteDisjunction) );
1031  SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpDisjunction) );
1032  SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseDisjunction) );
1033  SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolDisjunction, CONSHDLR_MAXPREROUNDS,
1035  SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintDisjunction) );
1036  SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropDisjunction, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP,
1038  SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransDisjunction) );
1039  SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxDisjunction) );
1040 
1042  "constraints/" CONSHDLR_NAME "/alwaysbranch",
1043  "alawys perform branching if one of the constraints is violated, otherwise only if all integers are fixed",
1044  &conshdlrdata->alwaysbranch, FALSE, DEFAULT_ALWAYSBRANCH, NULL, NULL) );
1045 
1046  return SCIP_OKAY;
1047 }
1048 
1049 /** creates and captures a disjunction constraint
1050  *
1051  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
1052  */
1054  SCIP* scip, /**< SCIP data structure */
1055  SCIP_CONS** cons, /**< pointer to hold the created constraint */
1056  const char* name, /**< name of constraint */
1057  int nconss, /**< number of initial constraints in disjunction */
1058  SCIP_CONS** conss, /**< initial constraint in disjunction */
1059  SCIP_CONS* relaxcons, /**< a conjunction constraint containing the linear relaxation of the disjunction constraint, or NULL */
1060  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
1061  * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
1062  SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
1063  * TRUE for model constraints, FALSE for additional, redundant constraints. */
1064  SCIP_Bool check, /**< should the constraint be checked for feasibility?
1065  * TRUE for model constraints, FALSE for additional, redundant constraints. */
1066  SCIP_Bool local, /**< is constraint only valid locally?
1067  * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
1068  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
1069  * Usually set to FALSE. In column generation applications, set to TRUE if pricing
1070  * adds coefficients to this constraint. */
1071  SCIP_Bool dynamic /**< is constraint subject to aging?
1072  * Usually set to FALSE. Set to TRUE for own cuts which
1073  * are separated as constraints. */
1074  )
1075 {
1076  SCIP_CONSHDLR* conshdlr;
1077  SCIP_CONSDATA* consdata;
1078 
1079  /* find the disjunction constraint handler */
1080  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
1081  if( conshdlr == NULL )
1082  {
1083  SCIPerrorMessage("disjunction constraint handler not found\n");
1084  return SCIP_PLUGINNOTFOUND;
1085  }
1086 
1087  /* create constraint data */
1088  SCIP_CALL( consdataCreate(scip, &consdata, conss, nconss, relaxcons) );
1089 
1090  /* create constraint */
1091  SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, FALSE, enforce, check, FALSE,
1092  local, modifiable, dynamic, FALSE, FALSE) );
1093 
1094  return SCIP_OKAY;
1095 }
1096 
1097 /** creates and captures a cumulative constraint
1098  * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
1099  * method SCIPcreateConsDisjunction(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
1100  *
1101  * @see SCIPcreateConsDisjunction() for information about the basic constraint flag configuration
1102  *
1103  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
1104  */
1106  SCIP* scip, /**< SCIP data structure */
1107  SCIP_CONS** cons, /**< pointer to hold the created constraint */
1108  const char* name, /**< name of constraint */
1109  int nconss, /**< number of initial constraints in disjunction */
1110  SCIP_CONS** conss, /**< initial constraint in disjunction */
1111  SCIP_CONS* relaxcons /**< a conjunction constraint containing the linear relaxation of the disjunction constraint, or NULL */
1112  )
1113 {
1114  assert(scip != NULL);
1115 
1116  SCIP_CALL( SCIPcreateConsDisjunction(scip, cons, name, nconss, conss, relaxcons,
1117  TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
1118 
1119  return SCIP_OKAY;
1120 }
1121 
1122 
1123 /** adds constraint to the disjunction of constraints */
1125  SCIP* scip, /**< SCIP data structure */
1126  SCIP_CONS* cons, /**< disjunction constraint */
1127  SCIP_CONS* addcons /**< additional constraint in disjunction */
1128  )
1129 {
1130  SCIP_CONSDATA* consdata;
1131 
1132  assert(cons != NULL);
1133  assert(addcons != NULL);
1134 
1135  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
1136  {
1137  SCIPerrorMessage("constraint is not a disjunction constraint\n");
1138  return SCIP_INVALIDDATA;
1139  }
1140 
1141  consdata = SCIPconsGetData(cons);
1142  assert(consdata != NULL);
1143 
1144  SCIP_CALL( consdataAddCons(scip, consdata, addcons) );
1145 
1146  return SCIP_OKAY;
1147 
1148 }
1149 
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
Definition: cons.c:4143
constraint handler for disjunction constraints
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
Definition: scip.c:6291
#define CONSHDLR_NAME
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip.c:821
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:8245
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
Definition: scip.c:6314
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip.c:6604
static SCIP_DECL_CONSCOPY(consCopyDisjunction)
SCIP_Real SCIPgetLocalTransEstimate(SCIP *scip)
Definition: scip.c:13369
SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
Definition: scip.c:6036
SCIP_RETCODE SCIPresetConsAge(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:28400
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:12663
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip.c:46813
static SCIP_DECL_CONSPROP(consPropDisjunction)
#define CONSHDLR_ENFOPRIORITY
int SCIPgetNPseudoBranchCands(SCIP *scip)
Definition: scip.c:37365
void SCIPdeactivateSolViolationUpdates(SCIP *scip)
Definition: scip.c:13822
SCIP_RETCODE SCIPdelConsNode(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons)
Definition: scip.c:13247
#define CONSHDLR_PROPFREQ
SCIP_RETCODE SCIPtransformConss(SCIP *scip, int nconss, SCIP_CONS **conss, SCIP_CONS **transconss)
Definition: scip.c:28213
#define FALSE
Definition: def.h:64
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:5894
SCIP_RETCODE SCIPparseCons(SCIP *scip, SCIP_CONS **cons, const char *str, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode, SCIP_Bool *success)
Definition: scip.c:27668
#define TRUE
Definition: def.h:63
#define SCIPdebug(x)
Definition: pub_message.h:74
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition: cons.c:8265
static SCIP_DECL_CONSCHECK(consCheckDisjunction)
static SCIP_DECL_CONSPARSE(consParseDisjunction)
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip.h:22602
#define CONSHDLR_EAGERFREQ
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip.h:22628
static SCIP_DECL_CONSENFORELAX(consEnforelaxDisjunction)
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:22632
static SCIP_DECL_CONSENFOLP(consEnfolpDisjunction)
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip.h:22585
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip.c:1017
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:8255
SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
Definition: scip.c:6337
#define SCIPdebugMsg
Definition: scip.h:455
SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
Definition: scip.c:6521
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition: cons.c:8047
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip.c:1343
static SCIP_RETCODE enforceConstraint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss, SCIP_RESULT *result)
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:27584
static SCIP_DECL_CONSFREE(consFreeDisjunction)
#define CONSHDLR_DESC
#define CONSHDLR_PROP_TIMING
static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata)
static SCIP_DECL_CONSPRINT(consPrintDisjunction)
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip.h:22599
#define CONSHDLR_PRESOLTIMING
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
Definition: scip.c:6060
#define SCIPerrorMessage
Definition: pub_message.h:45
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4113
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:12591
static SCIP_RETCODE consdataAddCons(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_CONS *cons)
SCIP_RETCODE SCIPaddConsLocal(SCIP *scip, SCIP_CONS *cons, SCIP_NODE *validnode)
Definition: scip.c:13216
SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:13297
static SCIP_DECL_CONSLOCK(consLockDisjunction)
SCIP_RETCODE SCIPcheckCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_RESULT *result)
Definition: scip.c:28690
SCIP_RETCODE SCIPsetConsChecked(SCIP *scip, SCIP_CONS *cons, SCIP_Bool check)
Definition: scip.c:27934
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:7986
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:8205
static SCIP_RETCODE branch(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_RESULT *result)
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
Definition: scip.c:6085
SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4133
SCIP_RETCODE SCIPcreateConsBasicDisjunction(SCIP *scip, SCIP_CONS **cons, const char *name, int nconss, SCIP_CONS **conss, SCIP_CONS *relaxcons)
SCIP_RETCODE SCIPtransformCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **transcons)
Definition: scip.c:28172
SCIP_RETCODE SCIPcreateChild(SCIP *scip, SCIP_NODE **node, SCIP_Real nodeselprio, SCIP_Real estimate)
Definition: scip.c:37577
#define SCIP_CALL(x)
Definition: def.h:350
static SCIP_DECL_CONSINITLP(consInitlpDisjunction)
#define SCIPensureBlockMemoryArray(scip, ptr, arraysizeptr, minsize)
Definition: scip.h:22601
static SCIP_DECL_CONSTRANS(consTransDisjunction)
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8225
SCIP_RETCODE SCIPcaptureCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:27726
struct SCIP_ConsData SCIP_CONSDATA
Definition: type_cons.h:50
SCIP_RETCODE SCIPgetConsCopy(SCIP *sourcescip, SCIP *targetscip, SCIP_CONS *sourcecons, SCIP_CONS **targetcons, SCIP_CONSHDLR *sourceconshdlr, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *name, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode, SCIP_Bool global, SCIP_Bool *valid)
Definition: scip.c:2533
static SCIP_DECL_CONSPRESOL(consPresolDisjunction)
SCIP_RETCODE SCIPaddConsNode(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons, SCIP_NODE *validnode)
Definition: scip.c:13146
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:22620
#define SCIP_Bool
Definition: def.h:61
SCIP_RETCODE SCIPaddConsElemDisjunction(SCIP *scip, SCIP_CONS *cons, SCIP_CONS *addcons)
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip.c:29091
void SCIPactivateSolViolationUpdates(SCIP *scip)
Definition: scip.c:13814
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8006
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition: cons.c:8115
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8185
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:8155
#define CONSHDLR_DELAYPROP
static SCIP_RETCODE checkCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_RESULT *result)
SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
Definition: scip.c:6498
static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyDisjunction)
SCIP_RETCODE SCIPincludeConshdlrDisjunction(SCIP *scip)
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip.c:35836
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition: cons.c:8016
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip.c:27761
SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
Definition: scip.c:6253
void SCIPupdateSolConsViolation(SCIP *scip, SCIP_SOL *sol, SCIP_Real absviol, SCIP_Real relviol)
Definition: scip.c:13790
static SCIP_RETCODE branchCons(SCIP *scip, SCIP_CONS *cons, SCIP_RESULT *result)
#define CONSHDLR_MAXPREROUNDS
#define SCIP_Real
Definition: def.h:149
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8235
#define CONSHDLR_NEEDSCONS
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:8175
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8165
SCIP_RETCODE SCIPaddConsLocks(SCIP *scip, SCIP_CONS *cons, int nlockspos, int nlocksneg)
Definition: scip.c:28660
static SCIP_DECL_CONSDELETE(consDeleteDisjunction)
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition: type_cons.h:49
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip.h:22605
#define CONSHDLR_CHECKPRIORITY
static SCIP_RETCODE consdataCreate(SCIP *scip, SCIP_CONSDATA **consdata, SCIP_CONS **conss, int nconss, SCIP_CONS *relaxcons)
#define DEFAULT_ALWAYSBRANCH
SCIP_Longint SCIPgetNNodes(SCIP *scip)
Definition: scip.c:42133
SCIP_RETCODE SCIPcreateConsDisjunction(SCIP *scip, SCIP_CONS **cons, const char *name, int nconss, SCIP_CONS **conss, SCIP_CONS *relaxcons, SCIP_Bool initial, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic)
static SCIP_DECL_CONSENFOPS(consEnfopsDisjunction)
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip.c:4239
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip.h:22624
static SCIP_RETCODE propagateCons(SCIP *scip, SCIP_CONS *cons, int *ndelconss)
SCIP_RETCODE SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
Definition: scip.c:5994