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