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-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_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 
295  /* check all constraints */
296  for( i = 0; i < nconss && *result != SCIP_FEASIBLE; ++i )
297  {
298  SCIP_CALL( SCIPcheckCons(scip, conss[i], sol, checkintegrality, checklprows, FALSE, result) );
299  assert(*result == SCIP_FEASIBLE || *result == SCIP_INFEASIBLE);
300  }
301 
302  if( printreason && *result == SCIP_INFEASIBLE )
303  {
304  SCIPinfoMessage(scip, NULL, "constraint %s is violated, all sub-constraints in this disjunction are violated by this given solution\n", SCIPconsGetName(cons));
305  SCIPdebug( SCIP_CALL( SCIPprintCons(scip, cons, NULL) ) );
306  }
307 
308  return SCIP_OKAY;
309 }
310 
311 /** propagation method for disjunction constraint */
312 static
314  SCIP* scip, /**< SCIP data structure */
315  SCIP_CONS* cons, /**< disjunctive constraint */
316  int* ndelconss /**< pointer to count number of deleted constraints */
317  )
318 {
319  SCIP_CONSDATA* consdata;
320  SCIP_CONS** conss;
321  int nconss;
322  int c;
323 
324  assert(scip != NULL);
325  assert(cons != NULL);
326  assert(ndelconss != NULL);
327 
328  consdata = SCIPconsGetData(cons);
329  assert(consdata != NULL);
330 
331  conss = consdata->conss;
332  assert(conss != NULL);
333 
334  nconss = consdata->nconss;
335  assert(nconss >= 1);
336 
337  for( c = 0; c < nconss; ++c )
338  {
339  /* if a constraint of the disjunction is already active, the disjunction is enforce by this constraint and
340  * therefore redundant and can be locally deleted
341  */
342  if( SCIPconsIsActive(conss[c]) )
343  {
344  /* if we can globally delete the whole disjunctive constraint, because one constraint is already active, we
345  * might need to update the check stage
346  */
347  if( SCIPgetStage(scip) == SCIP_STAGE_PRESOLVING || SCIPgetNNodes(scip) == 0 )
348  {
349  /* if disjunctive constraint needs to be checked, the upgraded constraint also needs to be checked */
350  if( SCIPconsIsChecked(cons) )
351  {
352  SCIP_CALL( SCIPsetConsChecked(scip, conss[c], TRUE) );
353  }
354  }
355 
356  (*ndelconss)++;
357  SCIP_CALL( SCIPdelConsLocal(scip, cons) );
358  break;
359  }
360  /* if a sub-constraint is globally deleted, it means that this constraint is redundant and always fulfilled and
361  * this makes also this disjunction redundant
362  */
363  else if( SCIPconsIsDeleted(conss[c]) )
364  {
365  (*ndelconss)++;
366  SCIP_CALL( SCIPdelCons(scip, cons) );
367  break;
368  }
369  }
370 
371  return SCIP_OKAY;
372 }
373 
374 /** helper function to enforce constraints */
375 static
377  SCIP* scip, /**< SCIP data structure */
378  SCIP_CONSHDLR* conshdlr, /**< constraint handler */
379  SCIP_CONS** conss, /**< constraints to process */
380  int nconss, /**< number of constraints */
381  SCIP_RESULT* result /**< pointer to store the result of the enforcing call */
382  )
383 {
384  SCIP_CONSHDLRDATA* conshdlrdata;
386  int c;
387 
388  *result = SCIP_FEASIBLE;
389 
390  conshdlrdata = SCIPconshdlrGetData(conshdlr);
391  assert(conshdlrdata != NULL);
392 
393  branch = SCIPgetNPseudoBranchCands(scip) == 0 || conshdlrdata->alwaysbranch;
394 
395  for( c = 0; c < nconss && *result != SCIP_BRANCHED; ++c )
396  {
397  /* check the disjunction */
398  SCIP_CALL( checkCons(scip, conss[c], NULL, FALSE, FALSE, FALSE, result) );
399 
400  if( *result == SCIP_INFEASIBLE && branch )
401  {
402  SCIP_CALL( branchCons(scip, conss[c], result) );
403  }
404  }
405 
406  return SCIP_OKAY;
407 }
408 
409 /*
410  * Callback methods of constraint handler
411  */
412 
413 /** copy method for constraint handler plugins (called when SCIP copies plugins) */
414 static
415 SCIP_DECL_CONSHDLRCOPY(conshdlrCopyDisjunction)
416 { /*lint --e{715}*/
417  assert(scip != NULL);
418  assert(conshdlr != NULL);
419  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
420 
421  /* call inclusion method of constraint handler */
423 
424  *valid = TRUE;
425 
426  return SCIP_OKAY;
427 }
428 
429 /** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
430 static
431 SCIP_DECL_CONSFREE(consFreeDisjunction)
432 {
433  SCIP_CONSHDLRDATA* conshdlrdata;
434 
435  assert(scip != NULL);
436  assert(conshdlr != NULL);
437  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
438 
439  /* free constraint handler data */
440  conshdlrdata = SCIPconshdlrGetData(conshdlr);
441  assert(conshdlrdata != NULL);
442 
443  SCIPfreeBlockMemory(scip, &conshdlrdata);
444 
445  SCIPconshdlrSetData(conshdlr, NULL);
446 
447  return SCIP_OKAY;
448 }
449 
450 /** frees specific constraint data */
451 static
452 SCIP_DECL_CONSDELETE(consDeleteDisjunction)
453 { /*lint --e{715}*/
454  SCIP_CALL( consdataFree(scip, consdata) );
455 
456  return SCIP_OKAY;
457 }
458 
459 
460 /** transforms constraint data into data belonging to the transformed problem */
461 static
462 SCIP_DECL_CONSTRANS(consTransDisjunction)
463 { /*lint --e{715}*/
464  SCIP_CONSDATA* sourcedata;
465  SCIP_CONSDATA* targetdata;
466 
467  /* get constraint data of source constraint */
468  sourcedata = SCIPconsGetData(sourcecons);
469  assert(sourcedata != NULL);
470 
471  SCIP_CALL( consdataCreate(scip, &targetdata, sourcedata->conss, sourcedata->nconss, sourcedata->relaxcons) );
472 
473  /* create target constraint */
474  SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
475  SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
476  SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
477  SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
478  SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
479 
480  return SCIP_OKAY;
481 }
482 
483 /** LP initialization method of constraint handler */
484 static
485 SCIP_DECL_CONSINITLP(consInitlpDisjunction)
486 { /*lint --e{715}*/
487  SCIP_CONSDATA* consdata;
488  int c;
489 
490  *infeasible = FALSE;
491 
492  for( c = 0; c < nconss; ++c )
493  {
494  consdata = SCIPconsGetData(conss[c]);
495  assert(consdata != NULL);
496 
497  /* if we have a relaxation constraint and it is not active, then we add it locally */
498  if( consdata->relaxcons != NULL && !SCIPconsIsActive(consdata->relaxcons) )
499  {
500  SCIP_CALL( SCIPaddConsLocal(scip, consdata->relaxcons, NULL) );
501  }
502  }
503 
504  return SCIP_OKAY;
505 }
506 
507 
508 /** constraint enforcing method of constraint handler for LP solutions */
509 static
510 SCIP_DECL_CONSENFOLP(consEnfolpDisjunction)
511 { /*lint --e{715}*/
512  SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, result) );
513 
514  return SCIP_OKAY;
515 }
516 
517 
518 /** constraint enforcing method of constraint handler for relaxation solutions */
519 static
520 SCIP_DECL_CONSENFORELAX(consEnforelaxDisjunction)
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 pseudo solutions */
529 static
530 SCIP_DECL_CONSENFOPS(consEnfopsDisjunction)
531 { /*lint --e{715}*/
532  SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, result) );
533 
534  return SCIP_OKAY;
535 }
536 
537 
538 /** feasibility check method of constraint handler for integral solutions */
539 static
540 SCIP_DECL_CONSCHECK(consCheckDisjunction)
541 { /*lint --e{715}*/
542  int c;
543 
544  *result = SCIP_FEASIBLE;
545 
546  for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
547  {
548  SCIP_RESULT tmpres;
549 
550  /* check the disjunction */
551  SCIP_CALL( checkCons(scip, conss[c], sol, checkintegrality, checklprows, printreason, &tmpres) );
552  assert(tmpres == SCIP_FEASIBLE || tmpres == SCIP_INFEASIBLE);
553 
554  if( tmpres == SCIP_INFEASIBLE )
555  *result = SCIP_INFEASIBLE;
556  }
557 
558  return SCIP_OKAY;
559 }
560 
561 
562 /** domain propagation method of constraint handler */
563 static
564 SCIP_DECL_CONSPROP(consPropDisjunction)
565 { /*lint --e{715}*/
566  int ndelconss;
567  int c;
568 
569  ndelconss = 0;
570 
571  /* in probing mode we do not for deletable constraints */
572  if( !SCIPinProbing(scip) )
573  {
574  for( c = 0; c < nconss; ++c )
575  {
576  /* propagate constraint */
577  SCIP_CALL( propagateCons(scip, conss[c], &ndelconss) );
578  }
579  }
580 
581  /* adjust result code */
582  if( ndelconss > 0 )
583  *result = SCIP_REDUCEDDOM;
584  else
585  *result = SCIP_DIDNOTFIND;
586 
587  return SCIP_OKAY;
588 }
589 
590 
591 /** presolving method of constraint handler */
592 static
593 SCIP_DECL_CONSPRESOL(consPresolDisjunction)
594 { /*lint --e{715}*/
595  SCIP_CONSDATA* consdata;
596  int oldndelconss;
597  int c;
598 
599  assert(result != NULL);
600 
601  *result = SCIP_DIDNOTFIND;
602  oldndelconss = *ndelconss;
603 
604  /* all disjunction constraints with one constraint can be replaced with that corresponding constraint */
605  for( c = 0; c < nconss; ++c )
606  {
607  consdata = SCIPconsGetData(conss[c]);
608  assert(consdata != NULL);
609 
610  if( !SCIPconsIsModifiable(conss[c]) && consdata->nconss == 1 )
611  {
612  /* add constraint to the problem */
613  if( !SCIPconsIsActive(consdata->conss[0]) )
614  {
615  SCIP_CONS* subcons = consdata->conss[0];
616 
617  /* if disjunctive constraint needs to be checked, the upgraded constraint also needs to be checked */
618  if( SCIPconsIsChecked(conss[c]) )
619  {
620  SCIP_CALL( SCIPsetConsChecked(scip, subcons, TRUE) );
621  }
622 
623  SCIP_CALL( SCIPaddCons(scip, subcons) );
624  }
625 
626  /* remove disjunction constraint */
627  SCIP_CALL( SCIPdelCons(scip, conss[c]) );
628 
629  *result = SCIP_SUCCESS;
630 
631  continue;
632  }
633 
634  /* propagate constraint */
635  SCIP_CALL( propagateCons(scip, conss[c], ndelconss) );
636  }
637 
638  if( *ndelconss > oldndelconss )
639  *result = SCIP_SUCCESS;
640 
641  return SCIP_OKAY;
642 }
643 
644 
645 /** variable rounding lock method of constraint handler */
646 static
647 SCIP_DECL_CONSLOCK(consLockDisjunction)
648 { /*lint --e{715}*/
649  SCIP_CONSDATA* consdata;
650  int c;
651 
652  consdata = SCIPconsGetData(cons);
653  assert(consdata != NULL);
654 
655  /* lock sub constraints */
656  for( c = 0; c < consdata->nconss; ++c )
657  {
658  SCIP_CALL( SCIPaddConsLocks(scip, consdata->conss[c], nlockspos, nlocksneg) );
659  }
660 
661  return SCIP_OKAY;
662 }
663 
664 
665 /** constraint display method of constraint handler */
666 static
667 SCIP_DECL_CONSPRINT(consPrintDisjunction)
668 { /*lint --e{715}*/
669  SCIP_CONSDATA* consdata;
670  int i;
671 
672  assert(scip != NULL);
673  assert(conshdlr != NULL);
674  assert(cons != NULL);
675 
676  consdata = SCIPconsGetData(cons);
677  assert(consdata != NULL);
678 
679  SCIPinfoMessage(scip, file, "disjunction(");
680 
681  for( i = 0; i < consdata->nconss; ++i )
682  {
683  if( i > 0 )
684  SCIPinfoMessage(scip, file, ", ");
685  SCIP_CALL( SCIPprintCons(scip, consdata->conss[i], file) );
686  }
687 
688  /* print relaxation */
689  if( consdata->relaxcons != NULL )
690  {
691  SCIPinfoMessage(scip, file, ",, ");
692  SCIP_CALL( SCIPprintCons(scip, consdata->relaxcons, file) );
693  }
694 
695  SCIPinfoMessage(scip, file, ")");
696 
697  return SCIP_OKAY;
698 }
699 
700 /** constraint parsing method of constraint handler */
701 static
702 SCIP_DECL_CONSPARSE(consParseDisjunction)
703 { /*lint --e{715}*/
704  SCIP_CONS** conss;
705  SCIP_Bool relaxed = FALSE;
706  int nconss;
707  int sconss;
708  char* token;
709  char* saveptr;
710  char* nexttokenstart;
711  char* copystr;
712 
713  assert(scip != NULL);
714  assert(conshdlr != NULL);
715  assert(cons != NULL);
716  assert(success != NULL);
717  assert(str != NULL);
718  assert(name != NULL);
719 
720  SCIPdebugMsg(scip, "parsing disjunction <%s>\n", name);
721 
722  *success = TRUE;
723 
724  /* allocate memory for constraint in disjunction, initial size is set to 10 */
725  nconss = 0;
726  sconss = 10;
727  SCIP_CALL( SCIPallocBufferArray(scip, &conss, sconss) );
728  SCIP_CALL( SCIPduplicateBufferArray(scip, &copystr, str, (int)strlen(str)+1) );
729 
730  /* find '(' at the beginning, string should start with 'disjunction(' */
731  saveptr = strpbrk(copystr, "("); /*lint !e158*/
732 
733  if( saveptr == NULL )
734  {
735  SCIPdebugMsg(scip, "error parsing disjunctive constraint: \"%s\"\n", str);
736  *success = FALSE;
737  goto TERMINATE;
738  }
739 
740  /* skip '(' */
741  ++saveptr;
742  /* remember token start position */
743  nexttokenstart = saveptr;
744 
745  /* brackets '(' and ')' can exist co we check for them and the constraint delimeter */
746  saveptr = strpbrk(saveptr, "(,");
747 
748  /* brackets '(' and ')' can exist in the rest of the string so we need to skip them to find the end of the first
749  * sub-constraint marked by a ','
750  */
751  if( saveptr != NULL )
752  {
753  do
754  {
755  int bracketcounter = 0;
756 
757  if( *saveptr == '(' )
758  {
759  do
760  {
761  ++bracketcounter;
762  ++saveptr;
763 
764  /* find last ending bracket */
765  while( bracketcounter > 0 )
766  {
767  saveptr = strpbrk(saveptr, "()");
768 
769  if( saveptr != NULL )
770  {
771  if( *saveptr == '(' )
772  ++bracketcounter;
773  else
774  --bracketcounter;
775 
776  ++saveptr;
777  }
778  else
779  {
780  SCIPdebugMsg(scip, "error parsing disjunctive constraint: \"%s\"\n", str);
781  *success = FALSE;
782  goto TERMINATE;
783  }
784  }
785 
786  saveptr = strpbrk(saveptr, "(,");
787  }
788  while( saveptr != NULL && *saveptr == '(' );
789  }
790 
791  /* we found a ',' so the end of the first sub-constraint is determined */
792  if( saveptr != NULL )
793  {
794  assert(*saveptr == ',');
795 
796  /* resize constraint array if necessary */
797  if( nconss == sconss )
798  {
799  sconss = SCIPcalcMemGrowSize(scip, nconss+1);
800  assert(nconss < sconss);
801 
802  SCIP_CALL( SCIPreallocBufferArray(scip, &conss, sconss) );
803  }
804 
805  assert(saveptr > nexttokenstart);
806 
807  /* extract token for parsing */
808  SCIP_CALL( SCIPduplicateBufferArray(scip, &token, nexttokenstart, saveptr - nexttokenstart + 1) );
809  token[saveptr - nexttokenstart] = '\0';
810 
811  SCIPdebugMsg(scip, "disjunctive parsing token(constraint): %s\n", token);
812 
813  /* parsing a constraint, part of the disjunction */
814  SCIP_CALL( SCIPparseCons(scip, &(conss[nconss]), token, initial, separate, enforce, FALSE, propagate, TRUE, modifiable, dynamic, removable, stickingatnode, success) );
815 
816  SCIPfreeBufferArray(scip, &token);
817 
818  if( *success )
819  ++nconss;
820  else
821  {
822  SCIPdebugMsg(scip, "error parsing disjunctive constraint: \"%s\"\n", str);
823  goto TERMINATE;
824  }
825  /* skip ',' delimeter */
826  ++saveptr;
827  /* remember token start position */
828  nexttokenstart = saveptr;
829 
830  /* check if we found the last constraint, which is a conjunctive relaxation of the disjunction, and in the
831  * CIP format marked by two consecutive ','
832  */
833  if( *nexttokenstart == ',' )
834  {
835  /* remember token start position */
836  nexttokenstart = saveptr+1;
837 
838  relaxed = TRUE;
839  break;
840  }
841 
842  saveptr = strpbrk(saveptr, "(,");
843  }
844  }
845  while( saveptr != NULL );
846  }
847 
848  /* find end of disjunction constraint */
849  saveptr = strrchr(nexttokenstart, ')');
850 
851  if( saveptr == NULL )
852  {
853  SCIPdebugMsg(scip, "error parsing disjunctive constraint: \"%s\"\n", str);
854  *success = FALSE;
855  goto TERMINATE;
856  }
857  /* parse last sub-constraint */
858  else
859  {
860  /* resize constraint array if necessary */
861  if( nconss == sconss )
862  {
863  ++sconss;
864  SCIP_CALL( SCIPreallocBufferArray(scip, &conss, sconss) );
865  }
866 
867  assert(saveptr > nexttokenstart);
868 
869  /* extract token for parsing */
870  SCIP_CALL( SCIPduplicateBufferArray(scip, &token, nexttokenstart, saveptr - nexttokenstart + 1) );
871  token[saveptr - nexttokenstart] = '\0';
872 
873  SCIPdebugMsg(scip, "disjunctive parsing token(constraint): %s\n", token);
874 
875  /* parsing a constraint, part of the disjunction */
876  SCIP_CALL( SCIPparseCons(scip, &(conss[nconss]), token, initial, separate, enforce, FALSE, propagate, TRUE, modifiable, dynamic, removable, stickingatnode, success) );
877 
878  if( *success )
879  ++nconss;
880 
881  SCIPfreeBufferArray(scip, &token);
882  }
883  assert(nconss > 0 || !(*success));
884 
885  /* if parsing sub-constraints was fine, create the disjunctive constraint */
886  if( *success )
887  {
888  /* create disjunctive constraint */
889  SCIP_CALL( SCIPcreateConsDisjunction(scip, cons, name, relaxed ? nconss - 1: nconss, conss, relaxed ? conss[nconss - 1] : NULL,
890  initial, enforce, check, local, modifiable, dynamic) );
891  }
892 
893  /* free parsed constraints */
894  for( --nconss; nconss >= 0; --nconss )
895  {
896  SCIP_CALL( SCIPreleaseCons(scip, &conss[nconss]) );
897  }
898 
899  TERMINATE:
900  /* free temporary memory */
901  SCIPfreeBufferArray(scip, &copystr);
902  SCIPfreeBufferArray(scip, &conss);
903 
904  return SCIP_OKAY;
905 }
906 
907 
908 /** constraint copying method of constraint handler */
909 static
910 SCIP_DECL_CONSCOPY(consCopyDisjunction)
911 { /*lint --e{715}*/
912  SCIP_CONSDATA* sourcedata;
913  SCIP_CONS** sourceconss;
914  SCIP_CONS** conss;
915  int nconss;
916  int c;
917 
918  *valid = TRUE;
919 
920  sourcedata = SCIPconsGetData(sourcecons);
921  assert(sourcedata != NULL);
922 
923  nconss = sourcedata->nconss;
924 
925  SCIP_CALL( SCIPallocBufferArray(scip, &conss, nconss) );
926  sourceconss = sourcedata->conss;
927 
928  /* copy each constraint one by one */
929  for( c = 0; c < nconss && (*valid); ++c )
930  {
931  SCIP_CALL( SCIPgetConsCopy(sourcescip, scip, sourceconss[c], &conss[c], SCIPconsGetHdlr(sourceconss[c]),
932  varmap, consmap, SCIPconsGetName(sourceconss[c]),
933  SCIPconsIsInitial(sourceconss[c]), SCIPconsIsSeparated(sourceconss[c]), SCIPconsIsEnforced(sourceconss[c]),
934  SCIPconsIsChecked(sourceconss[c]), SCIPconsIsPropagated(sourceconss[c]),
935  SCIPconsIsLocal(sourceconss[c]), SCIPconsIsModifiable(sourceconss[c]),
936  SCIPconsIsDynamic(sourceconss[c]), SCIPconsIsRemovable(sourceconss[c]), SCIPconsIsStickingAtNode(sourceconss[c]),
937  global, valid) );
938  assert(!(*valid) || conss[c] != NULL);
939  }
940 
941  if( *valid )
942  {
943  SCIP_CONS* sourcerelaxcons;
944  SCIP_CONS* targetrelaxcons;
945 
946  sourcerelaxcons = sourcedata->relaxcons;
947  targetrelaxcons = NULL;
948 
949  if( sourcerelaxcons != NULL )
950  {
951  SCIP_CALL( SCIPgetConsCopy(sourcescip, scip, sourcerelaxcons, &targetrelaxcons, SCIPconsGetHdlr(sourcerelaxcons),
952  varmap, consmap, SCIPconsGetName(sourcerelaxcons),
953  SCIPconsIsInitial(sourcerelaxcons), SCIPconsIsSeparated(sourcerelaxcons), SCIPconsIsEnforced(sourcerelaxcons),
954  SCIPconsIsChecked(sourcerelaxcons), SCIPconsIsPropagated(sourcerelaxcons),
955  SCIPconsIsLocal(sourcerelaxcons), SCIPconsIsModifiable(sourcerelaxcons),
956  SCIPconsIsDynamic(sourcerelaxcons), SCIPconsIsRemovable(sourcerelaxcons),
957  SCIPconsIsStickingAtNode(sourcerelaxcons),
958  global, valid) );
959  }
960 
961  if( *valid )
962  {
963  if( name == NULL )
964  {
965  SCIP_CALL( SCIPcreateConsDisjunction(scip, cons, SCIPconsGetName(sourcecons), nconss, conss, targetrelaxcons,
966  initial, enforce, check, local, modifiable, dynamic) );
967  }
968  else
969  {
970  SCIP_CALL( SCIPcreateConsDisjunction(scip, cons, name, nconss, conss, targetrelaxcons,
971  initial, enforce, check, local, modifiable, dynamic) );
972  }
973 
974  if( targetrelaxcons != NULL )
975  {
976  SCIP_CALL( SCIPreleaseCons(scip, &targetrelaxcons) );
977  }
978  }
979  }
980 
981  /* release the copied constraints */
982  for( c = (*valid ? c - 1 : c - 2); c >= 0; --c )
983  {
984  assert(conss[c] != NULL);
985  SCIP_CALL( SCIPreleaseCons(scip, &conss[c]) );
986  }
987 
988  SCIPfreeBufferArray(scip, &conss);
989 
990  return SCIP_OKAY;
991 }
992 
993 
994 /*
995  * constraint specific interface methods
996  */
997 
998 /** creates the handler for disjunction constraints and includes it in SCIP */
1000  SCIP* scip /**< SCIP data structure */
1001  )
1002 {
1003  SCIP_CONSHDLRDATA* conshdlrdata;
1004  SCIP_CONSHDLR* conshdlr;
1005 
1006  /* create disjunction constraint handler data */
1007  SCIP_CALL( SCIPallocBlockMemory(scip, &conshdlrdata) );
1008 
1009  /* include constraint handler */
1012  consEnfolpDisjunction, consEnfopsDisjunction, consCheckDisjunction, consLockDisjunction,
1013  conshdlrdata) );
1014 
1015  assert(conshdlr != NULL);
1016 
1017  /* set non-fundamental callbacks via specific setter functions */
1018  SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyDisjunction, consCopyDisjunction) );
1019  SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeDisjunction) );
1020  SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteDisjunction) );
1021  SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpDisjunction) );
1022  SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseDisjunction) );
1023  SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolDisjunction, CONSHDLR_MAXPREROUNDS,
1025  SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintDisjunction) );
1026  SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropDisjunction, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP,
1028  SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransDisjunction) );
1029  SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxDisjunction) );
1030 
1032  "constraints/" CONSHDLR_NAME "/alwaysbranch",
1033  "alawys perform branching if one of the constraints is violated, otherwise only if all integers are fixed",
1034  &conshdlrdata->alwaysbranch, FALSE, DEFAULT_ALWAYSBRANCH, NULL, NULL) );
1035 
1036  return SCIP_OKAY;
1037 }
1038 
1039 /** creates and captures a disjunction constraint
1040  *
1041  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
1042  */
1044  SCIP* scip, /**< SCIP data structure */
1045  SCIP_CONS** cons, /**< pointer to hold the created constraint */
1046  const char* name, /**< name of constraint */
1047  int nconss, /**< number of initial constraints in disjunction */
1048  SCIP_CONS** conss, /**< initial constraint in disjunction */
1049  SCIP_CONS* relaxcons, /**< a conjunction constraint containing the linear relaxation of the disjunction constraint, or NULL */
1050  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
1051  * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
1052  SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
1053  * TRUE for model constraints, FALSE for additional, redundant constraints. */
1054  SCIP_Bool check, /**< should the constraint be checked for feasibility?
1055  * TRUE for model constraints, FALSE for additional, redundant constraints. */
1056  SCIP_Bool local, /**< is constraint only valid locally?
1057  * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
1058  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
1059  * Usually set to FALSE. In column generation applications, set to TRUE if pricing
1060  * adds coefficients to this constraint. */
1061  SCIP_Bool dynamic /**< is constraint subject to aging?
1062  * Usually set to FALSE. Set to TRUE for own cuts which
1063  * are separated as constraints. */
1064  )
1065 {
1066  SCIP_CONSHDLR* conshdlr;
1067  SCIP_CONSDATA* consdata;
1068 
1069  /* find the disjunction constraint handler */
1070  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
1071  if( conshdlr == NULL )
1072  {
1073  SCIPerrorMessage("disjunction constraint handler not found\n");
1074  return SCIP_PLUGINNOTFOUND;
1075  }
1076 
1077  /* create constraint data */
1078  SCIP_CALL( consdataCreate(scip, &consdata, conss, nconss, relaxcons) );
1079 
1080  /* create constraint */
1081  SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, FALSE, enforce, check, FALSE,
1082  local, modifiable, dynamic, FALSE, FALSE) );
1083 
1084  return SCIP_OKAY;
1085 }
1086 
1087 /** creates and captures a cumulative constraint
1088  * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
1089  * method SCIPcreateConsDisjunction(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
1090  *
1091  * @see SCIPcreateConsDisjunction() for information about the basic constraint flag configuration
1092  *
1093  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
1094  */
1096  SCIP* scip, /**< SCIP data structure */
1097  SCIP_CONS** cons, /**< pointer to hold the created constraint */
1098  const char* name, /**< name of constraint */
1099  int nconss, /**< number of initial constraints in disjunction */
1100  SCIP_CONS** conss, /**< initial constraint in disjunction */
1101  SCIP_CONS* relaxcons /**< a conjunction constraint containing the linear relaxation of the disjunction constraint, or NULL */
1102  )
1103 {
1104  assert(scip != NULL);
1105 
1106  SCIP_CALL( SCIPcreateConsDisjunction(scip, cons, name, nconss, conss, relaxcons,
1107  TRUE, TRUE, TRUE, FALSE, FALSE, FALSE) );
1108 
1109  return SCIP_OKAY;
1110 }
1111 
1112 
1113 /** adds constraint to the disjunction of constraints */
1115  SCIP* scip, /**< SCIP data structure */
1116  SCIP_CONS* cons, /**< disjunction constraint */
1117  SCIP_CONS* addcons /**< additional constraint in disjunction */
1118  )
1119 {
1120  SCIP_CONSDATA* consdata;
1121 
1122  assert(cons != NULL);
1123  assert(addcons != NULL);
1124 
1125  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
1126  {
1127  SCIPerrorMessage("constraint is not a disjunction constraint\n");
1128  return SCIP_INVALIDDATA;
1129  }
1130 
1131  consdata = SCIPconsGetData(cons);
1132  assert(consdata != NULL);
1133 
1134  SCIP_CALL( consdataAddCons(scip, consdata, addcons) );
1135 
1136  return SCIP_OKAY;
1137 
1138 }
1139 
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:6228
#define CONSHDLR_NAME
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_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip.c:6541
static SCIP_DECL_CONSCOPY(consCopyDisjunction)
SCIP_Real SCIPgetLocalTransEstimate(SCIP *scip)
Definition: scip.c:13183
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
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip.c:45601
static SCIP_DECL_CONSPROP(consPropDisjunction)
#define CONSHDLR_ENFOPRIORITY
int SCIPgetNPseudoBranchCands(SCIP *scip)
Definition: scip.c:36492
SCIP_RETCODE SCIPdelConsNode(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons)
Definition: scip.c:13061
#define CONSHDLR_PROPFREQ
SCIP_RETCODE SCIPtransformConss(SCIP *scip, int nconss, SCIP_CONS **conss, SCIP_CONS **transconss)
Definition: scip.c:27775
#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:5831
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:27230
#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:8160
static SCIP_DECL_CONSCHECK(consCheckDisjunction)
static SCIP_DECL_CONSPARSE(consParseDisjunction)
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip.h:21907
#define CONSHDLR_EAGERFREQ
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip.h:21933
static SCIP_DECL_CONSENFORELAX(consEnforelaxDisjunction)
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:21937
static SCIP_DECL_CONSENFOLP(consEnfolpDisjunction)
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip.h:21890
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip.c:1010
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:8150
SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
Definition: scip.c:6274
#define SCIPdebugMsg
Definition: scip.h:451
SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
Definition: scip.c:6458
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition: cons.c:7942
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip.c:1336
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:27146
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:21904
#define CONSHDLR_PRESOLTIMING
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
Definition: scip.c:5997
#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:12410
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:13030
SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:13111
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:28252
SCIP_RETCODE SCIPsetConsChecked(SCIP *scip, SCIP_CONS *cons, SCIP_Bool check)
Definition: scip.c:27496
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:7881
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:8100
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
Definition: scip.c:6022
SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4133
#define NULL
Definition: lpi_spx1.cpp:137
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:27734
SCIP_RETCODE SCIPcreateChild(SCIP *scip, SCIP_NODE **node, SCIP_Real nodeselprio, SCIP_Real estimate)
Definition: scip.c:36704
#define SCIP_CALL(x)
Definition: def.h:306
static SCIP_DECL_CONSINITLP(consInitlpDisjunction)
#define SCIPensureBlockMemoryArray(scip, ptr, arraysizeptr, minsize)
Definition: scip.h:21906
static SCIP_DECL_CONSTRANS(consTransDisjunction)
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8120
SCIP_RETCODE SCIPcaptureCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:27288
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:2524
static SCIP_DECL_CONSPRESOL(consPresolDisjunction)
SCIP_RETCODE SCIPaddConsNode(SCIP *scip, SCIP_NODE *node, SCIP_CONS *cons, SCIP_NODE *validnode)
Definition: scip.c:12960
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:21925
#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:28652
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:7901
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
#define CONSHDLR_DELAYPROP
static SCIP_RETCODE branch(SCIP *scip, SCIP_BRANCHRULE *branchrule, SCIP_Bool allowaddcons, SCIP_RESULT *result)
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:6435
static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyDisjunction)
SCIP_RETCODE SCIPincludeConshdlrDisjunction(SCIP *scip)
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip.c:35033
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition: cons.c:7911
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip.c:27323
SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
Definition: scip.c:6190
static SCIP_RETCODE branchCons(SCIP *scip, SCIP_CONS *cons, SCIP_RESULT *result)
#define CONSHDLR_MAXPREROUNDS
#define SCIP_Real
Definition: def.h:135
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8130
#define CONSHDLR_NEEDSCONS
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:8070
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8060
SCIP_RETCODE SCIPaddConsLocks(SCIP *scip, SCIP_CONS *cons, int nlockspos, int nlocksneg)
Definition: scip.c:28222
static SCIP_DECL_CONSDELETE(consDeleteDisjunction)
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition: type_cons.h:49
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip.h:21910
#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:41182
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:4176
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip.h:21929
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:5931