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