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