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