Scippy

SCIP

Solving Constraint Integer Programs

cons_linking.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_linking.c
26 * @ingroup DEFPLUGINS_CONS
27 * @brief constraint handler for linking constraints
28 * @author Stefan Heinz
29 * @author Jens Schulz
30 *
31 * The constraints handler stores linking constraints between a linking variable (integer or continuous) and an array of binary variables. Such
32 * a linking constraint has the form:
33 *
34 * linkvar = sum_{i=1}^n {vals[i] * binvars[i]}
35 *
36 * with the additional side condition that exactly one binary variable has to be one (set partitioning condition).
37 *
38 * This constraint can be created only with the linking variable if it is an integer variable. In this case the binary variables are only created on
39 * demand. That is, whenever someone asks for the binary variables. Therefore, such constraints can be used to get a
40 * "binary representation" of the domain of the linking variable which will be dynamically created.
41 *
42 *
43 * @todo add pairwise comparison of constraints in presolving (fast hash table version and complete pairwise comparison)
44 * @todo in case the integer variable is set to lower or upper bound it follows that only the corresponding binary
45 * variable has a positive value which is one, this can be used to fasten the checking routine
46 */
47
48/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
49
51#include "scip/cons_linear.h"
52#include "scip/cons_linking.h"
53#include "scip/cons_setppc.h"
54#include "scip/pub_cons.h"
55#include "scip/pub_event.h"
56#include "scip/pub_lp.h"
57#include "scip/pub_message.h"
58#include "scip/pub_misc.h"
59#include "scip/pub_misc_sort.h"
60#include "scip/pub_var.h"
61#include "scip/scip_conflict.h"
62#include "scip/scip_cons.h"
63#include "scip/scip_copy.h"
64#include "scip/scip_cut.h"
65#include "scip/scip_event.h"
66#include "scip/scip_general.h"
67#include "scip/scip_lp.h"
68#include "scip/scip_mem.h"
69#include "scip/scip_message.h"
70#include "scip/scip_nlp.h"
71#include "scip/scip_numerics.h"
72#include "scip/scip_param.h"
73#include "scip/scip_prob.h"
74#include "scip/scip_probing.h"
75#include "scip/scip_sol.h"
76#include "scip/scip_tree.h"
77#include "scip/scip_var.h"
78#include "scip/symmetry_graph.h"
80#include <ctype.h>
81#include <string.h>
82
83/* constraint handler properties */
84#define CONSHDLR_NAME "linking"
85#define CONSHDLR_DESC "linking constraint x = sum_{i=1}^{n} c_i*y_i, y1+...+yn = 1, x real, y's binary"
86
87#define EVENTHDLR_NAME "linking"
88#define EVENTHDLR_DESC "event handler for linking constraints"
89
90#define CONSHDLR_SEPAPRIORITY 750000 /**< priority of the constraint handler for separation */
91#define CONSHDLR_ENFOPRIORITY -2050000 /**< priority of the constraint handler for constraint enforcing */
92#define CONSHDLR_CHECKPRIORITY -750000 /**< priority of the constraint handler for checking feasibility */
93#define CONSHDLR_SEPAFREQ 1 /**< frequency for separating cuts; zero means to separate only in the root node */
94#define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
95#define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation, propagation and enforcement, -1 for no eager evaluations, 0 for first only */
96#define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler participates in (-1: no limit) */
97#define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
98#define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
99#define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
100
101#define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP /**< propagation timing mask of the constraint handler */
102#define CONSHDLR_PRESOLTIMING SCIP_PRESOLTIMING_MEDIUM /**< presolving timing of the constraint handler (fast, medium, or exhaustive) */
103
104
105#define HASHSIZE_BINVARSCONS 500 /**< minimal size of hash table in linking constraint handler */
106#define DEFAULT_LINEARIZE FALSE /**< should the linking constraint be linearize after the binary variable are created */
107
108/*
109 * Data structures
110 */
111
112/** constraint data for linking constraints */
113struct SCIP_ConsData
114{
115 SCIP_VAR* linkvar; /**< continuous variable which is linked */
116 SCIP_VAR** binvars; /**< binary variables */
117 SCIP_Real* vals; /**< coefficients */
118 SCIP_ROW* row1; /**< LP row for the linking itself */
119 SCIP_ROW* row2; /**< LP row ensuring the set partitioning condition of the binary variables */
120 SCIP_NLROW* nlrow1; /**< NLP row for the linking itself */
121 SCIP_NLROW* nlrow2; /**< NLP row ensuring the set partitioning condition of the binary variables */
122 int nbinvars; /**< number of binary variables */
123 int sizebinvars; /**< size of the binary variable array */
124 int nfixedzeros; /**< current number of variables fixed to zero in the constraint */
125 int nfixedones; /**< current number of variables fixed to one in the constraint */
126 int firstnonfixed; /**< index of first locally non-fixed binary variable in binvars array */
127 int lastnonfixed; /**< index of last locally non-fixed binary variable in binvars array */
128 unsigned int cliqueadded:1; /**< was the set partitioning condition already added as clique? */
129 unsigned int sorted:1; /**< are the coefficients of the binary variables are sorted in non-decreasing order */
130};
131
132/** constraint handler data */
133struct SCIP_ConshdlrData
134{
135 SCIP_EVENTHDLR* eventhdlr; /**< event handler for bound change events on binary variables */
136 SCIP_HASHMAP* varmap; /**< hash map mapping a linking variable to its linking constraint */
137 SCIP_Bool linearize; /**< should the linking constraint be linearize after the binary variable are created */
138};
139
140/*
141 * Local methods
142 */
143
144/** returns for a given linking variable the corresponding hash map key */
145static
147 SCIP_VAR* var /**< variable to get the hash map key for */
148 )
149{
150 /* return the unique variable index + 1 */
151 return (void*)(size_t)(SCIPvarGetIndex(var) + 1); /*lint !e571 !e776*/
152}
153
154/* sort binary variable in non-decreasing order w.r.t. coefficients */
155static
157 SCIP_CONSDATA* consdata /**< linking constraint data */
158 )
159{
160 if( consdata->sorted )
161 return;
162
163 /* sort binary variable in non-decreasing order w.r.t. coefficients */
164 SCIPsortRealPtr(consdata->vals, (void**)consdata->binvars, consdata->nbinvars);
165
166 consdata->sorted = TRUE;
167}
168
169
170/** installs rounding locks for the binary variables in the given linking constraint */
171static
173 SCIP* scip, /**< SCIP data structure */
174 SCIP_CONS* cons, /**< linking constraint */
175 SCIP_VAR** binvars, /**< binary variables */
176 int nbinvars /**< number of binary variables */
177 )
178{
179 int b;
180
181 for( b = 0; b < nbinvars; ++b )
182 {
183 SCIP_CALL( SCIPlockVarCons(scip, binvars[b], cons, TRUE, TRUE) );
184 }
185
186 return SCIP_OKAY;
187}
188
189/** creates constraint handler data for the linking constraint handler */
190static
192 SCIP* scip, /**< SCIP data structure */
193 SCIP_CONSHDLRDATA** conshdlrdata, /**< pointer to store the constraint handler data */
194 SCIP_EVENTHDLR* eventhdlr /**< event handler */
195 )
196{
197 assert(scip != NULL);
198 assert(conshdlrdata != NULL);
199 assert(eventhdlr != NULL);
200
201 SCIP_CALL( SCIPallocBlockMemory(scip, conshdlrdata) );
202
203 /* create hash map */
204 (*conshdlrdata)->varmap = NULL;
205
206 /* set event handler for bound change events on binary variables */
207 (*conshdlrdata)->eventhdlr = eventhdlr;
208
209 return SCIP_OKAY;
210}
211
212/** frees constraint handler data for linking constraint handler */
213static
215 SCIP* scip, /**< SCIP data structure */
216 SCIP_CONSHDLRDATA** conshdlrdata /**< pointer to the constraint handler data */
217 )
218{
219 assert(conshdlrdata != NULL);
220 assert(*conshdlrdata != NULL);
221
222 /* free hash map */
223 if( (*conshdlrdata)->varmap != NULL )
224 SCIPhashmapFree(&(*conshdlrdata)->varmap);
225
226 /* free memory of constraint handler data */
227 SCIPfreeBlockMemory(scip, conshdlrdata);
228}
229
230/** prints linking constraint to file stream */
231static
233 SCIP* scip, /**< SCIP data structure */
234 SCIP_CONSDATA* consdata, /**< linking constraint data */
235 FILE* file /**< output file (or NULL for standard output) */
236 )
237{
238 SCIP_VAR** binvars;
239 SCIP_VAR* linkvar;
240 int nbinvars;
241
242 assert(scip != NULL);
243 assert(consdata != NULL);
244
245 linkvar = consdata->linkvar;
246 binvars = consdata->binvars;
247 nbinvars = consdata->nbinvars;
248
249 assert(linkvar != NULL);
250 assert(binvars != NULL || nbinvars == 0);
251
252 /* print linking variable */
253 SCIP_CALL( SCIPwriteVarName(scip, file, linkvar, FALSE) );
254
255 SCIPinfoMessage(scip, file, " = ");
256
257 if( nbinvars == 0 )
258 {
259 SCIPinfoMessage(scip, file, " no binary variables yet");
260 }
261 else
262 {
263 assert(binvars != NULL);
264
265 SCIP_CALL( SCIPwriteVarsLinearsum(scip, file, binvars, consdata->vals, nbinvars, FALSE) );
266 }
267
268 return SCIP_OKAY;
269}
270
271/** catches events for variable at given position */
272static
274 SCIP* scip, /**< SCIP data structure */
275 SCIP_CONSDATA* consdata, /**< linking constraint data */
276 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
277 int pos /**< array position of variable to catch bound change events for */
278 )
279{
280 SCIP_VAR* var;
281
282 assert(consdata != NULL);
283 assert(eventhdlr != NULL);
284 assert(0 <= pos && pos < consdata->nbinvars);
285 assert(consdata->binvars != NULL);
286
287 var = consdata->binvars[pos];
288 assert(var != NULL);
289
290 /* catch bound change events on variable */
291 /**@todo do we have to add the event SCIP_EVENTTYPE_VARFIXED? */
293
294 /* update the fixed variables counters for this variable */
295 if( SCIPisEQ(scip, SCIPvarGetUbLocal(var), 0.0) )
296 consdata->nfixedzeros++;
297 else if( SCIPisEQ(scip, SCIPvarGetLbLocal(var), 1.0) )
298 consdata->nfixedones++;
299
300 return SCIP_OKAY;
301}
302
303/** drops events for variable at given position */
304static
306 SCIP* scip, /**< SCIP data structure */
307 SCIP_CONSDATA* consdata, /**< linking constraint data */
308 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
309 int pos /**< array position of variable to catch bound change events for */
310 )
311{
312 SCIP_VAR* var;
313
314 assert(consdata != NULL);
315 assert(eventhdlr != NULL);
316 assert(0 <= pos && pos < consdata->nbinvars);
317 assert(consdata->binvars != NULL);
318
319 var = consdata->binvars[pos];
320 assert(var != NULL);
321
322 /* drop events on variable */
323 SCIP_CALL( SCIPdropVarEvent(scip, var, SCIP_EVENTTYPE_BOUNDCHANGED, eventhdlr, (SCIP_EVENTDATA*)consdata, -1) );
324
325 /* update the fixed variables counters for this variable */
326 if( SCIPisEQ(scip, SCIPvarGetUbLocal(var), 0.0) )
327 consdata->nfixedzeros--;
328 else if( SCIPisEQ(scip, SCIPvarGetLbLocal(var), 1.0) )
329 consdata->nfixedones--;
330
331 return SCIP_OKAY;
332}
333
334/** catches bound change events for all variables in transformed linking constraint */
335static
337 SCIP* scip, /**< SCIP data structure */
338 SCIP_CONSDATA* consdata, /**< linking constraint data */
339 SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
340 )
341{
342 int i;
343
344 assert(consdata != NULL);
345
346 /* author bzfhende
347 *
348 * TODO should we catch events even in the trivial case of only 1 binary variable
349 */
350
351 /* catch event for every single variable */
352 for( i = 0; i < consdata->nbinvars; ++i )
353 {
354 SCIP_CALL( catchEvent(scip, consdata, eventhdlr, i) );
355 }
356
357 return SCIP_OKAY;
358}
359
360/** drops bound change events for all variables in transformed linking constraint */
361static
363 SCIP* scip, /**< SCIP data structure */
364 SCIP_CONSDATA* consdata, /**< linking constraint data */
365 SCIP_EVENTHDLR* eventhdlr /**< event handler to call for the event processing */
366 )
367{
368 int i;
369
370 assert(consdata != NULL);
371
372 /* author bzfhende
373 *
374 * TODO drop the events even in the trivial case nbinvars == 1?
375 */
376
377 /* drop event of every single variable */
378 for( i = 0; i < consdata->nbinvars; ++i )
379 {
380 SCIP_CALL( dropEvent(scip, consdata, eventhdlr, i) );
381 }
382
383 return SCIP_OKAY;
384}
385
386/** linearize the given linking constraint into a set partitioning constraint for the binary variables and a linear
387 * constraint for the linking between the linking variable and the binary variables */
388static
390 SCIP* scip, /**< SCIP data structure */
391 SCIP_CONS* cons, /**< linking constraint */
392 SCIP_CONSDATA* consdata /**< linking constraint data */
393 )
394{
395 SCIP_CONS* lincons;
396 int b;
397
398 SCIPdebugMsg(scip, "linearized linking constraint <%s>\n", SCIPconsGetName(cons));
399
400 /* create set partitioning constraint for the binary variables */
401 SCIP_CALL( SCIPcreateConsSetpart(scip, &lincons, SCIPconsGetName(cons), consdata->nbinvars, consdata->binvars,
405 SCIP_CALL( SCIPaddCons(scip, lincons) );
406 SCIP_CALL( SCIPreleaseCons(scip, &lincons) );
407
408 /* create linear constraint for the linking between the binary variables and the linking variable */
409 SCIP_CALL( SCIPcreateConsLinear(scip, &lincons, SCIPconsGetName(cons), 0, NULL, NULL, 0.0, 0.0,
413
414 for( b = 0; b < consdata->nbinvars; ++b )
415 {
416 SCIP_CALL( SCIPaddCoefLinear(scip, lincons, consdata->binvars[b], consdata->vals[b]) );
417 }
418 SCIP_CALL( SCIPaddCoefLinear(scip, lincons, consdata->linkvar, -1.0) );
419
420 SCIP_CALL( SCIPaddCons(scip, lincons) );
421 SCIP_CALL( SCIPreleaseCons(scip, &lincons) );
422
423 return SCIP_OKAY;
424}
425
426/** creates the binary variables */
427static
429 SCIP* scip, /**< SCIP data structure */
430 SCIP_CONS* cons, /**< linking constraint */
431 SCIP_CONSDATA* consdata, /**< linking constraint data */
432 SCIP_EVENTHDLR* eventhdlr, /**< event handler for bound change events on binary variables */
433 SCIP_Bool linearize /**< should the linking constraint be linearized */
434 )
435{
436 SCIP_VAR* linkvar;
437 SCIP_VAR* binvar;
438 int lb;
439 int ub;
440 char name[SCIP_MAXSTRLEN];
441 int nbinvars;
442 int b;
443
444 assert(scip != NULL);
445 assert(consdata != NULL);
446 assert(consdata->nbinvars == 0);
447 assert(consdata->binvars == NULL);
448
449 SCIPdebugMsg(scip, "create binary variables for linking variable <%s>\n", SCIPvarGetName(consdata->linkvar));
450
451 /* author bzfhende
452 *
453 * TODO ensure that this method is only called for integer linking variables, because it does not make sense for continuous linking variables.
454 */
455
456 linkvar = consdata->linkvar;
459
460 nbinvars = ub - lb + 1;
461 assert(nbinvars > 0);
462
463 /* allocate block memory for the binary variables */
464 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->binvars, nbinvars) );
465 /* allocate block memory for the binary variables */
466 SCIP_CALL( SCIPallocBlockMemoryArray(scip, &consdata->vals, nbinvars) );
467 consdata->sizebinvars = nbinvars;
468
469 /* check if the linking variable is fixed */
470 if( nbinvars == 1 )
471 {
472 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s[%d]", SCIPvarGetName(linkvar), lb);
473
474 /* creates and captures a fixed binary variables */
475 SCIP_CALL( SCIPcreateVar(scip, &binvar, name, 1.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
476 FALSE, TRUE, NULL, NULL, NULL, NULL, NULL) );
477 SCIP_CALL( SCIPaddVar(scip, binvar) );
478
479 consdata->binvars[0] = binvar;
480 consdata->vals[0] = lb;
481 }
482 else
483 {
484 for( b = 0; b < nbinvars; ++b)
485 {
486 (void)SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s[%d]", SCIPvarGetName(linkvar), lb + b);
487
488 /* creates and captures variables */
489 SCIP_CALL( SCIPcreateVar(scip, &binvar, name, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
490 TRUE, TRUE, NULL, NULL, NULL, NULL, NULL) );
491
492 /* add variable to the problem */
493 SCIP_CALL( SCIPaddVar(scip, binvar) );
494 consdata->binvars[b] = binvar;
495 consdata->vals[b] = lb + b;
496 }
497 }
498
499 consdata->nbinvars = nbinvars;
500
501 assert(consdata->nfixedzeros == 0);
502 assert(consdata->nfixedones == 0);
503
505 {
506 /* (rounding) lock binary variable */
507 SCIP_CALL( lockRounding(scip, cons, consdata->binvars, consdata->nbinvars) );
508
509 /* catch bound change events of variables */
510 SCIP_CALL( catchAllEvents(scip, consdata, eventhdlr) );
511
512 if( nbinvars > 1 )
513 {
514 if( linearize )
515 {
516 SCIP_CALL( consdataLinearize(scip, cons, consdata) );
517 }
518 else
519 {
520 /* enable constraint */
521 SCIP_CALL( SCIPenableCons(scip, cons) );
522 }
523 }
524 }
525
526 return SCIP_OKAY;
527}
528
529/** creates consdata */
530static
532 SCIP* scip, /**< SCIP data structure */
533 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
534 SCIP_CONSDATA** consdata, /**< pointer to constraint data */
535 SCIP_VAR* linkvar, /**< linking variable which is linked */
536 SCIP_VAR** binvars, /**< binary variables */
537 SCIP_Real* vals, /**< coefficients of the binary variables */
538 int nbinvars /**< number of binary starting variables */
539 )
540{
541 int v;
542
543 assert(scip!= NULL);
544 assert(consdata != NULL);
545 assert(linkvar != NULL);
546 assert(binvars != NULL || nbinvars == 0);
547 assert(SCIPvarGetType(linkvar) != SCIP_VARTYPE_CONTINUOUS || nbinvars > 0);
548
549 /* allocate memory for consdata */
550 SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
551
552 (*consdata)->linkvar = linkvar;
553 (*consdata)->nbinvars = nbinvars;
554 (*consdata)->sizebinvars = nbinvars;
555 (*consdata)->row1 = NULL;
556 (*consdata)->row2 = NULL;
557 (*consdata)->nlrow1 = NULL;
558 (*consdata)->nlrow2 = NULL;
559 (*consdata)->cliqueadded = FALSE;
560
561 /* initialize constraint state */
562 (*consdata)->sorted = FALSE;
563 (*consdata)->firstnonfixed = 0;
564 (*consdata)->lastnonfixed = nbinvars - 1;
565 (*consdata)->nfixedzeros = 0;
566 (*consdata)->nfixedones = 0;
567
568 if( nbinvars == 0 )
569 {
570 (*consdata)->binvars = NULL;
571 (*consdata)->vals = NULL;
572 }
573 else
574 {
575 /* copy binary variable array */
576 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->binvars, binvars, nbinvars) );
577
578 /* copy coefficients */
579 SCIP_CALL( SCIPduplicateBlockMemoryArray(scip, &(*consdata)->vals, vals, nbinvars) );
580 }
581
582 /* get transformed variable, if we are in the transformed problem */
584 {
585 if( nbinvars > 0 )
586 {
587 SCIP_CALL( SCIPgetTransformedVars(scip, nbinvars, (*consdata)->binvars, (*consdata)->binvars) );
588
589 /* catch bound change events of variables */
590 SCIP_CALL( catchAllEvents(scip, *consdata, eventhdlr) );
591 }
592
593 SCIP_CALL( SCIPgetTransformedVar(scip, (*consdata)->linkvar, &(*consdata)->linkvar) );
594 }
595
596 /* author bzfhende
597 *
598 * TODO do we need to forbid multi-aggregations? This was only needed if we substitute and resubstitute linking
599 * variables into linear constraints.
600 */
601
602 /* capture variables */
603 for( v = 0; v < nbinvars; ++v )
604 {
605 assert((*consdata)->binvars[v] != NULL);
606 SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->binvars[v]) );
607 }
608 SCIP_CALL( SCIPcaptureVar(scip, (*consdata)->linkvar) );
609
610 return SCIP_OKAY;
611}
612
613
614/** free consdata */
615static
617 SCIP* scip, /**< SCIP data structure */
618 SCIP_CONSDATA** consdata /**< pointer to consdata */
619 )
620{
621 int v;
622
623 assert(consdata != NULL);
624 assert(*consdata != NULL);
625 assert((*consdata)->nbinvars == 0 || (*consdata)->binvars != NULL);
626
627 /* release the rows */
628 if( (*consdata)->row1 != NULL )
629 {
630 assert((*consdata)->row2 != NULL);
631
632 SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->row1) );
633 SCIP_CALL( SCIPreleaseRow(scip, &(*consdata)->row2) );
634 }
635
636 /* release the nlrows */
637 if( (*consdata)->nlrow1 != NULL )
638 {
639 assert((*consdata)->nlrow2 != NULL);
640
641 SCIP_CALL( SCIPreleaseNlRow(scip, &(*consdata)->nlrow1) );
642 SCIP_CALL( SCIPreleaseNlRow(scip, &(*consdata)->nlrow2) );
643 }
644
645 /* capture variables */
646 for( v = 0; v < (*consdata)->nbinvars; ++v )
647 {
648 assert((*consdata)->binvars[v] != NULL);
649 SCIP_CALL( SCIPreleaseVar(scip, &(*consdata)->binvars[v]) );
650 }
651 SCIP_CALL( SCIPreleaseVar(scip, &(*consdata)->linkvar) );
652
653 /* free binary variable array */
654 if( (*consdata)->sizebinvars > 0 )
655 {
656 /* if constraint belongs to transformed problem space, drop bound change events on variables */
657 SCIPfreeBlockMemoryArray(scip, &(*consdata)->vals, (*consdata)->sizebinvars);
658 SCIPfreeBlockMemoryArray(scip, &(*consdata)->binvars, (*consdata)->sizebinvars);
659 }
660
661 /* check if the fixed counters are reset */
662 assert((*consdata)->nfixedzeros == 0);
663 assert((*consdata)->nfixedones == 0);
664
665 /* free constraint data */
666 SCIPfreeBlockMemory(scip, consdata);
667
668 return SCIP_OKAY;
669}
670
671
672/** analyzes conflicting assignment on given constraint where reason comes from the linking variable lower or upper
673 * bound
674 */
675static
677 SCIP* scip, /**< SCIP data structure */
678 SCIP_CONS* cons, /**< linking constraint to be processed */
679 SCIP_VAR* linkvar, /**< linking variable */
680 SCIP_VAR* binvar, /**< binary variable is the reason */
681 SCIP_Bool lblinkvar, /**< lower bound of linking variable is the reason */
682 SCIP_Bool ublinkvar /**< upper bound of linking variable is the reason */
683 )
684{
685 assert(scip != NULL);
686
687 /* conflict analysis can only be applied in solving stage and if it is turned on */
689 return SCIP_OKAY;
690
691 /* initialize conflict analysis, and add all variables of infeasible constraint to conflict candidate queue */
693
694 if( lblinkvar )
695 {
696 assert(linkvar != NULL);
697 SCIP_CALL( SCIPaddConflictLb(scip, linkvar, NULL) );
698 }
699
700 if( ublinkvar )
701 {
702 assert(linkvar != NULL);
703 SCIP_CALL( SCIPaddConflictUb(scip, linkvar, NULL) );
704 }
705
706 if( binvar != NULL )
707 {
709 }
710
711 /* analyze the conflict */
713
714 return SCIP_OKAY;
715}
716
717/* author bzfhende
718 *
719 * TODO check if the method below produces valid results even if the variable is continuous
720 */
721
722/** fix linking variable to the value of the binary variable at pos */
723static
725 SCIP* scip, /**< SCIP data structure */
726 SCIP_CONS* cons, /**< linking constraint to be processed */
727 int pos, /**< position of binary variable */
728 SCIP_Bool* cutoff /**< pointer to store TRUE, if the node can be cut off */
729 )
730{
731 SCIP_CONSDATA* consdata;
732 SCIP_VAR* linkvar;
733 SCIP_Bool infeasible;
734 SCIP_Bool tightened;
735 SCIP_Real coef;
736
737 consdata = SCIPconsGetData(cons);
738 assert(consdata != NULL);
739
740 linkvar = consdata->linkvar;
741 coef = consdata->vals[pos];
742
743 /* change lower bound of the linking variable */
744 SCIP_CALL( SCIPinferVarLbCons(scip, linkvar, coef, cons, pos, TRUE, &infeasible, &tightened) );
745
746 if( infeasible )
747 {
748 assert(coef > SCIPvarGetUbLocal(linkvar));
749 assert(coef >= SCIPvarGetLbLocal(linkvar));
750
751 SCIP_CALL( analyzeConflict(scip, cons, linkvar, consdata->binvars[pos], FALSE, TRUE) );
752
753 *cutoff = TRUE;
754 return SCIP_OKAY;
755 }
756 assert(SCIPisFeasLE(scip, coef, SCIPvarGetUbLocal(linkvar)));
757
758 /* change upper bound of the integer variable */
759 SCIP_CALL( SCIPinferVarUbCons(scip, linkvar, coef, cons, pos, TRUE, &infeasible, &tightened) );
760
761 if( infeasible )
762 {
763 assert(coef < SCIPvarGetLbLocal(linkvar));
764 assert(coef <= SCIPvarGetUbLocal(linkvar));
765
766 SCIP_CALL( analyzeConflict(scip, cons, linkvar, consdata->binvars[pos], TRUE, FALSE) );
767
768 *cutoff = TRUE;
769 return SCIP_OKAY;
770 }
771
772 assert(SCIPisFeasEQ(scip, SCIPvarGetUbLocal(linkvar), SCIPvarGetLbLocal(linkvar)));
773
774 return SCIP_OKAY;
775}
776
777/** checks constraint for violation from the local bound of the linking variable, applies fixings to the binary
778 * variables if possible
779 */
780static
782 SCIP* scip, /**< SCIP data structure */
783 SCIP_CONS* cons, /**< linking constraint to be processed */
784 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
785 int* nchgbds, /**< pointer to store the number of changes (foxed) variable bounds */
786 SCIP_Bool* mustcheck /**< pointer to store whether this constraint must be checked for feasibility */
787 )
788{
789 SCIP_CONSDATA* consdata;
790 SCIP_VAR** binvars;
791 SCIP_VAR* linkvar;
792 SCIP_Real* vals;
793 SCIP_Real lb;
794 SCIP_Real ub;
795 int nbinvars;
796 int b;
797 SCIP_Bool infeasible;
798 SCIP_Bool tightened;
799
800 assert(cons != NULL);
801 assert(SCIPconsGetHdlr(cons) != NULL);
802 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
803 assert(cutoff != NULL);
804 assert(nchgbds != NULL);
805 assert(mustcheck != NULL);
806
807 consdata = SCIPconsGetData(cons);
808 assert(consdata != NULL);
809
810 /* ensure that the binary variables are sorted in non-decreasing order w.r.t. their coefficients */
811 consdataSort(consdata);
812
813 nbinvars = consdata->nbinvars;
814
815 /* in case there is only at most one binary variables, the constraints should already be disabled */
816 assert(nbinvars > 1);
817
818 /* if more than one binary variable is fixed to one or at least nbinvars minus one variable are fixed to zero */
819 if( consdata->nfixedones > 0 || consdata->nfixedzeros >= nbinvars-1 )
820 return SCIP_OKAY;
821
822 linkvar = consdata->linkvar;
823 assert(linkvar != NULL);
824
825 binvars = consdata->binvars;
826 vals = consdata->vals;
827
828 lb = SCIPvarGetLbLocal(linkvar);
829 ub = SCIPvarGetUbLocal(linkvar);
830
831 assert(lb <= ub);
832
833#ifndef NDEBUG
834 /* check that the first variable are locally fixed to zero */
835 for( b = 0; b < consdata->firstnonfixed; ++b )
836 assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
837
838 /* check that the last variable are locally fixed to zero */
839 for( b = consdata->lastnonfixed + 1; b < nbinvars; ++b )
840 assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
841#endif
842
843 for( b = consdata->firstnonfixed; b < nbinvars; ++b )
844 {
845 if( SCIPisLT(scip, vals[b], lb) )
846 {
847 SCIP_VAR* var;
848
849 var = binvars[b];
850 assert(var != NULL);
851
852 SCIPdebugMsg(scip, "fix variable <%s> to zero due to the lower bound of the linking variable <%s> [%g,%g]\n",
853 SCIPvarGetName(var), SCIPvarGetName(linkvar), lb, ub);
854
855 SCIP_CALL( SCIPinferBinvarCons(scip, var, FALSE, cons, -2, &infeasible, &tightened) );
856
857 if( infeasible )
858 {
859 SCIP_CALL( analyzeConflict(scip, cons, linkvar, var, TRUE, FALSE) );
860 *cutoff = TRUE;
861 return SCIP_OKAY;
862 }
863
864 if( tightened )
865 (*nchgbds)++;
866
867 /* adjust constraint state */
868 consdata->firstnonfixed++;
869 }
870 else
871 break;
872 }
873
874 /* fix binary variables to zero if not yet fixed, from local upper bound + 1*/
875 for( b = consdata->lastnonfixed; b >= 0; --b )
876 {
877 if( SCIPisGT(scip, vals[b], ub) )
878 {
879 SCIP_VAR* var;
880
881 var = binvars[b];
882 assert(var != NULL);
883
884 SCIPdebugMsg(scip, "fix variable <%s> to zero due to the upper bound of the linking variable <%s> [%g,%g]\n",
885 SCIPvarGetName(var), SCIPvarGetName(linkvar), lb, ub);
886
887 SCIP_CALL( SCIPinferBinvarCons(scip, var, FALSE, cons, -3, &infeasible, &tightened) );
888
889 if( infeasible )
890 {
891 SCIP_CALL( analyzeConflict(scip, cons, linkvar, var, FALSE, TRUE) );
892 *cutoff = TRUE;
893 return SCIP_OKAY;
894 }
895
896 if( tightened )
897 (*nchgbds)++;
898
899 /* adjust constraint state */
900 consdata->lastnonfixed--;
901 }
902 else
903 break;
904 }
905
906 if( consdata->firstnonfixed > consdata->lastnonfixed )
907 {
908 *cutoff = TRUE;
909 return SCIP_OKAY;
910 }
911
912 *mustcheck = (*nchgbds) == 0;
913
914 /* if linking variable is fixed, create for the binary variables which have a coefficient equal to the fixed value a
915 * set partitioning constraint
916 */
917 if( SCIPisEQ(scip, lb, ub) )
918 {
919 if( consdata->firstnonfixed == consdata->lastnonfixed )
920 {
921 SCIP_VAR* var;
922
923 var = binvars[consdata->firstnonfixed];
924
925 SCIPdebugMsg(scip, "fix variable <%s> to one due to the fixed linking variable <%s> [%g,%g]\n",
926 SCIPvarGetName(var), SCIPvarGetName(linkvar), lb, ub);
927
928 /* TODO can the forbidden cases be covered more elegantly? */
930 return SCIP_OKAY;
931
935 return SCIP_OKAY;
936
937 SCIP_CALL( SCIPinferBinvarCons(scip, var, TRUE, cons, -6, &infeasible, &tightened) );
938
939 if( infeasible )
940 {
941 SCIP_CALL( analyzeConflict(scip, cons, linkvar, var, TRUE, TRUE) );
942 *cutoff = TRUE;
943 return SCIP_OKAY;
944 }
945
946 if( tightened )
947 (*nchgbds)++;
948
949 SCIPdebugMsg(scip, " -> disabling linking constraint <%s>\n", SCIPconsGetName(cons));
951
952 *mustcheck = FALSE;
953 }
954 else if( SCIPgetDepth(scip) <= 0 )
955 {
956 SCIP_CONS* setppc;
957 SCIP_VAR** vars;
958 int nvars;
959
960 /* get sub array of variables which have the same coefficient */
961 vars = &consdata->binvars[consdata->firstnonfixed];
962 nvars = consdata->lastnonfixed - consdata->firstnonfixed + 1;
963
964 SCIP_CALL( SCIPcreateConsSetpart(scip, &setppc, SCIPconsGetName(cons), nvars, vars,
968
969 SCIP_CALL( SCIPaddCons(scip, setppc) );
970 SCIP_CALL( SCIPreleaseCons(scip, &setppc) );
971
973 }
974 }
975
976 return SCIP_OKAY;
977}
978
979/** deletes coefficient at given position from the binary variable array */
980static
982 SCIP* scip, /**< SCIP data structure */
983 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
984 SCIP_CONS* cons, /**< linking constraint */
985 int pos /**< position of coefficient to delete */
986 )
987{
988 SCIP_CONSDATA* consdata;
989 SCIP_VAR* var;
990
991 assert(scip != NULL);
992 assert(eventhdlr != NULL);
993
994 consdata = SCIPconsGetData(cons);
995 assert(consdata != NULL);
996 assert(0 <= pos && pos < consdata->nbinvars);
997
998 var = consdata->binvars[pos];
999 assert(var != NULL);
1000 assert(SCIPconsIsTransformed(cons) == SCIPvarIsTransformed(var));
1001
1002 /* remove the rounding locks for the deleted variable */
1003 SCIP_CALL( SCIPunlockVarCons(scip, var, cons, TRUE, TRUE) );
1004
1005 /* if we are in transformed problem, delete the event data of the variable */
1006 if( SCIPconsIsTransformed(cons) )
1007 {
1008 SCIP_CONSHDLR* conshdlr;
1009 SCIP_CONSHDLRDATA* conshdlrdata;
1010
1011 /* get event handler */
1012 conshdlr = SCIPconsGetHdlr(cons);
1013 conshdlrdata = SCIPconshdlrGetData(conshdlr);
1014 assert(conshdlrdata != NULL);
1015 assert(conshdlrdata->eventhdlr != NULL);
1016
1017 /* drop bound change events of variable */
1018 SCIP_CALL( dropEvent(scip, consdata, conshdlrdata->eventhdlr, pos) );
1019 }
1020
1021 /* move the last variable to the free slot */
1022 if( pos != consdata->nbinvars - 1 )
1023 {
1024 consdata->binvars[pos] = consdata->binvars[consdata->nbinvars-1];
1025 consdata->vals[pos] = consdata->vals[consdata->nbinvars-1];
1026 consdata->sorted = FALSE;
1027 }
1028
1029 consdata->nbinvars--;
1030
1031 /* release variable */
1032 SCIP_CALL( SCIPreleaseVar(scip, &var) );
1033
1034 return SCIP_OKAY;
1035}
1036
1037/** remove the trailing and leading binary variables that are fixed to zero */
1038static
1040 SCIP* scip, /**< SCIP data structure */
1041 SCIP_EVENTHDLR* eventhdlr, /**< event handler to call for the event processing */
1042 SCIP_CONS* cons /**< linking constraint */
1043 )
1044{
1045 SCIP_CONSDATA* consdata;
1046 int nbinvars;
1047 int b;
1048
1049 consdata = SCIPconsGetData(cons);
1050 assert(consdata != NULL);
1051 assert(consdata->sorted);
1052
1054 assert(!SCIPinProbing(scip));
1055 assert(!SCIPinRepropagation(scip));
1056
1057 nbinvars = consdata->nbinvars;
1058
1059 for( b = nbinvars - 1; b > consdata->lastnonfixed; --b )
1060 {
1061 SCIP_CALL( delCoefPos(scip, eventhdlr, cons, b) );
1062 }
1063
1064 for( b = consdata->firstnonfixed - 1; b >= 0; --b )
1065 {
1066 SCIP_CALL( delCoefPos(scip, eventhdlr, cons, b) );
1067 }
1068
1069 for( b = consdata->nbinvars - 1; b >= 0; --b )
1070 {
1071 if( SCIPvarGetUbLocal(consdata->binvars[b]) < 0.5 )
1072 {
1073 SCIP_CALL( delCoefPos(scip, eventhdlr, cons, b) );
1074 }
1075 }
1076
1077 /* set the constraint state */
1078 consdata->firstnonfixed = 0;
1079 consdata->lastnonfixed = consdata->nbinvars - 1;
1080
1081 return SCIP_OKAY;
1082}
1083
1084/** tightened the linking variable due to binary variables which are fixed to zero */
1085static
1087 SCIP* scip, /**< SCIP data structure */
1088 SCIP_CONS* cons, /**< linking constraint to be processed */
1089 SCIP_CONSDATA* consdata, /**< linking constraint to be processed */
1090 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
1091 int* nchgbds /**< pointer to store the number of changed variable bounds */
1092 )
1093{
1094 SCIP_VAR** binvars;
1095 SCIP_VAR* linkvar;
1096 SCIP_Real* vals;
1097
1098 SCIP_Bool infeasible;
1099 SCIP_Bool tightened;
1100 int nbinvars;
1101 int b;
1102
1103 /* if more than one binary variable is fixed to one or at least nbinvars minus one variable are fixed to zero return */
1104 if( consdata->nfixedones > 1 || consdata->nfixedzeros >= consdata->nbinvars-1 )
1105 return SCIP_OKAY;
1106
1107 if( *cutoff )
1108 return SCIP_OKAY;
1109
1110 assert(consdata->sorted);
1111
1112 linkvar = consdata->linkvar;
1113 binvars = consdata->binvars;
1114 vals = consdata->vals;
1115 nbinvars = consdata->nbinvars;
1116
1117#ifndef NDEBUG
1118 /* check that the first variable are locally fixed to zero */
1119 for( b = 0; b < consdata->firstnonfixed; ++b )
1120 assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
1121#endif
1122
1123 assert(consdata->firstnonfixed < nbinvars);
1124 assert(consdata->lastnonfixed < nbinvars);
1125
1126 /* find first non fixed binary variable */
1127 for( b = consdata->firstnonfixed; b < nbinvars; ++b )
1128 {
1129 if( SCIPvarGetUbLocal(binvars[b]) > 0.5 )
1130 break;
1131
1132 consdata->firstnonfixed++;
1133 }
1134
1135 SCIP_CALL( SCIPinferVarLbCons(scip, linkvar, vals[b], cons, -4, TRUE, &infeasible, &tightened) );
1136
1137 /* start conflict analysis if infeasible */
1138 if( infeasible )
1139 {
1140 /* analyze the cutoff if if SOLVING stage and conflict analysis is turned on */
1142 {
1143 SCIPdebugMsg(scip, "conflict at <%s> due to bounds and fixed binvars: [lb,ub] = [%g,%g]; b= %d; coef = %g \n",
1144 SCIPvarGetName(linkvar), SCIPvarGetLbLocal(linkvar), SCIPvarGetUbLocal(linkvar), b, vals[b]);
1145
1147
1148 /* ??????????? use resolve method and only add binvars which are needed to exceed the upper bound */
1149
1150 /* add conflicting variables */
1151 SCIP_CALL( SCIPaddConflictUb(scip, linkvar, NULL) );
1152
1153 for( b = 0; b < consdata->firstnonfixed; ++b )
1154 {
1155 SCIP_CALL( SCIPaddConflictBinvar(scip, binvars[b]) );
1156 }
1157
1158 /* analyze the conflict */
1160 }
1161
1162 *cutoff = TRUE;
1163 return SCIP_OKAY;
1164 }
1165
1166 if( tightened )
1167 (*nchgbds)++;
1168
1169#ifndef NDEBUG
1170 /* check that the last variable are locally fixed to zero */
1171 for( b = consdata->lastnonfixed + 1; b < nbinvars; ++b )
1172 assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
1173#endif
1174
1175 /* find last non fixed variable */
1176 for( b = consdata->lastnonfixed; b >= 0; --b )
1177 {
1178 if( SCIPvarGetUbLocal(binvars[b]) > 0.5 )
1179 break;
1180
1181 consdata->lastnonfixed--;
1182 }
1183
1185 SCIP_CALL( SCIPinferVarUbCons(scip, linkvar, (SCIP_Real)vals[b], cons, -5, TRUE, &infeasible, &tightened) );
1186
1187 if( infeasible )
1188 {
1189 /* conflict analysis can only be applied in solving stage and if conflict analysis is turned on */
1191 {
1192 SCIPdebugMsg(scip, "conflict at <%s> due to bounds and fixed binvars: [lb,ub] = [%g,%g]; b = %d; coef = %g,\n",
1193 SCIPvarGetName(linkvar), SCIPvarGetLbLocal(linkvar), SCIPvarGetUbLocal(linkvar), b, vals[b]);
1194
1196
1197 /* ??????????? use resolve method and only add binvars which are needed to fall below the lower bound */
1198
1199 /* add conflicting variables */
1200 SCIP_CALL( SCIPaddConflictLb(scip, linkvar, NULL) );
1201
1202 for( b = consdata->lastnonfixed + 1; b < nbinvars; ++b )
1203 {
1204 SCIP_CALL( SCIPaddConflictBinvar(scip, binvars[b]) );
1205 }
1206
1207 /* analyze the conflict */
1209 }
1210
1211 *cutoff = TRUE;
1212 return SCIP_OKAY;
1213 }
1214
1215 if( tightened )
1216 (*nchgbds)++;
1217
1218 return SCIP_OKAY;
1219}
1220
1221/** checks constraint for violation only looking at the fixed binary variables, applies further fixings if possible */
1222static
1224 SCIP* scip, /**< SCIP data structure */
1225 SCIP_CONS* cons, /**< linking constraint to be processed */
1226 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
1227 int* nchgbds, /**< pointer to store the number of changed variable bounds */
1228 SCIP_Bool* addcut, /**< pointer to store whether this constraint must be added as a cut */
1229 SCIP_Bool* mustcheck /**< pointer to store whether this constraint must be checked for feasibility */
1230 )
1231{
1232 SCIP_CONSDATA* consdata;
1233 SCIP_Bool infeasible;
1234 SCIP_Bool tightened;
1235
1236 assert(cons != NULL);
1237 assert(SCIPconsGetHdlr(cons) != NULL);
1238 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
1239 assert(cutoff != NULL);
1240 assert(nchgbds != NULL);
1241 assert(addcut != NULL);
1242 assert(mustcheck != NULL);
1243
1244 consdata = SCIPconsGetData(cons);
1245 assert(consdata != NULL);
1246 assert(consdata->nbinvars == 0 || consdata->binvars != NULL);
1247 assert(0 <= consdata->nfixedzeros && consdata->nfixedzeros <= consdata->nbinvars);
1248 assert(0 <= consdata->nfixedones && consdata->nfixedones <= consdata->nbinvars);
1249
1250 /* ensure that the binary variables are sorted in non-decreasing order w.r.t. their coefficients */
1251 consdataSort(consdata);
1252
1253 /* in case there is only at most one binary variables, the constraints should already be disabled */
1254 assert(consdata->nbinvars > 1);
1255
1256 if( *cutoff )
1257 return SCIP_OKAY;
1258
1259 if( consdata->nfixedones == 1 )
1260 {
1261 /* exactly one variable is fixed to 1:
1262 * - all other binary variables in a set partitioning must be zero
1263 * - linking variable is fixed to that binary variable
1264 */
1265 if( consdata->nfixedzeros < consdata->nbinvars - 1 ||
1266 SCIPisLT(scip, SCIPvarGetLbLocal(consdata->linkvar), SCIPvarGetUbLocal(consdata->linkvar)) )
1267 {
1268 SCIP_VAR** vars;
1269 SCIP_VAR* var;
1270#ifndef NDEBUG
1271 SCIP_Bool fixedonefound;
1272#endif
1273 int nvars;
1274 int v;
1275
1276 SCIPdebugMsg(scip, " -> fixing all other variables to zero due to the set partitioning condition <%s>\n",
1277 SCIPconsGetName(cons));
1278
1279 /* unfixed variables exist: fix them to zero;
1280 * this could result in additional variables fixed to one due to aggregations; in this case, the
1281 * constraint is infeasible in local bounds
1282 */
1283 vars = consdata->binvars;
1284 nvars = consdata->nbinvars;
1285#ifndef NDEBUG
1286 fixedonefound = FALSE;
1287#endif
1288
1289 for( v = 0; v < nvars && consdata->nfixedones == 1 && !(*cutoff); ++v )
1290 {
1291 var = vars[v];
1292 assert(SCIPvarIsBinary(var));
1293 /* TODO can this be handled more elegantly? */
1295 continue;
1296
1300 continue;
1301
1302 if( SCIPvarGetLbLocal(var) < 0.5 )
1303 {
1304 SCIP_CALL( SCIPinferBinvarCons(scip, var, FALSE, cons, -1, &infeasible, &tightened) );
1305 assert(!infeasible);
1306 SCIPdebugMsg(scip, " -> fixed <%s> to zero (tightened=%u)\n", SCIPvarGetName(var), tightened);
1307 }
1308 else
1309 {
1310#ifndef NDEBUG
1311 fixedonefound = TRUE;
1312#endif
1313 /* fix linking variable */
1314 /* TODO check if variable status allows fixing (probably in consFixLinkvar) */
1315 SCIP_CALL( consFixLinkvar(scip, cons, v, cutoff) );
1316 }
1317 }
1318 if( !(*cutoff) )
1319 {
1320 /* the fixed to one variable must have been found, and at least one variable must have been fixed */
1321 assert(consdata->nfixedones >= 1 || fixedonefound);
1322
1324 (*nchgbds)++;
1325 }
1326 }
1327
1328 /* now all other variables are fixed to zero:
1329 * the constraint is feasible, and if it's not modifiable, it is redundant
1330 */
1331 if( !SCIPconsIsModifiable(cons) && consdata->nfixedones == 1 )
1332 {
1333 SCIPdebugMsg(scip, " -> disabling set linking constraint <%s>\n", SCIPconsGetName(cons));
1335 }
1336 }
1337 else if( consdata->nfixedones >= 2 )
1338 {
1339 /* at least two variables are fixed to 1:
1340 * - the set partitioning condition is violated
1341 */
1342 SCIPdebugMsg(scip, " -> conflict on " CONSHDLR_NAME " constraint <%s> due to the set partitioning condition\n", SCIPconsGetName(cons));
1343
1345
1346 /* conflict analysis can only be applied in solving stage and if it is applicable */
1348 {
1349 SCIP_VAR** vars;
1350 int nvars;
1351 int n;
1352 int v;
1353
1354 vars = consdata->binvars;
1355 nvars = consdata->nbinvars;
1356
1357 /* initialize conflict analysis, and add the two variables assigned to one to conflict candidate queue */
1359
1360 n = 0;
1361
1362 for( v = 0; v < nvars && n < 2; ++v )
1363 {
1364 if( SCIPvarGetLbLocal(vars[v]) > 0.5 )
1365 {
1367 n++;
1368 }
1369 }
1370 assert(n == 2);
1371
1372 /* analyze the conflict */
1374 }
1375
1376 *cutoff = TRUE;
1377 }
1378 else if( consdata->nfixedzeros == consdata->nbinvars )
1379 {
1380 /* all variables are fixed to zero:
1381 * - the set partitioning condition is violated, and if it's unmodifiable, the node
1382 * can be cut off -- otherwise, the constraint must be added as a cut and further pricing must
1383 * be performed
1384 */
1385 assert(consdata->nfixedones == 0);
1386
1387 SCIPdebugMsg(scip, " -> " CONSHDLR_NAME " constraint <%s> is infeasible due to the set partitioning condition\n",
1388 SCIPconsGetName(cons));
1389
1391 if( SCIPconsIsModifiable(cons) )
1392 *addcut = TRUE;
1393 else
1394 {
1395 /* conflict analysis can only be applied in solving stage and if it is applicable */
1397 {
1398 SCIP_VAR** vars;
1399 int nvars;
1400 int v;
1401
1402 vars = consdata->binvars;
1403 nvars = consdata->nbinvars;
1404
1405 /* initialize conflict analysis, add all variables of infeasible constraint to conflict candidate queue */
1407
1408 for( v = 0; v < nvars; ++v )
1409 {
1410 assert(SCIPvarGetUbLocal(vars[v]) < 0.5);
1412 }
1413
1414 /* analyze the conflict */
1416 }
1417 *cutoff = TRUE;
1418 }
1419 }
1420 else if( consdata->nfixedzeros == consdata->nbinvars - 1 )
1421 {
1422 /* all variables except one are fixed to zero:
1423 * - an unmodifiable set partitioning constraint is feasible and can be disabled after the
1424 * remaining variable is fixed to one
1425 * - a modifiable set partitioning constraint must be checked manually
1426 */
1427 assert(consdata->nfixedones == 0);
1428
1429 if( !SCIPconsIsModifiable(cons) )
1430 {
1431 SCIP_VAR** vars;
1432 SCIP_VAR* var;
1433 int nvars;
1434 int v;
1435
1436 /* search the single variable that can be fixed */
1437 vars = consdata->binvars;
1438 nvars = consdata->nbinvars;
1439 for( v = 0; v < nvars && !(*cutoff); ++v )
1440 {
1441 var = vars[v];
1442 assert(SCIPisFeasZero(scip, SCIPvarGetLbLocal(var)));
1444
1445 if( SCIPvarGetUbLocal(var) > 0.5 )
1446 {
1447 assert(SCIPvarGetLbLocal(var) < 0.5);
1448 SCIPdebugMsg(scip, " -> fixing remaining binary variable <%s> to one in " CONSHDLR_NAME " constraint <%s>\n",
1449 SCIPvarGetName(var), SCIPconsGetName(cons));
1450
1452 {
1453 SCIP_CALL( SCIPinferBinvarCons(scip, var, TRUE, cons, -1, &infeasible, &tightened) );
1454 assert(!infeasible);
1455 assert(tightened);
1456 }
1457
1458 /* fix linking variable */
1459 /* TODO check if variable status allows fixing (probably in consFixLinkvar)*/
1460 SCIP_CALL( consFixLinkvar(scip, cons, v, cutoff) );
1461 break;
1462 }
1463 }
1464 assert(v < nvars);
1465 assert(consdata->nfixedzeros == consdata->nbinvars - 1);
1466 assert(consdata->nfixedones == 1);
1467
1469 (*nchgbds)++;
1470 }
1471 }
1472 else
1473 {
1474 SCIP_CALL( tightenedLinkvar(scip, cons, consdata, cutoff, nchgbds) );
1475 }
1476
1477 *mustcheck = (*nchgbds) == 0;
1478
1479 assert(consdata->nfixedzeros + consdata->nfixedones <= consdata->nbinvars);
1480
1481 return SCIP_OKAY;
1482}
1483
1484/** returns whether the given solution is feasible for the given linking constraint */
1485static
1487 SCIP* scip, /**< SCIP data structure */
1488 SCIP_CONS* cons, /**< linking constraint to be checked */
1489 SCIP_SOL* sol /**< primal solution, or NULL for current LP/pseudo solution */
1490 )
1491{
1492 SCIP_CONSDATA* consdata;
1493 SCIP_VAR** binvars;
1494 SCIP_Real* vals;
1495 SCIP_Real solval;
1496 SCIP_Real linksum;
1497 SCIP_Real linkvarval;
1498 SCIP_Real setpartsum;
1499 SCIP_Real setpartsumbound;
1500 SCIP_Real absviol;
1501 SCIP_Real relviol;
1502 int nbinvars;
1503 int b;
1504
1505 assert(scip != NULL);
1506 assert(cons != NULL);
1507
1508 SCIPdebugMsg(scip, "checking linking constraint <%s> for feasibility of solution %p\n", SCIPconsGetName(cons), (void*)sol);
1509
1510 consdata = SCIPconsGetData(cons);
1511 assert(consdata != NULL);
1512 assert(consdata->binvars != NULL || consdata->nbinvars == 0);
1513
1514 /* in case there is only at most one binary variables, the constraints should already be disabled */
1515 assert(consdata->nbinvars > 1);
1516
1517 /* calculate the constraint's activity for the linking part and the set partitioning part */
1518 binvars = consdata->binvars;
1519 vals = consdata->vals;
1520 nbinvars = consdata->nbinvars;
1521
1522 linksum = 0.0;
1523 setpartsum = 0.0;
1524 setpartsumbound = 1.0 + 2*SCIPfeastol(scip);
1525
1526 for( b = 0; b < nbinvars && setpartsum < setpartsumbound; ++b ) /* if sum >= sumbound, the feasibility is clearly decided */
1527 {
1528 assert(SCIPvarIsBinary(binvars[b]));
1529
1530 solval = SCIPgetSolVal(scip, sol, binvars[b]);
1531 assert(SCIPisFeasGE(scip, solval, 0.0) && SCIPisFeasLE(scip, solval, 1.0));
1532
1533 linksum += vals[b] * solval;
1534 setpartsum += solval;
1535 }
1536
1537 /* calculate and update absolute and relative violation of the equality constraint */
1538 linkvarval = SCIPgetSolVal(scip, sol, consdata->linkvar);
1539 absviol = REALABS(linksum - linkvarval);
1540 relviol = REALABS(SCIPrelDiff(linksum, linkvarval));
1541 if( sol != NULL )
1542 SCIPupdateSolLPConsViolation(scip, sol, absviol, relviol);
1543
1544 /* calculate and update absolute and relative violation of the set partitioning constraint */
1545 absviol = REALABS(setpartsum - 1.0);
1546 relviol = REALABS(SCIPrelDiff(setpartsum, 1.0));
1547 if( sol != NULL )
1548 SCIPupdateSolLPConsViolation(scip, sol, absviol, relviol);
1549
1550 /* check if the fixed binary variable match with the linking variable */
1551 return SCIPisFeasEQ(scip, linksum, linkvarval) && SCIPisFeasEQ(scip, setpartsum, 1.0);
1552}
1553
1554#ifdef SCIP_DISABLED_CODE
1555/* The following should work, but does not seem to be tested well. */
1556
1557/** transfer aggregated integer variables to the corresponding binary variables */
1558static
1560 SCIP* scip, /**< SCIP data structure */
1561 SCIP_HASHMAP* varmap, /**< hash map mapping a integer variables to its linking constraint */
1562 SCIP_CONS** conss, /**< array of linking constraint */
1563 int nconss, /**< number of linking constraints */
1564 int* naggrvars, /**< pointer to store the number of aggregate variables */
1565 SCIP_Bool* cutoff /**< pointer to store if a cutoff was detected */
1566 )
1567{
1568 SCIP_CONS* aggrcons;
1569 SCIP_CONSDATA* aggrconsdata;
1570 SCIP_CONSDATA* consdata;
1571 SCIP_VAR** binvars;
1572 SCIP_VAR** aggrbinvars;
1573 SCIP_VAR* linkvar;
1574 SCIP_VAR* aggrvar;
1575 SCIP_Real aggrconst;
1576 SCIP_Real aggrscalar;
1577 SCIP_Bool infeasible;
1578 SCIP_Bool redundant;
1579 SCIP_Bool aggregated;
1580 int offset;
1581 int aggroffset;
1582 int nbinvars;
1583 int shift;
1584 int b;
1585 int c;
1586
1587 assert(varmap != NULL);
1588
1589 for( c = 0; c < nconss; ++c )
1590 {
1591 consdata = SCIPconsGetData(conss[c]);
1592 assert(consdata != NULL);
1593
1594 linkvar = consdata->linkvar;
1595 assert(linkvar != NULL);
1596
1598 {
1599 aggrvar = SCIPvarGetAggrVar(linkvar);
1600 aggrcons = (SCIP_CONS*) SCIPhashmapGetImage(varmap, getHashmapKey(aggrvar));
1601
1602 /* check if the aggregate variable belongs to a linking constraint */
1603 if( aggrcons != NULL )
1604 {
1605 aggrconsdata = SCIPconsGetData(aggrcons);
1606 assert(aggrconsdata != NULL);
1607
1608 aggrconst = SCIPvarGetAggrConstant(linkvar);
1609 aggrscalar = SCIPvarGetAggrScalar(linkvar);
1610
1611 /**@todo extend the aggregation for those cases were the aggrscalar is not equal to 1.0 */
1612 if( SCIPisEQ(scip, aggrscalar, 1.0 ) )
1613 {
1614 /* since both variables are integer variable and the aggrscalar is 1.0 the aggrconst should
1615 * integral
1616 */
1617 assert(SCIPisIntegral(scip, aggrconst));
1618 shift = SCIPconvertRealToInt(scip, aggrconst);
1619
1620 offset = consdata->offset;
1621 binvars = consdata->binvars;
1622 aggroffset = aggrconsdata->offset;
1623 aggrbinvars = aggrconsdata->binvars;
1624
1625 nbinvars = MIN(consdata->nbinvars + offset, aggrconsdata->nbinvars + shift + aggroffset);
1626
1627 for( b = MAX(offset, aggroffset-shift); b < nbinvars; ++b )
1628 {
1629 assert(b - offset >= 0);
1630 assert(b + shift - aggroffset >= 0);
1631 assert(b < consdata->nbinvars);
1632 assert(b < aggrconsdata->nbinvars - shift);
1633
1634 /* add aggregation x - y = 0.0 */
1635 SCIP_CALL( SCIPaggregateVars(scip, binvars[b-offset], aggrbinvars[b+shift-aggroffset], 1.0, -1.0, 0.0,
1636 &infeasible, &redundant, &aggregated) );
1637
1638 if( infeasible )
1639 {
1640 (*cutoff) = TRUE;
1641 return SCIP_OKAY;
1642 }
1643
1644 if( aggregated )
1645 (*naggrvars)++;
1646 }
1647 }
1648 }
1649 }
1650 }
1651 return SCIP_OKAY;
1652}
1653#endif
1654
1655/** create two rows for the linking constraint
1656 *
1657 * - row1: {sum_{b=1}^n-1 vals[b] * binvars[b]} - linkvar = 0
1658 * - row2: {sum_{b=0}^n-1 binvars[b]} = 1.0
1659 */
1660static
1662 SCIP* scip, /**< SCIP data structure */
1663 SCIP_CONS* cons /**< linking constraint */
1664 )
1665{
1666 SCIP_CONSDATA* consdata;
1667 char rowname[SCIP_MAXSTRLEN];
1668 int b;
1669
1670 assert( cons != NULL);
1671
1672 /* get constraint data */
1673 consdata = SCIPconsGetData(cons);
1674 assert(consdata != NULL);
1675 assert(consdata->row1 == NULL);
1676 assert(consdata->row2 == NULL);
1677 assert(consdata->nbinvars > 1);
1678
1679 /* create the LP row which captures the linking between the real and binary variables */
1680 (void)SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s[link]", SCIPconsGetName(cons));
1681
1682 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row1, cons, rowname, 0.0, 0.0,
1684
1685 /* add linking variable to the row */
1686 assert(consdata->linkvar != NULL);
1687 SCIP_CALL( SCIPaddVarToRow(scip, consdata->row1, consdata->linkvar, -1.0) );
1688
1689 /* adding binary variables to the row */
1690 assert(consdata->binvars != NULL);
1691 for( b = 0; b < consdata->nbinvars; ++b )
1692 {
1693 SCIP_CALL( SCIPaddVarToRow(scip, consdata->row1, consdata->binvars[b], consdata->vals[b]) );
1694 }
1695
1696 /* create the LP row which captures the set partitioning condition of the binary variables */
1697 (void)SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s[setppc]", SCIPconsGetName(cons));
1698 assert( consdata->nbinvars > 0 );
1699
1700 SCIP_CALL( SCIPcreateEmptyRowCons(scip, &consdata->row2, cons, rowname, 1.0, 1.0,
1702
1703 SCIP_CALL( SCIPaddVarsToRowSameCoef(scip, consdata->row2, consdata->nbinvars, consdata->binvars, 1.0) );
1704
1705 return SCIP_OKAY;
1706}
1707
1708
1709/** adds linking constraint as cut to the LP */
1710static
1712 SCIP* scip, /**< SCIP data structure */
1713 SCIP_CONS* cons, /**< linking constraint */
1714 SCIP_Bool* cutoff /**< whether a cutoff has been detected */
1715 )
1716{
1717 SCIP_CONSDATA* consdata;
1718
1719 assert( cutoff != NULL );
1720 *cutoff = FALSE;
1721
1722 consdata = SCIPconsGetData(cons);
1723 assert(consdata != NULL);
1724
1725 /* in case there is only at most one binary variables, the constraints should already be disabled */
1726 assert(consdata->nbinvars > 1);
1727
1728 if( consdata->row1 == NULL )
1729 {
1730 assert(consdata->row2 == NULL);
1731
1732 /* convert linking data into LP rows */
1733 SCIP_CALL( createRows(scip, cons) );
1734 }
1735 assert(consdata->row1 != NULL);
1736 assert(consdata->row2 != NULL);
1737
1738 /* insert LP linking row as cut */
1739 if( !SCIProwIsInLP(consdata->row1) )
1740 {
1741 SCIPdebugMsg(scip, "adding linking row of constraint <%s> as cut to the LP\n", SCIPconsGetName(cons));
1742 SCIP_CALL( SCIPaddRow(scip, consdata->row1, TRUE/*FALSE*/, cutoff) );
1743 }
1744
1745 /* insert LP set partitioning row as cut */
1746 if( !SCIProwIsInLP(consdata->row2) )
1747 {
1748 SCIPdebugMsg(scip, "adding set partitioning row of constraint <%s> as cut to the LP\n", SCIPconsGetName(cons));
1749 SCIP_CALL( SCIPaddRow(scip, consdata->row2, TRUE/*FALSE*/, cutoff) );
1750 }
1751
1752 return SCIP_OKAY;
1753}
1754
1755/** adds linking constraint as rows to the NLP, if not added yet */
1756static
1758 SCIP* scip, /**< SCIP data structure */
1759 SCIP_CONS* cons /**< linking constraint */
1760 )
1761{
1762 SCIP_CONSDATA* consdata;
1763
1764 assert(SCIPisNLPConstructed(scip));
1765
1766 /* skip deactivated, redundant, or local constraints (the NLP does not allow for local rows at the moment) */
1767 if( !SCIPconsIsActive(cons) || !SCIPconsIsChecked(cons) || SCIPconsIsLocal(cons) )
1768 return SCIP_OKAY;
1769
1770 consdata = SCIPconsGetData(cons);
1771 assert(consdata != NULL);
1772
1773 if( consdata->nlrow1 == NULL )
1774 {
1775 char rowname[SCIP_MAXSTRLEN];
1776 SCIP_Real* coefs;
1777 int i;
1778
1779 assert(consdata->nlrow2 == NULL);
1780
1781 /* create the NLP row which captures the linking between the real and binary variables */
1782 (void)SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s[link]", SCIPconsGetName(cons));
1783
1784 /* create nlrow1 with binary variables */
1785 SCIP_CALL( SCIPcreateNlRow(scip, &consdata->nlrow1, rowname,
1786 0.0, consdata->nbinvars, consdata->binvars, consdata->vals, NULL, 0.0, 0.0, SCIP_EXPRCURV_LINEAR) );
1787 /* add linking variable to the row */
1788 SCIP_CALL( SCIPaddLinearCoefToNlRow(scip, consdata->nlrow1, consdata->linkvar, -1.0) );
1789
1790 /* create the NLP row which captures the set partitioning condition of the binary variables */
1791 (void)SCIPsnprintf(rowname, SCIP_MAXSTRLEN, "%s[setppc]", SCIPconsGetName(cons));
1792
1793 SCIP_CALL( SCIPallocBufferArray(scip, &coefs, consdata->nbinvars) );
1794 for( i = 0; i < consdata->nbinvars; ++i )
1795 coefs[i] = 1.0;
1796
1797 SCIP_CALL( SCIPcreateNlRow(scip, &consdata->nlrow2, rowname,
1798 0.0, consdata->nbinvars, consdata->binvars, coefs, NULL, 1.0, 1.0, SCIP_EXPRCURV_LINEAR) );
1799
1800 SCIPfreeBufferArray(scip, &coefs);
1801 }
1802
1803 assert(SCIPnlrowIsInNLP(consdata->nlrow1) == SCIPnlrowIsInNLP(consdata->nlrow2));
1804 if( !SCIPnlrowIsInNLP(consdata->nlrow1) )
1805 {
1806 SCIP_CALL( SCIPaddNlRow(scip, consdata->nlrow1) );
1807 SCIP_CALL( SCIPaddNlRow(scip, consdata->nlrow2) );
1808 }
1809
1810 return SCIP_OKAY;
1811}
1812
1813/** checks constraint for violation, and adds it as a cuts if possible */
1814static
1816 SCIP* scip, /**< SCIP data structure */
1817 SCIP_CONS* cons, /**< linking constraint to be separated */
1818 SCIP_SOL* sol, /**< primal CIP solution, NULL for current LP solution */
1819 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
1820 SCIP_Bool* separated, /**< pointer to store TRUE, if a cut was found */
1821 int* nchgbds /**< pointer to store the number of changed variables bounds */
1822 )
1823{
1824 SCIP_CONSDATA* consdata;
1825 SCIP_Bool addcut;
1826 SCIP_Bool mustcheck;
1827
1828 assert(cons != NULL);
1829 assert(SCIPconsGetHdlr(cons) != NULL);
1830 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
1831 assert(cutoff != NULL);
1832 assert(separated != NULL);
1833 assert(nchgbds != NULL);
1834
1835 consdata = SCIPconsGetData(cons);
1836 assert(consdata != NULL);
1837
1838 /* in case there is only at most one binary variables, the constraints should already be disabled */
1839 assert(consdata->nbinvars > 1);
1840
1841 SCIPdebugMsg(scip, "separating constraint <%s>\n", SCIPconsGetName(cons));
1842
1843 *cutoff = FALSE;
1844 addcut = FALSE;
1845 mustcheck = TRUE;
1846
1847 /* check constraint for violation only looking at the fixed variables, apply further fixings if possible */
1848 if( sol == NULL )
1849 {
1850 SCIP_CALL( processRealBoundChg(scip, cons, cutoff, nchgbds, &mustcheck) );
1851 }
1852
1853 if( mustcheck && !(*cutoff) )
1854 {
1855 /* variable's fixings didn't give us any information -> we have to check the constraint */
1856 if( sol == NULL && consdata->row1 != NULL )
1857 {
1858 SCIP_Real feasibility;
1859 SCIP_Real tmp;
1860
1861 assert(consdata->row2 != NULL);
1862
1863 /* skip constraints already in the LP */
1864 if( SCIProwIsInLP(consdata->row1) && SCIProwIsInLP(consdata->row2))
1865 return SCIP_OKAY;
1866
1867 feasibility = 1.0;
1868
1869 /* check first row (linking) for feasibility */
1870 if( !SCIProwIsInLP(consdata->row1) )
1871 {
1872 tmp = SCIPgetRowLPFeasibility(scip, consdata->row1);
1873 feasibility = MIN(feasibility, tmp);
1874 }
1875
1876 /* check second row (setppc) for feasibility */
1877 if( !SCIProwIsInLP(consdata->row2) )
1878 {
1879 tmp = SCIPgetRowLPFeasibility(scip, consdata->row2);
1880 feasibility = MIN(feasibility, tmp);
1881 }
1882 addcut = SCIPisFeasNegative(scip, feasibility);
1883 }
1884 else
1885 addcut = !checkCons(scip, cons, sol);
1886
1887 if( !addcut )
1888 {
1889 /* constraint was feasible -> increase age */
1890 SCIP_CALL( SCIPincConsAge(scip, cons) );
1891 }
1892 }
1893
1894 if( addcut )
1895 {
1896 /* insert LP row as cut */
1897 assert(!(*cutoff));
1898 SCIP_CALL( addCuts(scip, cons, cutoff) );
1900 *separated = TRUE;
1901 }
1902
1903 return SCIP_OKAY;
1904}
1905
1906/** enforces the pseudo solution on the given constraint */
1907static
1909 SCIP* scip, /**< SCIP data structure */
1910 SCIP_CONS* cons, /**< linking constraint to be separated */
1911 SCIP_Bool* cutoff, /**< pointer to store TRUE, if the node can be cut off */
1912 SCIP_Bool* infeasible, /**< pointer to store TRUE, if the constraint was infeasible */
1913 int* nchgbds, /**< pointer to store the number of changed variable bounds */
1914 SCIP_Bool* solvelp /**< pointer to store TRUE, if the LP has to be solved */
1915 )
1916{
1917 SCIP_Bool addcut;
1918 SCIP_Bool mustcheck;
1919
1920 assert(!SCIPhasCurrentNodeLP(scip));
1921 assert(cons != NULL);
1922 assert(SCIPconsGetHdlr(cons) != NULL);
1923 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
1924 assert(cutoff != NULL);
1925 assert(infeasible != NULL);
1926 assert(nchgbds != NULL);
1927 assert(solvelp != NULL);
1928
1929 addcut = FALSE;
1930 mustcheck = TRUE;
1931
1932 /* check constraint for violation only looking at the fixed variables, apply further fixings if possible */
1933 SCIP_CALL( processRealBoundChg(scip, cons, cutoff, nchgbds, &mustcheck) );
1934 SCIP_CALL( processBinvarFixings(scip, cons, cutoff, nchgbds, &addcut, &mustcheck) );
1935
1936 if( mustcheck )
1937 {
1938 assert(!addcut);
1939
1940 if( checkCons(scip, cons, NULL) )
1941 {
1942 /* constraint was feasible -> increase age */
1943 SCIP_CALL( SCIPincConsAge(scip, cons) );
1944 }
1945 else
1946 {
1947 /* constraint was infeasible -> reset age */
1949 *infeasible = TRUE;
1950 }
1951 }
1952
1953 if( addcut )
1954 {
1955 assert(!(*cutoff));
1956 /* a cut must be added to the LP -> we have to solve the LP immediately */
1958 *solvelp = TRUE;
1959 }
1960
1961 return SCIP_OKAY;
1962}
1963
1964/** helper function to enforce constraints */
1965static
1967 SCIP* scip, /**< SCIP data structure */
1968 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
1969 SCIP_CONS** conss, /**< constraints to process */
1970 int nconss, /**< number of constraints */
1971 int nusefulconss, /**< number of useful (non-obsolete) constraints to process */
1972 SCIP_SOL* sol, /**< solution to enforce (NULL for the LP solution) */
1973 SCIP_RESULT* result /**< pointer to store the result of the enforcing call */
1974 )
1975{
1976 SCIP_Bool cutoff;
1977 SCIP_Bool separated;
1978 int nchgbds;
1979 int c;
1980
1981 assert(conshdlr != NULL);
1982 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
1983 assert(nconss == 0 || conss != NULL);
1984 assert(result != NULL);
1985
1986 SCIPdebugMsg(scip, "Enforcing %d linking constraints for %s solution\n", nconss, sol == NULL ? "LP" : "relaxation");
1987
1988 cutoff = FALSE;
1989 separated = FALSE;
1990 nchgbds = 0;
1991
1992 /* check all useful linking constraints for feasibility */
1993 for( c = 0; c < nusefulconss && !cutoff && nchgbds == 0; ++c )
1994 {
1995 SCIP_CALL( separateCons(scip, conss[c], sol, &cutoff, &separated, &nchgbds) );
1996 }
1997
1998 /* check all obsolete linking constraints for feasibility */
1999 for( c = nusefulconss; c < nconss && !cutoff && !separated && nchgbds == 0; ++c )
2000 {
2001 SCIP_CALL( separateCons(scip, conss[c], sol, &cutoff, &separated, &nchgbds) );
2002 }
2003
2004 /* return the correct result */
2005 if( cutoff )
2006 *result = SCIP_CUTOFF;
2007 else if( nchgbds > 0 )
2008 *result = SCIP_REDUCEDDOM;
2009 else if( separated )
2010 *result = SCIP_SEPARATED;
2011 else
2012 *result = SCIP_FEASIBLE;
2013
2014 return SCIP_OKAY;
2015}
2016
2017/** adds symmetry information of constraint to a symmetry detection graph */
2018static
2020 SCIP* scip, /**< SCIP pointer */
2021 SYM_SYMTYPE symtype, /**< type of symmetries that need to be added */
2022 SCIP_CONS* cons, /**< constraint */
2023 SYM_GRAPH* graph, /**< symmetry detection graph */
2024 SCIP_Bool* success /**< pointer to store whether symmetry information could be added */
2025 )
2026{
2027 SCIP_CONSDATA* consdata;
2028 SCIP_VAR** vars;
2029 SCIP_Real* vals;
2030 SCIP_Real constant = 0.0;
2031 int nlocvars;
2032 int nvars;
2033 int i;
2034
2035 assert(scip != NULL);
2036 assert(cons != NULL);
2037 assert(graph != NULL);
2038 assert(success != NULL);
2039
2040 consdata = SCIPconsGetData(cons);
2041 assert(consdata != NULL);
2042
2043 /* get active variables of the constraint */
2044 nvars = SCIPgetNVars(scip);
2045 nlocvars = consdata->nbinvars + 1;
2046
2047 SCIP_CALL( SCIPallocBufferArray(scip, &vars, nvars) );
2048 SCIP_CALL( SCIPallocBufferArray(scip, &vals, nvars) );
2049
2050 /* get binary variables */
2051 for( i = 0; i < consdata->nbinvars; ++i )
2052 {
2053 vars[i] = consdata->binvars[i];
2054 vals[i] = consdata->vals[i];
2055 }
2056
2057 /* get linking variable */
2058 vars[consdata->nbinvars] = consdata->linkvar;
2059 vals[consdata->nbinvars] = -1.0;
2060
2061 SCIP_CALL( SCIPgetSymActiveVariables(scip, symtype, &vars, &vals, &nlocvars, &constant, SCIPisTransformed(scip)) );
2062
2063 SCIP_CALL( SCIPextendPermsymDetectionGraphLinear(scip, graph, vars, vals, nlocvars,
2064 cons, -constant, -constant, success) );
2065
2066 SCIPfreeBufferArray(scip, &vals);
2067 SCIPfreeBufferArray(scip, &vars);
2068
2069 return SCIP_OKAY;
2070}
2071
2072/*
2073 * Callback methods of constraint handler
2074 */
2075
2076/** copy method for constraint handler plugins (called when SCIP copies plugins) */
2077static
2078SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinking)
2079{ /*lint --e{715}*/
2080 assert(scip != NULL);
2081 assert(conshdlr != NULL);
2082 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2083
2084 /* call inclusion method of constraint handler */
2086
2087 *valid = TRUE;
2088
2089 return SCIP_OKAY;
2090}
2091
2092/** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
2093static
2094SCIP_DECL_CONSFREE(consFreeLinking)
2095{
2096 SCIP_CONSHDLRDATA* conshdlrdata;
2097
2098 assert(conshdlr != NULL);
2099 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2100 assert(scip != NULL);
2101
2102 /* free constraint handler data */
2103 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2104 assert(conshdlrdata != NULL);
2105
2106 conshdlrdataFree(scip, &conshdlrdata);
2107
2108 return SCIP_OKAY;
2109}
2110
2111
2112/** presolving initialization method of constraint handler (called when presolving is about to begin) */
2113static
2114SCIP_DECL_CONSINITPRE(consInitpreLinking)
2115{ /*lint --e{715}*/
2116 SCIP_CONSHDLRDATA* conshdlrdata;
2117 SCIP_CONSDATA* consdata;
2118 int c;
2119
2120 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2121 assert(conshdlrdata != NULL);
2122
2123 /* disable all linking constraints which contain at most one binary variable */
2124 for( c = 0; c < nconss; ++c )
2125 {
2126 consdata = SCIPconsGetData(conss[c]);
2127 assert(consdata != NULL);
2128
2129 /* skip constraints which are not added */
2130 if( !SCIPconsIsAdded(conss[c]) )
2131 continue;
2132
2133 if( consdata->nbinvars <= 1 )
2134 {
2135 SCIP_CALL( SCIPdisableCons(scip, conss[c]) );
2136 assert(consdata->nbinvars == 0 || SCIPvarGetLbGlobal(consdata->binvars[0]) > 0.5);
2137 }
2138 else if( conshdlrdata->linearize )
2139 {
2140 SCIP_CALL( consdataLinearize(scip, conss[c], consdata) );
2141 SCIP_CALL( SCIPdelCons(scip, conss[c]) );
2142 }
2143 }
2144
2145 return SCIP_OKAY;
2146}
2147
2148/** solving process initialization method of constraint handler */
2149static
2150SCIP_DECL_CONSINITSOL(consInitsolLinking)
2151{ /*lint --e{715}*/
2152 /* add nlrow representations to NLP, if NLP had been constructed */
2154 {
2155 int c;
2156 for( c = 0; c < nconss; ++c )
2157 {
2158 SCIP_CALL( addNlrow(scip, conss[c]) );
2159 }
2160 }
2161
2162 return SCIP_OKAY;
2163}
2164
2165/** solving process deinitialization method of constraint handler (called before branch and bound process data is freed) */
2166static
2167SCIP_DECL_CONSEXITSOL(consExitsolLinking)
2168{ /*lint --e{715}*/
2169 SCIP_CONSDATA* consdata;
2170 int c;
2171
2172 for( c = 0; c < nconss; ++c )
2173 {
2174 consdata = SCIPconsGetData(conss[c]);
2175 assert(consdata != NULL);
2176
2177 /* release the rows and nlrows of all constraints */
2178 if( consdata->row1 != NULL )
2179 {
2180 assert(consdata->row2 != NULL);
2181
2182 SCIP_CALL( SCIPreleaseRow(scip, &consdata->row1) );
2183 SCIP_CALL( SCIPreleaseRow(scip, &consdata->row2) );
2184 }
2185
2186 if( consdata->nlrow1 != NULL )
2187 {
2188 assert(consdata->nlrow2 != NULL);
2189
2190 SCIP_CALL( SCIPreleaseNlRow(scip, &consdata->nlrow1) );
2191 SCIP_CALL( SCIPreleaseNlRow(scip, &consdata->nlrow2) );
2192 }
2193 }
2194
2195 return SCIP_OKAY;
2196}
2197
2198
2199/** frees specific constraint data */
2200static
2201SCIP_DECL_CONSDELETE(consDeleteLinking)
2202{ /*lint --e{715}*/
2203 SCIP_CONSHDLRDATA* conshdlrdata;
2204
2205 assert(conshdlr != NULL);
2206 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2207 assert(consdata != NULL);
2208 assert(*consdata != NULL);
2209
2210 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2211 assert(conshdlrdata != NULL);
2212 assert(conshdlrdata->eventhdlr != NULL);
2213
2214 /* remove linking constraint form variable hash map */
2215 assert(conshdlrdata->varmap != NULL);
2216 assert(SCIPhashmapExists(conshdlrdata->varmap, getHashmapKey((*consdata)->linkvar)));
2217 SCIP_CALL( SCIPhashmapRemove(conshdlrdata->varmap, getHashmapKey((*consdata)->linkvar)) );
2218
2219 if( (*consdata)->nbinvars > 0 && SCIPisTransformed(scip) )
2220 {
2221 SCIP_CALL( dropAllEvents(scip, *consdata, conshdlrdata->eventhdlr) );
2222 }
2223
2224 /* free consdata */
2225 SCIP_CALL( consdataFree(scip, consdata) );
2226
2227 return SCIP_OKAY;
2228}
2229
2230
2231/** transforms constraint data into data belonging to the transformed problem */
2232static
2233SCIP_DECL_CONSTRANS(consTransLinking)
2234{ /*lint --e{715}*/
2235 SCIP_CONSDATA* sourcedata;
2236 SCIP_CONSDATA* targetdata;
2237 SCIP_CONSHDLRDATA* conshdlrdata;
2238
2239 assert(conshdlr != NULL);
2240 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2242 assert(sourcecons != NULL);
2243 assert(targetcons != NULL);
2244
2245 /* free constraint handler data */
2246 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2247 assert(conshdlrdata != NULL);
2248 assert(conshdlrdata->eventhdlr != NULL);
2249
2250 sourcedata = SCIPconsGetData(sourcecons);
2251 assert(sourcedata != NULL);
2252 assert(sourcedata->row1 == NULL); /* in original problem, there cannot be LP rows */
2253 assert(sourcedata->row2 == NULL); /* in original problem, there cannot be LP rows */
2254
2255 SCIPdebugMsg(scip, "transform linking constraint for variable <%s>\n", SCIPvarGetName(sourcedata->linkvar));
2256
2257 /* create constraint data for target constraint */
2258 SCIP_CALL( consdataCreate(scip, conshdlrdata->eventhdlr, &targetdata,
2259 sourcedata->linkvar, sourcedata->binvars, sourcedata->vals, sourcedata->nbinvars) );
2260
2261 /* create target constraint */
2262 SCIP_CALL( SCIPcreateCons(scip, targetcons, SCIPconsGetName(sourcecons), conshdlr, targetdata,
2263 SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
2264 SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons),
2265 SCIPconsIsLocal(sourcecons), SCIPconsIsModifiable(sourcecons),
2266 SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons), SCIPconsIsStickingAtNode(sourcecons)) );
2267
2268 /* insert (transformed) linking constraint into the hash map */
2269 assert(conshdlrdata->varmap != NULL);
2270 SCIP_CALL( SCIPhashmapInsert(conshdlrdata->varmap, getHashmapKey(targetdata->linkvar), *targetcons) );
2271
2272 return SCIP_OKAY;
2273}
2274
2275/** LP initialization method of constraint handler (called before the initial LP relaxation at a node is solved) */
2276static
2277SCIP_DECL_CONSINITLP(consInitlpLinking)
2278{ /*lint --e{715}*/
2279 SCIP_CONSDATA* consdata;
2280 int c;
2281
2282 *infeasible = FALSE;
2283
2284 for( c = 0; c < nconss && !(*infeasible); ++c )
2285 {
2286 assert(SCIPconsIsInitial(conss[c]));
2287
2288 consdata = SCIPconsGetData(conss[c]);
2289 assert(consdata != NULL);
2290
2291 if( consdata->nbinvars <= 1 )
2292 continue;
2293
2294 SCIP_CALL( addCuts(scip, conss[c], infeasible) );
2295 }
2296
2297 return SCIP_OKAY;
2298}
2299
2300
2301/** separation method of constraint handler for LP solutions */
2302static
2303SCIP_DECL_CONSSEPALP(consSepalpLinking)
2304{ /*lint --e{715}*/
2305 SCIP_Bool cutoff;
2306 SCIP_Bool separated;
2307 int nchgbds;
2308 int c;
2309
2310 assert(conshdlr != NULL);
2311 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2312 assert(nconss == 0 || conss != NULL);
2313 assert(result != NULL);
2314
2315 SCIPdebugMsg(scip, "separating %d/%d linking constraints\n", nusefulconss, nconss);
2316
2317 cutoff = FALSE;
2318 separated = FALSE;
2319 nchgbds = 0;
2320
2321 /* check all useful linking constraints for feasibility */
2322 for( c = 0; c < nusefulconss && !cutoff; ++c )
2323 {
2324 SCIP_CALL( separateCons(scip, conss[c], NULL, &cutoff, &separated, &nchgbds) );
2325 }
2326
2327 /* return the correct result */
2328 if( cutoff )
2329 *result = SCIP_CUTOFF;
2330 else if( nchgbds > 0 )
2331 *result = SCIP_REDUCEDDOM;
2332 else if( separated )
2333 *result = SCIP_SEPARATED;
2334 else
2335 *result = SCIP_DIDNOTFIND;
2336
2337 return SCIP_OKAY;
2338}
2339
2340
2341/** separation method of constraint handler for arbitrary primal solutions */
2342static
2343SCIP_DECL_CONSSEPASOL(consSepasolLinking)
2344{ /*lint --e{715}*/
2345 SCIP_Bool cutoff;
2346 SCIP_Bool separated;
2347 int nchgbds;
2348 int c;
2349
2350 assert(conshdlr != NULL);
2351 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2352 assert(nconss == 0 || conss != NULL);
2353 assert(result != NULL);
2354
2355 SCIPdebugMsg(scip, "separating %d/%d " CONSHDLR_NAME " constraints\n", nusefulconss, nconss);
2356
2357 cutoff = FALSE;
2358 separated = FALSE;
2359 nchgbds = 0;
2360
2361 /* check all useful set partitioning / packing / covering constraints for feasibility */
2362 for( c = 0; c < nusefulconss && !cutoff; ++c )
2363 {
2364 SCIP_CALL( separateCons(scip, conss[c], sol, &cutoff, &separated, &nchgbds) );
2365 }
2366
2367 /* return the correct result */
2368 if( cutoff )
2369 *result = SCIP_CUTOFF;
2370 else if( nchgbds > 0 )
2371 *result = SCIP_REDUCEDDOM;
2372 else if( separated )
2373 *result = SCIP_SEPARATED;
2374 else
2375 *result = SCIP_DIDNOTFIND;
2376
2377 return SCIP_OKAY;
2378}
2379
2380
2381/** constraint enforcing method of constraint handler for LP solutions */
2382static
2383SCIP_DECL_CONSENFOLP(consEnfolpLinking)
2384{ /*lint --e{715}*/
2385 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, NULL, result) );
2386
2387 return SCIP_OKAY;
2388}
2389
2390
2391/** constraint enforcing method of constraint handler for relaxation solutions */
2392static
2393SCIP_DECL_CONSENFORELAX(consEnforelaxLinking)
2394{ /*lint --e{715}*/
2395 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, sol, result) );
2396
2397 return SCIP_OKAY;
2398}
2399
2400
2401/** constraint enforcing method of constraint handler for pseudo solutions */
2402static
2403SCIP_DECL_CONSENFOPS(consEnfopsLinking)
2404{ /*lint --e{715}*/
2405 SCIP_Bool cutoff;
2406 SCIP_Bool infeasible;
2407 int nchgbds;
2408 SCIP_Bool solvelp;
2409 int c;
2410
2411 assert(conshdlr != NULL);
2412 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2413 assert(nconss == 0 || conss != NULL);
2414 assert(result != NULL);
2415
2416 SCIPdebugMsg(scip, "pseudo enforcing %d " CONSHDLR_NAME " constraints\n", nconss);
2417
2418 if( objinfeasible )
2419 {
2420 *result = SCIP_DIDNOTRUN;
2421 return SCIP_OKAY;
2422 }
2423
2424 cutoff = FALSE;
2425 infeasible = FALSE;
2426 nchgbds = 0;
2427 solvelp = FALSE;
2428
2429 /* check all linking constraint for domain reductions and feasibility */
2430 for( c = 0; c < nconss && !cutoff && !solvelp; ++c )
2431 {
2432 SCIP_CALL( enforcePseudo(scip, conss[c], &cutoff, &infeasible, &nchgbds, &solvelp) );
2433 }
2434
2435 if( cutoff )
2436 *result = SCIP_CUTOFF;
2437 else if( nchgbds > 0 )
2438 *result = SCIP_REDUCEDDOM;
2439 else if( solvelp )
2440 *result = SCIP_SOLVELP;
2441 else if( infeasible )
2442 *result = SCIP_INFEASIBLE;
2443 else
2444 *result = SCIP_FEASIBLE;
2445
2446 return SCIP_OKAY;
2447}
2448
2449
2450/** feasibility check method of constraint handler for integral solutions */
2451static
2452SCIP_DECL_CONSCHECK(consCheckLinking)
2453{ /*lint --e{715}*/
2454 SCIP_CONS* cons;
2455 SCIP_CONSDATA* consdata;
2456 int c;
2457
2458 assert(conshdlr != NULL);
2459 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2460 assert(nconss == 0 || conss != NULL);
2461 assert(result != NULL);
2462
2463 *result = SCIP_FEASIBLE;
2464
2465 /* check all linking constraints for feasibility */
2466 for( c = 0; c < nconss && (*result == SCIP_FEASIBLE || completely); ++c )
2467 {
2468 cons = conss[c];
2469 consdata = SCIPconsGetData(cons);
2470 assert(consdata != NULL);
2471
2472 if( consdata->nbinvars > 1 && (checklprows || consdata->row1 == NULL || !SCIProwIsInLP(consdata->row1)) )
2473 {
2474 if( !checkCons(scip, cons, sol) )
2475 {
2476 /* constraint is violated */
2477 *result = SCIP_INFEASIBLE;
2478
2479 if( printreason )
2480 {
2481 int pos;
2482 int b;
2483
2484 pos = -1;
2485
2486#ifndef NDEBUG
2487 for( b = 0; b < consdata->nbinvars; ++b )
2488 {
2489 assert(consdata->binvars[b] != NULL);
2490 assert(SCIPvarIsBinary(consdata->binvars[b]));
2491 }
2492#endif
2493
2494 SCIP_CALL( SCIPprintCons(scip, cons, NULL) );
2495 SCIPinfoMessage(scip, NULL, ";\n");
2496
2497 /* check that at most one binary variable is fixed */
2498 for( b = 0; b < consdata->nbinvars; ++b )
2499 {
2500 assert( SCIPisFeasIntegral(scip, SCIPgetSolVal(scip, sol, consdata->binvars[b])) );
2501
2502 /* check if binary variable is fixed */
2503 if( SCIPgetSolVal(scip, sol, consdata->binvars[b]) > 0.5 )
2504 {
2505 if( pos != -1 )
2506 {
2507 SCIPinfoMessage(scip, NULL, "violation: more than one binary variable is set to one");
2508 break;
2509 }
2510 pos = b ;
2511 }
2512 }
2513
2514 /* check that at least one binary variable is fixed */
2515 if( pos == -1 )
2516 {
2517 SCIPinfoMessage(scip, NULL, "violation: none of the binary variables is set to one\n");
2518 }
2519 else if( !SCIPisFeasEQ(scip, consdata->vals[pos], SCIPgetSolVal(scip, sol, consdata->linkvar)) )
2520 {
2521 /* check if the fixed binary variable match with the linking variable */
2522 SCIPinfoMessage(scip, NULL, "violation: <%s> = <%g> and <%s> is one\n",
2523 SCIPvarGetName(consdata->linkvar), SCIPgetSolVal(scip, sol, consdata->linkvar),
2524 SCIPvarGetName(consdata->binvars[pos]) );
2525 }
2526 }
2527 }
2528 }
2529 }
2530
2531 return SCIP_OKAY;
2532}
2533
2534/** domain propagation method of constraint handler */
2535static
2536SCIP_DECL_CONSPROP(consPropLinking)
2537{ /*lint --e{715}*/
2538 SCIP_Bool cutoff = FALSE;
2539 int nchgbds = 0;
2540 int c;
2541
2542 assert(conshdlr != NULL);
2543 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2544 assert(nconss == 0 || conss != NULL);
2545 assert(result != NULL);
2546
2547 SCIPdebugMsg(scip, "propagating %d/%d " CONSHDLR_NAME " constraints\n", nusefulconss, nconss);
2548
2549 /* propagate all useful set partitioning / packing / covering constraints */
2550 for( c = 0; c < nusefulconss && !cutoff; ++c )
2551 {
2552 SCIP_Bool addcut;
2553 SCIP_Bool mustcheck;
2554
2555 SCIP_CALL( processRealBoundChg(scip, conss[c], &cutoff, &nchgbds, &mustcheck) );
2556 SCIP_CALL( processBinvarFixings(scip, conss[c], &cutoff, &nchgbds, &addcut, &mustcheck) );
2557 } /*lint !e438*/
2558
2559 /* return the correct result */
2560 if( cutoff )
2561 *result = SCIP_CUTOFF;
2562 else if( nchgbds > 0 )
2563 *result = SCIP_REDUCEDDOM;
2564 else
2565 *result = SCIP_DIDNOTFIND;
2566
2567 return SCIP_OKAY;
2568}
2569
2570
2571/** presolving method of constraint handler */
2572static
2573SCIP_DECL_CONSPRESOL(consPresolLinking)
2574{ /*lint --e{715}*/
2575 SCIP_CONSHDLRDATA* conshdlrdata;
2576 int oldnfixedvars;
2577 int oldnchgbds;
2578 int oldnaggrvars;
2579 int oldndelconss;
2580 int firstchange;
2581 int firstclique;
2582 int lastclique;
2583 int c;
2584 SCIP_Bool fixed;
2585 SCIP_Bool cutoff;
2586 SCIP_Bool infeasible;
2587 SCIP_Bool mustcheck;
2588
2589 assert(conshdlr != NULL);
2590 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
2591 assert(scip != NULL);
2592 assert(result != NULL);
2593
2594 SCIPdebugMsg(scip, "presolve %d linking constraints\n", nconss);
2595
2596 (*result) = SCIP_DIDNOTFIND;
2597
2598 oldnchgbds = *nchgbds;
2599 oldnaggrvars = *naggrvars;
2600 oldnfixedvars = *nfixedvars;
2601 oldndelconss = *ndelconss;
2602 cutoff = FALSE;
2603
2604 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2605 assert(conshdlrdata != NULL);
2606
2607 /* process constraints */
2608 firstchange = INT_MAX;
2609 firstclique = INT_MAX;
2610 lastclique = -1;
2611
2612 /* check for each linking constraint the set partitioning condition */
2613 for( c = 0; c < nconss && !SCIPisStopped(scip); ++c )
2614 {
2615 SCIP_CONS* cons;
2616 SCIP_CONSDATA* consdata;
2617
2618 assert(*result != SCIP_CUTOFF);
2619
2620 cons = conss[c];
2621 assert(cons != NULL);
2622 assert(!SCIPconsIsModifiable(cons));
2623
2624 SCIPdebugMsg(scip, "presolve linking constraints <%s>\n", SCIPconsGetName(cons));
2625
2626 consdata = SCIPconsGetData(cons);
2627 assert(consdata != NULL);
2628
2629 if( !SCIPconsIsEnabled(cons) /* || consdata->nbinvars <= 1 */ )
2630 continue;
2631
2632 /* in case there is only at most one binary variables, the constraints should already be disabled */
2633 assert(consdata->nbinvars > 1);
2634
2635 /*SCIPdebugMsg(scip, "presolving set partitioning / packing / covering constraint <%s>\n", SCIPconsGetName(cons));*/
2636 if( consdata->nfixedones >= 2 )
2637 {
2638 /* at least two variables are fixed to 1:
2639 * - a linking constraint is infeasible due to the set partitioning condition
2640 */
2641 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s> is infeasible\n", SCIPconsGetName(cons));
2642 *result = SCIP_CUTOFF;
2643 return SCIP_OKAY;
2644 }
2645
2646 if( consdata->nfixedones == 1 )
2647 {
2648 /* exactly one variable is fixed to 1:
2649 * - all other binary variables must be zero due to the set partitioning condition
2650 * - linking variable has to be fixed to corresponding binary variable which is fixed to one
2651 * - if constraint is not modifiable it can be removed
2652 */
2653 SCIP_VAR* var;
2654 int v;
2655
2656 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s> has a binary variable fixed to 1.0\n", SCIPconsGetName(cons));
2657
2658 for( v = 0; v < consdata->nbinvars; ++v )
2659 {
2660 var = consdata->binvars[v];
2661 assert(var != NULL);
2662
2663 if( SCIPvarGetLbGlobal(var) < 0.5 && SCIPvarGetUbGlobal(var) > 0.5 )
2664 {
2665 SCIP_CALL( SCIPfixVar(scip, var, 0.0, &infeasible, &fixed) );
2666
2667 if( infeasible )
2668 {
2669 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s>: infeasible fixing <%s> == 0\n",
2670 SCIPconsGetName(cons), SCIPvarGetName(var));
2671
2672 *result = SCIP_CUTOFF;
2673 return SCIP_OKAY;
2674 }
2675 assert(fixed);
2676 (*nfixedvars)++;
2677 }
2678 else if( SCIPvarGetLbGlobal(var) > 0.5 )
2679 {
2680 /* fix linking variable */
2681 assert(SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_LOOSE
2682 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_AGGREGATED
2683 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_COLUMN
2684 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_FIXED
2685 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_NEGATED);
2686 SCIP_CALL( SCIPfixVar(scip, consdata->linkvar, consdata->vals[v], &infeasible, &fixed) );
2687
2688 if( infeasible )
2689 {
2690 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s>: infeasible fixing <%s> == %g\n",
2691 SCIPconsGetName(cons), SCIPvarGetName(consdata->linkvar), consdata->vals[v]);
2692
2693 *result = SCIP_CUTOFF;
2694 return SCIP_OKAY;
2695 }
2696
2697 if( fixed )
2698 (*nfixedvars)++;
2699 }
2700 }
2701
2702 /* now all other variables are fixed to zero:
2703 * the constraint is feasible, and if it's not modifiable, it is redundant
2704 */
2705 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s> is redundant\n", SCIPconsGetName(cons));
2706 SCIP_CALL( SCIPdelCons(scip, cons) );
2707 (*ndelconss)++;
2708 continue;
2709 }
2710
2711 if( consdata->nfixedzeros == consdata->nbinvars )
2712 {
2713 /* all variables are fixed to zero:
2714 * - a linking constraint is infeasible due the set partitioning condition
2715 */
2716 assert(consdata->nfixedones == 0);
2717
2718 SCIPdebugMsg(scip, "linking constraint <%s> is infeasible due to set partitioning condition\n", SCIPconsGetName(cons));
2719 *result = SCIP_CUTOFF;
2720 return SCIP_OKAY;
2721 }
2722
2723 if( consdata->nfixedzeros == consdata->nbinvars - 1 )
2724 {
2725 /* all variables except one are fixed to zero:
2726 * - a linking constraint is feasible due the set partitioning condition
2727 * - the remaining binary variable can be fixed to one
2728 * - linking variable has to be fixed to corresponding binary variable which is fixed to one
2729 * - constraint can be deleted since it is not modifiable
2730 */
2731 SCIP_VAR* var;
2732 int v;
2733
2734 assert(consdata->nfixedones == 0);
2735
2736 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s> has only one binary variable not fixed to zero\n",
2737 SCIPconsGetName(cons));
2738
2739 /* search unfixed variable */
2740 /* intentional empty for loop to increment counter to proper position */
2741 /* TODO speed up loop by considering only variables between firstnonfixed and lastnonfixed */
2742 for( v = 0; v < consdata->nbinvars && SCIPvarGetUbGlobal(consdata->binvars[v]) < 0.5; ++v ); /*lint !e722*/
2743 assert(v < consdata->nbinvars);
2744 var = consdata->binvars[v];
2745
2746 /* fix remaining binary variable */
2747 SCIP_CALL( SCIPfixVar(scip, var, 1.0, &infeasible, &fixed) );
2748 if( infeasible )
2749 {
2750 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s>: infeasible fixing <%s> == 1\n",
2751 SCIPconsGetName(cons), SCIPvarGetName(var));
2752 *result = SCIP_CUTOFF;
2753 return SCIP_OKAY;
2754 }
2755 assert(fixed);
2756 (*nfixedvars)++;
2757
2758 /* fix linking variable */
2759 assert(SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_LOOSE
2760 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_AGGREGATED
2761 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_COLUMN
2762 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_FIXED
2763 || SCIPvarGetStatus(consdata->linkvar) == SCIP_VARSTATUS_NEGATED);
2764 SCIP_CALL( SCIPfixVar(scip, consdata->linkvar, consdata->vals[v], &infeasible, &fixed) );
2765
2766 if( infeasible )
2767 {
2768 SCIPdebugMsg(scip, CONSHDLR_NAME " constraint <%s>: infeasible fixing <%s> == %g\n",
2769 SCIPconsGetName(cons), SCIPvarGetName(consdata->linkvar), consdata->vals[v]);
2770
2771 *result = SCIP_CUTOFF;
2772 return SCIP_OKAY;
2773 }
2774 assert(!SCIPvarIsActive(consdata->linkvar) || fixed);
2775 if( fixed )
2776 (*nfixedvars)++;
2777
2778 /* delete constraint from problem */
2779 SCIP_CALL( SCIPdelCons(scip, cons) );
2780 (*ndelconss)++;
2781 continue;
2782 }
2783
2784 if( consdata->nfixedzeros == consdata->nbinvars - 2 ) /*lint !e641*/
2785 {
2786 SCIP_VAR* var;
2787 SCIP_VAR* var1;
2788 SCIP_VAR* var2;
2789 SCIP_Bool redundant;
2790 SCIP_Bool aggregated;
2791 int v;
2792
2793 /* aggregate variable, if set partitioning condition consists only of two
2794 * non-fixed variables
2795 */
2796
2797 /* search unfixed variable */
2798 var1 = NULL;
2799 var2 = NULL;
2800 for( v = 0; v < consdata->nbinvars && var2 == NULL; ++v )
2801 {
2802 var = consdata->binvars[v];
2803 if( SCIPvarGetUbGlobal(var) > 0.5 )
2804 {
2805 if( var1 == NULL )
2806 var1 = var;
2807 else
2808 var2 = var;
2809 }
2810 }
2811 assert(var1 != NULL && var2 != NULL);
2812
2813 /* aggregate binary equality var1 + var2 == 1 */
2814 SCIPdebugMsg(scip, "" CONSHDLR_NAME " constraint <%s>: aggregate <%s> + <%s> == 1\n",
2815 SCIPconsGetName(cons), SCIPvarGetName(var1), SCIPvarGetName(var2));
2816 SCIP_CALL( SCIPaggregateVars(scip, var1, var2, 1.0, 1.0, 1.0, &infeasible, &redundant, &aggregated) );
2817
2818 /* evaluate aggregation result */
2819 if( infeasible )
2820 {
2821 SCIPdebugMsg(scip, "linking constraint <%s>: infeasible aggregation <%s> + <%s> == 1\n",
2822 SCIPconsGetName(cons), SCIPvarGetName(var1), SCIPvarGetName(var2));
2823 *result = SCIP_CUTOFF;
2824 return SCIP_OKAY;
2825 }
2826 if( aggregated )
2827 (*naggrvars)++;
2828 }
2829
2830 /* apply real bound to binary variables */
2831 SCIP_CALL( processRealBoundChg(scip, cons, &cutoff, nchgbds, &mustcheck) );
2832
2833 /* tightened linking variable */
2834 SCIP_CALL( tightenedLinkvar(scip, cons, consdata, &cutoff, nchgbds) );
2835
2836 /* remove the trailing and leeading binary variable which are fixed to zero */
2837 SCIP_CALL( removeFixedBinvars(scip, conshdlrdata->eventhdlr, cons) );
2838
2839 /* fix the linking variable to the only remaining value and the corresponding binary variable to 1.0 */
2840 if( ! cutoff && consdata->nbinvars == 1 )
2841 {
2842 SCIP_VAR* linkvar;
2843 SCIP_VAR* binvar;
2844 SCIP_Real val;
2845
2846 linkvar = consdata->linkvar;
2847 binvar = consdata->binvars[0];
2848 val = consdata->vals[0];
2849
2850 SCIPdebugMsg(scip, "linking constraint <%s>: fix <%s> to %16.9g as only one binary variable remains",
2851 SCIPconsGetName(cons), SCIPvarGetName(linkvar), val);
2852
2853 SCIP_CALL( SCIPfixVar(scip, binvar, 1.0, &infeasible, &fixed) );
2854 assert(fixed);
2855 ++(*nfixedvars);
2856
2857 if( ! infeasible )
2858 {
2859 SCIP_CALL( SCIPfixVar(scip, linkvar, val, &infeasible, &fixed) );
2860 assert(fixed);
2861 ++(*nfixedvars);
2862 }
2863 cutoff = infeasible;
2864
2865 SCIP_CALL(SCIPdelCons(scip, cons));
2866 ++(*ndelconss);
2867 }
2868
2869 if( cutoff )
2870 {
2871 *result = SCIP_CUTOFF;
2872 return SCIP_OKAY;
2873 }
2874
2875 /* remember the first changed constraint to begin the next redundancy round with */
2876 if( firstchange == INT_MAX )
2877 firstchange = c;
2878
2879 /* remember the first and last constraints for which we have to add the clique information */
2880 if( !consdata->cliqueadded && consdata->nbinvars >= 2 )
2881 {
2882 if( firstclique == INT_MAX )
2883 firstclique = c;
2884 lastclique = c;
2885 }
2886 }
2887
2888 /* add clique and implication information */
2889 for( c = firstclique; c < lastclique && !SCIPisStopped(scip); ++c )
2890 {
2891 SCIP_CONS* cons;
2892 SCIP_CONSDATA* consdata;
2893
2894 assert(*result != SCIP_CUTOFF);
2895
2896 cons = conss[c];
2897 assert(cons != NULL);
2898
2899 /* ignore deleted constraints */
2900 if( !SCIPconsIsActive(cons) )
2901 continue;
2902
2903 consdata = SCIPconsGetData(cons);
2904 assert(consdata != NULL);
2905
2906 if( !consdata->cliqueadded && consdata->nbinvars >= 3 )
2907 {
2908 /* add set partitioning condition as clique */
2909 int ncliquebdchgs;
2910
2911 SCIP_CALL( SCIPaddClique(scip, consdata->binvars, NULL, consdata->nbinvars, TRUE, &infeasible, &ncliquebdchgs) );
2912 *nchgbds += ncliquebdchgs;
2913
2914 if( infeasible )
2915 {
2916 *result = SCIP_CUTOFF;
2917 return SCIP_OKAY;
2918 }
2919
2920 consdata->cliqueadded = TRUE;
2921 }
2922 }
2923
2924#ifdef SCIP_DISABLED_CODE
2925 /* The following should work, but does not seem to be tested well. */
2926
2927 /* transfer aggregated linking variables to the corresponding binary variables */
2928 SCIP_CALL( aggregateVariables(scip, conshdlrdata->varmap, conss, nconss, naggrvars, &cutoff) );
2929#endif
2930
2931 if( cutoff )
2932 *result = SCIP_CUTOFF;
2933 else if( oldndelconss < *ndelconss || oldnfixedvars < *nfixedvars || oldnchgbds < *nchgbds || oldnaggrvars < *naggrvars)
2934 *result = SCIP_SUCCESS;
2935
2936 return SCIP_OKAY; /*lint !e438*/
2937}
2938
2939
2940/** propagation conflict resolving method of constraint handler */
2941static
2942SCIP_DECL_CONSRESPROP(consRespropLinking)
2943{ /*lint --e{715}*/
2944 SCIP_CONSDATA* consdata;
2945 SCIP_VAR* linkvar;
2946 int v;
2947
2948 SCIPdebugMsg(scip, "conflict resolving method of " CONSHDLR_NAME " constraint handler\n");
2949
2950 consdata = SCIPconsGetData(cons);
2951 assert(consdata != NULL);
2952
2953 linkvar = consdata->linkvar;
2954 assert(linkvar != NULL);
2955
2956 *result = SCIP_DIDNOTFIND;
2957
2958 if( inferinfo == -1 )
2959 {
2960 /* we have to resolve a fixing of a binary variable which was done due to fixed binary variables */
2961 assert(SCIPvarIsBinary(infervar));
2962 assert(SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, FALSE)));
2963 assert(SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, FALSE)));
2964
2965 if( boundtype == SCIP_BOUNDTYPE_UPPER )
2966 {
2967 /* we fixed the binary variable to zero since one of the other binary variable was fixed to one (set
2968 * partitioning condition)
2969 */
2970 assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
2971
2972 for( v = 0; v < consdata->nbinvars; ++v )
2973 {
2974 if( SCIPgetVarLbAtIndex(scip, consdata->binvars[v], bdchgidx, FALSE) > 0.5 )
2975 {
2976 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->binvars[v]) );
2977 break;
2978 }
2979 }
2980 assert(v < consdata->nbinvars);
2981 }
2982 else
2983 {
2984 /* we fixed the binary variable to one since all other binary variable were fixed to zero */
2985 assert(boundtype == SCIP_BOUNDTYPE_LOWER);
2986 assert(SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) > 0.5);
2987
2988 for( v = 0; v < consdata->nbinvars; ++v )
2989 {
2990 if( consdata->binvars[v] != infervar )
2991 {
2992 /* the reason variable must be assigned to zero */
2993 assert(SCIPgetVarUbAtIndex(scip, consdata->binvars[v], bdchgidx, FALSE) < 0.5);
2994 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->binvars[v]) );
2995 }
2996 }
2997 }
2998 }
2999 else if( inferinfo == -2 )
3000 {
3001 /* we have to resolve a fixing of a binary variable which was done due to the linking variable lower bound */
3002 assert(SCIPvarIsBinary(infervar));
3003 assert(SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
3004 assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5); /*@repair: neu*/
3005 assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, FALSE) > 0.5); /*@repair: neu*/
3006 assert( SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
3007 assert( SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
3008
3009 SCIP_CALL( SCIPaddConflictLb(scip, linkvar, bdchgidx) );
3010 }
3011 else if( inferinfo == -3 )
3012 {
3013 /* we have to resolve a fixing of a binary variable which was done due to the linking variable upper bound */
3014 assert(SCIPvarIsBinary(infervar));
3015 assert(SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
3016 assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, TRUE) < 0.5);
3017 assert(SCIPgetVarUbAtIndex(scip, infervar, bdchgidx, FALSE) > 0.5);
3018 assert( SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
3019 assert( SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
3020
3021 SCIP_CALL( SCIPaddConflictUb(scip, linkvar, bdchgidx) );
3022 }
3023 else if( inferinfo == -4 )
3024 {
3025 SCIP_VAR** binvars;
3026 SCIP_Real* vals;
3027 SCIP_Real lb;
3028 int nbinvars;
3029 int b;
3030
3031 /* we tightened the lower bound of the linking variable due the fixing of the corresponding binary variable to zero */
3032 assert(infervar == linkvar);
3033 assert(boundtype == SCIP_BOUNDTYPE_LOWER);
3034
3035 binvars = consdata->binvars;
3036 nbinvars = consdata->nbinvars;
3037 vals = consdata->vals;
3038
3039 /* get propagated lower bound */
3040 lb = SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, TRUE);
3041
3042 for( b = 0; b < nbinvars; ++b )
3043 {
3044 if( vals[b] >= lb )
3045 break;
3046
3047 assert(SCIPvarGetUbLocal(binvars[b]) < 0.5);
3048 SCIP_CALL( SCIPaddConflictBinvar(scip, binvars[b]) );
3049 }
3050 }
3051 else if( inferinfo == -5 )
3052 {
3053 SCIP_VAR** binvars;
3054 SCIP_Real* vals;
3055 SCIP_Real ub;
3056 int nbinvars;
3057 int b;
3058
3059 /* we tightened the upper bound of the linking variable due the fixing of the corresponding binary variable two zero */
3060
3061 assert(infervar == linkvar);
3062 assert(boundtype == SCIP_BOUNDTYPE_UPPER);
3063
3064 binvars = consdata->binvars;
3065 nbinvars = consdata->nbinvars;
3066 vals = consdata->vals;
3067
3068 /* get old and new upper bound */
3069 ub = SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, TRUE);
3070
3071 /* resolve tightening of upper bound of the linking variable by binary variables */
3072 for( b = nbinvars - 1; b >= 0; --b )
3073 {
3074 if( vals[b] <= ub )
3075 break;
3076
3077 SCIP_CALL( SCIPaddConflictBinvar(scip, binvars[b]) );
3078 }
3079 }
3080 else if( inferinfo == -6 )
3081 {
3082 /* we fixed a binary variable to one since the linking variable was fixed */
3083 assert(SCIPvarIsBinary(infervar));
3084 assert(boundtype == SCIP_BOUNDTYPE_LOWER);
3085 assert( SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
3086 assert( SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
3087 assert( SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
3088 assert( SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, linkvar, bdchgidx, FALSE)) );
3089
3090 assert( !SCIPisFeasEQ(scip, SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, TRUE), SCIPgetVarLbAtIndex(scip, infervar, bdchgidx, FALSE)) );
3091
3092 SCIP_CALL( SCIPaddConflictLb(scip, linkvar, bdchgidx) );
3093 SCIP_CALL( SCIPaddConflictUb(scip, linkvar, bdchgidx) );
3094 }
3095 else
3096 {
3097 /* we fixed the linking variable to (vals[inferinfo]) since the corresponding binary variable was fixed to one */
3098 assert(infervar == linkvar);
3099 assert(inferinfo >= 0);
3100 assert(inferinfo < consdata->nbinvars);
3101 assert(SCIPisEQ(scip, consdata->vals[inferinfo], SCIPgetVarUbAtIndex(scip, consdata->linkvar, bdchgidx, TRUE))
3102 || SCIPisEQ(scip, consdata->vals[inferinfo], SCIPgetVarLbAtIndex(scip, consdata->linkvar, bdchgidx, TRUE)));
3103
3104 assert(SCIPgetVarLbAtIndex(scip, consdata->binvars[inferinfo], bdchgidx, FALSE) > 0.5);
3105 SCIP_CALL( SCIPaddConflictBinvar(scip, consdata->binvars[inferinfo]) );
3106 }
3107
3108 *result = SCIP_SUCCESS;
3109
3110 return SCIP_OKAY;
3111}
3112
3113/** variable rounding lock method of constraint handler */
3114static
3115SCIP_DECL_CONSLOCK(consLockLinking)
3116{ /*lint --e{715}*/
3117 SCIP_CONSDATA* consdata;
3118 int b;
3119
3120 assert(locktype == SCIP_LOCKTYPE_MODEL);
3121
3122 consdata = SCIPconsGetData(cons);
3123 assert(consdata != NULL);
3124
3125 /* lock linking variable in both directions */
3126 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->linkvar, locktype, nlockspos + nlocksneg, nlockspos + nlocksneg) );
3127
3128 /* look binary variables in both directions */
3129 for( b = 0; b < consdata->nbinvars; ++b )
3130 {
3131 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->binvars[b], locktype, nlockspos + nlocksneg, nlockspos + nlocksneg) );
3132 }
3133
3134 return SCIP_OKAY;
3135}
3136
3137/** constraint activation notification method of constraint handler */
3138static
3139SCIP_DECL_CONSACTIVE(consActiveLinking)
3140{ /*lint --e{715}*/
3141 assert(cons != NULL);
3142 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
3143 assert(SCIPconsIsTransformed(cons));
3144
3146 {
3147 SCIP_CALL( addNlrow(scip, cons) );
3148 }
3149
3150 return SCIP_OKAY;
3151}
3152
3153
3154/** constraint deactivation notification method of constraint handler */
3155static
3156SCIP_DECL_CONSDEACTIVE(consDeactiveLinking)
3157{ /*lint --e{715}*/
3158 SCIP_CONSDATA* consdata;
3159
3160 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
3161 assert(SCIPconsIsTransformed(cons));
3162
3163 /* get constraint data */
3164 consdata = SCIPconsGetData(cons);
3165 assert(consdata != NULL);
3166
3167 /* remove row from NLP, if still in solving
3168 * if we are in exitsolve, the whole NLP will be freed anyway
3169 */
3170 if( SCIPgetStage(scip) == SCIP_STAGE_SOLVING && consdata->nlrow1 != NULL )
3171 {
3172 assert(consdata->nlrow2 != NULL);
3173 SCIP_CALL( SCIPdelNlRow(scip, consdata->nlrow1) );
3174 SCIP_CALL( SCIPdelNlRow(scip, consdata->nlrow2) );
3175 }
3176
3177 return SCIP_OKAY;
3178}
3179
3180/** constraint enabling notification method of constraint handler */
3181static
3182SCIP_DECL_CONSENABLE(consEnableLinking)
3183{ /*lint --e{715}*/
3184#ifdef SCIP_DISABLED_CODE
3185 /** @todo The following might help, but it would need to be tested whether it speeds up the solution process. */
3186 SCIP_CONSHDLRDATA* conshdlrdata;
3187 SCIP_CONSDATA* consdata;
3188
3189 conshdlrdata = SCIPconshdlrGetData(conshdlr);
3190 assert(conshdlrdata != NULL);
3191
3192 consdata = SCIPconsGetData(cons);
3193 assert(consdata != NULL);
3194
3195 if( consdata->nbinvars <= 1 )
3196 {
3197 SCIP_CALL( SCIPdisableCons(scip, cons) );
3198 assert(consdata->nbinvars == 0 || SCIPvarGetLbGlobal(consdata->binvars[0]) > 0.5);
3199 }
3200 else if( conshdlrdata->linearize )
3201 {
3202 SCIP_CALL( consdataLinearize(scip, cons, consdata) );
3203 SCIP_CALL( SCIPdelCons(scip, cons) );
3204 }
3205#endif
3206 return SCIP_OKAY;
3207}
3208
3209/** constraint display method of constraint handler */
3210static
3211SCIP_DECL_CONSPRINT(consPrintLinking)
3212{ /*lint --e{715}*/
3213 assert(scip != NULL);
3214 assert(conshdlr != NULL);
3215 assert(cons != NULL);
3216
3218
3219 return SCIP_OKAY;
3220}
3221
3222
3223/** constraint copying method of constraint handler */
3224static
3225SCIP_DECL_CONSCOPY(consCopyLinking)
3226{ /*lint --e{715}*/
3227 SCIP_CONSDATA* sourceconsdata;
3228 SCIP_VAR** binvars;
3229 SCIP_VAR* linkvar;
3230 SCIP_Real* vals;
3231 const char* consname;
3232 int nbinvars;
3233 int v;
3234
3235 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(sourcecons)), CONSHDLR_NAME) != 0 )
3236 {
3237 SCIPerrorMessage("constraint is not a linking constraint\n");
3238 SCIPABORT();
3239 return SCIP_INVALIDDATA; /*lint !e527*/
3240 }
3241
3242 (*valid) = TRUE;
3243
3244 sourceconsdata = SCIPconsGetData(sourcecons);
3245 assert(sourceconsdata != NULL);
3246
3247 /* get number of binary variables, linking variables */
3248 nbinvars = sourceconsdata->nbinvars;
3249 linkvar = sourceconsdata->linkvar;
3250
3251 /* duplicate variable array */
3252 if( nbinvars > 0 )
3253 {
3254 SCIP_CALL( SCIPduplicateBufferArray(scip, &binvars, sourceconsdata->binvars, nbinvars) );
3255 SCIP_CALL( SCIPduplicateBufferArray(scip, &vals, sourceconsdata->vals, nbinvars) );
3256 }
3257 else
3258 {
3259 binvars = NULL;
3260 vals = NULL;
3261 }
3262
3263 /* get copy for the binary variables */
3264 for( v = 0; v < nbinvars && *valid; ++v )
3265 {
3266 assert(binvars != NULL); /* for flexelint */
3267 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, binvars[v], &binvars[v], varmap, consmap, global, valid) );
3268 assert(!(*valid) || binvars[v] != NULL);
3269 }
3270
3271 /* copy the linking variable */
3272 if( *valid )
3273 {
3274 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, linkvar, &linkvar, varmap, consmap, global, valid) );
3275 assert(!(*valid) || linkvar != NULL);
3276 }
3277
3278 /* only create the target constraint, if all variables could be copied */
3279 if( *valid )
3280 {
3281 if( name != NULL )
3282 consname = name;
3283 else
3284 consname = SCIPconsGetName(sourcecons);
3285
3286 SCIP_CALL( SCIPcreateConsLinking(scip, cons, consname, linkvar, binvars, vals, nbinvars,
3287 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3288 }
3289
3290 /* free buffer array */
3291 if( nbinvars > 0 )
3292 {
3294 SCIPfreeBufferArrayNull(scip, &binvars);
3295 }
3296
3297 return SCIP_OKAY;
3298}
3299
3300/** constraint parsing method of constraint handler */
3301static
3302SCIP_DECL_CONSPARSE(consParseLinking)
3303{ /*lint --e{715}*/
3304 SCIP_VAR** binvars;
3305 SCIP_VAR* linkvar;
3306 SCIP_Real* vals;
3307 char* endptr;
3308 int varssize;
3309 int nbinvars;
3310
3311 assert(scip != NULL);
3312 assert(success != NULL);
3313 assert(str != NULL);
3314 assert(name != NULL);
3315 assert(cons != NULL);
3316
3317 *success = TRUE;
3318
3319 /* parse linking variable */
3320 SCIP_CALL( SCIPparseVarName(scip, str, &linkvar, &endptr) );
3321
3322 if( linkvar == NULL )
3323 {
3324 SCIPerrorMessage("unknown variable name at '%s'\n", str);
3325 *success = FALSE;
3326 return SCIP_OKAY;
3327 }
3328
3329 /* find "==" */
3330 endptr = strchr(endptr, '=');
3331
3332 /* if the string end has been reached without finding the "==" */
3333 if( endptr == NULL )
3334 {
3335 SCIPerrorMessage("Could not find initializing '='.\n");
3336 *success = FALSE;
3337 return SCIP_OKAY;
3338 }
3339
3340 str = endptr;
3341
3342 /* skip "==" */
3343 str += *(str+1) == '=' ? 2 : 1;
3344
3345 /* skip whitespace */
3346 SCIP_CALL( SCIPskipSpace((char**)&str) );
3347
3348 nbinvars = 0;
3349 varssize = 16;
3350 SCIP_CALL( SCIPallocBufferArray(scip, &binvars, varssize) );
3351 SCIP_CALL( SCIPallocBufferArray(scip, &vals, varssize) );
3352
3353 /* check for the string "no binary variables yet" */
3354 if( strncmp(str, "no binary variables yet", 24) != 0 )
3355 {
3356 int requsize;
3357 int v;
3358
3359 /* parse linear sum to get variables and coefficients */
3360 SCIP_CALL( SCIPparseVarsLinearsum(scip, str, binvars, vals, &nbinvars, varssize, &requsize, &endptr, success) );
3361
3362 if( *success && requsize > varssize )
3363 {
3364 /* realloc buffers and try again */
3365 varssize = requsize;
3366 SCIP_CALL( SCIPreallocBufferArray(scip, &binvars, varssize) );
3367 SCIP_CALL( SCIPreallocBufferArray(scip, &vals, varssize) );
3368
3369 SCIP_CALL( SCIPparseVarsLinearsum(scip, str, binvars, vals, &nbinvars, varssize, &requsize, &endptr, success) );
3370 assert(!*success || requsize <= varssize); /* if successful, then should have had enough space now */
3371 }
3372
3373 /* check coefficients */
3374 if( *success )
3375 {
3376 /* convert SCIP_Real to integer */
3377 for( v = 0; v < nbinvars; ++v )
3378 {
3379 if( SCIPisIntegral(scip, vals[v]) )
3380 vals[v] = SCIPconvertRealToInt(scip, vals[v]);
3381 }
3382 }
3383 }
3384
3385 if( *success )
3386 {
3387 SCIP_CALL( SCIPcreateConsLinking(scip, cons, name, linkvar, binvars, vals, nbinvars,
3388 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3389 }
3390
3391 SCIPfreeBufferArray(scip, &vals);
3392 SCIPfreeBufferArray(scip, &binvars);
3393
3394 return SCIP_OKAY;
3395}
3396
3397/** constraint method of constraint handler which returns the variables (if possible) */
3398static
3399SCIP_DECL_CONSGETVARS(consGetVarsLinking)
3400{ /*lint --e{715}*/
3401 SCIP_CONSDATA* consdata;
3402
3403 consdata = SCIPconsGetData(cons);
3404 assert(consdata != NULL);
3405
3406 if( varssize < consdata->nbinvars + 1)
3407 (*success) = FALSE;
3408 else
3409 {
3410 assert(vars != NULL);
3411
3412 BMScopyMemoryArray(vars, consdata->binvars, consdata->nbinvars);
3413 vars[consdata->nbinvars] = consdata->linkvar;
3414 (*success) = TRUE;
3415 }
3416
3417 return SCIP_OKAY;
3418}
3419
3420/** constraint method of constraint handler which returns the number of variables (if possible) */
3421static
3422SCIP_DECL_CONSGETNVARS(consGetNVarsLinking)
3423{ /*lint --e{715}*/
3424 SCIP_CONSDATA* consdata;
3425
3426 consdata = SCIPconsGetData(cons);
3427 assert(consdata != NULL);
3428
3429 (*nvars) = consdata->nbinvars + 1;
3430 (*success) = TRUE;
3431
3432 return SCIP_OKAY;
3433}
3434
3435/** constraint handler method which returns the permutation symmetry detection graph of a constraint */
3436static
3437SCIP_DECL_CONSGETPERMSYMGRAPH(consGetPermsymGraphLinking)
3438{ /*lint --e{715}*/
3439 SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_PERM, cons, graph, success) );
3440
3441 return SCIP_OKAY;
3442}
3443
3444/** constraint handler method which returns the signed permutation symmetry detection graph of a constraint */
3445static
3446SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH(consGetSignedPermsymGraphLinking)
3447{ /*lint --e{715}*/
3448 SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_SIGNPERM, cons, graph, success) );
3449
3450 return SCIP_OKAY;
3451}
3452
3453/*
3454 * Callback methods of event handler
3455 */
3456
3457/** execution method of event handler */
3458static
3459SCIP_DECL_EVENTEXEC(eventExecBinvar)
3460{ /*lint --e{715}*/
3461 SCIP_CONSDATA* consdata;
3462 SCIP_EVENTTYPE eventtype;
3463
3464 assert(eventhdlr != NULL);
3465 assert(eventdata != NULL);
3466 assert(strcmp(SCIPeventhdlrGetName(eventhdlr), EVENTHDLR_NAME) == 0);
3467 assert(event != NULL);
3468
3469 consdata = (SCIP_CONSDATA*)eventdata;
3470 assert(consdata != NULL);
3471
3472 eventtype = SCIPeventGetType(event);
3473 switch( eventtype )
3474 {
3476 consdata->nfixedones++;
3477 break;
3479 consdata->nfixedones--;
3480 consdata->firstnonfixed = 0;
3481 consdata->lastnonfixed = consdata->nbinvars - 1;
3482 break;
3484 consdata->nfixedzeros++;
3485 break;
3487 consdata->firstnonfixed = 0;
3488 consdata->lastnonfixed = consdata->nbinvars - 1;
3489 consdata->nfixedzeros--;
3490 break;
3491 default:
3492 SCIPerrorMessage("invalid event type\n");
3493 return SCIP_INVALIDDATA;
3494 }
3495 assert(0 <= consdata->nfixedzeros && consdata->nfixedzeros <= consdata->nbinvars);
3496 assert(0 <= consdata->nfixedones && consdata->nfixedones <= consdata->nbinvars);
3497
3498 /*debugMsg(scip, " -> constraint has %d zero-fixed and %d one-fixed of %d variables\n",
3499 consdata->nfixedzeros, consdata->nfixedones, consdata->nvars);*/
3500
3501 return SCIP_OKAY;
3502}
3503
3504/*
3505 * constraint specific interface methods
3506 */
3507
3508/** creates the handler for linking constraints and includes it in SCIP */
3510 SCIP* scip /**< SCIP data structure */
3511 )
3512{
3513 SCIP_CONSHDLRDATA* conshdlrdata;
3514 SCIP_CONSHDLR* conshdlr;
3515 SCIP_EVENTHDLR* eventhdlr;
3516
3517 /* create event handler for bound change events */
3519 eventExecBinvar, NULL) );
3520
3521 /* create linking constraint handler data */
3522 SCIP_CALL( conshdlrdataCreate(scip, &conshdlrdata, eventhdlr) );
3523
3524 /* include constraint handler */
3527 consEnfolpLinking, consEnfopsLinking, consCheckLinking, consLockLinking,
3528 conshdlrdata) );
3529
3530 assert(conshdlr != NULL);
3531
3532 /* set non-fundamental callbacks via specific setter functions */
3533 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopyLinking, consCopyLinking) );
3534 SCIP_CALL( SCIPsetConshdlrActive(scip, conshdlr, consActiveLinking) );
3535 SCIP_CALL( SCIPsetConshdlrDeactive(scip, conshdlr, consDeactiveLinking) );
3536 SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteLinking) );
3537 SCIP_CALL( SCIPsetConshdlrEnable(scip, conshdlr, consEnableLinking) );
3538 SCIP_CALL( SCIPsetConshdlrInitsol(scip, conshdlr, consInitsolLinking) );
3539 SCIP_CALL( SCIPsetConshdlrExitsol(scip, conshdlr, consExitsolLinking) );
3540 SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeLinking) );
3541 SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsLinking) );
3542 SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsLinking) );
3543 SCIP_CALL( SCIPsetConshdlrInitpre(scip, conshdlr, consInitpreLinking) );
3544 SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpLinking) );
3545 SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseLinking) );
3547 SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintLinking) );
3550 SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropLinking) );
3551 SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpLinking, consSepasolLinking, CONSHDLR_SEPAFREQ,
3553 SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransLinking) );
3554 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxLinking) );
3555 SCIP_CALL( SCIPsetConshdlrGetPermsymGraph(scip, conshdlr, consGetPermsymGraphLinking) );
3556 SCIP_CALL( SCIPsetConshdlrGetSignedPermsymGraph(scip, conshdlr, consGetSignedPermsymGraphLinking) );
3557
3558 /* include the linear constraint to linking constraint upgrade in the linear constraint handler */
3559 /* SCIP_CALL( SCIPincludeLinconsUpgrade(scip, linconsUpgdLinking, LINCONSUPGD_PRIORITY, CONSHDLR_NAME) ); */
3560
3561 /* add linking constraint handler parameters */
3563 "constraints/" CONSHDLR_NAME "/linearize", "this constraint will not propagate or separate, linear and setppc are used?",
3564 &conshdlrdata->linearize, FALSE, DEFAULT_LINEARIZE, NULL, NULL) );
3565
3566 return SCIP_OKAY;
3567}
3568
3569/** creates and captures a linking constraint
3570 *
3571 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
3572 */
3574 SCIP* scip, /**< SCIP data structure */
3575 SCIP_CONS** cons, /**< pointer to hold the created constraint */
3576 const char* name, /**< name of constraint */
3577 SCIP_VAR* linkvar, /**< linking variable (continuous or integer) which should be linked */
3578 SCIP_VAR** binvars, /**< binary variables */
3579 SCIP_Real* vals, /**< coefficients of the binary variables */
3580 int nbinvars, /**< number of binary starting variables */
3581 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
3582 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
3583 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
3584 * Usually set to TRUE. */
3585 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
3586 * TRUE for model constraints, FALSE for additional, redundant constraints. */
3587 SCIP_Bool check, /**< should the constraint be checked for feasibility?
3588 * TRUE for model constraints, FALSE for additional, redundant constraints. */
3589 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
3590 * Usually set to TRUE. */
3591 SCIP_Bool local, /**< is constraint only valid locally?
3592 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
3593 SCIP_Bool modifiable, /**< is constraint modifiable (subject to column generation)?
3594 * Usually set to FALSE. In column generation applications, set to TRUE if pricing
3595 * adds coefficients to this constraint. */
3596 SCIP_Bool dynamic, /**< is constraint subject to aging?
3597 * Usually set to FALSE. Set to TRUE for own cuts which
3598 * are separated as constraints. */
3599 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
3600 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
3601 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
3602 * if it may be moved to a more global node?
3603 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
3604 )
3605{
3606 SCIP_CONSHDLR* conshdlr;
3607 SCIP_CONSDATA* consdata;
3608 SCIP_CONSHDLRDATA* conshdlrdata;
3609 int k;
3610
3611 assert(scip != NULL);
3612 assert(!SCIPisInfinity(scip, -SCIPvarGetLbGlobal(linkvar)));
3613 assert(!SCIPisInfinity(scip, SCIPvarGetUbGlobal(linkvar)));
3614
3615 /* find the linking constraint handler */
3616 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
3617 if( conshdlr == NULL )
3618 {
3619 SCIPerrorMessage("linking constraint handler not found\n");
3620 return SCIP_PLUGINNOTFOUND;
3621 }
3622
3623 SCIPdebugMsg(scip, "create linking constraint for variable <%s> with %d binary variables (SCIP stage %d)\n",
3624 SCIPvarGetName(linkvar), nbinvars, SCIPgetStage(scip));
3625 for( k = 0; k < nbinvars; k++ )
3626 {
3627 SCIPdebugMsg(scip, "Var %d : <%s>\n", k, SCIPvarGetName(binvars[k]));
3628 }
3629
3630 /* get constraint handler data */
3631 conshdlrdata = SCIPconshdlrGetData(conshdlr);
3632 assert(conshdlrdata != NULL);
3633
3634 if( conshdlrdata->varmap == NULL )
3635 {
3636 SCIP_CALL( SCIPhashmapCreate(&conshdlrdata->varmap, SCIPblkmem(scip), HASHSIZE_BINVARSCONS) );
3637 }
3638 assert(conshdlrdata->varmap != NULL);
3639
3640 /* check if the linking for the requests linking variable already exists */
3641 assert(!SCIPhashmapExists(conshdlrdata->varmap, getHashmapKey(linkvar)));
3642
3643 /* create the constraint specific data */
3644 SCIP_CALL( consdataCreate(scip, conshdlrdata->eventhdlr, &consdata, linkvar, binvars, vals, nbinvars) );
3645
3646 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata,
3647 initial, separate, enforce, check, propagate, local, modifiable, dynamic, removable, stickingatnode) );
3648
3649 /* create binary variables for the real domain */
3650 if( nbinvars == 0 )
3651 {
3652 SCIP_CALL( consdataCreateBinvars(scip, *cons, consdata, conshdlrdata->eventhdlr, conshdlrdata->linearize) );
3653 }
3654
3655 /* insert linking constraint into the hash map */
3656 SCIP_CALL( SCIPhashmapInsert(conshdlrdata->varmap, getHashmapKey(linkvar), *cons) );
3657 assert(SCIPhashmapExists(conshdlrdata->varmap, getHashmapKey(linkvar)));
3658
3659 return SCIP_OKAY;
3660}
3661
3662/** creates and captures a linking constraint
3663 * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
3664 * method SCIPcreateConsLinking(); all flags can be set via SCIPsetCons<Flagname>-methods in scip.h
3665 *
3666 * @see SCIPcreateConsLinking() for information about the basic constraint flag configuration
3667 *
3668 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
3669 */
3671 SCIP* scip, /**< SCIP data structure */
3672 SCIP_CONS** cons, /**< pointer to hold the created constraint */
3673 const char* name, /**< name of constraint */
3674 SCIP_VAR* linkvar, /**< linking variable (continuous or integer) which should be linked */
3675 SCIP_VAR** binvars, /**< binary variables, or NULL */
3676 SCIP_Real* vals, /**< coefficients of the binary variables */
3677 int nbinvars /**< number of binary variables */
3678 )
3679{
3680 assert(scip != NULL);
3681
3682 SCIP_CALL( SCIPcreateConsLinking(scip, cons, name, linkvar, binvars, vals, nbinvars,
3684
3685 return SCIP_OKAY;
3686}
3687
3688/** checks if for the given linking variable (continuous or integer) a linking constraint exists */
3690 SCIP* scip, /**< SCIP data structure */
3691 SCIP_VAR* linkvar /**< linking variable (continuous or integer) which should be linked */
3692 )
3693{
3694 SCIP_CONSHDLR* conshdlr;
3695 SCIP_CONSHDLRDATA* conshdlrdata;
3696
3697 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
3698 assert(conshdlr != NULL);
3699
3700 conshdlrdata = SCIPconshdlrGetData(conshdlr);
3701 assert(conshdlrdata != NULL);
3702
3703 return (conshdlrdata->varmap != NULL) && SCIPhashmapExists(conshdlrdata->varmap, getHashmapKey(linkvar));
3704}
3705
3706/** returns the linking constraint belonging the given linking variable (continuous or integer) or NULL if it does not exist yet */
3708 SCIP* scip, /**< SCIP data structure */
3709 SCIP_VAR* linkvar /**< linking variable (continuous or integer) which should be linked */
3710 )
3711{
3712 SCIP_CONSHDLR* conshdlr;
3713 SCIP_CONSHDLRDATA* conshdlrdata;
3714
3715 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
3716 assert(conshdlr != NULL);
3717
3718 conshdlrdata = SCIPconshdlrGetData(conshdlr);
3719 assert(conshdlrdata != NULL);
3720
3721 if( conshdlrdata->varmap != NULL )
3722 return (SCIP_CONS*) SCIPhashmapGetImage(conshdlrdata->varmap, getHashmapKey(linkvar));
3723 else
3724 return NULL;
3725}
3726
3727/** returns the linking variable (continuous or integer) of the linking constraint */
3729 SCIP* scip, /**< SCIP data structure */
3730 SCIP_CONS* cons /**< linking constraint */
3731 )
3732{
3733 SCIP_CONSDATA* consdata;
3734
3735 assert(scip != NULL);
3736
3737 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
3738 {
3739 SCIPerrorMessage("constraint is not a " CONSHDLR_NAME " constraint\n");
3740 SCIPABORT();
3741 return NULL; /*lint !e527*/
3742 }
3743
3744 consdata = SCIPconsGetData(cons);
3745 assert(consdata != NULL);
3746
3747 return consdata->linkvar;
3748}
3749
3750/** returns the binary variables of the linking constraint */
3752 SCIP* scip, /**< SCIP data structure */
3753 SCIP_CONS* cons, /**< linking constraint */
3754 SCIP_VAR*** binvars, /**< pointer to store the binary variables array pointer */
3755 int* nbinvars /**< pointer to store the number of returned binary variables */
3756 )
3757{
3758 SCIP_CONSDATA* consdata;
3759
3760 assert(scip != NULL);
3761
3762 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
3763 {
3764 SCIPerrorMessage("constraint is not a " CONSHDLR_NAME " constraint\n");
3765 SCIPABORT();
3766 return SCIP_INVALIDDATA; /*lint !e527*/
3767 }
3768
3769 consdata = SCIPconsGetData(cons);
3770 assert(consdata != NULL);
3771
3772 if( consdata->binvars == NULL )
3773 {
3774 SCIP_CONSHDLR* conshdlr;
3775 SCIP_CONSHDLRDATA* conshdlrdata;
3776
3777 conshdlr = SCIPconsGetHdlr(cons);
3778 assert(conshdlr != NULL);
3779
3780 conshdlrdata = SCIPconshdlrGetData(conshdlr);
3781 assert(conshdlrdata != NULL);
3782
3783 SCIP_CALL( consdataCreateBinvars(scip, cons, consdata, conshdlrdata->eventhdlr, conshdlrdata->linearize) );
3784 }
3785
3786 assert(consdata->binvars != NULL);
3787
3788 if( binvars != NULL )
3789 (*binvars) = consdata->binvars;
3790 if( nbinvars != NULL )
3791 (*nbinvars) = consdata->nbinvars;
3792
3793 return SCIP_OKAY;
3794}
3795
3796/** returns the number of binary variables of the linking constraint */
3798 SCIP* scip, /**< SCIP data structure */
3799 SCIP_CONS* cons /**< linking constraint */
3800 )
3801{
3802 SCIP_CONSDATA* consdata;
3803
3804 assert(scip != NULL);
3805
3806 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
3807 {
3808 SCIPerrorMessage("constraint is not a " CONSHDLR_NAME " constraint\n");
3809 SCIPABORT();
3810 return -1; /*lint !e527*/
3811 }
3812
3813 consdata = SCIPconsGetData(cons);
3814 assert(consdata != NULL);
3815
3816 return consdata->nbinvars;
3817}
3818
3819/** returns the coefficients of the binary variables */
3821 SCIP* scip, /**< SCIP data structure */
3822 SCIP_CONS* cons /**< linking constraint */
3823 )
3824{
3825 SCIP_CONSDATA* consdata;
3826
3827 assert(scip != NULL);
3828
3829 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
3830 {
3831 SCIPerrorMessage("constraint is not a " CONSHDLR_NAME " constraint\n");
3832 SCIPABORT();
3833 return NULL; /*lint !e527*/
3834 }
3835
3836 consdata = SCIPconsGetData(cons);
3837 assert(consdata != NULL);
3838 consdataSort(consdata);
3839
3840 return consdata->vals;
3841}
3842
3843/** return all binary variable information of the linking constraint */
3845 SCIP_CONS* cons, /**< linking constraint */
3846 SCIP_VAR*** binvars, /**< pointer to store binary variables, or NULL */
3847 SCIP_Real** vals, /**< pointer to store the binary coefficients, or NULL */
3848 int* nbinvars /**< pointer to store the number of binary variables, or NULL */
3849 )
3850{
3851 SCIP_CONSDATA* consdata;
3852
3853 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) != 0 )
3854 {
3855 SCIPerrorMessage("constraint is not a " CONSHDLR_NAME " constraint\n");
3856 SCIPABORT();
3857 return SCIP_ERROR;
3858 }
3859
3860 consdata = SCIPconsGetData(cons);
3861 assert(consdata != NULL);
3862
3863 consdataSort(consdata);
3864
3865 if( binvars != NULL )
3866 *binvars = consdata->binvars;
3867 if( vals != NULL )
3868 *vals = consdata->vals;
3869 if( nbinvars != NULL )
3870 *nbinvars = consdata->nbinvars;
3871
3872 return SCIP_OKAY;
3873}
SCIP_VAR ** b
Definition: circlepacking.c:65
static SCIP_RETCODE aggregateVariables(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nfixedvars, int *naggrvars)
Constraint handler for linear constraints in their most general form, .
static SCIP_DECL_CONSRESPROP(consRespropLinking)
static SCIP_RETCODE consdataLinearize(SCIP *scip, SCIP_CONS *cons, SCIP_CONSDATA *consdata)
Definition: cons_linking.c:389
static SCIP_RETCODE consdataPrint(SCIP *scip, SCIP_CONSDATA *consdata, FILE *file)
Definition: cons_linking.c:232
static SCIP_DECL_CONSENFORELAX(consEnforelaxLinking)
#define CONSHDLR_NEEDSCONS
Definition: cons_linking.c:99
#define CONSHDLR_SEPAFREQ
Definition: cons_linking.c:93
static SCIP_RETCODE analyzeConflict(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *linkvar, SCIP_VAR *binvar, SCIP_Bool lblinkvar, SCIP_Bool ublinkvar)
Definition: cons_linking.c:676
static SCIP_RETCODE enforcePseudo(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, SCIP_Bool *infeasible, int *nchgbds, SCIP_Bool *solvelp)
static SCIP_DECL_CONSHDLRCOPY(conshdlrCopyLinking)
#define CONSHDLR_CHECKPRIORITY
Definition: cons_linking.c:92
static SCIP_DECL_CONSDEACTIVE(consDeactiveLinking)
static SCIP_RETCODE addCuts(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff)
#define CONSHDLR_DESC
Definition: cons_linking.c:85
static SCIP_RETCODE catchAllEvents(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linking.c:336
static SCIP_RETCODE consFixLinkvar(SCIP *scip, SCIP_CONS *cons, int pos, SCIP_Bool *cutoff)
Definition: cons_linking.c:724
static SCIP_RETCODE dropEvent(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr, int pos)
Definition: cons_linking.c:305
static SCIP_RETCODE dropAllEvents(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linking.c:362
static SCIP_RETCODE removeFixedBinvars(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_CONS *cons)
#define CONSHDLR_PROP_TIMING
Definition: cons_linking.c:101
static SCIP_DECL_CONSINITSOL(consInitsolLinking)
static SCIP_DECL_CONSTRANS(consTransLinking)
static SCIP_DECL_CONSENFOPS(consEnfopsLinking)
static void conshdlrdataFree(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata)
Definition: cons_linking.c:214
static SCIP_RETCODE processBinvarFixings(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool *addcut, SCIP_Bool *mustcheck)
static void * getHashmapKey(SCIP_VAR *var)
Definition: cons_linking.c:146
#define CONSHDLR_MAXPREROUNDS
Definition: cons_linking.c:96
static SCIP_RETCODE lockRounding(SCIP *scip, SCIP_CONS *cons, SCIP_VAR **binvars, int nbinvars)
Definition: cons_linking.c:172
static SCIP_Bool checkCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol)
#define CONSHDLR_SEPAPRIORITY
Definition: cons_linking.c:90
static SCIP_DECL_CONSPRINT(consPrintLinking)
static SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH(consGetSignedPermsymGraphLinking)
static SCIP_DECL_CONSENABLE(consEnableLinking)
#define DEFAULT_LINEARIZE
Definition: cons_linking.c:106
static SCIP_DECL_CONSACTIVE(consActiveLinking)
static SCIP_RETCODE addSymmetryInformation(SCIP *scip, SYM_SYMTYPE symtype, SCIP_CONS *cons, SYM_GRAPH *graph, SCIP_Bool *success)
static SCIP_DECL_CONSEXITSOL(consExitsolLinking)
static SCIP_RETCODE catchEvent(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr, int pos)
Definition: cons_linking.c:273
static SCIP_RETCODE processRealBoundChg(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *cutoff, int *nchgbds, SCIP_Bool *mustcheck)
Definition: cons_linking.c:781
static SCIP_RETCODE consdataCreate(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_CONSDATA **consdata, SCIP_VAR *linkvar, SCIP_VAR **binvars, SCIP_Real *vals, int nbinvars)
Definition: cons_linking.c:531
static SCIP_RETCODE consdataCreateBinvars(SCIP *scip, SCIP_CONS *cons, SCIP_CONSDATA *consdata, SCIP_EVENTHDLR *eventhdlr, SCIP_Bool linearize)
Definition: cons_linking.c:428
static SCIP_DECL_EVENTEXEC(eventExecBinvar)
static SCIP_DECL_CONSGETVARS(consGetVarsLinking)
static SCIP_DECL_CONSSEPALP(consSepalpLinking)
static SCIP_DECL_CONSCHECK(consCheckLinking)
static SCIP_DECL_CONSPARSE(consParseLinking)
static SCIP_DECL_CONSPRESOL(consPresolLinking)
static SCIP_RETCODE tightenedLinkvar(SCIP *scip, SCIP_CONS *cons, SCIP_CONSDATA *consdata, SCIP_Bool *cutoff, int *nchgbds)
static SCIP_DECL_CONSPROP(consPropLinking)
#define CONSHDLR_PROPFREQ
Definition: cons_linking.c:94
static SCIP_RETCODE createRows(SCIP *scip, SCIP_CONS *cons)
static SCIP_DECL_CONSINITLP(consInitlpLinking)
static SCIP_DECL_CONSCOPY(consCopyLinking)
#define CONSHDLR_PRESOLTIMING
Definition: cons_linking.c:102
static SCIP_RETCODE delCoefPos(SCIP *scip, SCIP_EVENTHDLR *eventhdlr, SCIP_CONS *cons, int pos)
Definition: cons_linking.c:981
static SCIP_RETCODE enforceConstraint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss, int nusefulconss, SCIP_SOL *sol, SCIP_RESULT *result)
static SCIP_RETCODE consdataFree(SCIP *scip, SCIP_CONSDATA **consdata)
Definition: cons_linking.c:616
static void consdataSort(SCIP_CONSDATA *consdata)
Definition: cons_linking.c:156
static SCIP_RETCODE addNlrow(SCIP *scip, SCIP_CONS *cons)
static SCIP_RETCODE separateCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool *cutoff, SCIP_Bool *separated, int *nchgbds)
#define CONSHDLR_EAGERFREQ
Definition: cons_linking.c:95
#define EVENTHDLR_DESC
Definition: cons_linking.c:88
static SCIP_RETCODE conshdlrdataCreate(SCIP *scip, SCIP_CONSHDLRDATA **conshdlrdata, SCIP_EVENTHDLR *eventhdlr)
Definition: cons_linking.c:191
#define CONSHDLR_ENFOPRIORITY
Definition: cons_linking.c:91
static SCIP_DECL_CONSGETPERMSYMGRAPH(consGetPermsymGraphLinking)
#define CONSHDLR_DELAYSEPA
Definition: cons_linking.c:97
static SCIP_DECL_CONSLOCK(consLockLinking)
static SCIP_DECL_CONSENFOLP(consEnfolpLinking)
#define HASHSIZE_BINVARSCONS
Definition: cons_linking.c:105
#define CONSHDLR_NAME
Definition: cons_linking.c:84
#define EVENTHDLR_NAME
Definition: cons_linking.c:87
static SCIP_DECL_CONSDELETE(consDeleteLinking)
static SCIP_DECL_CONSINITPRE(consInitpreLinking)
static SCIP_DECL_CONSFREE(consFreeLinking)
static SCIP_DECL_CONSSEPASOL(consSepasolLinking)
static SCIP_DECL_CONSGETNVARS(consGetNVarsLinking)
#define CONSHDLR_DELAYPROP
Definition: cons_linking.c:98
constraint handler for linking binary variables to a linking (continuous or integer) variable
Constraint handler for the set partitioning / packing / covering constraints .
#define NULL
Definition: def.h:266
#define SCIP_MAXSTRLEN
Definition: def.h:287
#define SCIP_Bool
Definition: def.h:91
#define MIN(x, y)
Definition: def.h:242
#define SCIP_Real
Definition: def.h:172
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define MAX(x, y)
Definition: def.h:238
#define SCIPABORT()
Definition: def.h:345
#define REALABS(x)
Definition: def.h:196
#define SCIP_CALL(x)
Definition: def.h:373
int SCIPgetNBinvarsLinking(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPgetBinvarsLinking(SCIP *scip, SCIP_CONS *cons, SCIP_VAR ***binvars, int *nbinvars)
SCIP_Bool SCIPexistsConsLinking(SCIP *scip, SCIP_VAR *linkvar)
SCIP_VAR * SCIPgetLinkvarLinking(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPaddCoefLinear(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *var, SCIP_Real val)
SCIP_CONS * SCIPgetConsLinking(SCIP *scip, SCIP_VAR *linkvar)
SCIP_RETCODE SCIPcreateConsLinking(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *linkvar, SCIP_VAR **binvars, SCIP_Real *vals, int nbinvars, 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_RETCODE SCIPcreateConsLinear(SCIP *scip, SCIP_CONS **cons, const char *name, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real lhs, SCIP_Real rhs, 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_RETCODE SCIPcreateConsSetpart(SCIP *scip, SCIP_CONS **cons, const char *name, 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_setppc.c:9368
SCIP_RETCODE SCIPcreateConsBasicLinking(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *linkvar, SCIP_VAR **binvars, SCIP_Real *vals, int nbinvars)
SCIP_Real * SCIPgetValsLinking(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPgetBinvarsDataLinking(SCIP_CONS *cons, SCIP_VAR ***binvars, SCIP_Real **vals, int *nbinvars)
SCIP_RETCODE SCIPincludeConshdlrLinking(SCIP *scip)
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)
Definition: scip_general.c:606
SCIP_Bool SCIPisStopped(SCIP *scip)
Definition: scip_general.c:734
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:390
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1668
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
void SCIPhashmapFree(SCIP_HASHMAP **hashmap)
Definition: misc.c:3111
void * SCIPhashmapGetImage(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3264
SCIP_RETCODE SCIPhashmapInsert(SCIP_HASHMAP *hashmap, void *origin, void *image)
Definition: misc.c:3159
SCIP_RETCODE SCIPhashmapCreate(SCIP_HASHMAP **hashmap, BMS_BLKMEM *blkmem, int mapsize)
Definition: misc.c:3077
SCIP_Bool SCIPhashmapExists(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3426
SCIP_RETCODE SCIPhashmapRemove(SCIP_HASHMAP *hashmap, void *origin)
Definition: misc.c:3442
SCIP_RETCODE SCIPdelConsLocal(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:3475
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
#define SCIPdebugMsg
Definition: scip_message.h:78
SCIP_Real SCIPrelDiff(SCIP_Real val1, SCIP_Real val2)
Definition: misc.c:11215
SCIP_RETCODE SCIPaddBoolParam(SCIP *scip, const char *name, const char *desc, SCIP_Bool *valueptr, SCIP_Bool isadvanced, SCIP_Bool defaultvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition: scip_param.c:57
SCIP_RETCODE SCIPaddConflictLb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
SCIP_RETCODE SCIPinitConflictAnalysis(SCIP *scip, SCIP_CONFTYPE conftype, SCIP_Bool iscutoffinvolved)
SCIP_RETCODE SCIPaddConflictUb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
SCIP_Bool SCIPisConflictAnalysisApplicable(SCIP *scip)
SCIP_RETCODE SCIPaddConflictBinvar(SCIP *scip, SCIP_VAR *var)
SCIP_RETCODE SCIPanalyzeConflictCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success)
SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
Definition: scip_cons.c:808
SCIP_RETCODE SCIPsetConshdlrEnable(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENABLE((*consenable)))
Definition: scip_cons.c:716
SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
Definition: scip_cons.c:540
SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETVARS((*consgetvars)))
Definition: scip_cons.c:831
SCIP_RETCODE SCIPsetConshdlrInitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITPRE((*consinitpre)))
Definition: scip_cons.c:492
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 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 SCIPsetConshdlrDeactive(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDEACTIVE((*consdeactive)))
Definition: scip_cons.c:693
SCIP_RETCODE SCIPsetConshdlrGetPermsymGraph(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETPERMSYMGRAPH((*consgetpermsymgraph)))
Definition: scip_cons.c:900
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
Definition: scip_cons.c:578
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
Definition: scip_cons.c:372
SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
Definition: scip_cons.c:323
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4197
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
Definition: scip_cons.c:347
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:941
SCIP_RETCODE SCIPsetConshdlrGetSignedPermsymGraph(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH((*consgetsignedpermsymgraph)))
Definition: scip_cons.c:924
SCIP_RETCODE SCIPsetConshdlrExitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSEXITSOL((*consexitsol)))
Definition: scip_cons.c:468
SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
Definition: scip_cons.c:624
SCIP_RETCODE SCIPsetConshdlrInitsol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITSOL((*consinitsol)))
Definition: scip_cons.c:444
SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4217
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
Definition: scip_cons.c:601
SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
Definition: scip_cons.c:647
SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETNVARS((*consgetnvars)))
Definition: scip_cons.c:854
SCIP_RETCODE SCIPsetConshdlrActive(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSACTIVE((*consactive)))
Definition: scip_cons.c:670
SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
Definition: scip_cons.c:785
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_RETCODE SCIPenableCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_cons.c:1838
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 SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:8523
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
SCIP_Bool SCIPconsIsEnabled(SCIP_CONS *cons)
Definition: cons.c:8311
SCIP_RETCODE SCIPdisableCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_cons.c:1872
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 SCIPconsIsAdded(SCIP_CONS *cons)
Definition: cons.c:8643
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
const char * SCIPeventhdlrGetName(SCIP_EVENTHDLR *eventhdlr)
Definition: event.c:324
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
SCIP_Bool SCIPhasCurrentNodeLP(SCIP *scip)
Definition: scip_lp.c:83
#define SCIPfreeBlockMemoryArray(scip, ptr, num)
Definition: scip_mem.h:110
#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 SCIPfreeBufferArrayNull(scip, ptr)
Definition: scip_mem.h:137
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip_mem.h:89
#define SCIPduplicateBlockMemoryArray(scip, ptr, source, num)
Definition: scip_mem.h:105
SCIP_RETCODE SCIPdelNlRow(SCIP *scip, SCIP_NLROW *nlrow)
Definition: scip_nlp.c:424
SCIP_RETCODE SCIPaddNlRow(SCIP *scip, SCIP_NLROW *nlrow)
Definition: scip_nlp.c:396
SCIP_Bool SCIPisNLPConstructed(SCIP *scip)
Definition: scip_nlp.c:110
SCIP_RETCODE SCIPaddLinearCoefToNlRow(SCIP *scip, SCIP_NLROW *nlrow, SCIP_VAR *var, SCIP_Real val)
Definition: scip_nlp.c:1161
SCIP_RETCODE SCIPreleaseNlRow(SCIP *scip, SCIP_NLROW **nlrow)
Definition: scip_nlp.c:1058
SCIP_Bool SCIPnlrowIsInNLP(SCIP_NLROW *nlrow)
Definition: nlp.c:1956
SCIP_RETCODE SCIPcreateNlRow(SCIP *scip, SCIP_NLROW **nlrow, const char *name, SCIP_Real constant, int nlinvars, SCIP_VAR **linvars, SCIP_Real *lincoefs, SCIP_EXPR *expr, SCIP_Real lhs, SCIP_Real rhs, SCIP_EXPRCURV curvature)
Definition: scip_nlp.c:954
SCIP_Bool SCIPinProbing(SCIP *scip)
Definition: scip_probing.c:97
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_RETCODE SCIPreleaseRow(SCIP *scip, SCIP_ROW **row)
Definition: scip_lp.c:1562
SCIP_Real SCIPgetRowLPFeasibility(SCIP *scip, SCIP_ROW *row)
Definition: scip_lp.c:2010
SCIP_Bool SCIProwIsInLP(SCIP_ROW *row)
Definition: lp.c:17523
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1213
void SCIPupdateSolLPConsViolation(SCIP *scip, SCIP_SOL *sol, SCIP_Real absviol, SCIP_Real relviol)
Definition: scip_sol.c:137
SCIP_Bool SCIPisFeasGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasZero(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasNegative(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisFeasLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisFeasIntegral(SCIP *scip, SCIP_Real val)
SCIP_Real SCIPfeastol(SCIP *scip)
SCIP_Bool SCIPisGT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
int SCIPconvertRealToInt(SCIP *scip, SCIP_Real real)
SCIP_Bool SCIPisLT(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPinRepropagation(SCIP *scip)
Definition: scip_tree.c:146
int SCIPgetDepth(SCIP *scip)
Definition: scip_tree.c:672
SCIP_RETCODE SCIPlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4474
SCIP_Bool SCIPvarIsActive(SCIP_VAR *var)
Definition: var.c:17747
SCIP_Bool SCIPvarIsBinary(SCIP_VAR *var)
Definition: var.c:17598
SCIP_RETCODE SCIPaddClique(SCIP *scip, SCIP_VAR **vars, SCIP_Bool *values, int nvars, SCIP_Bool isequation, SCIP_Bool *infeasible, int *nbdchgs)
Definition: scip_var.c:7044
SCIP_RETCODE SCIPgetTransformedVars(SCIP *scip, int nvars, SCIP_VAR **vars, SCIP_VAR **transvars)
Definition: scip_var.c:1480
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17537
SCIP_Real SCIPvarGetAggrConstant(SCIP_VAR *var)
Definition: var.c:17833
SCIP_Real SCIPvarGetUbLocal(SCIP_VAR *var)
Definition: var.c:18143
SCIP_Bool SCIPvarIsTransformed(SCIP_VAR *var)
Definition: var.c:17560
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:8524
SCIP_RETCODE SCIPinferVarUbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5738
SCIP_Real SCIPvarGetAggrScalar(SCIP_VAR *var)
Definition: var.c:17821
SCIP_VAR * SCIPvarGetProbvar(SCIP_VAR *var)
Definition: var.c:12217
SCIP_RETCODE SCIPparseVarName(SCIP *scip, const char *str, SCIP_VAR **var, char **endptr)
Definition: scip_var.c:533
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:17583
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:18087
int SCIPvarGetIndex(SCIP_VAR *var)
Definition: var.c:17757
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition: scip_var.c:4382
SCIP_RETCODE SCIPunlockVarCons(SCIP *scip, SCIP_VAR *var, SCIP_CONS *cons, SCIP_Bool lockdown, SCIP_Bool lockup)
Definition: scip_var.c:4560
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2128
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17418
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1248
SCIP_RETCODE SCIPparseVarsLinearsum(SCIP *scip, const char *str, SCIP_VAR **vars, SCIP_Real *vals, int *nvars, int varssize, int *requiredsize, char **endptr, SCIP_Bool *success)
Definition: scip_var.c:704
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:18133
SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: scip_var.c:114
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:18077
SCIP_RETCODE SCIPfixVar(SCIP *scip, SCIP_VAR *var, SCIP_Real fixedval, SCIP_Bool *infeasible, SCIP_Bool *fixed)
Definition: scip_var.c:8399
SCIP_RETCODE SCIPinferVarLbCons(SCIP *scip, SCIP_VAR *var, SCIP_Real newbound, SCIP_CONS *infercons, int inferinfo, SCIP_Bool force, SCIP_Bool *infeasible, SCIP_Bool *tightened)
Definition: scip_var.c:5624
SCIP_Real SCIPgetVarLbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:1992
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:5846
SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
Definition: scip_var.c:230
SCIP_RETCODE SCIPwriteVarsLinearsum(SCIP *scip, FILE *file, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Bool type)
Definition: scip_var.c:343
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:1439
SCIP_RETCODE SCIPcaptureVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_var.c:1214
SCIP_VAR * SCIPvarGetAggrVar(SCIP_VAR *var)
Definition: var.c:17809
void SCIPsortRealPtr(SCIP_Real *realarray, void **ptrarray, int len)
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10880
SCIP_RETCODE SCIPskipSpace(char **s)
Definition: misc.c:10869
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)
memory allocation routines
#define BMScopyMemoryArray(ptr, source, num)
Definition: memory.h:134
BMS_BLKMEM * SCIPblkmem(SCIP *scip)
Definition: scip_mem.c:57
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
public data structures and miscellaneous methods
methods for sorting joint arrays of various types
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 nonlinear relaxation
public methods for numerical tolerances
public methods for SCIP parameter handling
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
Definition: type_conflict.h:60
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition: type_cons.h:64
struct SCIP_ConsData SCIP_CONSDATA
Definition: type_cons.h:65
#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_EVENTTYPE_LBRELAXED
Definition: type_event.h:78
uint64_t SCIP_EVENTTYPE
Definition: type_event.h:151
#define SCIP_EVENTTYPE_LBTIGHTENED
Definition: type_event.h:77
#define SCIP_EVENTTYPE_UBRELAXED
Definition: type_event.h:80
@ SCIP_EXPRCURV_LINEAR
Definition: type_expr.h:65
@ SCIP_BOUNDTYPE_UPPER
Definition: type_lp.h:57
@ SCIP_BOUNDTYPE_LOWER
Definition: type_lp.h:56
@ SCIP_DIDNOTRUN
Definition: type_result.h:42
@ 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_SOLVELP
Definition: type_result.h:55
@ 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
Definition: type_retcode.h:52
@ SCIP_PLUGINNOTFOUND
Definition: type_retcode.h:54
@ SCIP_OKAY
Definition: type_retcode.h:42
@ SCIP_ERROR
Definition: type_retcode.h:43
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ SCIP_STAGE_PRESOLVING
Definition: type_set.h:49
@ SCIP_STAGE_SOLVING
Definition: type_set.h:53
@ SCIP_STAGE_TRANSFORMING
Definition: type_set.h:46
enum SYM_Symtype SYM_SYMTYPE
Definition: type_symmetry.h:64
@ SYM_SYMTYPE_SIGNPERM
Definition: type_symmetry.h:62
@ SYM_SYMTYPE_PERM
Definition: type_symmetry.h:61
@ SCIP_VARTYPE_CONTINUOUS
Definition: type_var.h:71
@ SCIP_VARTYPE_BINARY
Definition: type_var.h:62
@ SCIP_VARSTATUS_FIXED
Definition: type_var.h:52
@ SCIP_VARSTATUS_COLUMN
Definition: type_var.h:51
@ SCIP_VARSTATUS_MULTAGGR
Definition: type_var.h:54
@ SCIP_VARSTATUS_NEGATED
Definition: type_var.h:55
@ SCIP_VARSTATUS_AGGREGATED
Definition: type_var.h:53
@ SCIP_VARSTATUS_LOOSE
Definition: type_var.h:50
@ SCIP_LOCKTYPE_MODEL
Definition: type_var.h:97