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