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