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