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