Scippy

SCIP

Solving Constraint Integer Programs

cons_conjunction.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-2014 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file cons_conjunction.c
17  * @brief constraint handler for conjunction constraints
18  * @author Tobias Achterberg
19  */
20 
21 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
22 
23 #include <assert.h>
24 #include <string.h>
25 #include <limits.h>
26 
27 #include "scip/cons_conjunction.h"
28 
29 
30 /* constraint handler properties */
31 #define CONSHDLR_NAME "conjunction"
32 #define CONSHDLR_DESC "conjunction of constraints"
33 #define CONSHDLR_ENFOPRIORITY +900000 /**< priority of the constraint handler for constraint enforcing */
34 #define CONSHDLR_CHECKPRIORITY -900000 /**< priority of the constraint handler for checking feasibility */
35 #define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
36  * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
37 #define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
38 #define CONSHDLR_DELAYPRESOL FALSE /**< should presolving method be delayed, if other presolvers found reductions? */
39 #define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
40 
41 /*
42  * Data structures
43  */
44 
45 /** constraint data for conjunction constraints */
46 struct SCIP_ConsData
47 {
48  SCIP_CONS** conss; /**< constraints in conjunction */
49  int consssize; /**< size of conss array */
50  int nconss; /**< number of constraints in conjunction */
51 };
52 
53 
54 /*
55  * Local methods
56  */
57 
58 /** creates conjunction constraint data, captures initial constraints of conjunction */
59 static
61  SCIP* scip, /**< SCIP data structure */
62  SCIP_CONSDATA** consdata, /**< pointer to constraint data */
63  SCIP_CONS** conss, /**< initial constraint in conjunction */
64  int nconss /**< number of initial constraints in conjunction */
65  )
66 {
67  assert(consdata != NULL);
68 
69  SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
70  if( nconss > 0 )
71  {
72  SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->conss, conss, nconss) );
73  (*consdata)->consssize = nconss;
74  (*consdata)->nconss = nconss;
75 
76  if( SCIPisTransformed(scip) )
77  {
78  SCIP_CALL( SCIPtransformConss(scip, nconss, (*consdata)->conss, (*consdata)->conss) );
79  }
80  else
81  {
82  int c;
83 
84  for( c = 0; c < nconss; ++c )
85  {
86  SCIP_CALL( SCIPcaptureCons(scip, conss[c]) );
87  }
88  }
89  }
90  else
91  {
92  (*consdata)->conss = NULL;
93  (*consdata)->consssize = 0;
94  (*consdata)->nconss = 0;
95  }
96 
97  return SCIP_OKAY;
98 }
99 
100 /** frees constraint data and releases all constraints in conjunction */
101 static
103  SCIP* scip, /**< SCIP data structure */
104  SCIP_CONSDATA** consdata /**< pointer to constraint data */
105  )
106 {
107  int c;
108 
109  assert(consdata != NULL);
110  assert(*consdata != NULL);
111 
112  /* release constraints */
113  for( c = 0; c < (*consdata)->nconss; ++c )
114  {
115  SCIP_CALL( SCIPreleaseCons(scip, &(*consdata)->conss[c]) );
116  }
117 
118  /* free memory */
119  SCIPfreeBlockMemoryArrayNull(scip, &(*consdata)->conss, (*consdata)->consssize);
120  SCIPfreeBlockMemory(scip, consdata);
121 
122  return SCIP_OKAY;
123 }
124 
125 /** adds constraint to conjunction */
126 static
128  SCIP* scip, /**< SCIP data structure */
129  SCIP_CONSDATA* consdata, /**< constraint data */
130  SCIP_CONS* cons /**< constraint to add to the conjunction */
131  )
132 {
133  assert(consdata != NULL);
134 
135  /* get memory for additional constraint */
136  SCIP_CALL( SCIPensureBlockMemoryArray(scip, &consdata->conss, &consdata->consssize, consdata->nconss+1) );
137  assert(consdata->conss != NULL);
138  assert(consdata->nconss < consdata->consssize);
139 
140  /* insert constraint in array */
141  consdata->conss[consdata->nconss] = cons;
142  consdata->nconss++;
143 
144  if( SCIPisTransformed(scip) )
145  {
146  SCIP_CALL( SCIPtransformCons(scip, consdata->conss[consdata->nconss - 1], &(consdata->conss[consdata->nconss - 1])) );
147  }
148  else
149  {
150  /* capture constraint */
151  SCIP_CALL( SCIPcaptureCons(scip, cons) );
152  }
153 
154  return SCIP_OKAY;
155 }
156 
157 /** adds all constraints in conjunction constraints to the problem; disables unmodifiable conjunction constraints */
158 static
160  SCIP* scip, /**< SCIP data structure */
161  SCIP_CONS** conss, /**< active conjunction constraints */
162  int nconss, /**< number of active conjunction constraints */
163  SCIP_RESULT* result /**< pointer to store the result */
164  )
165 {
166  SCIP_CONSDATA* consdata;
167  int c;
168  int i;
169 
170  assert(result != NULL);
171 
172  for( c = 0; c < nconss; ++c )
173  {
174  consdata = SCIPconsGetData(conss[c]);
175  assert(consdata != NULL);
176 
177  /* add all inactive constraints to local subproblem */
178  for( i = 0; i < consdata->nconss; ++i )
179  {
180  /* update check flag for sub constraints when upgrade takes place */
181  if( SCIPconsIsChecked(conss[c]) )
182  {
183  /* make sure, the constraint is checked for feasibility */
184  SCIP_CALL( SCIPsetConsChecked(scip, consdata->conss[i], TRUE) );
185  }
186 
187  if( !SCIPconsIsActive(consdata->conss[i]) )
188  {
189  SCIPdebugMessage("adding constraint <%s> from add conjunction <%s>\n",
190  SCIPconsGetName(consdata->conss[i]), SCIPconsGetName(conss[c]));
191  SCIP_CALL( SCIPaddConsLocal(scip, consdata->conss[i], NULL) );
192  *result = SCIP_CONSADDED;
193  }
194  }
195 
196  /* disable conjunction constraint, if it is unmodifiable */
197  if( !SCIPconsIsModifiable(conss[c]) )
198  {
199  SCIP_CALL( SCIPdelConsLocal(scip, conss[c]) );
200  }
201  }
202 
203  return SCIP_OKAY;
204 }
205 
206 /** checks all constraints in conjunction constraints for feasibility */
207 static
209  SCIP* scip, /**< SCIP data structure */
210  SCIP_CONS** conss, /**< active conjunction constraints */
211  int nconss, /**< number of active conjunction constraints */
212  SCIP_SOL* sol, /**< solution to check */
213  SCIP_Bool checkintegrality, /**< has integrality to be checked? */
214  SCIP_Bool checklprows, /**< have current LP rows to be checked? */
215  SCIP_Bool printreason, /**< should the reason for the violation be printed? */
216  SCIP_RESULT* result /**< pointer to store the result */
217  )
218 {
219  SCIP_CONSDATA* consdata;
220  int c;
221  int i;
222 
223  assert(result != NULL);
224 
225  for( c = 0; c < nconss && *result == SCIP_FEASIBLE; ++c )
226  {
227  consdata = SCIPconsGetData(conss[c]);
228  assert(consdata != NULL);
229 
230  /* check all constraints */
231  for( i = 0; i < consdata->nconss && *result == SCIP_FEASIBLE; ++i )
232  {
233  SCIP_CALL( SCIPcheckCons(scip, consdata->conss[i], sol, checkintegrality, checklprows, printreason, result) );
234  assert(*result == SCIP_FEASIBLE || *result == SCIP_INFEASIBLE);
235  }
236 
237  if( printreason && *result == SCIP_INFEASIBLE )
238  {
239  SCIPinfoMessage(scip, NULL, "conjunction constraint %s is violated, at least the sub-constraint %s is violated by this given solution\n", SCIPconsGetName(conss[c]), SCIPconsGetName(consdata->conss[i-1]));
240  SCIPdebug( SCIP_CALL( SCIPprintCons(scip, conss[c], NULL) ) );
241  }
242  }
243 
244  return SCIP_OKAY;
245 }
246 
247 
248 /*
249  * Callback methods of constraint handler
250  */
251 
252 
253  /** copy method for constraint handler plugins (called when SCIP copies plugins) */
254 static
255 SCIP_DECL_CONSHDLRCOPY(conshdlrCopyConjunction)
256 { /*lint --e{715}*/
257  assert(scip != NULL);
258  assert(conshdlr != NULL);
259  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
260 
261  /* call inclusion method of constraint handler */
263 
264  *valid = TRUE;
265 
266  return SCIP_OKAY;
267 }
268 
269 
270 /** frees specific constraint data */
271 static
272 SCIP_DECL_CONSDELETE(consDeleteConjunction)
273 { /*lint --e{715}*/
274  SCIP_CALL( consdataFree(scip, consdata) );
275 
276  return SCIP_OKAY;
277 }
278 
279 /** transforms constraint data into data belonging to the transformed problem */
280 static
281 SCIP_DECL_CONSTRANS(consTransConjunction)
282 { /*lint --e{715}*/
283  SCIP_CONSDATA* sourcedata;
284  SCIP_CONSDATA* targetdata;
285  int c;
286 
287  /* create constraint data for target constraint */
288  SCIP_CALL( SCIPallocBlockMemory(scip, &targetdata) );
289 
290  /* get constraint data of source constraint */
291  sourcedata = SCIPconsGetData(sourcecons);
292 
293  if( sourcedata->nconss > 0 )
294  {
295  targetdata->consssize = sourcedata->nconss;
296  targetdata->nconss = sourcedata->nconss;
297  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &targetdata->conss, targetdata->consssize) );
298  for( c = 0; c < sourcedata->nconss; ++c )
299  {
300  SCIP_CALL( SCIPtransformCons(scip, sourcedata->conss[c], &targetdata->conss[c]) );
301  }
302  }
303  else
304  {
305  targetdata->conss = NULL;
306  targetdata->consssize = 0;
307  targetdata->nconss = 0;
308  }
309 
310  /* create target constraint */
311  SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
312  SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
313  SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
314  SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
315  SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
316 
317  return SCIP_OKAY;
318 }
319 
320 
321 /** constraint enforcing method of constraint handler for LP solutions */
322 static
323 SCIP_DECL_CONSENFOLP(consEnfolpConjunction)
324 { /*lint --e{715}*/
325  *result = SCIP_FEASIBLE;
326 
327  /* add all constraints to the current node */
328  SCIP_CALL( addAllConss(scip, conss, nconss, result) );
329 
330  return SCIP_OKAY;
331 }
332 
333 
334 /** constraint enforcing method of constraint handler for pseudo solutions */
335 static
336 SCIP_DECL_CONSENFOPS(consEnfopsConjunction)
337 { /*lint --e{715}*/
338  *result = SCIP_FEASIBLE;
339 
340  /* add all constraints to the current node */
341  SCIP_CALL( addAllConss(scip, conss, nconss, result) );
342 
343  return SCIP_OKAY;
344 }
345 
346 
347 /** feasibility check method of constraint handler for integral solutions */
348 static
349 SCIP_DECL_CONSCHECK(consCheckConjunction)
350 { /*lint --e{715}*/
351  *result = SCIP_FEASIBLE;
352 
353  /* check all constraints of the conjunction */
354  SCIP_CALL( checkAllConss(scip, conss, nconss, sol, checkintegrality, checklprows, printreason, result) );
355 
356  return SCIP_OKAY;
357 }
358 
359 
360 /** presolving method of constraint handler */
361 static
362 SCIP_DECL_CONSPRESOL(consPresolConjunction)
363 { /*lint --e{715}*/
364  SCIP_CONSDATA* consdata;
365  int c;
366  int i;
367 
368  assert(result != NULL);
369 
370  *result = SCIP_DIDNOTFIND;
371 
372  /* all constraints in a conjunction constraint of the global problem can be added directly to the problem and
373  * removed from the conjunction constraint;
374  * an unmodifiable conjunction constraint can be deleted
375  */
376  for( c = 0; c < nconss; ++c )
377  {
378  consdata = SCIPconsGetData(conss[c]);
379  assert(consdata != NULL);
380 
381  /* add all inactive constraints to the global problem */
382  for( i = 0; i < consdata->nconss; ++i )
383  {
384  /* update check flag for sub constraints when upgrade takes place */
385  if( SCIPconsIsChecked(conss[c]) )
386  {
387  /* make sure, the constraint is checked for feasibility */
388  SCIP_CALL( SCIPsetConsChecked(scip, consdata->conss[i], TRUE) );
389  }
390 
391  /* add constraint, if it is not active yet */
392  if( !SCIPconsIsActive(consdata->conss[i]) )
393  {
394  SCIPdebugMessage("adding constraint <%s> from add conjunction <%s>\n",
395  SCIPconsGetName(consdata->conss[i]), SCIPconsGetName(conss[c]));
396  SCIP_CALL( SCIPaddCons(scip, consdata->conss[i]) );
397  *result = SCIP_SUCCESS;
398  }
399  /* release constraint because it will be removed from the conjunction constraint */
400  SCIP_CALL( SCIPreleaseCons(scip, &(consdata->conss[i])) );
401  }
402  /* all constraints where removed, so we need to clear the array */
403  consdata->nconss = 0;
404 
405  /* delete conjunction constraint, if it is unmodifiable */
406  if( !SCIPconsIsModifiable(conss[c]) )
407  {
408  SCIP_CALL( SCIPdelCons(scip, conss[c]) );
409  }
410  }
411 
412  return SCIP_OKAY;
413 }
414 
415 
416 /** variable rounding lock method of constraint handler */
417 static
418 SCIP_DECL_CONSLOCK(consLockConjunction)
419 { /*lint --e{715}*/
420  SCIP_CONSDATA* consdata;
421  int c;
422 
423  consdata = SCIPconsGetData(cons);
424  assert(consdata != NULL);
425 
426  /* lock sub constraints */
427  for( c = 0; c < consdata->nconss; ++c )
428  {
429  SCIP_CALL( SCIPaddConsLocks(scip, consdata->conss[c], nlockspos, nlocksneg) );
430  }
431 
432  return SCIP_OKAY;
433 }
434 
435 
436 /** constraint display method of constraint handler */
437 static
438 SCIP_DECL_CONSPRINT(consPrintConjunction)
439 { /*lint --e{715}*/
440  SCIP_CONSDATA* consdata;
441  int i;
442 
443  assert( scip != NULL );
444  assert( conshdlr != NULL );
445  assert( cons != NULL );
446 
447  consdata = SCIPconsGetData(cons);
448  assert(consdata != NULL);
449 
450  SCIPinfoMessage(scip, file, "conjunction(");
451 
452  for( i = 0; i < consdata->nconss; ++i )
453  {
454  if( i > 0 )
455  SCIPinfoMessage(scip, file, ", ");
456  SCIP_CALL( SCIPprintCons(scip, consdata->conss[i], file) );
457  }
458  SCIPinfoMessage(scip, file, ")");
459 
460  return SCIP_OKAY;
461 }
462 
463 /** constraint parsing method of constraint handler */
464 static
465 SCIP_DECL_CONSPARSE(consParseConjunction)
466 { /*lint --e{715}*/
467  SCIP_CONS** conss;
468  int nconss;
469  int sconss;
470  char* token;
471  char* saveptr;
472  char* nexttokenstart;
473  char* copystr;
474 
475  assert(scip != NULL);
476  assert(conshdlr != NULL);
477  assert(cons != NULL);
478  assert(success != NULL);
479  assert(str != NULL);
480  assert(name != NULL);
481 
482  SCIPdebugMessage("parsing conjunction <%s>\n", name);
483 
484  *success = TRUE;
485 
486  /* allocate memory for constraint in conjunction, initial size is set to 10 */
487  nconss = 0;
488  sconss = 10;
489  SCIP_CALL( SCIPallocBufferArray(scip, &conss, sconss) );
490  SCIP_CALL( SCIPduplicateBufferArray(scip, &copystr, str, (int)strlen(str)+1) );
491 
492  /* find '(' at the beginning, string should start with 'conjunction(' */
493  saveptr = strpbrk(copystr, "("); /*lint !e158*/
494 
495  if( saveptr == NULL )
496  {
497  SCIPdebugMessage("error parsing conjunctive constraint: \"%s\"\n", str);
498  *success = FALSE;
499  goto TERMINATE;
500  }
501 
502  /* skip '(' */
503  ++saveptr;
504  /* remember token start position */
505  nexttokenstart = saveptr;
506 
507  /* brackets '(' and ')' can exist co we check for them and the constraint delimeter */
508  saveptr = strpbrk(saveptr, "(,");
509 
510  /* brackets '(' and ')' can exist in the rest of the string so we need to skip them to find the end of the first
511  * sub-constraint marked by a ','
512  */
513  if( saveptr != NULL )
514  {
515  do
516  {
517  int bracketcounter = 0;
518 
519  if( *saveptr == '(' )
520  {
521  do
522  {
523  ++bracketcounter;
524  ++saveptr;
525 
526  /* find last ending bracket */
527  while( bracketcounter > 0 )
528  {
529  saveptr = strpbrk(saveptr, "()");
530 
531  if( saveptr != NULL )
532  {
533  if( *saveptr == '(' )
534  ++bracketcounter;
535  else
536  --bracketcounter;
537 
538  ++saveptr;
539  }
540  else
541  {
542  SCIPdebugMessage("error parsing conjunctive constraint: \"%s\"\n", str);
543  *success = FALSE;
544  goto TERMINATE;
545  }
546  }
547 
548  saveptr = strpbrk(saveptr, "(,");
549  }
550  while( saveptr != NULL && *saveptr == '(' );
551  }
552 
553  /* we found a ',' so the end of the first sub-constraint is determined */
554  if( saveptr != NULL )
555  {
556  assert(*saveptr == ',');
557 
558  /* resize constraint array if necessary */
559  if( nconss == sconss )
560  {
561  sconss = SCIPcalcMemGrowSize(scip, nconss+1);
562  assert(nconss < sconss);
563 
564  SCIP_CALL( SCIPreallocBufferArray(scip, &conss, sconss) );
565  }
566 
567  assert(saveptr > nexttokenstart);
568 
569  /* extract token for parsing */
570  SCIP_CALL( SCIPduplicateBufferArray(scip, &token, nexttokenstart, saveptr - nexttokenstart + 1) );
571  token[saveptr - nexttokenstart] = '\0';
572 
573  SCIPdebugMessage("conjunctive parsing token(constraint): %s\n", token);
574 
575  /* parsing a constraint, part of the conjunction */
576  SCIP_CALL( SCIPparseCons(scip, &(conss[nconss]), token, initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, success) );
577 
578  SCIPfreeBufferArray(scip, &token);
579 
580  if( *success )
581  ++nconss;
582  else
583  {
584  SCIPdebugMessage("error parsing conjunctive constraint: \"%s\"\n", str);
585  goto TERMINATE;
586  }
587  /* skip ',' delimeter */
588  ++saveptr;
589  /* remember token start position */
590  nexttokenstart = saveptr;
591 
592  saveptr = strpbrk(saveptr, "(,");
593  }
594  }
595  while( saveptr != NULL );
596  }
597 
598  /* find end of conjunction constraint */
599  saveptr = strrchr(nexttokenstart, ')');
600 
601  if( saveptr == NULL )
602  {
603  SCIPdebugMessage("error parsing conjunctive constraint: \"%s\"\n", str);
604  *success = FALSE;
605  goto TERMINATE;
606  }
607  /* parse last sub-constraint */
608  else
609  {
610  /* resize constraint array if necessary */
611  if( nconss == sconss )
612  {
613  ++sconss;
614  SCIP_CALL( SCIPreallocBufferArray(scip, &conss, sconss) );
615  }
616 
617  assert(saveptr > nexttokenstart);
618 
619  /* extract token for parsing */
620  SCIP_CALL( SCIPduplicateBufferArray(scip, &token, nexttokenstart, saveptr - nexttokenstart + 1) );
621  token[saveptr - nexttokenstart] = '\0';
622 
623  SCIPdebugMessage("conjunctive parsing token(constraint): %s\n", token);
624 
625  /* parsing a constraint, part of the conjunction */
626  SCIP_CALL( SCIPparseCons(scip, &(conss[nconss]), token, initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, success) );
627 
628  if( *success )
629  ++nconss;
630 
631  SCIPfreeBufferArray(scip, &token);
632  }
633  assert(nconss > 0 || !(*success));
634 
635  /* if parsing sub-constraints was fine, create the conjunctive constraint */
636  if( *success )
637  {
638  /* create conjunctive constraint */
639  SCIP_CALL( SCIPcreateConsConjunction(scip, cons, name, nconss, conss,
640  enforce, check, local, modifiable, dynamic) );
641  }
642 
643  /* free parsed constraints */
644  for( --nconss; nconss >= 0; --nconss )
645  {
646  SCIP_CALL( SCIPreleaseCons(scip, &conss[nconss]) );
647  }
648 
649  TERMINATE:
650  /* free temporary memory */
651  SCIPfreeBufferArray(scip, &copystr);
652  SCIPfreeBufferArray(scip, &conss);
653 
654  return SCIP_OKAY;
655 }
656 
657 /** constraint copying method of constraint handler */
658 static
659 SCIP_DECL_CONSCOPY(consCopyConjunction)
660 { /*lint --e{715}*/
661  SCIP_CONSDATA* sourcedata;
662  SCIP_CONS** sourceconss;
663  SCIP_CONS** conss;
664  int nconss;
665  int c;
666 
667  *valid = TRUE;
668 
669  sourcedata = SCIPconsGetData(sourcecons);
670  assert(sourcedata != NULL);
671 
672  sourceconss = sourcedata->conss;
673  nconss = sourcedata->nconss;
674 
675  if( nconss > 0 )
676  {
677  assert(sourceconss != NULL);
678 
679  SCIP_CALL( SCIPallocBufferArray(scip, &conss, nconss) );
680 
681  /* copy each constraint one by one */
682  for( c = 0; c < nconss && (*valid); ++c )
683  {
684  SCIP_CALL( SCIPgetConsCopy(sourcescip, scip, sourceconss[c], &conss[c], SCIPconsGetHdlr(sourceconss[c]),
685  varmap, consmap, SCIPconsGetName(sourceconss[c]),
686  SCIPconsIsInitial(sourceconss[c]), SCIPconsIsSeparated(sourceconss[c]), SCIPconsIsEnforced(sourceconss[c]),
687  SCIPconsIsChecked(sourceconss[c]), SCIPconsIsPropagated(sourceconss[c]),
688  SCIPconsIsLocal(sourceconss[c]), SCIPconsIsModifiable(sourceconss[c]),
689  SCIPconsIsDynamic(sourceconss[c]), SCIPconsIsRemovable(sourceconss[c]), SCIPconsIsStickingAtNode(sourceconss[c]),
690  global, valid) );
691  assert(!(*valid) || conss[c] != NULL);
692  }
693 
694  if( *valid )
695  {
696  if( name == NULL )
697  {
698  SCIP_CALL( SCIPcreateConsConjunction(scip, cons, SCIPconsGetName(sourcecons), nconss, conss,
699  enforce, check, local, modifiable, dynamic) );
700  }
701  else
702  {
703  SCIP_CALL( SCIPcreateConsConjunction(scip, cons, name, nconss, conss,
704  enforce, check, local, modifiable, dynamic) );
705  }
706  }
707 
708  /* release the copied constraints */
709  for( c = (*valid ? c - 1 : c - 2); c >= 0; --c )
710  {
711  assert(conss[c] != NULL);
712  SCIP_CALL( SCIPreleaseCons(scip, &conss[c]) );
713  }
714 
715  SCIPfreeBufferArray(scip, &conss);
716  }
717 
718  return SCIP_OKAY;
719 }
720 
721 
722 /*
723  * constraint specific interface methods
724  */
725 
726 /** creates the handler for conjunction constraints and includes it in SCIP */
728  SCIP* scip /**< SCIP data structure */
729  )
730 {
731  SCIP_CONSHDLRDATA* conshdlrdata;
732  SCIP_CONSHDLR* conshdlr;
733  /* create conjunction constraint handler data */
734  conshdlrdata = NULL;
735 
736  /* include constraint handler */
739  consEnfolpConjunction, consEnfopsConjunction, consCheckConjunction, consLockConjunction,
740  conshdlrdata) );
741 
742  assert(conshdlr != NULL);
743 
744  /* set non-fundamental callbacks via specific setter functions */
745  SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyConjunction, consCopyConjunction) );
746  SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteConjunction) );
747  SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseConjunction) );
748  SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolConjunction, CONSHDLR_MAXPREROUNDS,
750  SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintConjunction) );
751  SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransConjunction) );
752 
753 
754  return SCIP_OKAY;
755 }
756 
757 /** creates and captures a conjunction constraint
758  *
759  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
760  */
762  SCIP* scip, /**< SCIP data structure */
763  SCIP_CONS** cons, /**< pointer to hold the created constraint */
764  const char* name, /**< name of constraint */
765  int nconss, /**< number of initial constraints in conjunction */
766  SCIP_CONS** conss, /**< initial constraint in conjunction */
767  SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
768  * TRUE for model constraints, FALSE for additional, redundant constraints. */
769  SCIP_Bool check, /**< should the constraint be checked for feasibility?
770  * TRUE for model constraints, FALSE for additional, redundant constraints. */
771  SCIP_Bool local, /**< is constraint only valid locally?
772  * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
773  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
774  * Usually set to FALSE. In column generation applications, set to TRUE if pricing
775  * adds coefficients to this constraint. */
776  SCIP_Bool dynamic /**< is constraint subject to aging?
777  * Usually set to FALSE. Set to TRUE for own cuts which
778  * are separated as constraints. */
779  )
780 {
781  SCIP_CONSHDLR* conshdlr;
782  SCIP_CONSDATA* consdata;
783 
784  /* find the conjunction constraint handler */
785  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
786  if( conshdlr == NULL )
787  {
788  SCIPerrorMessage("conjunction constraint handler not found\n");
789  return SCIP_PLUGINNOTFOUND;
790  }
791 
792  /* create constraint data */
793  SCIP_CALL( consdataCreate(scip, &consdata, conss, nconss) );
794 
795  /* create constraint */
796  SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, FALSE, FALSE, enforce, check, FALSE,
797  local, modifiable, dynamic, FALSE, FALSE) );
798 
799  return SCIP_OKAY;
800 }
801 
802 /** creates and captures an and constraint
803  * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
804  * method SCIPcreateConsConjunction(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
805  *
806  * @see SCIPcreateConsConjunction() for information about the basic constraint flag configuration
807  *
808  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
809  */
811  SCIP* scip, /**< SCIP data structure */
812  SCIP_CONS** cons, /**< pointer to hold the created constraint */
813  const char* name, /**< name of constraint */
814  int nconss, /**< number of initial constraints in conjunction */
815  SCIP_CONS** conss /**< initial constraint in conjunction */
816  )
817 {
818  assert(scip != NULL);
819 
820  SCIP_CALL( SCIPcreateConsConjunction(scip, cons, name, nconss, conss,
821  TRUE, TRUE, FALSE, FALSE, FALSE) );
822 
823  return SCIP_OKAY;
824 }
825 
826 /** adds constraint to the conjunction of constraints */
828  SCIP* scip, /**< SCIP data structure */
829  SCIP_CONS* cons, /**< conjunction constraint */
830  SCIP_CONS* addcons /**< additional constraint in conjunction */
831  )
832 {
833  SCIP_CONSDATA* consdata;
834 
835  assert(cons != NULL);
836  assert(addcons != NULL);
837 
838  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
839  {
840  SCIPerrorMessage("constraint is not a conjunction constraint\n");
841  return SCIP_INVALIDDATA;
842  }
843 
844  consdata = SCIPconsGetData(cons);
845  assert(consdata != NULL);
846 
847  SCIP_CALL( consdataAddCons(scip, consdata, addcons) );
848 
849  return SCIP_OKAY;
850 }
851 
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:51
SCIP_RETCODE SCIPincludeConshdlrConjunction(SCIP *scip)
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip.c:5600
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
Definition: scip.c:5332
static SCIP_DECL_CONSPARSE(consParseConjunction)
#define CONSHDLR_DESC
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:10913
SCIP_RETCODE SCIPtransformConss(SCIP *scip, int nconss, SCIP_CONS **conss, SCIP_CONS **transconss)
Definition: scip.c:23100
#define NULL
Definition: lpi_spx.cpp:129
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:7786
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition: cons.c:7618
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
Definition: scip.c:5078
SCIP_RETCODE SCIPcreateConsConjunction(SCIP *scip, SCIP_CONS **cons, const char *name, int nconss, SCIP_CONS **conss, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic)
SCIP_RETCODE SCIPparseCons(SCIP *scip, SCIP_CONS **cons, const char *str, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode, SCIP_Bool *success)
Definition: scip.c:22560
#define FALSE
Definition: def.h:52
#define TRUE
Definition: def.h:51
#define SCIPdebug(x)
Definition: pub_message.h:74
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:7577
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
Definition: scip.c:5539
SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_Bool delaypresol)
Definition: scip.c:5271
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 *success)
Definition: scip.c:2212
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip.h:19185
#define SCIPdebugMessage
Definition: pub_message.h:77
static SCIP_RETCODE consdataCreate(SCIP *scip, SCIP_CONSDATA **consdata, SCIP_CONS **conss, int nconss)
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:19214
static SCIP_DECL_CONSCOPY(consCopyConjunction)
SCIP_RETCODE SCIPcaptureCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:22618
SCIP_RETCODE SCIPaddConsElemConjunction(SCIP *scip, SCIP_CONS *cons, SCIP_CONS *addcons)
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:7776
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:7716
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip.c:23934
#define CONSHDLR_ENFOPRIORITY
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip.c:22651
static SCIP_DECL_CONSLOCK(consLockConjunction)
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip.h:19215
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:7706
#define CONSHDLR_NAME
static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata)
#define CONSHDLR_EAGERFREQ
static SCIP_DECL_CONSCHECK(consCheckConjunction)
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip.h:19183
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition: cons.c:7816
constraint handler for conjunction constraints
#define SCIPerrorMessage
Definition: pub_message.h:45
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:19221
static SCIP_RETCODE consdataAddCons(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_CONS *cons)
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip.h:19207
SCIP_RETCODE SCIPcheckCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_RESULT *result)
Definition: scip.c:23568
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:3873
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:7557
#define SCIP_CALL(x)
Definition: def.h:258
SCIP_RETCODE SCIPincludeConshdlrBasic(SCIP *scip, SCIP_CONSHDLR **conshdlrptr, const char *name, const char *desc, int enfopriority, int chckpriority, int eagerfreq, SCIP_Bool needscons, SCIP_DECL_CONSENFOLP((*consenfolp)), SCIP_DECL_CONSENFOPS((*consenfops)), SCIP_DECL_CONSCHECK((*conscheck)), SCIP_DECL_CONSLOCK((*conslock)), SCIP_CONSHDLRDATA *conshdlrdata)
Definition: scip.c:4936
static SCIP_DECL_CONSENFOLP(consEnfolpConjunction)
struct SCIP_ConsData SCIP_CONSDATA
Definition: type_cons.h:49
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition: cons.c:7587
static SCIP_RETCODE checkAllConss(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_SOL *sol, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_RESULT *result)
SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:11453
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip.c:983
SCIP_RETCODE SCIPcreateCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_CONSHDLR *conshdlr, SCIP_CONSDATA *consdata, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: scip.c:22476
#define SCIP_Bool
Definition: def.h:49
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:7796
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:7806
SCIP_RETCODE SCIPaddConsLocks(SCIP *scip, SCIP_CONS *cons, int nlockspos, int nlocksneg)
Definition: scip.c:23538
SCIP_RETCODE SCIPtransformCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **transcons)
Definition: scip.c:23060
#define SCIPensureBlockMemoryArray(scip, ptr, arraysizeptr, minsize)
Definition: scip.h:19201
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip.h:19204
static SCIP_DECL_CONSPRINT(consPrintConjunction)
#define CONSHDLR_CHECKPRIORITY
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
Definition: scip.c:5309
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:10850
static SCIP_DECL_CONSDELETE(consDeleteConjunction)
#define CONSHDLR_DELAYPRESOL
SCIP_RETCODE SCIPcreateConsBasicConjunction(SCIP *scip, SCIP_CONS **cons, const char *name, int nconss, SCIP_CONS **conss)
SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
Definition: scip.c:5516
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip.c:1239
static SCIP_DECL_CONSENFOPS(consEnfopsConjunction)
static SCIP_DECL_CONSTRANS(consTransConjunction)
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip.h:19217
static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyConjunction)
static SCIP_DECL_CONSPRESOL(consPresolConjunction)
#define CONSHDLR_MAXPREROUNDS
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:7736
SCIP_RETCODE SCIPsetConsChecked(SCIP *scip, SCIP_CONS *cons, SCIP_Bool check)
Definition: scip.c:22822
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip.h:19198
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition: type_cons.h:48
SCIP_RETCODE SCIPaddConsLocal(SCIP *scip, SCIP_CONS *cons, SCIP_NODE *validnode)
Definition: scip.c:11372
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip.c:38001
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:7726
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:7756
#define CONSHDLR_NEEDSCONS
static SCIP_RETCODE addAllConss(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_RESULT *result)