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