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-2018 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  SCIPdebugMsg(scip, "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, /**< Do constraints represented by rows in the current LP have to be checked? */
216  SCIP_Bool printreason, /**< Should the reason for the violation be printed? */
217  SCIP_Bool completely, /**< Should all violations be checked? */
218  SCIP_RESULT* result /**< pointer to store the result */
219  )
220 {
221  SCIP_CONSDATA* consdata;
222  int c;
223  int i;
224 
225  assert(result != NULL);
226 
227  *result = SCIP_FEASIBLE;
228 
229  for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
230  {
231  SCIP_RESULT subresult = SCIP_FEASIBLE;
232 
233  consdata = SCIPconsGetData(conss[c]);
234  assert(consdata != NULL);
235 
236  /* check all constraints */
237  for( i = 0; i < consdata->nconss && subresult == SCIP_FEASIBLE; ++i )
238  {
239  SCIP_CALL( SCIPcheckCons(scip, consdata->conss[i], sol, checkintegrality, checklprows, printreason, &subresult) );
240  assert(subresult == SCIP_FEASIBLE || subresult == SCIP_INFEASIBLE);
241  }
242 
243  if( subresult == SCIP_INFEASIBLE )
244  {
245  /* mark solution as violated */
246  *result = SCIP_INFEASIBLE;
247  /* update constraint violation in solution */
248  if ( sol != NULL )
249  SCIPupdateSolConsViolation(scip, sol, 1.0, 1.0);
250  if( printreason )
251  {
252  assert( 0 < i && i <= consdata->nconss );
253  SCIPinfoMessage(scip, NULL, "Conjunction constraint %s is violated, at least the sub-constraint %s is violated by this given solution.\n",
254  SCIPconsGetName(conss[c]), SCIPconsGetName(consdata->conss[i-1]));
255  SCIPdebug( SCIP_CALL( SCIPprintCons(scip, conss[c], NULL) ) );
256  }
257  }
258  }
259 
260  return SCIP_OKAY;
261 }
262 
263 
264 /*
265  * Callback methods of constraint handler
266  */
267 
268 
269  /** copy method for constraint handler plugins (called when SCIP copies plugins) */
270 static
271 SCIP_DECL_CONSHDLRCOPY(conshdlrCopyConjunction)
272 { /*lint --e{715}*/
273  assert(scip != NULL);
274  assert(conshdlr != NULL);
275  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
276 
277  /* call inclusion method of constraint handler */
279 
280  *valid = TRUE;
281 
282  return SCIP_OKAY;
283 }
284 
285 
286 /** frees specific constraint data */
287 static
288 SCIP_DECL_CONSDELETE(consDeleteConjunction)
289 { /*lint --e{715}*/
290  SCIP_CALL( consdataFree(scip, consdata) );
291 
292  return SCIP_OKAY;
293 }
294 
295 /** transforms constraint data into data belonging to the transformed problem */
296 static
297 SCIP_DECL_CONSTRANS(consTransConjunction)
298 { /*lint --e{715}*/
299  SCIP_CONSDATA* sourcedata;
300  SCIP_CONSDATA* targetdata;
301  int c;
302 
303  /* create constraint data for target constraint */
304  SCIP_CALL( SCIPallocBlockMemory(scip, &targetdata) );
305 
306  /* get constraint data of source constraint */
307  sourcedata = SCIPconsGetData(sourcecons);
308 
309  if( sourcedata->nconss > 0 )
310  {
311  targetdata->consssize = sourcedata->nconss;
312  targetdata->nconss = sourcedata->nconss;
313  SCIP_CALL( SCIPallocBlockMemoryArray(scip, &targetdata->conss, targetdata->consssize) );
314  for( c = 0; c < sourcedata->nconss; ++c )
315  {
316  SCIP_CALL( SCIPtransformCons(scip, sourcedata->conss[c], &targetdata->conss[c]) );
317  }
318  }
319  else
320  {
321  targetdata->conss = NULL;
322  targetdata->consssize = 0;
323  targetdata->nconss = 0;
324  }
325 
326  /* create target constraint */
327  SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
328  SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
329  SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
330  SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
331  SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
332 
333  return SCIP_OKAY;
334 }
335 
336 
337 /** constraint enforcing method of constraint handler for LP solutions */
338 static
339 SCIP_DECL_CONSENFOLP(consEnfolpConjunction)
340 { /*lint --e{715}*/
341  *result = SCIP_FEASIBLE;
342 
343  /* add all constraints to the current node */
344  SCIP_CALL( addAllConss(scip, conss, nconss, result) );
345 
346  return SCIP_OKAY;
347 }
348 
349 
350 /** constraint enforcing method of constraint handler for relaxation solutions */
351 static
352 SCIP_DECL_CONSENFORELAX(consEnforelaxConjunction)
353 { /*lint --e{715}*/
354  *result = SCIP_FEASIBLE;
355 
356  /* add all constraints to the current node */
357  SCIP_CALL( addAllConss(scip, conss, nconss, result) );
358 
359  return SCIP_OKAY;
360 }
361 
362 
363 /** constraint enforcing method of constraint handler for pseudo solutions */
364 static
365 SCIP_DECL_CONSENFOPS(consEnfopsConjunction)
366 { /*lint --e{715}*/
367  *result = SCIP_FEASIBLE;
368 
369  /* add all constraints to the current node */
370  SCIP_CALL( addAllConss(scip, conss, nconss, result) );
371 
372  return SCIP_OKAY;
373 }
374 
375 
376 /** feasibility check method of constraint handler for integral solutions */
377 static
378 SCIP_DECL_CONSCHECK(consCheckConjunction)
379 { /*lint --e{715}*/
380  *result = SCIP_FEASIBLE;
381 
382  /* check all constraints of the conjunction */
383  SCIP_CALL( checkAllConss(scip, conss, nconss, sol, checkintegrality, checklprows, printreason, completely, result) );
384 
385  return SCIP_OKAY;
386 }
387 
388 
389 /** presolving method of constraint handler */
390 static
391 SCIP_DECL_CONSPRESOL(consPresolConjunction)
392 { /*lint --e{715}*/
393  SCIP_CONSDATA* consdata;
394  int c;
395  int i;
396 
397  assert(result != NULL);
398 
399  *result = SCIP_DIDNOTFIND;
400 
401  /* all constraints in a conjunction constraint of the global problem can be added directly to the problem and
402  * removed from the conjunction constraint;
403  * an unmodifiable conjunction constraint can be deleted
404  */
405  for( c = 0; c < nconss; ++c )
406  {
407  consdata = SCIPconsGetData(conss[c]);
408  assert(consdata != NULL);
409 
410  /* add all inactive constraints to the global problem */
411  for( i = 0; i < consdata->nconss; ++i )
412  {
413  /* update check flag for sub constraints when upgrade takes place */
414  if( SCIPconsIsChecked(conss[c]) )
415  {
416  /* make sure, the constraint is checked for feasibility */
417  SCIP_CALL( SCIPsetConsChecked(scip, consdata->conss[i], TRUE) );
418  }
419 
420  /* add constraint, if it is not active yet */
421  if( !SCIPconsIsActive(consdata->conss[i]) )
422  {
423  SCIPdebugMsg(scip, "adding constraint <%s> from add conjunction <%s>\n",
424  SCIPconsGetName(consdata->conss[i]), SCIPconsGetName(conss[c]));
425  SCIP_CALL( SCIPaddCons(scip, consdata->conss[i]) );
426  *result = SCIP_SUCCESS;
427  }
428  /* release constraint because it will be removed from the conjunction constraint */
429  SCIP_CALL( SCIPreleaseCons(scip, &(consdata->conss[i])) );
430  }
431  /* all constraints where removed, so we need to clear the array */
432  consdata->nconss = 0;
433 
434  /* delete conjunction constraint, if it is unmodifiable */
435  if( !SCIPconsIsModifiable(conss[c]) )
436  {
437  SCIP_CALL( SCIPdelCons(scip, conss[c]) );
438  }
439  }
440 
441  return SCIP_OKAY;
442 }
443 
444 
445 /** variable rounding lock method of constraint handler */
446 static
447 SCIP_DECL_CONSLOCK(consLockConjunction)
448 { /*lint --e{715}*/
449  SCIP_CONSDATA* consdata;
450  int c;
451 
452  consdata = SCIPconsGetData(cons);
453  assert(consdata != NULL);
454 
455  /* lock sub constraints */
456  for( c = 0; c < consdata->nconss; ++c )
457  {
458  SCIP_CALL( SCIPaddConsLocks(scip, consdata->conss[c], nlockspos, nlocksneg) );
459  }
460 
461  return SCIP_OKAY;
462 }
463 
464 
465 /** constraint display method of constraint handler */
466 static
467 SCIP_DECL_CONSPRINT(consPrintConjunction)
468 { /*lint --e{715}*/
469  SCIP_CONSDATA* consdata;
470  int i;
471 
472  assert( scip != NULL );
473  assert( conshdlr != NULL );
474  assert( cons != NULL );
475 
476  consdata = SCIPconsGetData(cons);
477  assert(consdata != NULL);
478 
479  SCIPinfoMessage(scip, file, "conjunction(");
480 
481  for( i = 0; i < consdata->nconss; ++i )
482  {
483  if( i > 0 )
484  SCIPinfoMessage(scip, file, ", ");
485  SCIP_CALL( SCIPprintCons(scip, consdata->conss[i], file) );
486  }
487  SCIPinfoMessage(scip, file, ")");
488 
489  return SCIP_OKAY;
490 }
491 
492 /** constraint parsing method of constraint handler */
493 static
494 SCIP_DECL_CONSPARSE(consParseConjunction)
495 { /*lint --e{715}*/
496  SCIP_CONS** conss;
497  int nconss;
498  int sconss;
499  char* token;
500  char* saveptr;
501  char* nexttokenstart;
502  char* copystr;
503 
504  assert(scip != NULL);
505  assert(conshdlr != NULL);
506  assert(cons != NULL);
507  assert(success != NULL);
508  assert(str != NULL);
509  assert(name != NULL);
510 
511  SCIPdebugMsg(scip, "parsing conjunction <%s>\n", name);
512 
513  *success = TRUE;
514 
515  /* allocate memory for constraint in conjunction, initial size is set to 10 */
516  nconss = 0;
517  sconss = 10;
518  SCIP_CALL( SCIPallocBufferArray(scip, &conss, sconss) );
519  SCIP_CALL( SCIPduplicateBufferArray(scip, &copystr, str, (int)strlen(str)+1) );
520 
521  /* find '(' at the beginning, string should start with 'conjunction(' */
522  saveptr = strpbrk(copystr, "("); /*lint !e158*/
523 
524  if( saveptr == NULL )
525  {
526  SCIPdebugMsg(scip, "error parsing conjunctive constraint: \"%s\"\n", str);
527  *success = FALSE;
528  goto TERMINATE;
529  }
530 
531  /* skip '(' */
532  ++saveptr;
533  /* remember token start position */
534  nexttokenstart = saveptr;
535 
536  /* brackets '(' and ')' can exist co we check for them and the constraint delimeter */
537  saveptr = strpbrk(saveptr, "(,");
538 
539  /* brackets '(' and ')' can exist in the rest of the string so we need to skip them to find the end of the first
540  * sub-constraint marked by a ','
541  */
542  if( saveptr != NULL )
543  {
544  do
545  {
546  int bracketcounter = 0;
547 
548  if( *saveptr == '(' )
549  {
550  do
551  {
552  ++bracketcounter;
553  ++saveptr;
554 
555  /* find last ending bracket */
556  while( bracketcounter > 0 )
557  {
558  saveptr = strpbrk(saveptr, "()");
559 
560  if( saveptr != NULL )
561  {
562  if( *saveptr == '(' )
563  ++bracketcounter;
564  else
565  --bracketcounter;
566 
567  ++saveptr;
568  }
569  else
570  {
571  SCIPdebugMsg(scip, "error parsing conjunctive constraint: \"%s\"\n", str);
572  *success = FALSE;
573  goto TERMINATE;
574  }
575  }
576 
577  saveptr = strpbrk(saveptr, "(,");
578  }
579  while( saveptr != NULL && *saveptr == '(' );
580  }
581 
582  /* we found a ',' so the end of the first sub-constraint is determined */
583  if( saveptr != NULL )
584  {
585  assert(*saveptr == ',');
586 
587  /* resize constraint array if necessary */
588  if( nconss == sconss )
589  {
590  sconss = SCIPcalcMemGrowSize(scip, nconss+1);
591  assert(nconss < sconss);
592 
593  SCIP_CALL( SCIPreallocBufferArray(scip, &conss, sconss) );
594  }
595 
596  assert(saveptr > nexttokenstart);
597 
598  /* extract token for parsing */
599  SCIP_CALL( SCIPduplicateBufferArray(scip, &token, nexttokenstart, saveptr - nexttokenstart + 1) );
600  token[saveptr - nexttokenstart] = '\0';
601 
602  SCIPdebugMsg(scip, "conjunctive parsing token(constraint): %s\n", token);
603 
604  /* parsing a constraint, part of the conjunction */
605  SCIP_CALL( SCIPparseCons(scip, &(conss[nconss]), token, initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, success) );
606 
607  SCIPfreeBufferArray(scip, &token);
608 
609  if( *success )
610  ++nconss;
611  else
612  {
613  SCIPdebugMsg(scip, "error parsing conjunctive constraint: \"%s\"\n", str);
614  goto TERMINATE;
615  }
616  /* skip ',' delimeter */
617  ++saveptr;
618  /* remember token start position */
619  nexttokenstart = saveptr;
620 
621  saveptr = strpbrk(saveptr, "(,");
622  }
623  }
624  while( saveptr != NULL );
625  }
626 
627  /* find end of conjunction constraint */
628  saveptr = strrchr(nexttokenstart, ')');
629 
630  if( saveptr == NULL )
631  {
632  SCIPdebugMsg(scip, "error parsing conjunctive constraint: \"%s\"\n", str);
633  *success = FALSE;
634  goto TERMINATE;
635  }
636  /* parse last sub-constraint */
637  else
638  {
639  /* resize constraint array if necessary */
640  if( nconss == sconss )
641  {
642  ++sconss;
643  SCIP_CALL( SCIPreallocBufferArray(scip, &conss, sconss) );
644  }
645 
646  assert(saveptr > nexttokenstart);
647 
648  /* extract token for parsing */
649  SCIP_CALL( SCIPduplicateBufferArray(scip, &token, nexttokenstart, saveptr - nexttokenstart + 1) );
650  token[saveptr - nexttokenstart] = '\0';
651 
652  SCIPdebugMsg(scip, "conjunctive parsing token(constraint): %s\n", token);
653 
654  /* parsing a constraint, part of the conjunction */
655  SCIP_CALL( SCIPparseCons(scip, &(conss[nconss]), token, initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode, success) );
656 
657  if( *success )
658  ++nconss;
659 
660  SCIPfreeBufferArray(scip, &token);
661  }
662  assert(nconss > 0 || !(*success));
663 
664  /* if parsing sub-constraints was fine, create the conjunctive constraint */
665  if( *success )
666  {
667  /* create conjunctive constraint */
668  SCIP_CALL( SCIPcreateConsConjunction(scip, cons, name, nconss, conss,
669  enforce, check, local, modifiable, dynamic) );
670  }
671 
672  /* free parsed constraints */
673  for( --nconss; nconss >= 0; --nconss )
674  {
675  SCIP_CALL( SCIPreleaseCons(scip, &conss[nconss]) );
676  }
677 
678  TERMINATE:
679  /* free temporary memory */
680  SCIPfreeBufferArray(scip, &copystr);
681  SCIPfreeBufferArray(scip, &conss);
682 
683  return SCIP_OKAY;
684 }
685 
686 /** constraint copying method of constraint handler */
687 static
688 SCIP_DECL_CONSCOPY(consCopyConjunction)
689 { /*lint --e{715}*/
690  SCIP_CONSDATA* sourcedata;
691  SCIP_CONS** sourceconss;
692  SCIP_CONS** conss;
693  int nconss;
694  int c;
695 
696  *valid = TRUE;
697 
698  sourcedata = SCIPconsGetData(sourcecons);
699  assert(sourcedata != NULL);
700 
701  sourceconss = sourcedata->conss;
702  nconss = sourcedata->nconss;
703 
704  if( nconss > 0 )
705  {
706  assert(sourceconss != NULL);
707 
708  SCIP_CALL( SCIPallocBufferArray(scip, &conss, nconss) );
709 
710  /* copy each constraint one by one */
711  for( c = 0; c < nconss && (*valid); ++c )
712  {
713  SCIP_CALL( SCIPgetConsCopy(sourcescip, scip, sourceconss[c], &conss[c], SCIPconsGetHdlr(sourceconss[c]),
714  varmap, consmap, SCIPconsGetName(sourceconss[c]),
715  SCIPconsIsInitial(sourceconss[c]), SCIPconsIsSeparated(sourceconss[c]), SCIPconsIsEnforced(sourceconss[c]),
716  SCIPconsIsChecked(sourceconss[c]), SCIPconsIsPropagated(sourceconss[c]),
717  SCIPconsIsLocal(sourceconss[c]), SCIPconsIsModifiable(sourceconss[c]),
718  SCIPconsIsDynamic(sourceconss[c]), SCIPconsIsRemovable(sourceconss[c]), SCIPconsIsStickingAtNode(sourceconss[c]),
719  global, valid) );
720  assert(!(*valid) || conss[c] != NULL);
721  }
722 
723  if( *valid )
724  {
725  if( name == NULL )
726  {
727  SCIP_CALL( SCIPcreateConsConjunction(scip, cons, SCIPconsGetName(sourcecons), nconss, conss,
728  enforce, check, local, modifiable, dynamic) );
729  }
730  else
731  {
732  SCIP_CALL( SCIPcreateConsConjunction(scip, cons, name, nconss, conss,
733  enforce, check, local, modifiable, dynamic) );
734  }
735  }
736 
737  /* release the copied constraints */
738  for( c = (*valid ? c - 1 : c - 2); c >= 0; --c )
739  {
740  assert(conss[c] != NULL);
741  SCIP_CALL( SCIPreleaseCons(scip, &conss[c]) );
742  }
743 
744  SCIPfreeBufferArray(scip, &conss);
745  }
746 
747  return SCIP_OKAY;
748 }
749 
750 
751 /*
752  * constraint specific interface methods
753  */
754 
755 /** creates the handler for conjunction constraints and includes it in SCIP */
757  SCIP* scip /**< SCIP data structure */
758  )
759 {
760  SCIP_CONSHDLR* conshdlr;
761 
762  /* include constraint handler */
765  consEnfolpConjunction, consEnfopsConjunction, consCheckConjunction, consLockConjunction,
766  NULL) );
767 
768  assert(conshdlr != NULL);
769 
770  /* set non-fundamental callbacks via specific setter functions */
771  SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyConjunction, consCopyConjunction) );
772  SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteConjunction) );
773  SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseConjunction) );
774  SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolConjunction, CONSHDLR_MAXPREROUNDS,
776  SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintConjunction) );
777  SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransConjunction) );
778  SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxConjunction) );
779 
780  return SCIP_OKAY;
781 }
782 
783 /** creates and captures a conjunction constraint
784  *
785  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
786  */
788  SCIP* scip, /**< SCIP data structure */
789  SCIP_CONS** cons, /**< pointer to hold the created constraint */
790  const char* name, /**< name of constraint */
791  int nconss, /**< number of initial constraints in conjunction */
792  SCIP_CONS** conss, /**< initial constraint in conjunction */
793  SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
794  * TRUE for model constraints, FALSE for additional, redundant constraints. */
795  SCIP_Bool check, /**< should the constraint be checked for feasibility?
796  * TRUE for model constraints, FALSE for additional, redundant constraints. */
797  SCIP_Bool local, /**< is constraint only valid locally?
798  * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
799  SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
800  * Usually set to FALSE. In column generation applications, set to TRUE if pricing
801  * adds coefficients to this constraint. */
802  SCIP_Bool dynamic /**< is constraint subject to aging?
803  * Usually set to FALSE. Set to TRUE for own cuts which
804  * are separated as constraints. */
805  )
806 {
807  SCIP_CONSHDLR* conshdlr;
808  SCIP_CONSDATA* consdata;
809 
810  /* find the conjunction constraint handler */
811  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
812  if( conshdlr == NULL )
813  {
814  SCIPerrorMessage("conjunction constraint handler not found\n");
815  return SCIP_PLUGINNOTFOUND;
816  }
817 
818  /* create constraint data */
819  SCIP_CALL( consdataCreate(scip, &consdata, conss, nconss) );
820 
821  /* create constraint */
822  SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, FALSE, FALSE, enforce, check, FALSE,
823  local, modifiable, dynamic, FALSE, FALSE) );
824 
825  return SCIP_OKAY;
826 }
827 
828 /** creates and captures an and constraint
829  * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
830  * method SCIPcreateConsConjunction(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
831  *
832  * @see SCIPcreateConsConjunction() for information about the basic constraint flag configuration
833  *
834  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
835  */
837  SCIP* scip, /**< SCIP data structure */
838  SCIP_CONS** cons, /**< pointer to hold the created constraint */
839  const char* name, /**< name of constraint */
840  int nconss, /**< number of initial constraints in conjunction */
841  SCIP_CONS** conss /**< initial constraint in conjunction */
842  )
843 {
844  assert(scip != NULL);
845 
846  SCIP_CALL( SCIPcreateConsConjunction(scip, cons, name, nconss, conss,
847  TRUE, TRUE, FALSE, FALSE, FALSE) );
848 
849  return SCIP_OKAY;
850 }
851 
852 /** adds constraint to the conjunction of constraints */
854  SCIP* scip, /**< SCIP data structure */
855  SCIP_CONS* cons, /**< conjunction constraint */
856  SCIP_CONS* addcons /**< additional constraint in conjunction */
857  )
858 {
859  SCIP_CONSDATA* consdata;
860 
861  assert(cons != NULL);
862  assert(addcons != NULL);
863 
864  if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
865  {
866  SCIPerrorMessage("constraint is not a conjunction constraint\n");
867  return SCIP_INVALIDDATA;
868  }
869 
870  consdata = SCIPconsGetData(cons);
871  assert(consdata != NULL);
872 
873  SCIP_CALL( consdataAddCons(scip, consdata, addcons) );
874 
875  return SCIP_OKAY;
876 }
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
Definition: scip.c:6291
#define SCIPallocBlockMemoryArray(scip, ptr, num)
Definition: scip.h:22587
static SCIP_DECL_CONSPARSE(consParseConjunction)
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:8245
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
Definition: scip.c:6314
#define CONSHDLR_DESC
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip.c:6604
SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
Definition: scip.c:6036
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:12663
int SCIPcalcMemGrowSize(SCIP *scip, int num)
Definition: scip.c:46813
SCIP_RETCODE SCIPtransformConss(SCIP *scip, int nconss, SCIP_CONS **conss, SCIP_CONS **transconss)
Definition: scip.c:28213
#define FALSE
Definition: def.h:64
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:5894
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:27668
#define TRUE
Definition: def.h:63
#define SCIPdebug(x)
Definition: pub_message.h:74
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition: cons.c:8265
static SCIP_RETCODE checkAllConss(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_SOL *sol, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_Bool completely, SCIP_RESULT *result)
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip.h:22602
static SCIP_RETCODE consdataCreate(SCIP *scip, SCIP_CONSDATA **consdata, SCIP_CONS **conss, int nconss)
static SCIP_DECL_CONSCOPY(consCopyConjunction)
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip.h:22628
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:22632
#define CONSHDLR_ENFOPRIORITY
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip.h:22585
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip.c:1017
static SCIP_DECL_CONSLOCK(consLockConjunction)
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:8255
#define SCIPdebugMsg
Definition: scip.h:455
SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
Definition: scip.c:6521
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition: cons.c:8047
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip.c:1343
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:27584
#define CONSHDLR_NAME
static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata)
#define CONSHDLR_EAGERFREQ
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip.h:22599
SCIP_RETCODE SCIPcreateConsBasicConjunction(SCIP *scip, SCIP_CONS **cons, const char *name, int nconss, SCIP_CONS **conss)
static SCIP_DECL_CONSCHECK(consCheckConjunction)
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
Definition: scip.c:6060
constraint handler for conjunction constraints
#define SCIPerrorMessage
Definition: pub_message.h:45
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4113
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:12591
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.c:13216
SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:13297
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:28690
SCIP_RETCODE SCIPsetConsChecked(SCIP *scip, SCIP_CONS *cons, SCIP_Bool check)
Definition: scip.c:27934
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:7986
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:8205
SCIP_RETCODE SCIPaddConsElemConjunction(SCIP *scip, SCIP_CONS *cons, SCIP_CONS *addcons)
SCIP_RETCODE SCIPtransformCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **transcons)
Definition: scip.c:28172
#define SCIP_CALL(x)
Definition: def.h:350
SCIP_RETCODE SCIPincludeConshdlrConjunction(SCIP *scip)
#define SCIPensureBlockMemoryArray(scip, ptr, arraysizeptr, minsize)
Definition: scip.h:22601
static SCIP_DECL_CONSENFOLP(consEnfolpConjunction)
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8225
#define CONSHDLR_PRESOLTIMING
SCIP_RETCODE SCIPcaptureCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:27726
struct SCIP_ConsData SCIP_CONSDATA
Definition: type_cons.h:50
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.c:2533
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:22620
#define SCIP_Bool
Definition: def.h:61
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip.c:29091
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8006
static SCIP_DECL_CONSENFORELAX(consEnforelaxConjunction)
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8185
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:8155
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 SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
Definition: scip.c:6498
static SCIP_DECL_CONSPRINT(consPrintConjunction)
#define CONSHDLR_CHECKPRIORITY
static SCIP_DECL_CONSDELETE(consDeleteConjunction)
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition: cons.c:8016
static SCIP_DECL_CONSENFOPS(consEnfopsConjunction)
static SCIP_DECL_CONSTRANS(consTransConjunction)
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip.c:27761
SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
Definition: scip.c:6253
void SCIPupdateSolConsViolation(SCIP *scip, SCIP_SOL *sol, SCIP_Real absviol, SCIP_Real relviol)
Definition: scip.c:13790
static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyConjunction)
static SCIP_DECL_CONSPRESOL(consPresolConjunction)
#define CONSHDLR_MAXPREROUNDS
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8235
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:8175
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8165
SCIP_RETCODE SCIPaddConsLocks(SCIP *scip, SCIP_CONS *cons, int nlockspos, int nlocksneg)
Definition: scip.c:28660
#define SCIPfreeBlockMemoryArrayNull(scip, ptr, num)
Definition: scip.h:22605
#define CONSHDLR_NEEDSCONS
#define SCIPreallocBufferArray(scip, ptr, num)
Definition: scip.h:22624
static SCIP_RETCODE addAllConss(SCIP *scip, SCIP_CONS **conss, int nconss, SCIP_RESULT *result)