SCIP Doxygen Documentation
 
Loading...
Searching...
No Matches
cons_or.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-2024 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_or.c
26 * @ingroup DEFPLUGINS_CONS
27 * @brief Constraint handler for "or" constraints, \f$r = x_1 \vee x_2 \vee \dots \vee x_n\f$
28 * @author Tobias Achterberg
29 * @author Stefan Heinz
30 * @author Michael Winkler
31 *
32 * This constraint handler deals with "or" constraint. These are constraint of the form:
33 *
34 * \f[
35 * r = x_1 \vee x_2 \vee \dots \vee x_n
36 * \f]
37 *
38 * where \f$x_i\f$ is a binary variable for all \f$i\f$. Hence, \f$r\f$ is also of binary type. The variable \f$r\f$ is
39 * called resultant and the \f$x\f$'s operators.
40 */
41
42/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
43
45#include "scip/cons_and.h"
46#include "scip/cons_or.h"
47#include "scip/pub_cons.h"
48#include "scip/pub_event.h"
49#include "scip/pub_lp.h"
50#include "scip/pub_message.h"
51#include "scip/pub_misc.h"
52#include "scip/pub_var.h"
53#include "scip/scip_conflict.h"
54#include "scip/scip_cons.h"
55#include "scip/scip_copy.h"
56#include "scip/scip_cut.h"
57#include "scip/scip_event.h"
58#include "scip/scip_general.h"
59#include "scip/scip_lp.h"
60#include "scip/scip_mem.h"
61#include "scip/scip_message.h"
62#include "scip/scip_numerics.h"
63#include "scip/scip_prob.h"
64#include "scip/scip_probing.h"
65#include "scip/scip_sol.h"
66#include "scip/scip_tree.h"
67#include "scip/scip_var.h"
68#include "scip/symmetry_graph.h"
70#include <string.h>
71
72
73/* constraint handler properties */
74#define CONSHDLR_NAME "or"
75#define CONSHDLR_DESC "constraint handler for or constraints: r = or(x1, ..., xn)"
76#define CONSHDLR_SEPAPRIORITY +850000 /**< priority of the constraint handler for separation */
77#define CONSHDLR_ENFOPRIORITY -850000 /**< priority of the constraint handler for constraint enforcing */
78#define CONSHDLR_CHECKPRIORITY -850000 /**< priority of the constraint handler for checking feasibility */
79#define CONSHDLR_SEPAFREQ 0 /**< frequency for separating cuts; zero means to separate only in the root node */
80#define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
81#define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
82 * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
83#define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
84#define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
85#define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
86#define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
87
88#define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP /**< propagation timing mask of the constraint handler */
89#define CONSHDLR_PRESOLTIMING SCIP_PRESOLTIMING_MEDIUM /**< presolving timing of the constraint handler (fast, medium, or exhaustive) */
90
91#define EVENTHDLR_NAME "or"
92#define EVENTHDLR_DESC "event handler for or constraints"
93
94
95/*
96 * Data structures
97 */
98
99/** constraint data for or constraints */
100struct SCIP_ConsData
101{
102 SCIP_VAR** vars; /**< variables in the or operation */
103 SCIP_VAR* resvar; /**< resultant variable */
104 SCIP_ROW** rows; /**< rows for linear relaxation of or constraint */
105 int nvars; /**< number of variables in or operation */
106 int varssize; /**< size of vars array */
107 int rowssize; /**< size of rows array */
108 int watchedvar1; /**< position of first watched operator variable */
109 int watchedvar2; /**< position of second watched operator variable */
110 int filterpos1; /**< event filter position of first watched operator variable */
111 int filterpos2; /**< event filter position of second watched operator variable */
112 unsigned int propagated:1; /**< is constraint already preprocessed/propagated? */
113 unsigned int nofixedone:1; /**< is none of the operator variables fixed to TRUE? */
114 unsigned int impladded:1; /**< were the implications of the constraint already added? */
115 unsigned int opimpladded:1; /**< was the implication for 2 operands with fixed resultant added? */
116};
117
118/** constraint handler data */
119struct SCIP_ConshdlrData
120{
121 SCIP_EVENTHDLR* eventhdlr; /**< event handler for events on watched variables */
122};
123
124
125/*
126 * Propagation rules
127 */
128
130{
131 PROPRULE_1 = 0, /**< v_i = TRUE => r = TRUE */
132 PROPRULE_2 = 1, /**< r = FALSE => v_i = FALSE for all i */
133 PROPRULE_3 = 2, /**< v_i = FALSE for all i => r = FALSE */
134 PROPRULE_4 = 3, /**< r = TRUE, v_i = FALSE for all i except j => v_j = TRUE */
135 PROPRULE_INVALID = 4 /**< propagation was applied without a specific propagation rule */
137typedef enum Proprule PROPRULE;
138
139
140/*
141 * Local methods
142 */
143
144/** installs rounding locks for the given variable in the given or constraint */
145static
147 SCIP* scip, /**< SCIP data structure */
148 SCIP_CONS* cons, /**< or constraint */
149 SCIP_VAR* var /**< variable of constraint entry */
150 )
151{
153
154 /* rounding in both directions may violate the constraint */
156
157 return SCIP_OKAY;
158}
159
160/** removes rounding locks for the given variable in the given or constraint */
161static
163 SCIP* scip, /**< SCIP data structure */
164 SCIP_CONS* cons, /**< or constraint */
165 SCIP_VAR* var /**< variable of constraint entry */
166 )
167{
169
170 /* rounding in both directions may violate the constraint */
172
173 return SCIP_OKAY;
174}
175
176/** creates constraint handler data */
177static
179 SCIP* scip, /**< SCIP data structure */
180 SCIP_CONSHDLRDATA** conshdlrdata, /**< pointer to store the constraint handler data */
181 SCIP_EVENTHDLR* eventhdlr /**< event handler */
182 )
183{
184 assert(scip != NULL);
185 assert(conshdlrdata != NULL);
186 assert(eventhdlr != NULL);
187
188 SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
189
190 /* set event handler for catching events on watched variables */
191 (*conshdlrdata)->eventhdlr = eventhdlr;
192
193 return SCIP_OKAY;
194}
195
196/** frees constraint handler data */
197static
199 SCIP* scip, /**< SCIP data structure */
200 SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to the constraint handler data */
201 )
202{
203 assert(conshdlrdata != NULL);
204 assert(*conshdlrdata != NULL);
205
206 SCIPfreeBlockMemory(scip, conshdlrdata);
207}
208
209/** gets number of LP rows needed for the LP relaxation of the constraint */
210static
212 SCIP_CONSDATA* consdata /**< constraint data */
213 )
214{
215 assert(consdata != NULL);
216
217 return consdata->nvars + 1;
218}
219
220/** catches events for the watched variable at given position */
221static
223 SCIP* scip, /**< SCIP data structure */
224 SCIP_CONSDATA* consdata, /**< or constraint data */
225 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
226 int pos, /**< array position of variable to catch bound change events for */
227 int* filterpos /**< pointer to store position of event filter entry */
228 )
229{
230 assert(consdata != NULL);
231 assert(consdata->vars != NULL);
232 assert(eventhdlr != NULL);
233 assert(0 <= pos && pos < consdata->nvars);
234 assert(filterpos != NULL);
235
236 /* catch tightening events for upper bound and relaxed events for lower bounds on watched variable */
238 eventhdlr, (SCIP_EVENTDATA*)consdata, filterpos) );
239
240 return SCIP_OKAY;
241}
242
243
244/** drops events for the watched variable at given position */
245static
247 SCIP* scip, /**< SCIP data structure */
248 SCIP_CONSDATA* consdata, /**< or constraint data */
249 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
250 int pos, /**< array position of watched variable to drop bound change events for */
251 int filterpos /**< position of event filter entry */
252 )
253{
254 assert(consdata != NULL);
255 assert(consdata->vars != NULL);
256 assert(eventhdlr != NULL);
257 assert(0 <= pos && pos < consdata->nvars);
258 assert(filterpos >= 0);
259
260 /* drop tightening events for upper bound and relaxed events for lower bounds on watched variable */
262 eventhdlr, (SCIP_EVENTDATA*)consdata, filterpos) );
263
264 return SCIP_OKAY;
265}
266
267/** catches needed events on all variables of constraint, except the special ones for watched variables */
268static
270 SCIP* scip, /**< SCIP data structure */
271 SCIP_CONSDATA* consdata, /**< or constraint data */
272 SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
273 )
274{
275 int i;
276
277 assert(consdata != NULL);
278
279 /* catch bound change events for both bounds on resultant variable */
281 eventhdlr, (SCIP_EVENTDATA*)consdata, NULL) );
282
283 /* catch tightening events for lower bound and relaxed events for upper bounds on operator variables */
284 for( i = 0; i < consdata->nvars; ++i )
285 {
287 eventhdlr, (SCIP_EVENTDATA*)consdata, NULL) );
288 }
289
290 return SCIP_OKAY;
291}
292
293/** drops events on all variables of constraint, except the special ones for watched variables */
294static
296 SCIP* scip, /**< SCIP data structure */
297 SCIP_CONSDATA* consdata, /**< or constraint data */
298 SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
299 )
300{
301 int i;
302
303 assert(consdata != NULL);
304
305 /* drop bound change events for both bounds on resultant variable */
307 eventhdlr, (SCIP_EVENTDATA*)consdata, -1) );
308
309 /* drop tightening events for lower bound and relaxed events for upper bounds on operator variables */
310 for( i = 0; i < consdata->nvars; ++i )
311 {
313 eventhdlr, (SCIP_EVENTDATA*)consdata, -1) );
314 }
315
316 return SCIP_OKAY;
317}
318
319/** stores the given variable numbers as watched variables, and updates the event processing */
320static
322 SCIP* scip, /**< SCIP data structure */
323 SCIP_CONSDATA* consdata, /**< or constraint data */
324 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
325 int watchedvar1, /**< new first watched variable */
326 int watchedvar2 /**< new second watched variable */
327 )
328{
329 assert(consdata != NULL);
330 assert(watchedvar1 == -1 || watchedvar1 != watchedvar2);
331 assert(watchedvar1 != -1 || watchedvar2 == -1);
332 assert(watchedvar1 == -1 || (0 <= watchedvar1 && watchedvar1 < consdata->nvars));
333 assert(watchedvar2 == -1 || (0 <= watchedvar2 && watchedvar2 < consdata->nvars));
334
335 /* if one watched variable is equal to the old other watched variable, just switch positions */
336 if( watchedvar1 == consdata->watchedvar2 || watchedvar2 == consdata->watchedvar1 )
337 {
338 int tmp;
339
340 tmp = consdata->watchedvar1;
341 consdata->watchedvar1 = consdata->watchedvar2;
342 consdata->watchedvar2 = tmp;
343 tmp = consdata->filterpos1;
344 consdata->filterpos1 = consdata->filterpos2;
345 consdata->filterpos2 = tmp;
346 }
347 assert(watchedvar1 == -1 || watchedvar1 != consdata->watchedvar2);
348 assert(watchedvar2 == -1 || watchedvar2 != consdata->watchedvar1);
349
350 /* drop events on old watched variables */
351 if( consdata->watchedvar1 != -1 && consdata->watchedvar1 != watchedvar1 )
352 {
353 assert(consdata->filterpos1 != -1);
354 SCIP_CALL( consdataDropWatchedEvents(scip, consdata, eventhdlr, consdata->watchedvar1, consdata->filterpos1) );
355 }
356 if( consdata->watchedvar2 != -1 && consdata->watchedvar2 != watchedvar2 )
357 {
358 assert(consdata->filterpos2 != -1);
359 SCIP_CALL( consdataDropWatchedEvents(scip, consdata, eventhdlr, consdata->watchedvar2, consdata->filterpos2) );
360 }
361
362 /* catch events on new watched variables */
363 if( watchedvar1 != -1 && watchedvar1 != consdata->watchedvar1 )
364 {
365 SCIP_CALL( consdataCatchWatchedEvents(scip, consdata, eventhdlr, watchedvar1, &consdata->filterpos1) );
366 }
367 if( watchedvar2 != -1 && watchedvar2 != consdata->watchedvar2 )
368 {
369 SCIP_CALL( consdataCatchWatchedEvents(scip, consdata, eventhdlr, watchedvar2, &consdata->filterpos2) );
370 }
371
372 /* set the new watched variables */
373 consdata->watchedvar1 = watchedvar1;
374 consdata->watchedvar2 = watchedvar2;
375
376 return SCIP_OKAY;
377}
378
379/** ensures, that the vars array can store at least num entries */
380static
382 SCIP* scip, /**< SCIP data structure */
383 SCIP_CONSDATA* consdata, /**< linear constraint data */
384 int num /**< minimum number of entries to store */
385 )
386{
387 assert(consdata != NULL);
388 assert(consdata->nvars <= consdata->varssize);
389
390 if( num > consdata->varssize )
391 {
392 int newsize;
393
395 SCIP_CALL( SCIPreallocBlockMemoryArray(scip, &consdata->vars, consdata->varssize, newsize) );
396 consdata->varssize = newsize;
397 }
398 assert(num <= consdata->varssize);
399
400 return SCIP_OKAY;
401}
402
403/** creates constraint data for or constraint */
404static
406 SCIP* scip, /**< SCIP data structure */
407 SCIP_CONSDATA** consdata, /**< pointer to store the constraint data */
408 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
409 int nvars, /**< number of variables in the or operation */
410 SCIP_VAR** vars, /**< variables in or operation */
411 SCIP_VAR* resvar /**< resultant variable */
412 )
413{
414 assert(consdata != NULL);
415 assert(nvars == 0 || vars != NULL);
416 assert(resvar != NULL);
417
418 SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
419 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vars, vars, nvars) );
420 (*consdata)->resvar = resvar;
421 (*consdata)->rows = NULL;
422 (*consdata)->nvars = nvars;
423 (*consdata)->varssize = nvars;
424 (*consdata)->rowssize = 0;
425 (*consdata)->watchedvar1 = -1;
426 (*consdata)->watchedvar2 = -1;
427 (*consdata)->filterpos1 = -1;
428 (*consdata)->filterpos2 = -1;
429 (*consdata)->propagated = FALSE;
430 (*consdata)->nofixedone = FALSE;
431 (*consdata)->impladded = FALSE;
432 (*consdata)->opimpladded = FALSE;
433
434 /* get transformed variables, if we are in the transformed problem */
436 {
437 SCIP_CALL( SCIPgetTransformedVars(scip, (*consdata)->nvars, (*consdata)->vars, (*consdata)->vars) );
438 SCIP_CALL( SCIPgetTransformedVar(scip, (*consdata)->resvar, &(*consdata)->resvar) );
439
440 /* catch needed events on variables */
441 SCIP_CALL( consdataCatchEvents(scip, *consdata, eventhdlr) );
442 }
443
444 return SCIP_OKAY;
445}
446
447/** releases LP rows of constraint data and frees rows array */
448static
450 SCIP* scip, /**< SCIP data structure */
451 SCIP_CONSDATA* consdata /**< constraint data */
452 )
453{
454 int r;
455
456 assert(consdata != NULL);
457
458 if( consdata->rows != NULL )
459 {
460 int nrows;
461
462 nrows = consdataGetNRows(consdata);
463
464 for( r = 0; r < nrows; ++r )
465 {
466 SCIP_CALL( SCIPreleaseRow(scip, &consdata->rows[r]) );
467 }
468 SCIPfreeBlockMemoryArray(scip, &consdata->rows, consdata->rowssize);
469 }
470
471 return SCIP_OKAY;
472}
473
474/** frees constraint data for or constraint */
475static
477 SCIP* scip, /**< SCIP data structure */
478 SCIP_CONSDATA** consdata, /**< pointer to the constraint data */
479 SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
480 )
481{
482 assert(consdata != NULL);
483 assert(*consdata != NULL);
484
486 {
487 /* drop events for watched variables */
488 SCIP_CALL( consdataSwitchWatchedvars(scip, *consdata, eventhdlr, -1, -1) );
489
490 /* drop all other events on variables */
491 SCIP_CALL( consdataDropEvents(scip, *consdata, eventhdlr) );
492 }
493 else
494 {
495 assert((*consdata)->watchedvar1 == -1);
496 assert((*consdata)->watchedvar2 == -1);
497 }
498
499 /* release and free the rows */
500 SCIP_CALL( consdataFreeRows(scip, *consdata) );
501
502 SCIPfreeBlockMemoryArray(scip, &(*consdata)->vars, (*consdata)->varssize);
503 SCIPfreeBlockMemory(scip, consdata);
504
505 return SCIP_OKAY;
506}
507
508/** prints or constraint to file stream */
509static
511 SCIP* scip, /**< SCIP data structure */
512 SCIP_CONSDATA* consdata, /**< or constraint data */
513 FILE* file /**< output file (or NULL for standard output) */
514 )
515{
516 assert(consdata != NULL);
517
518 /* print resultant */
519 SCIP_CALL( SCIPwriteVarName(scip, file, consdata->resvar, TRUE) );
520
521 /* start the variable list */
522 SCIPinfoMessage(scip, file, " == or(");
523
524 /* print variable list */
525 SCIP_CALL( SCIPwriteVarsList(scip, file, consdata->vars, consdata->nvars, TRUE, ',') );
526
527 /* close the variable list */
528 SCIPinfoMessage(scip, file, ")");
529
530 return SCIP_OKAY;
531}
532
533/** adds coefficient in or constraint */
534static
536 SCIP* scip, /**< SCIP data structure */
537 SCIP_CONS* cons, /**< linear constraint */
538 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
539 SCIP_VAR* var /**< variable to add to the constraint */
540 )
541{
542 SCIP_CONSDATA* consdata;
543 SCIP_Bool transformed;
544
545 assert(var != NULL);
546
547 consdata = SCIPconsGetData(cons);
548 assert(consdata != NULL);
549 assert(consdata->rows == NULL);
550
551 /* are we in the transformed problem? */
552 transformed = SCIPconsIsTransformed(cons);
553
554 /* always use transformed variables in transformed constraints */
555 if( transformed )
556 {
558 }
559 assert(var != NULL);
560 assert(transformed == SCIPvarIsTransformed(var));
561
562 SCIP_CALL( consdataEnsureVarsSize(scip, consdata, consdata->nvars+1) );
563 consdata->vars[consdata->nvars] = var;
564 consdata->nvars++;
565
566 /* if we are in transformed problem, catch the variable's events */
567 if( transformed )
568 {
569 /* catch bound change events of variable */
571 eventhdlr, (SCIP_EVENTDATA*)consdata, NULL) );
572 }
573
574 /* install the rounding locks for the new variable */
575 SCIP_CALL( lockRounding(scip, cons, var) );
576
577 /**@todo update LP rows */
578 if( consdata->rows != NULL )
579 {
580 SCIPerrorMessage("cannot add coefficients to or constraint after LP relaxation was created\n");
581 return SCIP_INVALIDCALL;
582 }
583
584 return SCIP_OKAY;
585}
586
587/** deletes coefficient at given position from or constraint data */
588static
590 SCIP* scip, /**< SCIP data structure */
591 SCIP_CONS* cons, /**< or constraint */
592 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
593 int pos /**< position of coefficient to delete */
594 )
595{
596 SCIP_CONSDATA* consdata;
597
598 assert(eventhdlr != NULL);
599
600 consdata = SCIPconsGetData(cons);
601 assert(consdata != NULL);
602 assert(0 <= pos && pos < consdata->nvars);
603 assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(consdata->vars[pos]));
604
605 /* remove the rounding locks of the variable */
606 SCIP_CALL( unlockRounding(scip, cons, consdata->vars[pos]) );
607
608 if( SCIPconsIsTransformed(cons) )
609 {
610 /* drop bound change events of variable */
612 eventhdlr, (SCIP_EVENTDATA*)consdata, -1) );
613 }
614
615 if( SCIPconsIsTransformed(cons) )
616 {
617 /* if the position is watched, stop watching the position */
618 if( consdata->watchedvar1 == pos )
619 {
620 SCIP_CALL( consdataSwitchWatchedvars(scip, consdata, eventhdlr, consdata->watchedvar2, -1) );
621 }
622 if( consdata->watchedvar2 == pos )
623 {
624 SCIP_CALL( consdataSwitchWatchedvars(scip, consdata, eventhdlr, consdata->watchedvar1, -1) );
625 }
626 }
627 assert(pos != consdata->watchedvar1);
628 assert(pos != consdata->watchedvar2);
629
630 /* move the last variable to the free slot */
631 consdata->vars[pos] = consdata->vars[consdata->nvars-1];
632 consdata->nvars--;
633
634 /* if the last variable (that moved) was watched, update the watched position */
635 if( consdata->watchedvar1 == consdata->nvars )
636 consdata->watchedvar1 = pos;
637 if( consdata->watchedvar2 == consdata->nvars )
638 consdata->watchedvar2 = pos;
639
640 consdata->propagated = FALSE;
641
642 return SCIP_OKAY;
643}
644
645/** deletes all zero-fixed variables */
646static
648 SCIP* scip, /**< SCIP data structure */
649 SCIP_CONS* cons, /**< or constraint */
650 SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
651 )
652{
653 SCIP_CONSDATA* consdata;
654 SCIP_VAR* var;
655 int v;
656
657 consdata = SCIPconsGetData(cons);
658 assert(consdata != NULL);
659 assert(consdata->nvars == 0 || consdata->vars != NULL);
660
661 v = 0;
662 while( v < consdata->nvars )
663 {
664 var = consdata->vars[v];
666
667 if( SCIPvarGetUbGlobal(var) < 0.5 )
668 {
670 SCIP_CALL( delCoefPos(scip, cons, eventhdlr, v) );
671 }
672 else
673 {
675 SCIP_Bool negated;
676
677 /* get binary representative of variable */
679
680 /* check, if the variable should be replaced with the representative */
681 if( repvar != var )
682 {
683 /* delete old (aggregated) variable */
684 SCIP_CALL( delCoefPos(scip, cons, eventhdlr, v) );
685
686 /* add representative instead */
687 SCIP_CALL( addCoef(scip, cons, eventhdlr, repvar) );
688 }
689 else
690 ++v;
691 }
692 }
693
694 SCIPdebugMsg(scip, "after fixings: ");
695 SCIPdebug( SCIP_CALL(consdataPrint(scip, consdata, NULL)) );
696 SCIPdebugMsgPrint(scip, "\n");
697
698 return SCIP_OKAY;
699}
700
701/** creates LP rows corresponding to or constraint:
702 * - for each operator variable vi: resvar - vi >= 0
703 * - one additional row: resvar - v1 - ... - vn <= 0
704 */
705static
707 SCIP* scip, /**< SCIP data structure */
708 SCIP_CONS* cons /**< constraint to check */
709 )
710{
711 SCIP_CONSDATA* consdata;
713 int nvars;
714 int i;
715
716 consdata = SCIPconsGetData(cons);
717 assert(consdata != NULL);
718 assert(consdata->rows == NULL);
719
720 nvars = consdata->nvars;
721
722 /* get memory for rows */
723 consdata->rowssize = consdataGetNRows(consdata);
724 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->rows, consdata->rowssize) );
725 assert(consdata->rowssize == nvars+1);
726
727 /* create operator rows */
728 for( i = 0; i < nvars; ++i )
729 {
731 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->rows[i], cons, rowname, 0.0, SCIPinfinity(scip),
733 SCIP_CALL( SCIPaddVarToRow(scip, consdata->rows[i], consdata->resvar, 1.0) );
734 SCIP_CALL( SCIPaddVarToRow(scip, consdata->rows[i], consdata->vars[i], -1.0) );
735 }
736
737 /* create additional row */
739 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->rows[nvars], cons, rowname, -SCIPinfinity(scip), 0.0,
741 SCIP_CALL( SCIPaddVarToRow(scip, consdata->rows[nvars], consdata->resvar, 1.0) );
742 SCIP_CALL( SCIPaddVarsToRowSameCoef(scip, consdata->rows[nvars], nvars, consdata->vars, -1.0) );
743
744 return SCIP_OKAY;
745}
746
747/** adds linear relaxation of or constraint to the LP */
748static
750 SCIP* scip, /**< SCIP data structure */
751 SCIP_CONS* cons, /**< constraint to check */
752 SCIP_Bool* infeasible /**< pointer to store whether an infeasibility was detected */
753 )
754{
755 SCIP_CONSDATA* consdata;
756 int r;
757 int nrows;
758
759 consdata = SCIPconsGetData(cons);
760 assert(consdata != NULL);
761
762 if( consdata->rows == NULL )
763 {
765 }
766 assert( consdata->rows != NULL );
767
768 nrows = consdataGetNRows(consdata);
769
770 for( r = 0; r < nrows && !(*infeasible); ++r )
771 {
772 if( !SCIProwIsInLP(consdata->rows[r]) )
773 {
774 SCIP_CALL( SCIPaddRow(scip, consdata->rows[r], FALSE, infeasible) );
775 }
776 }
777
778 return SCIP_OKAY;
779}
780
781/** checks or constraint for feasibility of given solution: returns TRUE iff constraint is feasible */
782static
784 SCIP* scip, /**< SCIP data structure */
785 SCIP_CONS* cons, /**< constraint to check */
786 SCIP_SOL* sol, /**< solution to check, NULL for current solution */
787 SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
788 SCIP_Bool printreason, /**< Should the reason for the violation be printed? */
789 SCIP_Bool* violated /**< pointer to store whether the constraint is violated */
790 )
791{
792 SCIP_CONSDATA* consdata;
793 SCIP_Bool mustcheck;
794 int r;
795
796 assert(violated != NULL);
797
798 consdata = SCIPconsGetData(cons);
799 assert(consdata != NULL);
800
801 *violated = FALSE;
802
803 /* check, if we can skip this feasibility check, because all rows are in the LP and doesn't have to be checked */
805 mustcheck = mustcheck || (consdata->rows == NULL);
806 if( !mustcheck )
807 {
808 int nrows;
809
810 assert(consdata->rows != NULL);
811
812 nrows = consdataGetNRows(consdata);
813
814 for( r = 0; r < nrows; ++r )
815 {
816 mustcheck = !SCIProwIsInLP(consdata->rows[r]);
817 if( mustcheck )
818 break;
819 }
820 }
821
822 /* check feasibility of constraint if necessary */
823 if( mustcheck )
824 {
825 SCIP_Real solval;
826 SCIP_Real maxsolval;
827 SCIP_Real sumsolval;
828 SCIP_Real viol;
829 int maxsolind;
830 int i;
831
832 /* increase age of constraint; age is reset to zero, if a violation was found only in case we are in
833 * enforcement
834 */
835 if( sol == NULL )
836 {
837 SCIP_CALL( SCIPincConsAge(scip, cons) );
838 }
839
840 maxsolind = 0;
841 maxsolval = 0.0;
842 sumsolval = 0.0;
843
844 /* evaluate operator variables */
845 for( i = 0; i < consdata->nvars; ++i )
846 {
847 solval = SCIPgetSolVal(scip, sol, consdata->vars[i]);
848
849 if( solval > maxsolval )
850 {
851 maxsolind = i;
852 maxsolval = solval;
853 }
854
855 sumsolval += solval;
856 }
857
858 /* the resultant must be at least as large as every operator
859 * and at most as large as the sum of operators
860 */
861 solval = SCIPgetSolVal(scip, sol, consdata->resvar);
862 viol = MAX3(0.0, maxsolval - solval, solval - sumsolval);
863
864 if( SCIPisFeasPositive(scip, viol) )
865 {
866 *violated = TRUE;
867
868 /* only reset constraint age if we are in enforcement */
869 if( sol == NULL )
870 {
872 }
873
874 if( printreason )
875 {
876 SCIP_CALL( SCIPprintCons(scip, cons, NULL) );
877 SCIPinfoMessage(scip, NULL, ";\n");
878 SCIPinfoMessage(scip, NULL, "violation:");
879
880 if( SCIPisFeasPositive(scip, maxsolval - solval) )
881 {
882 SCIPinfoMessage(scip, NULL, " operand <%s> = TRUE and resultant <%s> = FALSE\n",
883 SCIPvarGetName(consdata->vars[maxsolind]), SCIPvarGetName(consdata->resvar));
884 }
885 else
886 {
887 SCIPinfoMessage(scip, NULL, " all operands are FALSE and resultant <%s> = TRUE\n",
888 SCIPvarGetName(consdata->resvar));
889 }
890 }
891 }
892
893 if( sol != NULL )
894 SCIPupdateSolConsViolation(scip, sol, viol, viol);
895 }
896
897 return SCIP_OKAY;
898}
899
900/** separates current LP solution */
901static
903 SCIP* scip, /**< SCIP data structure */
904 SCIP_CONS* cons, /**< constraint to check */
905 SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
906 SCIP_Bool* separated /**< pointer to store whether a cut was found */
907 )
908{
909 SCIP_CONSDATA* consdata;
910 SCIP_Real feasibility;
911 int r;
912 int nrows;
913
915
916 consdata = SCIPconsGetData(cons);
917 assert(consdata != NULL);
918
919 *separated = FALSE;
920
921 /* create all necessary rows for the linear relaxation */
922 if( consdata->rows == NULL )
923 {
925 }
926 assert(consdata->rows != NULL);
927
928 nrows = consdataGetNRows(consdata);
929
930 /* test all rows for feasibility and add infeasible rows */
931 for( r = 0; r < nrows; ++r )
932 {
933 if( !SCIProwIsInLP(consdata->rows[r]) )
934 {
935 feasibility = SCIPgetRowSolFeasibility(scip, consdata->rows[r], sol);
937 {
938 SCIP_Bool infeasible;
939
940 SCIP_CALL( SCIPaddRow(scip, consdata->rows[r], FALSE, &infeasible) );
941 assert( ! infeasible );
942 *separated = TRUE;
943 }
944 }
945 }
946
947 return SCIP_OKAY;
948}
949
950/** analyzes conflicting FALSE assignment to resultant of given constraint, and adds conflict constraint to problem */
951static
953 SCIP* scip, /**< SCIP data structure */
954 SCIP_CONS* cons, /**< or constraint that detected the conflict */
955 int truepos /**< position of operand that is fixed to TRUE */
956 )
957{
958 SCIP_CONSDATA* consdata;
959
960 /* conflict analysis can only be applied in solving stage and if it is applicable */
962 return SCIP_OKAY;
963
964 consdata = SCIPconsGetData(cons);
965 assert(consdata != NULL);
966 assert(SCIPvarGetUbLocal(consdata->resvar) < 0.5);
968 assert(SCIPvarGetLbLocal(consdata->vars[truepos]) > 0.5);
969
970 /* initialize conflict analysis, and add resultant and single operand variable to conflict candidate queue */
972
973 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->resvar) );
974 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->vars[truepos]) );
975
976 /* analyze the conflict */
978
979 return SCIP_OKAY;
980}
981
982/** analyzes conflicting TRUE assignment to resultant of given constraint, and adds conflict constraint to problem */
983static
985 SCIP* scip, /**< SCIP data structure */
986 SCIP_CONS* cons /**< or constraint that detected the conflict */
987 )
988{
989 SCIP_CONSDATA* consdata;
990 int v;
991
993
994 /* conflict analysis can only be applied in solving stage and if it is applicable */
996 return SCIP_OKAY;
997
998 consdata = SCIPconsGetData(cons);
999 assert(consdata != NULL);
1000 assert(SCIPvarGetLbLocal(consdata->resvar) > 0.5);
1001
1002 /* initialize conflict analysis, and add all variables of infeasible constraint to conflict candidate queue */
1004
1005 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->resvar) );
1006 for( v = 0; v < consdata->nvars; ++v )
1007 {
1008 assert(SCIPvarGetUbLocal(consdata->vars[v]) < 0.5);
1009 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->vars[v]) );
1010 }
1011
1012 /* analyze the conflict */
1014
1015 return SCIP_OKAY;
1016}
1017
1018/** propagates constraint with the following rules:
1019 * (1) v_i = TRUE => r = TRUE
1020 * (2) r = FALSE => v_i = FALSE for all i
1021 * (3) v_i = FALSE for all i => r = FALSE
1022 * (4) r = TRUE, v_i = FALSE for all i except j => v_j = TRUE
1023 */
1024static
1026 SCIP* scip, /**< SCIP data structure */
1027 SCIP_CONS* cons, /**< or constraint to be processed */
1028 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
1029 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
1030 int* nfixedvars /**< pointer to add up the number of found domain reductions */
1031 )
1032{
1033 SCIP_CONSDATA* consdata;
1034 SCIP_VAR* resvar;
1035 SCIP_VAR** vars;
1036 int nvars;
1037 int watchedvar1;
1038 int watchedvar2;
1039 int i;
1040 SCIP_Bool infeasible;
1041 SCIP_Bool tightened;
1042
1043 assert(cutoff != NULL);
1044 assert(nfixedvars != NULL);
1045
1046 consdata = SCIPconsGetData(cons);
1047 assert(consdata != NULL);
1048
1049 resvar = consdata->resvar;
1050 vars = consdata->vars;
1051 nvars = consdata->nvars;
1052
1053 /* don't process the constraint, if none of the operator variables was fixed to TRUE, and if the watched variables
1054 * and the resultant weren't fixed to any value since last propagation call
1055 */
1056 if( consdata->propagated )
1057 {
1058 assert(consdata->nofixedone);
1059 assert(SCIPisFeasEQ(scip, SCIPvarGetUbLocal(resvar), 1.0));
1060 return SCIP_OKAY;
1061 }
1062
1063 /* increase age of constraint; age is reset to zero, if a conflict or a propagation was found */
1065 {
1066 SCIP_CALL( SCIPincConsAge(scip, cons) );
1067 }
1068
1069 /* if one of the operator variables was fixed to TRUE, the resultant can be fixed to TRUE (rule (1)) */
1070 if( !consdata->nofixedone )
1071 {
1072 for( i = 0; i < nvars && SCIPvarGetLbLocal(vars[i]) < 0.5; ++i ) /* search fixed operator */
1073 {}
1074 if( i < nvars )
1075 {
1076 SCIPdebugMsg(scip, "constraint <%s>: operator var <%s> fixed to 1.0 -> fix resultant <%s> to 1.0\n",
1078 SCIP_CALL( SCIPinferBinvarCons(scip, resvar, TRUE, cons, (int)PROPRULE_1, &infeasible, &tightened) );
1079 if( infeasible )
1080 {
1081 /* use conflict analysis to get a conflict constraint out of the conflicting assignment */
1084 *cutoff = TRUE;
1085 }
1086 else
1087 {
1089 if( tightened )
1090 {
1092 (*nfixedvars)++;
1093 }
1094 }
1095
1096 return SCIP_OKAY;
1097 }
1098 else
1099 consdata->nofixedone = TRUE;
1100 }
1101 assert(consdata->nofixedone);
1102
1103 /* if resultant is fixed to FALSE, all operator variables can be fixed to FALSE (rule (2)) */
1104 if( SCIPvarGetUbLocal(resvar) < 0.5 )
1105 {
1106 for( i = 0; i < nvars && !(*cutoff); ++i )
1107 {
1108 SCIPdebugMsg(scip, "constraint <%s>: resultant var <%s> fixed to 0.0 -> fix operator var <%s> to 0.0\n",
1110 SCIP_CALL( SCIPinferBinvarCons(scip, vars[i], FALSE, cons, (int)PROPRULE_2, &infeasible, &tightened) );
1111 if( infeasible )
1112 {
1113 /* use conflict analysis to get a conflict constraint out of the conflicting assignment */
1116 *cutoff = TRUE;
1117 }
1118 else if( tightened )
1119 {
1121 (*nfixedvars)++;
1122 }
1123 }
1124
1125 if( !(*cutoff) )
1126 {
1128 }
1129
1130 return SCIP_OKAY;
1131 }
1132
1133 /* rules (3) and (4) can only be applied, if we know all operator variables */
1134 if( SCIPconsIsModifiable(cons) )
1135 return SCIP_OKAY;
1136
1137 /* rules (3) and (4) cannot be applied, if we have at least two unfixed variables left;
1138 * that means, we only have to watch (i.e. capture events) of two variables, and switch to other variables
1139 * if these ones get fixed
1140 */
1141 watchedvar1 = consdata->watchedvar1;
1142 watchedvar2 = consdata->watchedvar2;
1143
1144 /* check, if watched variables are still unfixed */
1145 if( watchedvar1 != -1 )
1146 {
1147 assert(SCIPvarGetLbLocal(vars[watchedvar1]) < 0.5); /* otherwise, rule (1) could be applied */
1148 if( SCIPvarGetUbLocal(vars[watchedvar1]) < 0.5 )
1149 watchedvar1 = -1;
1150 }
1151 if( watchedvar2 != -1 )
1152 {
1153 assert(SCIPvarGetLbLocal(vars[watchedvar2]) < 0.5); /* otherwise, rule (1) could be applied */
1154 if( SCIPvarGetUbLocal(vars[watchedvar2]) < 0.5 )
1155 watchedvar2 = -1;
1156 }
1157
1158 /* if only one watched variable is still unfixed, make it the first one */
1159 if( watchedvar1 == -1 )
1160 {
1161 watchedvar1 = watchedvar2;
1162 watchedvar2 = -1;
1163 }
1164 assert(watchedvar1 != -1 || watchedvar2 == -1);
1165
1166 /* if the watched variables are invalid (fixed), find new ones if existing */
1167 if( watchedvar2 == -1 )
1168 {
1169 for( i = 0; i < nvars; ++i )
1170 {
1171 assert(SCIPvarGetLbLocal(vars[i]) < 0.5); /* otherwise, rule (1) could be applied */
1172 if( SCIPvarGetUbLocal(vars[i]) > 0.5 )
1173 {
1174 if( watchedvar1 == -1 )
1175 {
1176 assert(watchedvar2 == -1);
1177 watchedvar1 = i;
1178 }
1179 else if( watchedvar1 != i )
1180 {
1181 watchedvar2 = i;
1182 break;
1183 }
1184 }
1185 }
1186 }
1187 assert(watchedvar1 != -1 || watchedvar2 == -1);
1188
1189 /* if all variables are fixed to FALSE, the resultant can also be fixed to FALSE (rule (3)) */
1190 if( watchedvar1 == -1 )
1191 {
1192 assert(watchedvar2 == -1);
1193
1194 SCIPdebugMsg(scip, "constraint <%s>: all operator vars fixed to 0.0 -> fix resultant <%s> to 0.0\n",
1195 SCIPconsGetName(cons), SCIPvarGetName(resvar));
1196 SCIP_CALL( SCIPinferBinvarCons(scip, resvar, FALSE, cons, (int)PROPRULE_3, &infeasible, &tightened) );
1197 if( infeasible )
1198 {
1199 /* use conflict analysis to get a conflict constraint out of the conflicting assignment */
1202 *cutoff = TRUE;
1203 }
1204 else
1205 {
1207 if( tightened )
1208 {
1210 (*nfixedvars)++;
1211 }
1212 }
1213
1214 return SCIP_OKAY;
1215 }
1216
1217 /* if resultant is fixed to TRUE, and only one operator variable is not fixed to FALSE, this operator variable
1218 * can be fixed to TRUE (rule (4))
1219 */
1220 if( SCIPvarGetLbLocal(resvar) > 0.5 && watchedvar2 == -1 )
1221 {
1222 assert(watchedvar1 != -1);
1223
1224 SCIPdebugMsg(scip, "constraint <%s>: resultant <%s> fixed to 1.0, only one unfixed operand -> fix operand <%s> to 1.0\n",
1225 SCIPconsGetName(cons), SCIPvarGetName(resvar), SCIPvarGetName(vars[watchedvar1]));
1226 SCIP_CALL( SCIPinferBinvarCons(scip, vars[watchedvar1], TRUE, cons, (int)PROPRULE_4, &infeasible, &tightened) );
1227 if( infeasible )
1228 {
1229 /* use conflict analysis to get a conflict constraint out of the conflicting assignment */
1232 *cutoff = TRUE;
1233 }
1234 else
1235 {
1237 if( tightened )
1238 {
1240 (*nfixedvars)++;
1241 }
1242 }
1243
1244 return SCIP_OKAY;
1245 }
1246
1247 /* switch to the new watched variables */
1248 SCIP_CALL( consdataSwitchWatchedvars(scip, consdata, eventhdlr, watchedvar1, watchedvar2) );
1249
1250 /* mark the constraint propagated */
1251 consdata->propagated = TRUE;
1252
1253 return SCIP_OKAY;
1254}
1255
1256/** resolves a conflict on the given variable by supplying the variables needed for applying the corresponding
1257 * propagation rule (see propagateCons()):
1258 * (1) v_i = TRUE => r = TRUE
1259 * (2) r = FALSE => v_i = FALSE for all i
1260 * (3) v_i = FALSE for all i => r = FALSE
1261 * (4) r = TRUE, v_i = FALSE for all i except j => v_j = TRUE
1262 */
1263static
1265 SCIP* scip, /**< SCIP data structure */
1266 SCIP_CONS* cons, /**< constraint that inferred the bound change */
1267 SCIP_VAR* infervar, /**< variable that was deduced */
1268 PROPRULE proprule, /**< propagation rule that deduced the value */
1269 SCIP_BDCHGIDX* bdchgidx, /**< bound change index (time stamp of bound change), or NULL for current time */
1270 SCIP_RESULT* result /**< pointer to store the result of the propagation conflict resolving call */
1271 )
1272{
1273 SCIP_CONSDATA* consdata;
1274 SCIP_VAR** vars;
1275 int nvars;
1276 int i;
1277
1278 assert(result != NULL);
1279
1280 consdata = SCIPconsGetData(cons);
1281 assert(consdata != NULL);
1282 vars = consdata->vars;
1283 nvars = consdata->nvars;
1284
1285 switch( proprule )
1286 {
1287 case PROPRULE_1:
1288 /* the resultant was inferred to TRUE, because one operand variable was TRUE */
1289 assert(SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) > 0.5);
1290 assert(infervar == consdata->resvar);
1291 for( i = 0; i < nvars; ++i )
1292 {
1293 if( SCIPgetVarLbAtIndex(scip, vars[i], bdchgidx, FALSE) > 0.5 )
1294 {
1296 break;
1297 }
1298 }
1299 assert(i < nvars);
1301 break;
1302
1303 case PROPRULE_2:
1304 /* the operand variable was inferred to FALSE, because the resultant was FALSE */
1305 assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
1306 assert(SCIPgetVarUbAtIndex(scip, consdata->resvar, bdchgidx, FALSE) < 0.5);
1307 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->resvar) );
1309 break;
1310
1311 case PROPRULE_3:
1312 /* the resultant was inferred to FALSE, because all operand variables were FALSE */
1313 assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
1314 assert(infervar == consdata->resvar);
1315 for( i = 0; i < nvars; ++i )
1316 {
1317 assert(SCIPgetVarUbAtIndex(scip, vars[i], bdchgidx, FALSE) < 0.5);
1319 }
1321 break;
1322
1323 case PROPRULE_4:
1324 /* the operand variable was inferred to TRUE, because the resultant was TRUE and all other operands were FALSE */
1325 assert(SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) > 0.5);
1326 assert(SCIPgetVarLbAtIndex(scip, consdata->resvar, bdchgidx, FALSE) > 0.5);
1327 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->resvar) );
1328 for( i = 0; i < nvars; ++i )
1329 {
1330 if( vars[i] != infervar )
1331 {
1332 assert(SCIPgetVarUbAtIndex(scip, vars[i], bdchgidx, FALSE) < 0.5);
1334 }
1335 }
1337 break;
1338
1339 case PROPRULE_INVALID:
1340 default:
1341 SCIPerrorMessage("invalid inference information %d in or constraint <%s>\n", proprule, SCIPconsGetName(cons));
1342 return SCIP_INVALIDDATA;
1343 }
1344
1345 return SCIP_OKAY;
1346}
1347
1348/** upgrades unmodifiable or constraint into an and constraint on negated variables */
1349static
1351 SCIP* scip, /**< SCIP data structure */
1352 SCIP_CONS* cons, /**< constraint that inferred the bound change */
1353 int* nupgdconss /**< pointer to count the number of constraint upgrades */
1354 )
1355{
1356 SCIP_CONSDATA* consdata;
1357 SCIP_VAR** negvars;
1360 int i;
1361
1362 assert(nupgdconss != NULL);
1363
1364 /* we cannot upgrade a modifiable constraint, since we don't know what additional variables to expect */
1365 if( SCIPconsIsModifiable(cons) )
1366 return SCIP_OKAY;
1367
1368 SCIPdebugMsg(scip, "upgrading or constraint <%s> into equivalent and constraint on negated variables\n",
1369 SCIPconsGetName(cons));
1370
1371 consdata = SCIPconsGetData(cons);
1372 assert(consdata != NULL);
1373
1374 /* get the negated versions of the variables */
1375 SCIP_CALL( SCIPallocBufferArray(scip, &negvars, consdata->nvars) );
1376 for( i = 0; i < consdata->nvars; ++i )
1377 {
1378 SCIP_CALL( SCIPgetNegatedVar(scip, consdata->vars[i], &negvars[i]) );
1379 }
1380 SCIP_CALL( SCIPgetNegatedVar(scip, consdata->resvar, &negresvar) );
1381
1382 /* create and add the and constraint */
1389
1390 /* delete the or constraint */
1391 SCIP_CALL( SCIPdelCons(scip, cons) );
1392
1393 /* free temporary memory */
1395
1396 (*nupgdconss)++;
1397
1398 return SCIP_OKAY;
1399}
1400
1401/** adds symmetry information of constraint to a symmetry detection graph */
1402static
1404 SCIP* scip, /**< SCIP pointer */
1405 SYM_SYMTYPE symtype, /**< type of symmetries that need to be added */
1406 SCIP_CONS* cons, /**< constraint */
1407 SYM_GRAPH* graph, /**< symmetry detection graph */
1408 SCIP_Bool* success /**< pointer to store whether symmetry information could be added */
1409 )
1410{
1411 SCIP_CONSDATA* consdata;
1412 SCIP_VAR** orvars;
1413 SCIP_VAR** vars;
1414 SCIP_Real* vals;
1415 SCIP_Real constant = 0.0;
1416 int nlocvars;
1417 int nvars;
1418 int i;
1419
1420 assert(scip != NULL);
1421 assert(cons != NULL);
1422 assert(graph != NULL);
1423 assert(success != NULL);
1424
1425 consdata = SCIPconsGetData(cons);
1426 assert(consdata != NULL);
1427
1428 /* get active variables of the constraint */
1430 nlocvars = SCIPgetNVarsOr(scip, cons);
1431
1434
1435 orvars = SCIPgetVarsOr(scip, cons);
1436 for( i = 0; i < consdata->nvars; ++i )
1437 {
1438 vars[i] = orvars[i];
1439 vals[i] = 1.0;
1440 }
1441
1444 vals[nlocvars++] = 2.0;
1445 assert(nlocvars <= nvars);
1446
1447 SCIP_CALL( SCIPgetSymActiveVariables(scip, symtype, &vars, &vals, &nlocvars, &constant, SCIPisTransformed(scip)) );
1448
1449 /* represent the OR constraint via the gadget for linear constraints and use the constant as lhs/rhs to
1450 * distinguish different OR constraints (OR constraints do not have an intrinsic right-hand side)
1451 */
1453 cons, -constant, -constant, success) );
1454
1455 SCIPfreeBufferArray(scip, &vals);
1457
1458 return SCIP_OKAY;
1459}
1460
1461/*
1462 * Callback methods of constraint handler
1463 */
1464
1465/** copy method for constraint handler plugins (called when SCIP copies plugins) */
1466static
1468{ /*lint --e{715}*/
1469 assert(scip != NULL);
1470 assert(conshdlr != NULL);
1472
1473 /* call inclusion method of constraint handler */
1475
1476 *valid = TRUE;
1477
1478 return SCIP_OKAY;
1479}
1480
1481/** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
1482static
1484{ /*lint --e{715}*/
1485 SCIP_CONSHDLRDATA* conshdlrdata;
1486
1487 /* free constraint handler data */
1488 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1489 assert(conshdlrdata != NULL);
1490
1491 conshdlrdataFree(scip, &conshdlrdata);
1492
1493 SCIPconshdlrSetData(conshdlr, NULL);
1494
1495 return SCIP_OKAY;
1496}
1497
1498
1499/** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
1500static
1502{ /*lint --e{715}*/
1503 SCIP_CONSDATA* consdata;
1504 int c;
1505
1506 /* release and free the rows of all constraints */
1507 for( c = 0; c < nconss; ++c )
1508 {
1509 consdata = SCIPconsGetData(conss[c]);
1510 SCIP_CALL( consdataFreeRows(scip, consdata) );
1511 }
1512
1513 return SCIP_OKAY;
1514}
1515
1516
1517/** frees specific constraint data */
1518static
1520{ /*lint --e{715}*/
1521 SCIP_CONSHDLRDATA* conshdlrdata;
1522
1523 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1524 assert(conshdlrdata != NULL);
1525
1526 SCIP_CALL( consdataFree(scip, consdata, conshdlrdata->eventhdlr) );
1527
1528 return SCIP_OKAY;
1529}
1530
1531
1532/** transforms constraint data into data belonging to the transformed problem */
1533static
1535{ /*lint --e{715}*/
1536 SCIP_CONSHDLRDATA* conshdlrdata;
1539
1540 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1541 assert(conshdlrdata != NULL);
1542
1545
1546 /* create target constraint data */
1547 SCIP_CALL( consdataCreate(scip, &targetdata, conshdlrdata->eventhdlr,
1548 sourcedata->nvars, sourcedata->vars, sourcedata->resvar) );
1549
1550 /* create target constraint */
1556
1557 return SCIP_OKAY;
1558}
1559
1560
1561/** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
1562static
1564{ /*lint --e{715}*/
1565 int i;
1566
1567 *infeasible = FALSE;
1568
1569 for( i = 0; i < nconss && !(*infeasible); i++ )
1570 {
1571 assert(SCIPconsIsInitial(conss[i]));
1572 SCIP_CALL( addRelaxation(scip, conss[i], infeasible) );
1573 }
1574
1575 return SCIP_OKAY;
1576}
1577
1578
1579/** separation method of constraint handler for LP solutions */
1580static
1582{ /*lint --e{715}*/
1583 SCIP_Bool separated;
1584 int c;
1585
1587
1588 /* separate all useful constraints */
1589 for( c = 0; c < nusefulconss; ++c )
1590 {
1591 SCIP_CALL( separateCons(scip, conss[c], NULL, &separated) );
1592 if( separated )
1594 }
1595
1596 /* combine constraints to get more cuts */
1597 /**@todo combine constraints to get further cuts */
1598
1599 return SCIP_OKAY;
1600}
1601
1602
1603/** separation method of constraint handler for arbitrary primal solutions */
1604static
1606{ /*lint --e{715}*/
1607 SCIP_Bool separated;
1608 int c;
1609
1611
1612 /* separate all useful constraints */
1613 for( c = 0; c < nusefulconss; ++c )
1614 {
1615 SCIP_CALL( separateCons(scip, conss[c], sol, &separated) );
1616 if( separated )
1618 }
1619
1620 /* combine constraints to get more cuts */
1621 /**@todo combine constraints to get further cuts */
1622
1623 return SCIP_OKAY;
1624}
1625
1626
1627/** constraint enforcing method of constraint handler for LP solutions */
1628static
1630{ /*lint --e{715}*/
1631 SCIP_Bool violated;
1632 int i;
1633
1634 /* method is called only for integral solutions, because the enforcing priority is negative */
1635 for( i = 0; i < nconss; i++ )
1636 {
1637 SCIP_CALL( checkCons(scip, conss[i], NULL, FALSE, FALSE, &violated) );
1638 if( violated )
1639 {
1640 SCIP_Bool separated;
1641
1642 SCIP_CALL( separateCons(scip, conss[i], NULL, &separated) );
1643
1644 /* if the solution is integral, the separation always finds a cut
1645 * if some implicit binary variable is not integral, then some other constraint needs to be enforced first
1646 */
1647 if( separated )
1649 else
1651
1652 return SCIP_OKAY;
1653 }
1654 }
1656
1657 return SCIP_OKAY;
1658}
1659
1660
1661/** constraint enforcing method of constraint handler for relaxation solutions */
1662static
1664{ /*lint --e{715}*/
1665 SCIP_Bool violated;
1666 int i;
1667
1668 /* method is called only for integral solutions, because the enforcing priority is negative */
1669 for( i = 0; i < nconss; i++ )
1670 {
1671 SCIP_CALL( checkCons(scip, conss[i], sol, FALSE, FALSE, &violated) );
1672 if( violated )
1673 {
1674 SCIP_Bool separated;
1675
1676 SCIP_CALL( separateCons(scip, conss[i], sol, &separated) );
1677
1678 /* if the solution is integral, the separation always finds a cut
1679 * if some implicit binary variable is not integral, then some other constraint needs to be enforced first
1680 */
1681 if( separated )
1683 else
1685
1686 return SCIP_OKAY;
1687 }
1688 }
1690
1691 return SCIP_OKAY;
1692}
1693
1694
1695/** constraint enforcing method of constraint handler for pseudo solutions */
1696static
1698{ /*lint --e{715}*/
1699 SCIP_Bool violated;
1700 int i;
1701
1702 /* method is called only for integral solutions, because the enforcing priority is negative */
1703 for( i = 0; i < nconss; i++ )
1704 {
1705 SCIP_CALL( checkCons(scip, conss[i], NULL, TRUE, FALSE, &violated) );
1706 if( violated )
1707 {
1709 return SCIP_OKAY;
1710 }
1711 }
1713
1714 return SCIP_OKAY;
1715}
1716
1717
1718/** feasibility check method of constraint handler for integral solutions */
1719static
1721{ /*lint --e{715}*/
1722 int i;
1723
1725
1726 /* method is called only for integral solutions, because the enforcing priority is negative */
1727 for( i = 0; i < nconss && (*result == SCIP_FEASIBLE || completely); i++ )
1728 {
1729 SCIP_Bool violated = FALSE;
1730
1731 SCIP_CALL( checkCons(scip, conss[i], sol, checklprows, printreason, &violated) );
1732
1733 if( violated )
1735 }
1736
1737 return SCIP_OKAY;
1738}
1739
1740
1741/** domain propagation method of constraint handler */
1742static
1744{ /*lint --e{715}*/
1745 SCIP_CONSHDLRDATA* conshdlrdata;
1746 SCIP_Bool cutoff;
1747 int nfixedvars;
1748 int c;
1749
1750 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1751 assert(conshdlrdata != NULL);
1752
1753 cutoff = FALSE;
1754 nfixedvars = 0;
1755
1756 /* propagate all useful constraints */
1757 for( c = 0; c < nusefulconss && !cutoff; ++c )
1758 {
1759 SCIP_CALL( propagateCons(scip, conss[c], conshdlrdata->eventhdlr, &cutoff, &nfixedvars) );
1760 }
1761
1762 /* return the correct result */
1763 if( cutoff )
1765 else if( nfixedvars > 0 )
1767 else
1769
1770 return SCIP_OKAY;
1771}
1772
1773
1774/** presolving method of constraint handler */
1775static
1777{ /*lint --e{715}*/
1778 SCIP_CONSHDLRDATA* conshdlrdata;
1779 SCIP_CONS* cons;
1780 SCIP_CONSDATA* consdata;
1781 SCIP_Bool cutoff;
1782 SCIP_Bool redundant;
1783 SCIP_Bool aggregated;
1784 int oldnfixedvars;
1785 int oldnaggrvars;
1786 int oldnupgdconss;
1787 int c;
1788
1789 assert(result != NULL);
1790
1792 oldnfixedvars = *nfixedvars;
1793 oldnaggrvars = *naggrvars;
1794 oldnupgdconss = *nupgdconss;
1795
1796 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1797 assert(conshdlrdata != NULL);
1798
1799 /* process constraints */
1800 cutoff = FALSE;
1801 for( c = 0; c < nconss && !cutoff && !SCIPisStopped(scip); ++c )
1802 {
1803 cons = conss[c];
1804 assert(cons != NULL);
1805 consdata = SCIPconsGetData(cons);
1806 assert(consdata != NULL);
1807
1808 /* force presolving the constraint in the initial round */
1809 if( nrounds == 0 )
1810 consdata->propagated = FALSE;
1811
1812 /* propagate constraint */
1813 SCIP_CALL( propagateCons(scip, cons, conshdlrdata->eventhdlr, &cutoff, nfixedvars) );
1814
1815 /* remove all variables that are fixed to one */
1816 SCIP_CALL( applyFixings(scip, cons, conshdlrdata->eventhdlr) );
1817
1818 /* transform or constraints into and constraints on the negated variables in order to improve
1819 * the pairwise constraint presolving possibilities
1820 */
1821 SCIP_CALL( upgradeCons(scip, cons, nupgdconss) );
1822
1823 if( !cutoff && !SCIPconsIsDeleted(cons) && !SCIPconsIsModifiable(cons) )
1824 {
1825 assert(consdata->nvars >= 1); /* otherwise, propagateCons() has deleted the constraint */
1826
1827 /* if only one variable is left, the resultant has to be equal to this single variable */
1828 if( consdata->nvars == 1 )
1829 {
1830 SCIPdebugMsg(scip, "or constraint <%s> has only one variable not fixed to 0.0\n", SCIPconsGetName(cons));
1831
1832 assert(consdata->vars != NULL);
1833 assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(consdata->vars[0]), 0.0));
1834 assert(SCIPisFeasEQ(scip, SCIPvarGetUbGlobal(consdata->vars[0]), 1.0));
1835
1836 /* aggregate variables: resultant - operand == 0 */
1837 SCIP_CALL( SCIPaggregateVars(scip, consdata->resvar, consdata->vars[0], 1.0, -1.0, 0.0,
1838 &cutoff, &redundant, &aggregated) );
1839 assert(redundant || SCIPdoNotAggr(scip));
1840
1841 if( aggregated )
1842 {
1843 assert(redundant);
1844 (*naggrvars)++;
1845 }
1846
1847 if( redundant )
1848 {
1849 /* delete constraint */
1850 SCIP_CALL( SCIPdelCons(scip, cons) );
1851 (*ndelconss)++;
1852 }
1853 }
1854 else if( !consdata->impladded )
1855 {
1856 int i;
1857
1858 /* add implications: resultant == 0 -> all operands == 0 */
1859 for( i = 0; i < consdata->nvars && !cutoff; ++i )
1860 {
1861 int nimplbdchgs;
1862
1863 SCIP_CALL( SCIPaddVarImplication(scip, consdata->resvar, FALSE, consdata->vars[i],
1865 *nchgbds += nimplbdchgs;
1866 }
1867 consdata->impladded = TRUE;
1868 }
1869
1870 /* if in r = x or y, the resultant is fixed to one, add implication x = 0 -> y = 1 */
1871 if( !cutoff && SCIPconsIsActive(cons) && consdata->nvars == 2 && !consdata->opimpladded
1872 && SCIPvarGetLbGlobal(consdata->resvar) > 0.5 )
1873 {
1874 int nimplbdchgs;
1875
1876 SCIP_CALL( SCIPaddVarImplication(scip, consdata->vars[0], FALSE, consdata->vars[1],
1878 (*nchgbds) += nimplbdchgs;
1879 consdata->opimpladded = TRUE;
1880 }
1881 }
1882 }
1883
1884 /* return the correct result code */
1885 if( cutoff )
1887 else if( *nfixedvars > oldnfixedvars || *naggrvars > oldnaggrvars || *nupgdconss > oldnupgdconss )
1889
1890 return SCIP_OKAY;
1891}
1892
1893
1894/** propagation conflict resolving method of constraint handler */
1895static
1897{ /*lint --e{715}*/
1898 SCIP_CALL( resolvePropagation(scip, cons, infervar, (PROPRULE)inferinfo, bdchgidx, result) );
1899
1900 return SCIP_OKAY;
1901}
1902
1903
1904/** variable rounding lock method of constraint handler */
1905static
1907{ /*lint --e{715}*/
1908 SCIP_CONSDATA* consdata;
1909 int i;
1910
1912
1913 consdata = SCIPconsGetData(cons);
1914 assert(consdata != NULL);
1915
1916 /* lock resultant variable */
1917 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->resvar, locktype, nlockspos + nlocksneg, nlockspos + nlocksneg) );
1918
1919 /* lock all operand variables */
1920 for( i = 0; i < consdata->nvars; ++i )
1921 {
1922 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->vars[i], locktype, nlockspos + nlocksneg, nlockspos + nlocksneg) );
1923 }
1924
1925 return SCIP_OKAY;
1926}
1927
1928
1929/** constraint display method of constraint handler */
1930static
1932{ /*lint --e{715}*/
1933 assert( scip != NULL );
1934 assert( conshdlr != NULL );
1935 assert( cons != NULL );
1936
1938
1939 return SCIP_OKAY;
1940}
1941
1942/** constraint copying method of constraint handler */
1943static
1945{ /*lint --e{715}*/
1947 SCIP_VAR** vars;
1949 SCIP_VAR* resvar;
1950 int nvars;
1951 int v;
1952
1953 assert(valid != NULL);
1954 (*valid) = TRUE;
1955 resvar = NULL;
1956
1957 /* get variables that need to be copied */
1959 sourcevars = SCIPgetVarsOr(sourcescip, sourcecons);
1960 nvars = SCIPgetNVarsOr(sourcescip, sourcecons);
1961
1962 if( nvars == -1 )
1963 return SCIP_INVALIDCALL;
1964
1965 /* allocate buffer array */
1967
1968 /* map operand variables to active variables of the target SCIP */
1969 for( v = 0; v < nvars && *valid; ++v )
1970 {
1971 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, sourcevars[v], &vars[v], varmap, consmap, global, valid) );
1972 assert(!(*valid) || vars[v] != NULL);
1973 }
1974
1975 /* map resultant to active variable of the target SCIP */
1976 if( *valid )
1977 {
1978 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, sourceresvar, &resvar, varmap, consmap, global, valid) );
1979 assert(!(*valid) || resvar != NULL);
1980
1981 if( *valid )
1982 {
1983 assert(resvar != NULL);
1985 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
1986 }
1987 }
1988
1989 /* free buffer array */
1991
1992 return SCIP_OKAY;
1993}
1994
1995/** constraint parsing method of constraint handler */
1996static
1998{ /*lint --e{715}*/
1999 SCIP_VAR** vars;
2000 SCIP_VAR* resvar;
2001 char* strcopy;
2002 char* token;
2003 char* saveptr;
2004 char* endptr;
2005 int requiredsize;
2006 int varssize;
2007 int nvars;
2008
2009 SCIPdebugMsg(scip, "parse <%s> as or constraint\n", str);
2010
2011 *success = FALSE;
2012
2013 /* copy string for truncating it */
2015
2016 /* cutoff "or" form the constraint string */
2017 token = SCIPstrtok(strcopy, "=", &saveptr );
2018
2019 /* parse variable name */
2020 SCIP_CALL( SCIPparseVarName(scip, token, &resvar, &endptr) );
2021
2022 if( resvar == NULL )
2023 {
2024 SCIPerrorMessage("resultant variable does not exist\n");
2025 }
2026 else
2027 {
2028 /* cutoff "or" form the constraint string */
2029 (void) SCIPstrtok(NULL, "(", &saveptr );
2030
2031 /* cutoff ")" form the constraint string */
2032 token = SCIPstrtok(NULL, ")", &saveptr );
2033
2034 varssize = 100;
2035 nvars = 0;
2036
2037 /* allocate buffer array for variables */
2038 SCIP_CALL( SCIPallocBufferArray(scip, &vars, varssize) );
2039
2040 /* parse string */
2041 SCIP_CALL( SCIPparseVarsList(scip, token, vars, &nvars, varssize, &requiredsize, &endptr, ',', success) );
2042
2043 if( *success )
2044 {
2045 /* check if the size of the variable array was great enough */
2046 if( varssize < requiredsize )
2047 {
2048 /* reallocate memory */
2049 varssize = requiredsize;
2050 SCIP_CALL( SCIPreallocBufferArray(scip, &vars, varssize) );
2051
2052 /* parse string again with the correct size of the variable array */
2053 SCIP_CALL( SCIPparseVarsList(scip, token, vars, &nvars, varssize, &requiredsize, &endptr, ',', success) );
2054 }
2055
2056 assert(*success);
2057 assert(varssize >= requiredsize);
2058
2059 /* create and constraint */
2060 SCIP_CALL( SCIPcreateConsOr(scip, cons, name, resvar, nvars, vars,
2061 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
2062 }
2063
2064 /* free variable buffer */
2066 }
2067
2068 /* free string buffer */
2070
2071 return SCIP_OKAY;
2072}
2073
2074/** constraint method of constraint handler which returns the variables (if possible) */
2075static
2077{ /*lint --e{715}*/
2078 SCIP_CONSDATA* consdata;
2079
2080 consdata = SCIPconsGetData(cons);
2081 assert(consdata != NULL);
2082
2084 (*success) = FALSE;
2085 else
2086 {
2087 BMScopyMemoryArray(vars, consdata->vars, consdata->nvars);
2088 vars[consdata->nvars] = consdata->resvar;
2089 (*success) = TRUE;
2090 }
2091
2092 return SCIP_OKAY;
2093}
2094
2095/** constraint method of constraint handler which returns the number of variable (if possible) */
2096static
2098{ /*lint --e{715}*/
2099 SCIP_CONSDATA* consdata;
2100
2101 assert(cons != NULL);
2102
2103 consdata = SCIPconsGetData(cons);
2104 assert(consdata != NULL);
2105
2106 (*nvars) = consdata->nvars + 1;
2107 (*success) = TRUE;
2108
2109 return SCIP_OKAY;
2110}
2111
2112/** constraint handler method which returns the permutation symmetry detection graph of a constraint */
2113static
2115{ /*lint --e{715}*/
2117
2118 return SCIP_OKAY;
2119}
2120
2121/** constraint handler method which returns the signed permutation symmetry detection graph of a constraint */
2122static
2129
2130/*
2131 * Callback methods of event handler
2132 */
2133
2134static
2136{ /*lint --e{715}*/
2137 SCIP_CONSDATA* consdata;
2138
2139 assert(eventhdlr != NULL);
2140 assert(eventdata != NULL);
2141 assert(event != NULL);
2142
2143 consdata = (SCIP_CONSDATA*)eventdata;
2144 assert(consdata != NULL);
2145
2146 /* check, if the variable was fixed to one */
2148 consdata->nofixedone = FALSE;
2149
2150 consdata->propagated = FALSE;
2151
2152 return SCIP_OKAY;
2153}
2154
2155
2156/*
2157 * constraint specific interface methods
2158 */
2159
2160/** creates the handler for or constraints and includes it in SCIP */
2162 SCIP* scip /**< SCIP data structure */
2163 )
2164{
2165 SCIP_CONSHDLRDATA* conshdlrdata;
2166 SCIP_CONSHDLR* conshdlr;
2167 SCIP_EVENTHDLR* eventhdlr;
2168
2169 /* create event handler for events on variables */
2171 eventExecOr, NULL) );
2172
2173 /* create constraint handler data */
2174 SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
2175
2176 /* include constraint handler */
2180 conshdlrdata) );
2181 assert(conshdlr != NULL);
2182
2183 /* set non-fundamental callbacks via specific setter functions */
2203
2204 return SCIP_OKAY;
2205}
2206
2207/** creates and captures an or constraint
2208 *
2209 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
2210 */
2212 SCIP* scip, /**< SCIP data structure */
2213 SCIP_CONS** cons, /**< pointer to hold the created constraint */
2214 const char* name, /**< name of constraint */
2215 SCIP_VAR* resvar, /**< resultant variable of the operation */
2216 int nvars, /**< number of operator variables in the constraint */
2217 SCIP_VAR** vars, /**< array with operator variables of constraint */
2218 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
2219 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
2220 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
2221 * Usually set to TRUE. */
2222 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
2223 * TRUE for model constraints, FALSE for additional, redundant constraints. */
2224 SCIP_Bool check, /**< should the constraint be checked for feasibility?
2225 * TRUE for model constraints, FALSE for additional, redundant constraints. */
2226 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
2227 * Usually set to TRUE. */
2228 SCIP_Bool local, /**< is constraint only valid locally?
2229 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
2230 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
2231 * Usually set to FALSE. In column generation applications, set to TRUE if pricing
2232 * adds coefficients to this constraint. */
2233 SCIP_Bool dynamic, /**< is constraint subject to aging?
2234 * Usually set to FALSE. Set to TRUE for own cuts which
2235 * are separated as constraints. */
2236 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
2237 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
2238 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
2239 * if it may be moved to a more global node?
2240 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
2241 )
2242{
2243 SCIP_CONSHDLR* conshdlr;
2244 SCIP_CONSHDLRDATA* conshdlrdata;
2245 SCIP_CONSDATA* consdata;
2246
2247 /* find the or constraint handler */
2248 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2249 if( conshdlr == NULL )
2250 {
2251 SCIPerrorMessage("or constraint handler not found\n");
2252 return SCIP_PLUGINNOTFOUND;
2253 }
2254
2255 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2256 assert(conshdlrdata != NULL);
2257
2258 /* create constraint data */
2259 SCIP_CALL( consdataCreate(scip, &consdata, conshdlrdata->eventhdlr, nvars, vars, resvar) );
2260
2261 /* create constraint */
2262 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
2263 local, modifiable, dynamic, removable, stickingatnode) );
2264
2265 return SCIP_OKAY;
2266}
2267
2268/** creates and captures an or constraint
2269 * in its most basic variant, i. e., with all constraint flags set to their default values
2270 *
2271 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
2272 */
2274 SCIP* scip, /**< SCIP data structure */
2275 SCIP_CONS** cons, /**< pointer to hold the created constraint */
2276 const char* name, /**< name of constraint */
2277 SCIP_VAR* resvar, /**< resultant variable of the operation */
2278 int nvars, /**< number of operator variables in the constraint */
2279 SCIP_VAR** vars /**< array with operator variables of constraint */
2280 )
2281{
2282 SCIP_CALL( SCIPcreateConsOr(scip, cons, name, resvar, nvars, vars, TRUE, TRUE, TRUE, TRUE, TRUE,
2283 FALSE, FALSE, FALSE, FALSE, FALSE) );
2284
2285 return SCIP_OKAY;
2286}
2287
2288/** gets number of variables in or constraint */
2290 SCIP* scip, /**< SCIP data structure */
2291 SCIP_CONS* cons /**< constraint data */
2292 )
2293{
2294 SCIP_CONSDATA* consdata;
2295
2296 assert(scip != NULL);
2297
2299 {
2300 SCIPerrorMessage("constraint is not an or constraint\n");
2301 SCIPABORT();
2302 return -1; /*lint !e527*/
2303 }
2304
2305 consdata = SCIPconsGetData(cons);
2306 assert(consdata != NULL);
2307
2308 return consdata->nvars;
2309}
2310
2311/** gets array of variables in or constraint */
2313 SCIP* scip, /**< SCIP data structure */
2314 SCIP_CONS* cons /**< constraint data */
2315 )
2316{
2317 SCIP_CONSDATA* consdata;
2318
2319 assert(scip != NULL);
2320
2322 {
2323 SCIPerrorMessage("constraint is not an or constraint\n");
2324 SCIPABORT();
2325 return NULL; /*lint !e527*/
2326 }
2327
2328 consdata = SCIPconsGetData(cons);
2329 assert(consdata != NULL);
2330
2331 return consdata->vars;
2332}
2333
2334/** gets the resultant variable in or constraint */
2336 SCIP* scip, /**< SCIP data structure */
2337 SCIP_CONS* cons /**< constraint data */
2338 )
2339{
2340 SCIP_CONSDATA* consdata;
2341
2342 assert(scip != NULL);
2343
2345 {
2346 SCIPerrorMessage("constraint is not a or constraint\n");
2347 SCIPABORT();
2348 return NULL; /*lint !e527*/
2349 }
2350
2351 consdata = SCIPconsGetData(cons);
2352 assert(consdata != NULL);
2353
2354 return consdata->resvar;
2355}
enum Proprule PROPRULE
Definition cons_and.c:179
Proprule
Definition cons_and.c:172
Constraint handler for AND constraints, .
static SCIP_RETCODE addRelaxation(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible)
Definition cons_or.c:749
enum Proprule PROPRULE
Definition cons_or.c:137
static SCIP_RETCODE consdataFreeRows(SCIP *scip, SCIP_CONSDATA *consdata)
Definition cons_or.c:449
static int consdataGetNRows(SCIP_CONSDATA *consdata)
Definition cons_or.c:211
static SCIP_RETCODE consdataPrint(SCIP *scip, SCIP_CONSDATA *consdata, FILE *file)
Definition cons_or.c:510
static SCIP_RETCODE consdataCatchWatchedEvents(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr, int pos, int *filterpos)
Definition cons_or.c:222
static SCIP_RETCODE consdataDropEvents(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr)
Definition cons_or.c:295
static SCIP_RETCODE consdataSwitchWatchedvars(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr, int watchedvar1, int watchedvar2)
Definition cons_or.c:321
#define CONSHDLR_NEEDSCONS
Definition cons_or.c:86
#define CONSHDLR_SEPAFREQ
Definition cons_or.c:79
static SCIP_RETCODE delCoefPos(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, int pos)
Definition cons_or.c:589
#define CONSHDLR_CHECKPRIORITY
Definition cons_or.c:78
#define CONSHDLR_DESC
Definition cons_or.c:75
static SCIP_RETCODE addCoef(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, SCIP_VAR *var)
Definition cons_or.c:535
static SCIP_RETCODE createRelaxation(SCIP *scip, SCIP_CONS *cons)
Definition cons_or.c:706
#define CONSHDLR_PROP_TIMING
Definition cons_or.c:88
static void conshdlrdataFree(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata)
Definition cons_or.c:198
static SCIP_RETCODE unlockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
Definition cons_or.c:162
#define CONSHDLR_MAXPREROUNDS
Definition cons_or.c:83
#define CONSHDLR_SEPAPRIORITY
Definition cons_or.c:76
static SCIP_RETCODE analyzeConflictOne(SCIP *scip, SCIP_CONS *cons)
Definition cons_or.c:984
static SCIP_RETCODE analyzeConflictZero(SCIP *scip, SCIP_CONS *cons, int truepos)
Definition cons_or.c:952
static SCIP_RETCODE addSymmetryInformation(SCIP *scip, SYM_SYMTYPE symtype, SCIP_CONS *cons, SYM_GRAPH *graph, SCIP_Bool *success)
Definition cons_or.c:1403
static SCIP_RETCODE lockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var)
Definition cons_or.c:146
static SCIP_RETCODE consdataEnsureVarsSize(SCIP *scip, SCIP_CONSDATA *consdata, int num)
Definition cons_or.c:381
@ PROPRULE_2
Definition cons_or.c:132
@ PROPRULE_1
Definition cons_or.c:131
@ PROPRULE_3
Definition cons_or.c:133
@ PROPRULE_INVALID
Definition cons_or.c:135
@ PROPRULE_4
Definition cons_or.c:134
static SCIP_RETCODE checkCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_Bool *violated)
Definition cons_or.c:783
static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata, SCIP_EVENTHDLR *eventhdlr)
Definition cons_or.c:476
static SCIP_RETCODE consdataDropWatchedEvents(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr, int pos, int filterpos)
Definition cons_or.c:246
#define CONSHDLR_PROPFREQ
Definition cons_or.c:80
static SCIP_RETCODE upgradeCons(SCIP *scip, SCIP_CONS *cons, int *nupgdconss)
Definition cons_or.c:1350
#define CONSHDLR_PRESOLTIMING
Definition cons_or.c:89
static SCIP_RETCODE propagateCons(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr, SCIP_Bool *cutoff, int *nfixedvars)
Definition cons_or.c:1025
#define CONSHDLR_EAGERFREQ
Definition cons_or.c:81
static SCIP_RETCODE separateCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool *separated)
Definition cons_or.c:902
#define EVENTHDLR_DESC
Definition cons_or.c:92
static SCIP_RETCODE conshdlrdataCreate(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata, SCIP_EVENTHDLR *eventhdlr)
Definition cons_or.c:178
static SCIP_RETCODE consdataCreate(SCIP *scip, SCIP_CONSDATA **consdata, SCIP_EVENTHDLR *eventhdlr, int nvars, SCIP_VAR **vars, SCIP_VAR *resvar)
Definition cons_or.c:405
#define CONSHDLR_ENFOPRIORITY
Definition cons_or.c:77
static SCIP_RETCODE applyFixings(SCIP *scip, SCIP_CONS *cons, SCIP_EVENTHDLR *eventhdlr)
Definition cons_or.c:647
static SCIP_RETCODE resolvePropagation(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *infervar, PROPRULE proprule, SCIP_BDCHGIDX *bdchgidx, SCIP_RESULT *result)
Definition cons_or.c:1264
#define CONSHDLR_DELAYSEPA
Definition cons_or.c:84
#define CONSHDLR_NAME
Definition cons_or.c:74
#define EVENTHDLR_NAME
Definition cons_or.c:91
#define CONSHDLR_DELAYPROP
Definition cons_or.c:85
static SCIP_RETCODE consdataCatchEvents(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr)
Definition cons_or.c:269
Constraint handler for "or" constraints, .
#define NULL
Definition def.h:267
#define SCIP_MAXSTRLEN
Definition def.h:288
#define MAX3(x, y, z)
Definition def.h:247
#define TRUE
Definition def.h:93
#define FALSE
Definition def.h:94
#define SCIPABORT()
Definition def.h:346
#define SCIP_CALL(x)
Definition def.h:374
SCIP_VAR ** SCIPgetVarsOr(SCIP *scip, SCIP_CONS *cons)
Definition cons_or.c:2312
int SCIPgetNVarsOr(SCIP *scip, SCIP_CONS *cons)
Definition cons_or.c:2289
SCIP_RETCODE SCIPcreateConsAnd(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *resvar, int nvars, SCIP_VAR **vars, 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 cons_and.c:5076
SCIP_RETCODE SCIPcreateConsBasicOr(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *resvar, int nvars, SCIP_VAR **vars)
Definition cons_or.c:2273
SCIP_VAR * SCIPgetResultantOr(SCIP *scip, SCIP_CONS *cons)
Definition cons_or.c:2335
SCIP_RETCODE SCIPcreateConsOr(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *resvar, int nvars, SCIP_VAR **vars, 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 cons_or.c:2211
SCIP_RETCODE SCIPincludeConshdlrOr(SCIP *scip)
Definition cons_or.c:2161
SCIP_RETCODE SCIPgetVarCopy(SCIP *sourcescip, SCIP *targetscip, SCIP_VAR *sourcevar, SCIP_VAR **targetvar, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, SCIP_Bool *success)
Definition scip_copy.c:711
SCIP_Bool SCIPisTransformed(SCIP *scip)
SCIP_Bool SCIPisStopped(SCIP *scip)
SCIP_STAGE SCIPgetStage(SCIP *scip)
int SCIPgetNVars(SCIP *scip)
Definition scip_prob.c:1992
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition scip_prob.c:2770
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition scip_prob.c:2843
SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
Definition scip_prob.c:3474
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
#define SCIPdebugMsgPrint
#define SCIPdebugMsg
SCIP_RETCODE SCIPinitConflictAnalysis(SCIP *scip, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
SCIP_Bool SCIPisConflictAnalysisApplicable(SCIP *scip)
SCIP_RETCODE SCIPaddConflictBinvar(SCIP *scip, SCIP_VAR *var)
SCIP_RETCODE SCIPanalyzeConflictCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
Definition cons.c:4227
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:372
SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
Definition scip_cons.c:540
SCIP_RETCODE SCIPsetConshdlrSepa(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSSEPALP((*conssepalp)), SCIP_DECL_CONSSEPASOL((*conssepasol)), int sepafreq, int sepapriority, SCIP_Bool delaysepa)
Definition scip_cons.c:235
SCIP_RETCODE SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
Definition scip_cons.c:281
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 SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:831
SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:785
SCIP_RETCODE SCIPsetConshdlrGetSignedPermsymGraph(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:924
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4197
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:941
SCIP_RETCODE SCIPsetConshdlrGetPermsymGraph(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:900
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:578
SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4217
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:601
SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:647
SCIP_RETCODE SCIPsetConshdlrExitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:468
SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:624
SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:854
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition cons.c:8244
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition cons.c:8473
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition cons.c:8234
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition cons.c:8383
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition scip_cons.c:2537
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition cons.c:8413
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition cons.c:8343
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition cons.c:8523
SCIP_Bool SCIPconsIsLockedType(SCIP_CONS *cons, SCIP_LOCKTYPE locktype)
Definition cons.c:8607
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition cons.c:8403
SCIP_Bool SCIPconsIsActive(SCIP_CONS *cons)
Definition cons.c:8275
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:998
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition cons.c:8433
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition cons.c:8453
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition cons.c:8214
SCIP_RETCODE SCIPresetConsAge(SCIP *scip, SCIP_CONS *cons)
Definition scip_cons.c:1813
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition cons.c:8463
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition cons.c:8493
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition scip_cons.c:1174
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition cons.c:8393
SCIP_RETCODE SCIPincConsAge(SCIP *scip, SCIP_CONS *cons)
Definition scip_cons.c:1785
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition cons.c:8483
SCIP_RETCODE SCIPaddRow(SCIP *scip, SCIP_ROW *row, SCIP_Bool forcecut, SCIP_Bool *infeasible)
Definition scip_cut.c:250
SCIP_RETCODE SCIPincludeEventhdlrBasic(SCIP *scip, SCIP_EVENTHDLR **eventhdlrptr, const char *name, const char *desc, SCIP_DECL_EVENTEXEC((*eventexec)), SCIP_EVENTHDLRDATA *eventhdlrdata)
Definition scip_event.c:104
SCIP_EVENTTYPE SCIPeventGetType(SCIP_EVENT *event)
Definition event.c:1030
SCIP_RETCODE SCIPcatchVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int *filterpos)
Definition scip_event.c:354
SCIP_RETCODE SCIPdropVarEvent(SCIP *scip, SCIP_VAR *var, SCIP_EVENTTYPE eventtype, SCIP_EVENTHDLR *eventhdlr, SCIP_EVENTDATA *eventdata, int filterpos)
Definition scip_event.c:400
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition scip_mem.h:110
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 SCIPreallocBlockMemoryArray(scip, ptr, oldnum, newnum)
Definition scip_mem.h:99
#define SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition scip_mem.h:105
SCIP_Bool SCIPinProbing(SCIP *scip)
SCIP_RETCODE SCIPaddVarsToRowSameCoef(SCIP *scip, SCIP_ROW *row, int nvars, SCIP_VAR **vars, SCIP_Real val)
Definition scip_lp.c:1773
SCIP_RETCODE SCIPcreateEmptyRowCons(SCIP *scip, SCIP_ROW **row, SCIP_CONS *cons, const char *name, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool removable)
Definition scip_lp.c:1422
SCIP_RETCODE SCIPaddVarToRow(SCIP *scip, SCIP_ROW *row, SCIP_VAR *var, SCIP_Real val)
Definition scip_lp.c:1701
SCIP_Real SCIPgetRowSolFeasibility(SCIP *scip, SCIP_ROW *row, SCIP_SOL *sol)
Definition scip_lp.c:2167
SCIP_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition scip_lp.c:1562
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition lp.c:17523
void SCIPupdateSolConsViolation(SCIP *scip, SCIP_SOL *sol, SCIP_Real absviol, SCIP_Real relviol)
Definition scip_sol.c:129
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition scip_sol.c:1217
SCIP_RETCODE SCIPgetSymActiveVariables(SCIP *scip, SYM_SYMTYPE symtype, SCIP_VAR ***vars, SCIP_Real **scalars, int *nvars, SCIP_Real *constant, SCIP_Bool transformed)
SCIP_RETCODE SCIPextendPermsymDetectionGraphLinear(SCIP *scip, SYM_GRAPH *graph, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_CONS *cons, SCIP_Real lhs, SCIP_Real rhs, SCIP_Bool *success)
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasPositive(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPinRepropagation(SCIP *scip)
Definition scip_tree.c:146
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition scip_var.c:4353
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition var.c:17599
SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition scip_var.c:1482
SCIP_Bool SCIPdoNotAggr(SCIP *scip)
Definition scip_var.c:8567
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition var.c:18144
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition var.c:17561
SCIP_RETCODE SCIPparseVarsList(SCIP *scip, const char *str, SCIP_VAR **vars, int *nvars, int varssize, int *requiredsize, char **endptr, char delimiter, SCIP_Bool *success)
Definition scip_var.c:610
SCIP_RETCODE SCIPaggregateVars(SCIP *scip, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *redundant, SCIP_Bool *aggregated)
Definition scip_var.c:8403
SCIP_RETCODE SCIPparseVarName(SCIP *scip, const char *str, SCIP_VAR **var, char **endptr)
Definition scip_var.c:533
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition var.c:18088
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition scip_var.c:4261
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition scip_var.c:4439
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition scip_var.c:2130
const char * SCIPvarGetName(SCIP_VAR *var)
Definition var.c:17419
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition scip_var.c:1529
SCIP_RETCODE SCIPaddVarImplication(SCIP *scip, SCIP_VAR *var, SCIP_Bool varfixing, SCIP_VAR *implvar, SCIP_BOUNDTYPE impltype, SCIP_Real implbound, SCIP_Bool *infeasible, int *nbdchgs)
Definition scip_var.c:6782
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition var.c:18134
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition var.c:18078
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition scip_var.c:1994
SCIP_RETCODE SCIPinferBinvarCons(SCIP *scip, SCIP_VAR *var, SCIP_Bool fixedval, SCIP_CONS *infercons, int inferinfo, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition scip_var.c:5725
SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
Definition scip_var.c:230
SCIP_RETCODE SCIPgetBinvarRepresentative(SCIP *scip, SCIP_VAR *var, SCIP_VAR **repvar, SCIP_Bool *negated)
Definition scip_var.c:1599
SCIP_RETCODE SCIPwriteVarsList(SCIP *scip, FILE *file, SCIP_VAR **vars, int nvars, SCIP_Bool type, char delimiter)
Definition scip_var.c:292
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition scip_var.c:1441
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition misc.c:10877
char * SCIPstrtok(char *s, const char *delim, char **ptrptr)
Definition misc.c:10818
return SCIP_OKAY
int c
SCIP_Bool cutoff
static SCIP_SOL * sol
int r
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
SCIP_VAR * var
static SCIP_Bool propagate
static SCIP_VAR ** vars
memory allocation routines
#define BMScopyMemoryArray(ptr, source, num)
Definition memory.h:134
public methods for managing constraints
public methods for managing events
public methods for LP management
public methods for message output
#define SCIPerrorMessage
Definition pub_message.h:64
#define SCIPdebug(x)
Definition pub_message.h:93
public data structures and miscellaneous methods
public methods for problem variables
public methods for conflict handler plugins and conflict analysis
public methods for constraint handler plugins and constraints
public methods for problem copies
public methods for cuts and aggregation rows
public methods for event handler plugins and event handlers
general public methods
public methods for the LP relaxation, rows and columns
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for global and local (sub)problems
public methods for the probing mode
public methods for solutions
public methods for the branch-and-bound tree
public methods for SCIP variables
structs for symmetry computations
methods for dealing with symmetry detection graphs
@ SCIP_CONFTYPE_PROPAGATION
#define SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH(x)
Definition type_cons.h:955
#define SCIP_DECL_CONSGETPERMSYMGRAPH(x)
Definition type_cons.h:937
#define SCIP_DECL_CONSENFOLP(x)
Definition type_cons.h:363
#define SCIP_DECL_CONSDELETE(x)
Definition type_cons.h:229
#define SCIP_DECL_CONSGETVARS(x)
Definition type_cons.h:866
#define SCIP_DECL_CONSPRINT(x)
Definition type_cons.h:768
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition type_cons.h:64
#define SCIP_DECL_CONSSEPALP(x)
Definition type_cons.h:288
#define SCIP_DECL_CONSENFORELAX(x)
Definition type_cons.h:388
#define SCIP_DECL_CONSPROP(x)
Definition type_cons.h:505
#define SCIP_DECL_CONSGETNVARS(x)
Definition type_cons.h:884
#define SCIP_DECL_CONSRESPROP(x)
Definition type_cons.h:611
#define SCIP_DECL_CONSENFOPS(x)
Definition type_cons.h:431
#define SCIP_DECL_CONSPARSE(x)
Definition type_cons.h:844
#define SCIP_DECL_CONSTRANS(x)
Definition type_cons.h:239
#define SCIP_DECL_CONSPRESOL(x)
Definition type_cons.h:560
#define SCIP_DECL_CONSINITLP(x)
Definition type_cons.h:259
#define SCIP_DECL_CONSLOCK(x)
Definition type_cons.h:675
#define SCIP_DECL_CONSCOPY(x)
Definition type_cons.h:809
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
#define SCIP_DECL_CONSEXITSOL(x)
Definition type_cons.h:216
#define SCIP_DECL_CONSFREE(x)
Definition type_cons.h:116
#define SCIP_DECL_CONSSEPASOL(x)
Definition type_cons.h:320
#define SCIP_EVENTTYPE_BOUNDCHANGED
Definition type_event.h:125
struct SCIP_EventData SCIP_EVENTDATA
Definition type_event.h:173
#define SCIP_EVENTTYPE_UBTIGHTENED
Definition type_event.h:79
#define SCIP_DECL_EVENTEXEC(x)
Definition type_event.h:253
#define SCIP_EVENTTYPE_LBRELAXED
Definition type_event.h:78
#define SCIP_EVENTTYPE_LBTIGHTENED
Definition type_event.h:77
#define SCIP_EVENTTYPE_UBRELAXED
Definition type_event.h:80
@ SCIP_BOUNDTYPE_UPPER
Definition type_lp.h:57
@ SCIP_BOUNDTYPE_LOWER
Definition type_lp.h:56
@ SCIP_CUTOFF
Definition type_result.h:48
@ SCIP_FEASIBLE
Definition type_result.h:45
@ SCIP_REDUCEDDOM
Definition type_result.h:51
@ SCIP_DIDNOTFIND
Definition type_result.h:44
@ SCIP_SEPARATED
Definition type_result.h:49
@ 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
@ SCIP_STAGE_SOLVING
Definition type_set.h:53
enum SYM_Symtype SYM_SYMTYPE
@ SYM_SYMTYPE_SIGNPERM
@ SYM_SYMTYPE_PERM
@ SCIP_LOCKTYPE_CONFLICT
Definition type_var.h:98
@ SCIP_LOCKTYPE_MODEL
Definition type_var.h:97