SCIP Doxygen Documentation
Loading...
Searching...
No Matches
cons_superindicator.c
Go to the documentation of this file.
1/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2/* */
3/* This file is part of the program and library */
4/* SCIP --- Solving Constraint Integer Programs */
5/* */
6/* Copyright (c) 2002-2026 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file cons_superindicator.c
26 * @ingroup DEFPLUGINS_CONS
27 * @brief constraint handler for indicator constraints over arbitrary constraint types
28 * @author Ambros Gleixner
29 * @author Frederic Pythoud
30 */
31
32/**@todo allow more types for slack constraint */
33/**@todo implement more upgrades, e.g., for nonlinear, quadratic, logicor slack constraints; upgrades could also help to
34 * handle difficult slack constraints such as pseudoboolean or indicator
35 */
36/**@todo unify enfolp and enfops, sepalp and sepaps callbacks */
37/**@todo enforce by branching on binary variable if slack constraint only returns SCIP_INFEASIBLE */
38/**@todo consider enforcing by adding slack constraint (or copy of it) locally if binary variable is fixed to 1
39 * (some constraint handler cannot enforce constraints that are not active)
40 */
41
42/*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
43
45#include "scip/cons_indicator.h"
46#include "scip/cons_linear.h"
48#include "scip/dialog_default.h"
49#include "scip/pub_cons.h"
50#include "scip/pub_dialog.h"
51#include "scip/pub_heur.h"
52#include "scip/pub_message.h"
53#include "scip/pub_misc.h"
54#include "scip/pub_sol.h"
55#include "scip/pub_var.h"
56#include "scip/scip_conflict.h"
57#include "scip/scip_cons.h"
58#include "scip/scip_copy.h"
59#include "scip/scip_dialog.h"
60#include "scip/scip_general.h"
61#include "scip/scip_mem.h"
62#include "scip/scip_message.h"
63#include "scip/scip_numerics.h"
64#include "scip/scip_param.h"
65#include "scip/scip_prob.h"
66#include "scip/scip_sol.h"
67#include "scip/scip_var.h"
68#include "scip/symmetry_graph.h"
69
70
71/* constraint handler properties */
72#define CONSHDLR_NAME "superindicator"
73#define CONSHDLR_DESC "constraint handler for indicator constraints over arbitrary constraint types"
74#define CONSHDLR_SEPAPRIORITY 0 /**< priority of the constraint handler for separation */
75#define CONSHDLR_ENFOPRIORITY -5000000 /**< priority of the constraint handler for constraint enforcing */
76#define CONSHDLR_CHECKPRIORITY -5000000 /**< priority of the constraint handler for checking feasibility */
77#define CONSHDLR_SEPAFREQ -1 /**< frequency for separating cuts; zero means to separate only in the root node */
78#define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
79#define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
80 * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
81#define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler
82 * participates in (-1: no limit) */
83#define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
84#define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
85#define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
86
87#define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP /**< propagation timing mask of the constraint handler */
88#define CONSHDLR_PRESOLTIMING SCIP_PRESOLTIMING_MEDIUM /**< presolving timing of the constraint handler (fast, medium, or exhaustive) */
89
90#define DEFAULT_CHECKSLACKTYPE TRUE /**< should type of slack constraint be checked when creating superindicator constraint? */
91#define DEFAULT_UPGDPRIOINDICATOR 1 /**< priority for upgrading to an indicator constraint (-1: never) */
92#define DEFAULT_UPGDPRIOLINEAR 2 /**< priority for upgrading to a linear constraint (-1: never) */
93#define DEFAULT_MAXUPGDCOEFLINEAR 1e4 /**< maximum big-M coefficient of binary variable in upgrade to a linear constraint
94 * (relative to smallest coefficient) */
95
96
97/*
98 * Data structures
99 */
100
101/** constraint data for superindicator constraints */
102struct SCIP_ConsData
103{
104 SCIP_CONS* slackcons; /**< constraint corresponding to the handled constraint */
105 SCIP_VAR* binvar; /**< binary variable for indicator constraint */
106};
107
108/** constraint handler data */
109struct SCIP_ConshdlrData
110{
111 SCIP_Bool checkslacktype; /**< should type of slack constraint be checked when creating superindicator constraint? */
112 SCIP_Real maxupgdcoeflinear; /**< maximum big-M coefficient of binary variable in upgrade to a linear constraint
113 * (relative to smallest coefficient) */
114 int upgdprioindicator; /**< priority for upgrading to an indicator constraint (-1: never) */
115 int upgdpriolinear; /**< priority for upgrading to a linear constraint (-1: never) */
116 int nrejects; /**< number of rejected calls to create method */
117};
118
119/*
120 * Local methods
121 */
122
123/** creates superindicator constraint data */
124static
126 SCIP* scip, /**< SCIP data structure */
127 SCIP_CONSDATA** consdata, /**< pointer to constraint data */
128 SCIP_VAR* binvar, /**< binary variable */
129 SCIP_CONS* slackcons /**< slack constraint */
130 )
131{
132 assert(scip != NULL);
133
134 SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
135
136 (*consdata)->binvar = binvar;
137 (*consdata)->slackcons = slackcons;
138
140 {
141 SCIPdebugMsg(scip, "creating the transformed data\n");
142
143 /* do not capture the slack constraint when scip is in transformed mode; this automatically happens in
144 * SCIPtransformCons() if necessary
145 */
146 SCIP_CALL( SCIPtransformCons(scip, (*consdata)->slackcons, &(*consdata)->slackcons) );
147
148 /* get transformed binary variable */
149 SCIP_CALL( SCIPgetTransformedVar(scip, (*consdata)->binvar, &(*consdata)->binvar) );
150 }
151 else
152 {
153 /* we need to capture the constraint to avoid that SCIP deletes them since they are not (yet) added to the problem */
154 SCIP_CALL( SCIPcaptureCons(scip, slackcons) );
155 }
156
157 assert((*consdata)->slackcons != NULL);
158
159 return SCIP_OKAY;
160}
161
162/** checks the feasibility of a superindicator constraint */
163static
165 SCIP* scip, /**< SCIP data structure */
166 SCIP_CONSDATA* consdata, /**< pointer to superindicator constraint data */
167 SCIP_SOL* sol, /**< pointer to the solution to be checked */
168 SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
169 SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
170 SCIP_Bool printreason, /**< Should the reason for the violation be printed? */
171 SCIP_RESULT* result /**< pointer to store the result of the test */
172 )
173{
174 SCIP_Real binval;
175
176 /* not to be called if infeasibility is already detected */
178
179 binval = SCIPgetSolVal(scip, sol, consdata->binvar);
180
181 /* check integrality of binary variable */
182 if( checkintegrality && !SCIPisIntegral(scip, binval) )
183 {
184 if( printreason )
185 {
186 SCIPinfoMessage(scip, NULL, "violation: binvar takes fractional value %.15g\n", binval);
187 }
188
190 }
191 /* if binvar is one, call SCIPcheckCons() for the slack constraint */
192 else if( binval > 0.5 )
193 {
194 assert(SCIPisFeasEQ(scip, binval, 1.0));
195
196 SCIP_CALL( SCIPcheckCons(scip, consdata->slackcons, sol, checkintegrality, checklprows, printreason, result) );
197
198 if( printreason && *result != SCIP_FEASIBLE )
199 {
200 SCIPinfoMessage(scip, NULL, "violation: SCIPcheckCons() for slack constraint <%s> returns infeasible while binvar <%s> == 1\n",
201 SCIPconsGetName(consdata->slackcons), SCIPvarGetName(consdata->binvar));
202 }
203
204#ifdef SCIP_DEBUG
205 {
206 /* checking in debug mode that different flags don't give us different results */
207 SCIP_RESULT testresultnotintegrality;
208 SCIP_RESULT testresultnotlprows;
209
210 SCIP_CALL( SCIPcheckCons(scip, consdata->slackcons, sol, checkintegrality, TRUE, TRUE, &testresultnotintegrality) );
211 SCIP_CALL( SCIPcheckCons(scip, consdata->slackcons, sol, TRUE, checklprows, TRUE, &testresultnotlprows) );
212
213 assert(*result == testresultnotintegrality);
214 assert(*result == testresultnotlprows);
215 }
216#endif
217
218 SCIPdebugMsg(scip, "binvar <%s> == 1, sol=%p --> SCIPcheckCons() on constraint <%s> --> %s\n",
219 SCIPvarGetName(consdata->binvar), (void*)sol, SCIPconsGetName(consdata->slackcons),
220 *result == SCIP_FEASIBLE ? "satisfied" : "violated");
221 }
222 /* if binval is zero, the superindicator constraint is feasible */
223 else
224 {
226 }
227
228 return SCIP_OKAY;
229}
230
231/** computes the minactivity, maxactivity, and minimal absolute value of nonzero coefficients of a linear constraint
232 * with respect to its global bounds
233 */
234static
236 SCIP* scip, /**< SCIP data structure */
237 SCIP_CONS* cons, /**< pointer to linear constraint */
238 SCIP_Real* minactivity, /**< pointer to return the minimal activity */
239 SCIP_Real* maxactivity, /**< pointer to return the maximal activity */
240 SCIP_Real* minabscoef /**< pointer to return the minimal absolute value of the coefficients */
241 )
242{
243 SCIP_VAR** vars;
244 SCIP_Real* vals;
245 SCIP_Bool ismininfinity;
246 SCIP_Bool ismaxinfinity;
247 int nvars;
248 int i;
249
250 assert(scip != NULL);
251 assert(cons != NULL);
252 assert(minactivity != NULL);
253 assert(maxactivity != NULL);
254 assert(minabscoef != NULL);
255
256 /* get nonzero elements */
257 vars = SCIPgetVarsLinear(scip, cons);
258 vals = SCIPgetValsLinear(scip, cons);
260
261 /* initialize values */
262 *minactivity = 0.0;
263 *maxactivity = 0.0;
264 *minabscoef = SCIPinfinity(scip);
265 ismininfinity = FALSE;
266 ismaxinfinity = FALSE;
267
268 /* we loop over all the coefficients of the constraint and we cannot end if the minactivity is infinite as we
269 * still need to compute the minimum absolute coefficient value
270 */
271 for( i = nvars-1; i >= 0; i-- )
272 {
273 SCIP_Real val;
274 SCIP_Real lb;
275 SCIP_Real ub;
276
277 val = vals[i];
280
281 /* update flags for infinite bounds */
282 ismininfinity = ismininfinity || (val > 0.0 && (SCIPisInfinity(scip, lb) || SCIPisInfinity(scip, -lb)))
283 || (val < 0.0 && (SCIPisInfinity(scip, ub) || SCIPisInfinity(scip, -ub)));
284
285 ismaxinfinity = ismaxinfinity || (val > 0.0 && (SCIPisInfinity(scip, ub) || SCIPisInfinity(scip, -ub)))
286 || (val < 0.0 && (SCIPisInfinity(scip, lb) || SCIPisInfinity(scip, -lb)));
287
288 /* update activities if not infinite */
289 if( !ismininfinity )
290 *minactivity += (val > 0.0) ? val * lb : val * ub;
291
292 if( !ismaxinfinity )
293 *maxactivity += (val > 0.0) ? val * ub : val * lb;
294
295 /* update minimal absolute coefficient value */
296 if( val > 0.0 && val < *minabscoef )
297 *minabscoef = val;
298 else if( val < 0.0 && -val < *minabscoef )
299 *minabscoef = -vals[i];
300 }
301
302 if( ismininfinity )
303 *minactivity = -SCIPinfinity(scip);
304
305 if( ismaxinfinity )
306 *maxactivity = SCIPinfinity(scip);
307}
308
309/** tries to upgrade superindicator constraint to an indicator constraint */
310static
312 SCIP* scip, /**< SCIP data structure */
313 SCIP_CONS* cons, /**< superindicator constraint to be upgraded */
314 SCIP_Bool* success, /**< pointer to store if the upgrading was successful */
315 SCIP_Bool* deleted /**< pointer to store if the constraint was deleted */
316 )
317{
318 SCIP_CONSHDLR* conshdlr;
319 SCIP_CONSDATA* consdata;
320 SCIP_CONS* indcons;
321
322 SCIP_Real lhs;
323 SCIP_Real rhs;
324 char name[SCIP_MAXSTRLEN];
325 int i;
326
327#ifdef SCIP_DEBUG
328 int nnewconss;
329#endif
330
331 assert(scip != NULL);
332 assert(cons != NULL);
333 assert(success != NULL);
334 assert(deleted != NULL);
335
336 *success = FALSE;
337 *deleted = FALSE;
338
339 SCIPdebug( nnewconss = 0 );
340
341 /* get data of superindicator constraint */
342 consdata = SCIPconsGetData(cons);
343 assert(consdata != NULL);
344
345 /* upgrade only for linear slack constraint */
346 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(consdata->slackcons)), "linear") != 0 )
347 return SCIP_OKAY;
348
349 /* upgrade only if indicator constraint handler found */
350 conshdlr = SCIPfindConshdlr(scip, "indicator");
351 if( conshdlr == NULL )
352 return SCIP_OKAY;
353
354 /* if linear slack constraint is free we can delete the superindicator constraint */
355 lhs = SCIPgetLhsLinear(scip, consdata->slackcons);
356 rhs = SCIPgetRhsLinear(scip, consdata->slackcons);
357 if( SCIPisInfinity(scip, -lhs) && SCIPisInfinity(scip, rhs) )
358 {
359 SCIP_CALL( SCIPdelCons(scip, cons) );
360 *deleted = TRUE;
361
362 SCIPdebugMsg(scip, "constraint <%s> deleted because of free slack constraint\n", SCIPconsGetName(cons));
363
364 return SCIP_OKAY;
365 }
366
367 /* upgrade rhs inequality */
368 if( !SCIPisInfinity(scip, rhs) )
369 {
370 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_upgd_indrhs", SCIPconsGetName(cons));
371
372 SCIP_CALL( SCIPcreateConsIndicator(scip, &indcons, name, consdata->binvar, SCIPgetNVarsLinear(scip, consdata->slackcons),
373 SCIPgetVarsLinear(scip, consdata->slackcons), SCIPgetValsLinear(scip, consdata->slackcons), rhs,
377
378 SCIP_CALL( SCIPaddCons(scip, indcons) );
379 SCIP_CALL( SCIPreleaseCons(scip, &indcons) );
380
381 SCIPdebug( nnewconss++ );
382 }
383
384 /* upgrade lhs inequality */
385 if( !SCIPisInfinity(scip, -lhs) )
386 {
387 SCIP_Real* negvals;
388 SCIP_Real* vals;
389 int nvars;
390
391 vals = SCIPgetValsLinear(scip, consdata->slackcons);
392 nvars = SCIPgetNVarsLinear(scip, consdata->slackcons);
393
394 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_upgd_indlhs", SCIPconsGetName(cons));
395
396 /* create array of negated coefficient values */
398 for( i = nvars-1; i >= 0; i-- )
399 negvals[i] = -vals[i];
400
401 SCIP_CALL( SCIPcreateConsIndicator(scip, &indcons, name, consdata->binvar, nvars,
402 SCIPgetVarsLinear(scip, consdata->slackcons), negvals, -lhs,
406
407 SCIP_CALL( SCIPaddCons(scip, indcons) );
408 SCIP_CALL( SCIPreleaseCons(scip, &indcons) );
409
410 SCIPfreeBufferArray(scip, &negvals);
411
412 SCIPdebug( nnewconss++ );
413 }
414
415 SCIPdebug( SCIPdebugMsg(scip, "constraint <%s> upgraded to %d indicator constraint%s\n",
416 SCIPconsGetName(cons), nnewconss, nnewconss == 1 ? "" : "s") );
417
418 /* delete the superindicator constraint */
419 SCIP_CALL( SCIPdelCons(scip, cons) );
420 *success = TRUE;
421
422 return SCIP_OKAY;
423}
424
425/** upgrades a superindicator constraint to a linear constraint if possible */
426static
428 SCIP* scip, /**< SCIP data structure */
429 SCIP_CONS* cons, /**< superindicator constraint to be upgraded */
430 SCIP_Bool* success, /**< pointer to store if the upgrading was successful */
431 SCIP_Bool* deleted /**< pointer to store if the constraint was deleted */
432 )
433{
434 SCIP_CONSHDLR* conshdlr;
435 SCIP_CONSDATA* consdata;
436 SCIP_CONS* slackcons;
437 SCIP_VAR** slackvars;
438 SCIP_VAR** newvars;
439 SCIP_Real* slackvals;
440 SCIP_Real* newvals;
441
442 SCIP_Real maxcoef;
443 SCIP_Real minabscoef;
444 SCIP_Real minact;
445 SCIP_Real maxact;
446 SCIP_Real lhs;
447 SCIP_Real rhs;
448
449 int nvars;
450 int i;
451
452#ifdef SCIP_DEBUG
453 int nnewconss;
454#endif
455
456 assert(scip != NULL);
457 assert(cons != NULL);
458 assert(success != NULL);
459 assert(deleted != NULL);
460
461 *success = FALSE;
462 *deleted = FALSE;
463
464 SCIPdebug( nnewconss = 0 );
465
466 /* get data of superindicator constraint */
467 consdata = SCIPconsGetData(cons);
468 assert(consdata != NULL);
469
470 slackcons = consdata->slackcons;
471 assert(slackcons != NULL);
472
473 /* upgrade only for linear slack constraint */
474 if( strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "linear") != 0 )
475 return SCIP_OKAY;
476
477 /**@todo store in conshdlrdata */
478
479 /* upgrade only if linear constraint handler found */
480 conshdlr = SCIPfindConshdlr(scip, "linear");
481 if( conshdlr == NULL )
482 return SCIP_OKAY;
483
484 /* if linear slack constraint is free we can delete the superindicator constraint */
485 rhs = SCIPgetRhsLinear(scip, slackcons);
486 lhs = SCIPgetLhsLinear(scip, slackcons);
487
488 if( SCIPisInfinity(scip, rhs) && SCIPisInfinity(scip, -lhs) )
489 {
490 SCIP_CALL( SCIPdelCons(scip, cons) );
491 *deleted = TRUE;
492
493 SCIPdebugMsg(scip, "constraint <%s> deleted because of free slack constraint\n", SCIPconsGetName(cons));
494
495 return SCIP_OKAY;
496 }
497
498 /* if linear slack constraint is redundant due to bounded activities we can delete the superindicator constraint */
499 extractLinearValues(scip, slackcons, &minact, &maxact, &minabscoef);
500 assert(!SCIPisInfinity(scip, minact));
501 assert(!SCIPisInfinity(scip, -maxact));
502
503 if( (SCIPisInfinity(scip, -lhs) || SCIPisLE(scip, lhs, minact)) && (SCIPisInfinity(scip, rhs) || SCIPisGE(scip, rhs, maxact)) )
504 {
505 SCIP_CALL( SCIPdelCons(scip, cons) );
506 *deleted = TRUE;
507
508 SCIPdebugMsg(scip, "constraint <%s> deleted because of redundant slack constraint\n", SCIPconsGetName(cons));
509
510 return SCIP_OKAY;
511 }
512
513 /* if the big-M coefficient is too large compared to the coefficients of the slack constraint, we do not upgrade to
514 * avoid numerical problems
515 */
516 maxcoef = minabscoef * SCIPconshdlrGetData(SCIPconsGetHdlr(cons))->maxupgdcoeflinear;
517
518 if( (!SCIPisInfinity(scip, rhs) && (SCIPisInfinity(scip, maxact) || SCIPisInfinity(scip, maxact - rhs) ||
519 maxact - rhs > maxcoef)) ||
520 (!SCIPisInfinity(scip, -lhs) && (SCIPisInfinity(scip, -minact) || SCIPisInfinity(scip, lhs - minact) ||
521 lhs - minact > maxcoef)) )
522 {
523 SCIPdebugMsg(scip, "constraint <%s> not upgraded to a linear constraint due to large big-M coefficient\n",
524 SCIPconsGetName(cons));
525 return SCIP_OKAY;
526 }
527
528 /* allocating memory for new constraint */
529 nvars = SCIPgetNVarsLinear(scip, slackcons);
530 SCIP_CALL( SCIPallocBufferArray(scip, &newvars, nvars+1) );
531 SCIP_CALL( SCIPallocBufferArray(scip, &newvals, nvars+1) );
532
533 /* copy the vars and the vals array */
534 slackvars = SCIPgetVarsLinear(scip, slackcons);
535 slackvals = SCIPgetValsLinear(scip, slackcons);
536
537 assert(slackvars != NULL);
538 assert(slackvals != NULL);
539
540 for( i = nvars-1; i >= 0; i-- )
541 {
542 newvars[i] = slackvars[i];
543 newvals[i] = slackvals[i];
544 }
545
546 /* add binary variable */
547 newvars[nvars] = consdata->binvar;
548 assert(newvars[nvars] != NULL);
549
550 assert(!SCIPisInfinity(scip, -lhs) || !SCIPisInfinity(scip, rhs));
551
552 /* create the upgraded constraint for rhs inequality */
553 if( !SCIPisInfinity(scip, rhs) )
554 {
555 SCIP_CONS* newcons;
556 char name[SCIP_MAXSTRLEN];
557
558 assert(!SCIPisInfinity(scip, -maxact) );
559 assert(!SCIPisInfinity(scip, maxact));
560
561 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_upgd_linrhs", SCIPconsGetName(cons));
562
563 /* compute big-M */
564 newvals[nvars] = maxact - rhs;
565 assert(!SCIPisInfinity(scip, newvals[nvars]));
566 assert(!SCIPisInfinity(scip, -newvals[nvars]));
567
568 /* rhs inequality is redundant if maxact is less equal rhs */
569 if( SCIPisPositive(scip, newvals[nvars]) )
570 {
571 SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, nvars+1, newvars, newvals, -SCIPinfinity(scip), maxact,
575
576 SCIP_CALL( SCIPaddCons(scip, newcons) );
577 SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
578
579 SCIPdebug( nnewconss++ );
580 }
581 }
582
583 /* create the upgraded constraint for rhs inequality */
584 if( !SCIPisInfinity(scip, -lhs) )
585 {
586 SCIP_CONS* newcons;
587 char name[SCIP_MAXSTRLEN];
588
589 assert(!SCIPisInfinity(scip, minact));
590 assert(!SCIPisInfinity(scip, -minact));
591
592 (void) SCIPsnprintf(name, SCIP_MAXSTRLEN, "%s_upgd_linlhs", SCIPconsGetName(cons));
593
594 /* compute big-M */
595 newvals[nvars] = minact - lhs;
596 assert(!SCIPisInfinity(scip, newvals[nvars]));
597 assert(!SCIPisInfinity(scip, -newvals[nvars]));
598
599 /* lhs inequality is redundant if minact is greater equal lhs */
600 if( SCIPisNegative(scip, newvals[nvars]) )
601 {
602 SCIP_CALL( SCIPcreateConsLinear(scip, &newcons, name, nvars+1, newvars, newvals, minact, SCIPinfinity(scip),
606
607 SCIP_CALL( SCIPaddCons(scip, newcons) );
608 SCIP_CALL( SCIPreleaseCons(scip, &newcons) );
609
610 SCIPdebug( nnewconss++ );
611 }
612 }
613
614 /* free memory */
615 SCIPfreeBufferArray(scip, &newvals);
616 SCIPfreeBufferArray(scip, &newvars);
617
618 SCIPdebug( SCIPdebugMsg(scip, "constraint <%s> upgraded to %d indicator constraint%s\n",
619 SCIPconsGetName(cons), nnewconss, nnewconss == 1 ? "" : "s") );
620
621 /* delete the superindicator constraint */
622 SCIP_CALL( SCIPdelCons(scip, cons) );
623 *success = TRUE;
624
625 return SCIP_OKAY;
626}
627
628/** tries to upgrade a superindicator constraint in order of the upgrade priority parameters */
629static
631 SCIP* scip, /**< SCIP data structure */
632 SCIP_CONS* cons, /**< superindicator constraint to be updated */
633 SCIP_Bool* success, /**< pointer to store if the constraint was upgraded */
634 SCIP_Bool* deleted /**< pointer to store if the constraint was deleted */
635 )
636{
637 SCIP_CONSHDLRDATA* conshdlrdata;
638
639 assert(scip != NULL);
640 assert(cons != NULL);
641 assert(success != NULL);
642 assert(deleted != NULL);
643
644 *success = FALSE;
645 *deleted = FALSE;
646
647 conshdlrdata = SCIPconshdlrGetData(SCIPconsGetHdlr(cons));
648
649 /* indicator upgrade before linear upgrade */
650 if( conshdlrdata->upgdprioindicator > conshdlrdata->upgdpriolinear )
651 {
652 assert(conshdlrdata->upgdprioindicator >= 0);
653
654 SCIP_CALL( upgradeIndicatorSuperindicator(scip, cons, success, deleted) );
655
656 if( !*deleted && !*success && conshdlrdata->upgdpriolinear >= 0 )
657 {
658 SCIP_CALL( upgradeLinearSuperindicator(scip, cons, success, deleted) );
659 }
660 }
661 /* linear upgrade before indicator upgrade */
662 else if( conshdlrdata->upgdpriolinear >= 0 )
663 {
664 SCIP_CALL( upgradeLinearSuperindicator(scip, cons, success, deleted) );
665
666 if( !*deleted && !*success && conshdlrdata->upgdprioindicator >= 0 )
667 {
668 SCIP_CALL( upgradeIndicatorSuperindicator(scip, cons, success, deleted) );
669 }
670 }
671
672 return SCIP_OKAY;
673}
674
675/** helper function to enforce constraints */ /*lint -e{715}*/
676static
678 SCIP* scip, /**< SCIP data structure */
679 SCIP_CONSHDLR* conshdlr, /**< constraint handler */
680 SCIP_CONS** conss, /**< constraints to process */
681 int nconss, /**< number of constraints */
682 int nusefulconss, /**< number of useful (non-obsolete) constraints to process */
683 SCIP_SOL* sol, /**< solution to enforce (NULL for the LP solution) */
684 SCIP_Bool solinfeasible, /**< was the solution already declared infeasible by a constraint handler? */
685 SCIP_RESULT* result /**< pointer to store the result of the enforcing call */
686 )
687{ /*lint --e{715}*/
688 SCIP_Bool cont;
689 int i;
690
691 assert(scip != NULL);
692 assert(conshdlr != NULL);
693 assert(result != NULL);
694
695 /* if the solution is infeasible anyway, skip the enforcement */
696 if( solinfeasible )
697 {
699 return SCIP_OKAY;
700 }
701
702 SCIPdebugMsg(scip, "executing enforcement callback for %s solution\n", sol == NULL ? "LP" : "relaxation");
703
704 cont = TRUE;
706
707#ifdef SCIP_OUTPUT
709#endif
710
711 /* check all constraints */
712 for( i = nconss-1; i >= 0 && cont; i-- )
713 {
714 SCIP_CONSDATA* consdata;
715 SCIP_RESULT locresult;
716
717 consdata = SCIPconsGetData(conss[i]);
718 assert(consdata != NULL);
719
720 locresult = SCIP_FEASIBLE;
721
722 /* enforce only if binvar is fixed to one */
723 if( SCIPvarGetLbLocal(consdata->binvar) > 0.5 )
724 {
725 assert(SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->binvar), 1.0));
726
727 if( sol == NULL )
728 {
729 SCIPdebugMsg(scip, "binvar <%s> == 1 locally --> SCIPenfolpCons() on constraint <%s>\n",
730 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
731
732 SCIP_CALL( SCIPenfolpCons(scip, consdata->slackcons, solinfeasible, &locresult) );
733 }
734 else
735 {
736 SCIPdebugMsg(scip, "binvar <%s> == 1 locally --> SCIPenforelaxCons() on constraint <%s>\n",
737 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
738
739 SCIP_CALL( SCIPenforelaxCons(scip, consdata->slackcons, sol, solinfeasible, &locresult) );
740 }
741
742 SCIPdebugPrintf(" --> %slocresult=%d\n", locresult == SCIP_FEASIBLE ? "satisfied, " : "", locresult);
743 }
744 /* otherwise check if we have not yet detected infeasibility */
745 else if( *result == SCIP_FEASIBLE )
746 {
747 SCIP_CALL( consdataCheckSuperindicator(scip, consdata, sol, TRUE, FALSE, FALSE, &locresult) );
748 }
749
750 /* evaluate result */
751 switch( locresult )
752 {
753 case SCIP_CUTOFF:
754 case SCIP_BRANCHED:
757 *result = locresult;
758 cont = FALSE;
759 break;
760 case SCIP_CONSADDED:
763 if( *result != SCIP_CUTOFF )
764 *result = locresult;
765 break;
766 case SCIP_REDUCEDDOM:
769 if( *result != SCIP_CUTOFF
770 && *result != SCIP_CONSADDED )
771 *result = locresult;
772 break;
773 case SCIP_SEPARATED:
776 if( *result != SCIP_CUTOFF
778 && *result != SCIP_REDUCEDDOM )
779 *result = locresult;
780 break;
781 case SCIP_INFEASIBLE:
784 if( *result != SCIP_CUTOFF
788 && *result != SCIP_BRANCHED )
789 *result = locresult;
790 break;
791 case SCIP_FEASIBLE:
792 break;
793 default:
794 SCIPerrorMessage("invalid SCIP result %d\n", locresult);
795 return SCIP_INVALIDRESULT;
796 } /*lint !e788*/
797 }
798
799 SCIPdebugMsg(scip, "enforcement result=%d\n", *result);
800
801 return SCIP_OKAY;
802}
803
804
805/** adds symmetry information of constraint to a symmetry detection graph */
806static
808 SCIP* scip, /**< SCIP pointer */
809 SYM_SYMTYPE symtype, /**< type of symmetries that need to be added */
810 SCIP_CONS* cons, /**< constraint */
811 SYM_GRAPH* graph, /**< symmetry detection graph */
812 SCIP_Bool* success /**< pointer to store whether symmetry information could be added */
813 )
814{
815 SYM_GRAPH* symgraph;
816 SCIP_CONSHDLR* conshdlr;
817 SCIP_CONSDATA* consdata;
818 SCIP_VAR** vars;
819 SCIP_Real* vals;
820 SCIP_Real constant;
821 int nlocvars;
822 int rootnode;
823 int subroot = -1;
824
825 assert(scip != NULL);
826 assert(cons != NULL);
827 assert(graph != NULL);
828 assert(success != NULL);
829
830 *success = TRUE;
831
832 consdata = SCIPconsGetData(cons);
833 assert(consdata != NULL);
834 assert(consdata->binvar != NULL);
835 assert(consdata->slackcons != NULL);
836
837 /* terminate if slackcons cannot provide a symmetry detection graph */
838 conshdlr = SCIPconsGetHdlr(consdata->slackcons);
839 assert(conshdlr != NULL);
840
841 if( (symtype == SYM_SYMTYPE_PERM && !SCIPconshdlrSupportsPermsymDetection(conshdlr))
843 {
844 *success = FALSE;
845 return SCIP_OKAY;
846 }
847
848 /* start building the symmetry detection graph for the superindicator constraint */
849 SCIP_CALL( SCIPaddSymgraphConsnode(scip, graph, cons, 0.0, 0.0, &rootnode) );
850
851 /* copy symmetry detection graph of slackcons, use modest estimation for graph size */
853 15, 15, 1, SCIPgetNVars(scip)) );
854
855 if( symtype == SYM_SYMTYPE_PERM )
856 {
857 SCIP_CALL( SCIPgetConsPermsymGraph(scip, consdata->slackcons, symgraph, success) );
858 }
859 else
860 {
861 assert(symtype == SYM_SYMTYPE_SIGNPERM);
862
863 SCIP_CALL( SCIPgetConsSignedPermsymGraph(scip, consdata->slackcons, symgraph, success) );
864 }
865
866 if( *success )
867 {
868 /* copy the symmetry detection graph and find its root node with index in target graph */
869 SCIP_CALL( SCIPcopySymgraphAsSubgraph(scip, symgraph, graph, consdata->slackcons, &subroot) );
870
871 if( subroot < 0 )
872 *success = FALSE;
873
874 /* connect root of superindicator constraint with root of copied graph */
875 SCIP_CALL( SCIPaddSymgraphEdge(scip, graph, rootnode, subroot, FALSE, 0.0) );
876 }
877 SCIP_CALL( SCIPfreeSymgraph(scip, &symgraph) );
878
879 if( !(*success) )
880 return SCIP_OKAY;
881
882 /* connect root node with binary variable (possibly resolve aggregation) */
885
886 vars[0] = consdata->binvar;
887 vals[0] = 1.0;
888 constant = 0.0;
889 nlocvars = 1;
890
891 SCIP_CALL( SCIPgetSymActiveVariables(scip, symtype, &vars, &vals, &nlocvars, &constant, SCIPisTransformed(scip)) );
892
893 if( nlocvars > 1 || !SCIPisEQ(scip, vals[0], 1.0) || !SCIPisZero(scip, constant) )
894 {
895 int opnodeidx;
896
897 /* encode aggregation by a sum-expression and connect it to indicator node */
898 SCIP_CALL( SCIPaddSymgraphOpnode(scip, graph, (int) SYM_CONSOPTYPE_SUM, &opnodeidx) ); /*lint !e641*/
899 SCIP_CALL( SCIPaddSymgraphEdge(scip, graph, rootnode, opnodeidx, FALSE, 0.0) );
900
901 /* add nodes and edges for variables in aggregation */
902 SCIP_CALL( SCIPaddSymgraphVarAggregation(scip, graph, opnodeidx, vars, vals, nlocvars, constant) );
903 }
904 else if( nlocvars == 1 )
905 {
906 int nodeidx;
907
908 if( symtype == SYM_SYMTYPE_SIGNPERM )
909 {
910 nodeidx = SCIPgetSymgraphVarnodeidx(scip, graph, vars[0]);
911 SCIP_CALL( SCIPaddSymgraphEdge(scip, graph, rootnode, nodeidx, TRUE, 1.0) );
912
913 nodeidx = SCIPgetSymgraphNegatedVarnodeidx(scip, graph, vars[0]);
914 SCIP_CALL( SCIPaddSymgraphEdge(scip, graph, rootnode, nodeidx, TRUE, -1.0) );
915 }
916 else
917 {
918 nodeidx = SCIPgetSymgraphVarnodeidx(scip, graph, vars[0]);
919 SCIP_CALL( SCIPaddSymgraphEdge(scip, graph, rootnode, nodeidx, TRUE, 1.0) );
920 }
921 }
924
925 return SCIP_OKAY;
926}
927
928
929/*
930 * Callback methods of constraint handler
931 */
932
933/** copy method for constraint handler plugins (called when SCIP copies plugins) */
934static
935SCIP_DECL_CONSHDLRCOPY(conshdlrCopySuperindicator)
936{ /*lint --e{715}*/
937 assert(scip != NULL);
938 assert(conshdlr != NULL);
939
941
942 /* call inclusion method of constraint handler */
944
945 *valid = TRUE;
946
947 return SCIP_OKAY;
948}
949
950/** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
951static
952SCIP_DECL_CONSFREE(consFreeSuperindicator)
953{ /*lint --e{715}*/
954 SCIP_CONSHDLRDATA* conshdlrdata;
955
956 assert(conshdlr != NULL);
957 assert(scip != NULL);
958
960
961 SCIPdebugMsg(scip, "freeing superindicator constraint handler data\n");
962
963 /* free constraint handler data */
964 conshdlrdata = SCIPconshdlrGetData(conshdlr);
965 assert(conshdlrdata != NULL);
966
967 SCIPfreeBlockMemory(scip, &conshdlrdata);
968
969 SCIPconshdlrSetData(conshdlr, NULL);
970
971 return SCIP_OKAY;
972}
973
974/** presolving initialization method of constraint handler (called when presolving is about to begin) */
975static
976SCIP_DECL_CONSINITPRE(consInitpreSuperindicator)
977{ /*lint --e{715}*/
978 SCIP_CONSDATA* consdata;
979 int i;
980
981 SCIPdebugMsg(scip, "initializing presolving\n");
982
983 for( i = nconss-1; i >= 0; i-- )
984 {
985 consdata = SCIPconsGetData(conss[i]);
986 assert(consdata != NULL);
987
988 /* make the constraint local to avoid wrong propagation */
989 SCIP_CALL( SCIPsetConsLocal(scip, consdata->slackcons, TRUE) );
990 }
991
992 return SCIP_OKAY;
993}
994
995/** frees specific constraint data */
996static
997SCIP_DECL_CONSDELETE(consDeleteSuperindicator)
998{ /*lint --e{715}*/
999 assert(conshdlr != NULL);
1000 assert(consdata != NULL);
1001 assert(*consdata != NULL);
1002 assert((*consdata)->slackcons != NULL);
1003
1005
1006 SCIPdebugMsg(scip, "deleting constraint <%s>\n", SCIPconsGetName(cons));
1007
1008 /* we have to release the slack constraint also in case we transformed it manually since it is captured automatically
1009 * in SCIPtransformCons()
1010 */
1011 SCIP_CALL( SCIPreleaseCons(scip, &((*consdata)->slackcons)) );
1012
1013 /* free memory */
1014 SCIPfreeBlockMemory(scip, consdata);
1015
1016 return SCIP_OKAY;
1017}
1018
1019/** transforms constraint data into data belonging to the transformed problem */
1020static
1021SCIP_DECL_CONSTRANS(consTransSuperindicator)
1022{ /*lint --e{715}*/
1023 SCIP_CONSDATA* sourcedata;
1024 SCIP_CONSDATA* targetdata;
1025 char newname[SCIP_MAXSTRLEN];
1026
1027 SCIPdebugMsg(scip, "transforming superindicator constraint <%s>\n", SCIPconsGetName(sourcecons));
1028
1029 /* get constraint data of source constraint */
1030 sourcedata = SCIPconsGetData(sourcecons);
1031 assert(sourcedata != NULL);
1032
1033 (void) SCIPsnprintf(newname, SCIP_MAXSTRLEN, "t_%s", SCIPconsGetName(sourcecons) );
1034 SCIP_CALL( consdataCreateSuperindicator(scip, &targetdata, sourcedata->binvar, sourcedata->slackcons) );
1035
1036 /* create target constraint and capture it at the same time */
1037 SCIP_CALL( SCIPcreateCons(scip, targetcons, newname, conshdlr, targetdata,
1038 SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
1039 SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons), SCIPconsIsLocal(sourcecons),
1040 SCIPconsIsModifiable(sourcecons), SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons),
1041 SCIPconsIsStickingAtNode(sourcecons)) );
1042
1043 return SCIP_OKAY;
1044}
1045
1046/** LP initialization method of constraint handler */
1047static
1048SCIP_DECL_CONSINITLP(consInitlpSuperindicator)
1049{
1050 int c;
1051
1052 assert(scip != NULL);
1053 assert(infeasible != NULL);
1054
1056
1057 *infeasible = FALSE;
1058
1059 SCIPdebugMsg(scip, "executing initlp callback\n");
1060
1061 for( c = nconss-1; c >= 0 && !(*infeasible); c-- )
1062 {
1063 SCIP_CONSDATA* consdata;
1064
1065 consdata = SCIPconsGetData(conss[c]);
1066
1067 assert(consdata != NULL);
1068 assert(SCIPconsIsInitial(conss[c]));
1069
1070 if( SCIPvarGetLbLocal(consdata->binvar) > 0.5 )
1071 {
1072 assert(SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->binvar), 1.0));
1073
1074 SCIPdebugMsg(scip, "binvar <%s> == 1 --> SCIPinitlpCons() on constraint <%s>\n",
1075 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
1076
1077 SCIP_CALL( SCIPinitlpCons(scip, consdata->slackcons, infeasible) );
1078 }
1079 }
1080
1081 return SCIP_OKAY;
1082}
1083
1084/** separation method of constraint handler for LP solutions */
1085static
1086SCIP_DECL_CONSSEPALP(consSepalpSuperindicator)
1087{ /*lint --e{715}*/
1088 int c;
1089
1090 assert(conshdlr != NULL);
1091 assert(conss != NULL);
1092 assert(result != NULL);
1093
1095
1097
1098 SCIPdebugMsg(scip, "executing sepalp callback\n");
1099
1100#ifdef SCIP_OUTPUT
1102#endif
1103
1104 /* check all useful constraints */
1105 for( c = nusefulconss-1; c >= 0 && *result != SCIP_CUTOFF; c-- )
1106 {
1107 SCIP_CONSDATA* consdata;
1108 SCIP_RESULT locresult;
1109
1110 consdata = SCIPconsGetData(conss[c]);
1111 assert(consdata != NULL);
1112
1113 locresult = SCIP_DELAYED;
1114
1115 /* separate only if binvar is fixed to one */
1116 if( SCIPvarGetLbLocal(consdata->binvar) > 0.5 )
1117 {
1118 assert(SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->binvar), 1.0));
1119
1120 SCIPdebugMsg(scip, "binvar <%s> == 1 --> SCIPsepalpCons() on constraint <%s>\n",
1121 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
1122
1123 SCIP_CALL( SCIPsepalpCons(scip, consdata->slackcons, &locresult) );
1124
1125 SCIPdebugMsgPrint(scip, " --> locresult=%d\n", locresult);
1126 }
1127
1128 /* evaluate result value */
1129 switch( locresult )
1130 {
1131 case SCIP_CUTOFF:
1132 case SCIP_CONSADDED:
1134 *result = locresult;
1135 break;
1136 case SCIP_REDUCEDDOM:
1138 if( *result != SCIP_CONSADDED )
1139 *result = locresult;
1140 break;
1141 case SCIP_SEPARATED:
1143 if( *result != SCIP_CONSADDED
1144 && *result != SCIP_REDUCEDDOM )
1145 *result = locresult;
1146 break;
1147 case SCIP_NEWROUND:
1149 if( *result != SCIP_CONSADDED
1150 && *result != SCIP_REDUCEDDOM
1151 && *result != SCIP_SEPARATED )
1152 *result = locresult;
1153 break;
1154 case SCIP_DIDNOTFIND:
1156 if( *result != SCIP_CONSADDED
1157 && *result != SCIP_REDUCEDDOM
1158 && *result != SCIP_NEWROUND
1159 && *result != SCIP_SEPARATED )
1160 *result = locresult;
1161 break;
1162 case SCIP_DIDNOTRUN:
1164 if( *result != SCIP_CONSADDED
1165 && *result != SCIP_REDUCEDDOM
1166 && *result != SCIP_NEWROUND
1167 && *result != SCIP_SEPARATED
1168 && *result != SCIP_DIDNOTFIND )
1169 *result = locresult;
1170 break;
1171 case SCIP_INFEASIBLE:
1173 if( *result != SCIP_CONSADDED
1174 && *result != SCIP_REDUCEDDOM
1175 && *result != SCIP_SEPARATED
1176 && *result != SCIP_DIDNOTFIND
1177 && *result != SCIP_DIDNOTRUN
1178 && *result != SCIP_NEWROUND )
1179 *result = locresult;
1180 break;
1181 case SCIP_DELAYED:
1182 break;
1183 default:
1184 SCIPerrorMessage("invalid SCIP result %d\n", locresult);
1185 return SCIP_INVALIDRESULT;
1186 } /*lint !e788*/
1187 }
1188
1189 SCIPdebugMsg(scip, "sepalp result=%d\n", *result);
1190
1191 return SCIP_OKAY;
1192}
1193
1194/** separation method of constraint handler for arbitrary primal solutions */
1195static
1196SCIP_DECL_CONSSEPASOL(consSepasolSuperindicator)
1197{ /*lint --e{715}*/
1198 int c;
1199
1200 assert(conshdlr != NULL);
1201 assert(conss != NULL);
1202 assert(result != NULL);
1203
1205
1207
1208 SCIPdebugMsg(scip, "executing sepasol callback\n");
1209
1210#ifdef SCIP_OUTPUT
1212#endif
1213
1214 /* check all the useful constraint */
1215 for( c = 0; c < nusefulconss && *result != SCIP_CUTOFF; ++c )
1216 {
1217 SCIP_CONSDATA* consdata;
1218 SCIP_RESULT locresult;
1219
1220 consdata = SCIPconsGetData(conss[c]);
1221 assert(consdata != NULL);
1222
1223 locresult = SCIP_DELAYED;
1224
1225 /* separate only if binvar is fixed to one */
1226 if( SCIPvarGetLbLocal(consdata->binvar) > 0.5 )
1227 {
1228 assert(SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->binvar), 1.0));
1229
1230 SCIPdebugMsg(scip, "binvar <%s> == 0 --> SCIPsepasolCons() on constraint <%s>\n",
1231 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
1232
1233 SCIP_CALL( SCIPsepasolCons(scip, consdata->slackcons, sol, &locresult) );
1234
1235 SCIPdebugMsgPrint(scip, " --> result=%d\n", locresult);
1236 }
1237
1238 /* evaluate result value */
1239 switch( locresult )
1240 {
1241 case SCIP_CUTOFF:
1242 case SCIP_CONSADDED:
1244 *result = locresult;
1245 break;
1246 case SCIP_REDUCEDDOM:
1248 if( *result != SCIP_CONSADDED )
1249 *result = locresult;
1250 break;
1251 case SCIP_SEPARATED:
1253 if( *result != SCIP_CONSADDED
1254 && *result != SCIP_REDUCEDDOM )
1255 *result = locresult;
1256 break;
1257 case SCIP_NEWROUND:
1259 if( *result != SCIP_CONSADDED
1260 && *result != SCIP_REDUCEDDOM
1261 && *result != SCIP_SEPARATED )
1262 *result = locresult;
1263 break;
1264 case SCIP_DIDNOTFIND:
1266 if( *result != SCIP_CONSADDED
1267 && *result != SCIP_REDUCEDDOM
1268 && *result != SCIP_NEWROUND
1269 && *result != SCIP_SEPARATED )
1270 *result = locresult;
1271 break;
1272 case SCIP_DIDNOTRUN:
1274 if( *result != SCIP_CONSADDED
1275 && *result != SCIP_REDUCEDDOM
1276 && *result != SCIP_NEWROUND
1277 && *result != SCIP_SEPARATED
1278 && *result != SCIP_DIDNOTFIND )
1279 *result = locresult;
1280 break;
1281 case SCIP_INFEASIBLE:
1283 if( *result != SCIP_CONSADDED
1284 && *result != SCIP_REDUCEDDOM
1285 && *result != SCIP_SEPARATED
1286 && *result != SCIP_DIDNOTFIND
1287 && *result != SCIP_DIDNOTRUN
1288 && *result != SCIP_NEWROUND )
1289 *result = locresult;
1290 break;
1291 case SCIP_DELAYED:
1292 break;
1293 default:
1294 SCIPerrorMessage("invalid SCIP result %d\n", locresult);
1295 return SCIP_INVALIDRESULT;
1296 } /*lint !e788*/
1297 }
1298
1299 SCIPdebugMsg(scip, "sepa sol result=%d\n", *result);
1300
1301 return SCIP_OKAY;
1302}
1303
1304/** constraint enforcing method of constraint handler for LP solutions */
1305static
1306SCIP_DECL_CONSENFOLP(consEnfolpSuperindicator)
1307{ /*lint --e{715}*/
1308 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, NULL, solinfeasible, result) );
1309
1310 return SCIP_OKAY;
1311}
1312
1313/** constraint enforcing method of constraint handler for relaxation solutions */
1314static
1315SCIP_DECL_CONSENFORELAX(consEnforelaxSuperindicator)
1316{ /*lint --e{715}*/
1317 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, sol, solinfeasible, result) );
1318
1319 return SCIP_OKAY;
1320}
1321
1322/** constraint enforcing method of constraint handler for pseudo solutions */
1323static
1324SCIP_DECL_CONSENFOPS(consEnfopsSuperindicator)
1325{ /*lint --e{715}*/
1326 SCIP_Bool cont;
1327 int i;
1328
1329 assert(scip != NULL);
1330 assert(conshdlr != NULL);
1331 assert(result != NULL);
1332
1333 /* if the solution is infeasible anyway, skip the enforcement */
1334 if( solinfeasible )
1335 {
1337 return SCIP_OKAY;
1338 }
1339 else if( objinfeasible )
1340 {
1342 return SCIP_OKAY;
1343 }
1344
1345 SCIPdebugMsg(scip, "executing enfops callback\n");
1346
1348 cont = TRUE;
1349
1350 /* check all contraints */
1351 for( i = nconss-1; i >= 0 && cont; i-- )
1352 {
1353 SCIP_CONSDATA* consdata;
1354 SCIP_RESULT locresult;
1355
1356 consdata = SCIPconsGetData(conss[i]);
1357 assert(consdata != NULL);
1358
1359 locresult = SCIP_DIDNOTRUN;
1360
1361 /* enforce only if binvar is fixed to one */
1362 if( SCIPvarGetLbLocal(consdata->binvar) > 0.5 )
1363 {
1364 assert(SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->binvar), 1.0));
1365
1366 SCIPdebugMsg(scip, "binvar <%s> == 1 locally --> SCIPenfopsCons() on constraint <%s>\n",
1367 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
1368
1369 SCIP_CALL( SCIPenfopsCons(scip, consdata->slackcons, solinfeasible, objinfeasible, &locresult) );
1370
1371 SCIPdebugMsgPrint(scip, " --> %slocresult=%d\n", locresult == SCIP_FEASIBLE ? "satisfied, " : "", locresult);
1372 }
1373 /* otherwise check if we have not yet detected infeasibility */
1374 else if( *result == SCIP_FEASIBLE || *result == SCIP_DIDNOTRUN )
1375 {
1376 SCIP_CALL( consdataCheckSuperindicator(scip, consdata, NULL, TRUE, FALSE, FALSE, &locresult) );
1377 }
1378
1379 /* evaluate result value */
1380 switch( locresult )
1381 {
1382 case SCIP_CUTOFF:
1383 case SCIP_BRANCHED:
1386 *result = locresult;
1387 cont = FALSE;
1388 break;
1389 case SCIP_CONSADDED:
1392 if( *result != SCIP_CUTOFF )
1393 *result = locresult;
1394 break;
1395 case SCIP_REDUCEDDOM:
1398 if( *result != SCIP_CUTOFF
1399 && *result != SCIP_CONSADDED )
1400 *result = locresult;
1401 break;
1402 case SCIP_SOLVELP:
1405 if( *result != SCIP_CUTOFF
1406 && *result != SCIP_CONSADDED
1407 && *result != SCIP_REDUCEDDOM
1408 && *result != SCIP_BRANCHED )
1409 *result = locresult;
1410 break;
1411 case SCIP_INFEASIBLE:
1414 if( *result != SCIP_CUTOFF
1415 && *result != SCIP_CONSADDED
1416 && *result != SCIP_REDUCEDDOM
1417 && *result != SCIP_BRANCHED
1418 && *result != SCIP_SOLVELP )
1419 *result = locresult;
1420 break;
1421 case SCIP_DIDNOTRUN:
1424 if( *result != SCIP_CUTOFF
1425 && *result != SCIP_CONSADDED
1426 && *result != SCIP_REDUCEDDOM
1427 && *result != SCIP_BRANCHED
1428 && *result != SCIP_SOLVELP
1429 && *result != SCIP_INFEASIBLE )
1430 *result = locresult;
1431 break;
1432 case SCIP_FEASIBLE:
1435 if( *result != SCIP_CUTOFF
1436 && *result != SCIP_CONSADDED
1437 && *result != SCIP_REDUCEDDOM
1438 && *result != SCIP_BRANCHED
1439 && *result != SCIP_SOLVELP
1440 && *result != SCIP_INFEASIBLE
1441 && *result != SCIP_DIDNOTRUN )
1442 *result = locresult;
1443 break;
1444 default:
1445 SCIPerrorMessage("invalid SCIP result %d\n", locresult);
1446 return SCIP_INVALIDRESULT;
1447 } /*lint !e788*/
1448 }
1449
1450 SCIPdebugMsg(scip, "enfops result=%d\n", *result);
1451
1452 return SCIP_OKAY;
1453}
1454
1455/** feasibility check method of constraint handler for integral solutions */
1456static
1457SCIP_DECL_CONSCHECK(consCheckSuperindicator)
1458{ /*lint --e{715}*/
1459 int i;
1460
1461 assert(scip != NULL);
1462 assert(conshdlr != NULL);
1463 assert(result != NULL);
1464 assert(sol != NULL);
1465
1467
1468 for( i = nconss-1; i >= 0 && (*result == SCIP_FEASIBLE || completely); i-- )
1469 {
1470 SCIP_CONSDATA* consdata;
1471
1472 consdata = SCIPconsGetData(conss[i]);
1473 SCIP_CALL( consdataCheckSuperindicator(scip, consdata, sol, checkintegrality, checklprows, printreason, result) );
1474 }
1475
1476 SCIPdebugMsg(scip, "checked solution from <%s> (checkintegrality=%u, checklprows=%u) --> result=%d (%sfeasible)\n",
1477 SCIPsolGetHeur(sol) == NULL ? "NULL" : SCIPheurGetName(SCIPsolGetHeur(sol)), checkintegrality, checklprows,
1478 *result, *result == SCIP_INFEASIBLE ? "in" : "");
1479
1480 return SCIP_OKAY;
1481}
1482
1483/** domain propagation method of constraint handler */
1484static
1485SCIP_DECL_CONSPROP(consPropSuperindicator)
1486{ /*lint --e{715}*/
1487 int i;
1488
1489 assert(scip != NULL);
1490 assert(conshdlr != NULL);
1491 assert(result != NULL);
1492
1494
1495 SCIPdebugMsg(scip, "executing prop callback\n");
1496
1497 /* loop over all useful contraints */
1498 for( i = nusefulconss-1; i >= 0 && *result != SCIP_CUTOFF; i-- )
1499 {
1500 SCIP_CONSDATA* consdata;
1501 SCIP_RESULT locresult;
1502
1503 consdata = SCIPconsGetData(conss[i]);
1504 assert(consdata != NULL);
1505
1506 locresult = SCIP_DIDNOTRUN;
1507
1508 /* propagate only if binvar is fixed to one */
1509 if( SCIPvarGetLbGlobal(consdata->binvar) > 0.5 )
1510 {
1511 assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(consdata->binvar), 1.0));
1512
1513 SCIPdebugMsg(scip, "binvar <%s> == 1 globally --> deleting superindicator and adding slack constraint <%s>\n",
1514 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
1515
1516 SCIP_CALL( SCIPsetConsLocal(scip, consdata->slackcons, FALSE) );
1517 SCIP_CALL( SCIPaddCons(scip, consdata->slackcons) );
1518 SCIP_CALL( SCIPdelCons(scip, conss[i]) );
1519
1520 locresult = SCIP_DIDNOTFIND;
1521 }
1522 else if( SCIPvarGetLbLocal(consdata->binvar) > 0.5 )
1523 {
1524 assert(SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->binvar), 1.0));
1525
1526 SCIPdebugMsg(scip, "binvar <%s> == 1 locally --> propagating slack constraint <%s>\n",
1527 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
1528
1529 SCIP_CALL( SCIPpropCons(scip, consdata->slackcons, proptiming, &locresult) );
1530
1531 SCIPdebugMsgPrint(scip, " --> locresult=%d\n", locresult);
1532 }
1533 /**@todo else propagate the domain of the binvar as well: start probing mode, fix binvar to one, propagate
1534 * constraint, and see whether we become infeasible; if this is implemented, the resprop callback must be
1535 * updated
1536 */
1537
1538 /* evaluate result value */
1539 switch( locresult )
1540 {
1541 case SCIP_CUTOFF:
1542 case SCIP_DELAYED:
1543 /* if propagation of one constraint is delayed, we want to propagate again unless the node is cut off */
1545 *result = locresult;
1546 break;
1547 case SCIP_REDUCEDDOM:
1549 if( *result != SCIP_DELAYED )
1550 *result = locresult;
1551 break;
1552 case SCIP_DIDNOTFIND:
1554 if( *result != SCIP_REDUCEDDOM
1555 && *result != SCIP_DELAYED )
1556 *result = locresult;
1557 break;
1558 case SCIP_DIDNOTRUN:
1560 if( *result != SCIP_REDUCEDDOM
1561 && *result != SCIP_DIDNOTFIND
1562 && *result != SCIP_DELAYED )
1563 *result = locresult;
1564 break;
1565 default:
1566 SCIPerrorMessage("invalid SCIP result %d\n", locresult);
1567 return SCIP_INVALIDRESULT;
1568 } /*lint !e788*/
1569 }
1570
1571 SCIPdebugMsg(scip, "prop result=%d\n", *result);
1572
1573 return SCIP_OKAY;
1574}
1575
1576/** presolving method of constraint handler */
1577static
1578SCIP_DECL_CONSPRESOL(consPresolSuperindicator)
1579{ /*lint --e{715}*/
1580 int i;
1581
1582 assert(scip != NULL);
1583 assert(conss != NULL);
1584 assert(conshdlr != NULL);
1585
1587
1588 SCIPdebugMsg(scip, "executing presol callback\n");
1589
1590 for( i = nconss-1; i >= 0 && *result != SCIP_CUTOFF; i-- )
1591 {
1592 SCIP_CONSDATA* consdata;
1593 SCIP_RESULT locresult;
1594
1595 consdata = SCIPconsGetData(conss[i]);
1596 assert(consdata != NULL);
1597
1598 locresult = SCIP_DIDNOTFIND;
1599
1600 /**@todo check whether the slack constraint is added to SCIP; in this case the superindicator can be deleted */
1601
1602 /**@todo check whether the slack constraint is a superindicator constraint and presolve */
1603
1604 /* if binvar is globally fixed to 1, we add the slack constraint and remove the superindicator */
1605 if( SCIPvarGetLbGlobal(consdata->binvar) > 0.5 )
1606 {
1607 assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(consdata->binvar), 1.0));
1608
1609 SCIPdebugMsg(scip, "binvar <%s> == 1 globally --> deleting superindicator and adding slack constraint <%s>\n",
1610 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
1611
1612 SCIP_CALL( SCIPsetConsLocal(scip, consdata->slackcons, FALSE) );
1613 SCIP_CALL( SCIPaddCons(scip, consdata->slackcons) );
1614 SCIP_CALL( SCIPdelCons(scip, conss[i]) );
1615
1616 locresult = SCIP_SUCCESS;
1617 }
1618 /* otherwise try upgrading */
1619 else
1620 {
1621 SCIP_Bool success;
1622 SCIP_Bool deleted;
1623
1624 SCIP_CALL( upgradeSuperindicator(scip, conss[i], &success, &deleted) );
1625
1626 /* update statistics */
1627 if( deleted )
1628 (*ndelconss)++;
1629 else if( success )
1630 (*nupgdconss)++;
1631
1632 /**@todo mark if upgrading failed to avoid trying too often; however, since upgrading might fail only due to
1633 * large domains, we may want to try again later, e.g., if SCIPisPresolveFinished() is TRUE
1634 */
1635
1636 if( deleted || success )
1637 locresult = SCIP_SUCCESS;
1638 }
1639 /**@todo else propagate the domain of the binvar as well: start probing mode, fix binvar to one, propagate
1640 * constraint, and see whether we become infeasible
1641 */
1642
1643 /* evaluate result value */
1644 switch( locresult )
1645 {
1646 case SCIP_SUCCESS:
1648 if( *result != SCIP_DELAYED )
1649 *result = locresult;
1650 break;
1651 default:
1652 assert(locresult == SCIP_DIDNOTFIND);
1655 *result = locresult;
1656 break;
1657 } /*lint !e788*/
1658 }
1659
1660 SCIPdebugMsg(scip, "presol result=%d\n", *result);
1661
1662 return SCIP_OKAY;
1663}
1664
1665/** propagation conflict resolving method of constraint handler */
1666static
1667SCIP_DECL_CONSRESPROP(consRespropSuperindicator)
1668{ /*lint --e{715}*/
1669 SCIP_CONSDATA* consdata;
1670
1671 assert(scip != NULL);
1672 assert(cons != NULL);
1673 assert(infervar != NULL);
1674 assert(bdchgidx != NULL);
1675 assert(result != NULL);
1676
1677 SCIPdebugMsg(scip, "executing resprop callback for constraint <%s>\n", SCIPconsGetName(cons));
1678
1679 consdata = SCIPconsGetData(cons);
1680 assert(consdata != NULL);
1681
1683
1684 /* check that we only propagated if the binvar is fixed to one */
1685 assert(SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, consdata->binvar, bdchgidx, TRUE), 1.0));
1686
1687 /* add tightened lower bound on binvar to conflict set */
1688 SCIP_CALL( SCIPaddConflictLb(scip, consdata->binvar, bdchgidx) );
1689
1690 /* call propagation conflict resolving method for the slack constraint */
1691 SCIP_CALL( SCIPrespropCons(scip, consdata->slackcons, infervar, inferinfo, boundtype, bdchgidx, relaxedbd, result) );
1692
1693 SCIPdebugMsgPrint(scip, " --> result=%d\n", *result);
1694
1695 return SCIP_OKAY;
1696}
1697
1698/** variable rounding lock method of constraint handler */
1699static
1700SCIP_DECL_CONSLOCK(consLockSuperindicator)
1701{ /*lint --e{715}*/
1702 SCIP_CONSDATA* consdata;
1703
1704 assert(scip != NULL);
1705 assert(locktype == SCIP_LOCKTYPE_MODEL);
1706
1707 SCIPdebugMsg(scip, "locking variables for constraint <%s>\n", SCIPconsGetName(cons));
1708
1709 consdata = SCIPconsGetData(cons);
1710 assert(consdata != NULL);
1711
1712 /* lock binvar up */
1713 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->binvar, locktype, nlocksneg, nlockspos) );
1714
1715 /* call lock method for the slack constraint */
1716 SCIP_CALL( SCIPaddConsLocksType(scip, consdata->slackcons, locktype, nlockspos, nlocksneg) );
1717
1718 return SCIP_OKAY;
1719}
1720
1721
1722/** constraint display method of constraint handler */
1723static
1724SCIP_DECL_CONSPRINT(consPrintSuperindicator)
1725{ /*lint --e{715}*/
1726 SCIP_CONSDATA* consdata;
1727 SCIP_VAR* binvar;
1728 int zeroone;
1729
1730 assert(scip != NULL);
1731 assert(conshdlr != NULL);
1732 assert(cons != NULL);
1733
1735
1736 consdata = SCIPconsGetData(cons);
1737 assert(consdata != NULL);
1738
1739 /* get binary variable */
1740 binvar = consdata->binvar;
1741 assert(binvar != NULL);
1742
1743 /* resolve negation if necessary */
1744 zeroone = 1;
1746 {
1747 zeroone = 0;
1748 binvar = SCIPvarGetNegatedVar(binvar);
1749 assert(binvar != NULL);
1750 }
1751
1752 /* print name of the binary variable */
1753 SCIP_CALL( SCIPwriteVarName(scip, file, binvar, TRUE) );
1754
1755 /* print implication */
1756 SCIPinfoMessage(scip, file, " = %d ->", zeroone);
1757
1758 /* print slack constraint */
1759 assert(consdata->slackcons != NULL);
1760 SCIP_CALL( SCIPprintCons(scip, consdata->slackcons, file) );
1761
1762 return SCIP_OKAY;
1763}
1764
1765/** constraint copying method of constraint handler */
1766static
1767SCIP_DECL_CONSCOPY(consCopySuperindicator)
1768{ /*lint --e{715}*/
1769 SCIP_CONSHDLR* conshdlrslack;
1770 SCIP_CONSDATA* sourceconsdata;
1771 SCIP_CONS* sourceslackcons;
1772 SCIP_CONS* targetslackcons;
1773 SCIP_VAR* targetbinvar;
1774 const char* consname;
1775
1776 assert(scip != NULL);
1777 assert(sourcescip != NULL);
1778 assert(sourcecons != NULL);
1779
1781
1782 *valid = TRUE;
1783
1784 if( name != NULL )
1785 consname = name;
1786 else
1787 consname = SCIPconsGetName(sourcecons);
1788
1789 SCIPdebugMsg(scip, "copying superindicator constraint <%s> to <%s>\n", SCIPconsGetName(sourcecons), consname);
1790
1791 if( modifiable )
1792 {
1793 SCIPwarningMessage(scip, "cannot create modifiable superindicator constraint when trying to copy constraint <%s>\n",
1794 SCIPconsGetName(sourcecons));
1795 *valid = FALSE;
1796 return SCIP_OKAY;
1797 }
1798
1799 sourceconsdata = SCIPconsGetData(sourcecons);
1800 assert(sourceconsdata != NULL);
1801
1802 /* get slack constraint */
1803 sourceslackcons = sourceconsdata->slackcons;
1804 assert(sourceslackcons != NULL);
1805
1806 /* if the slack constraint has been deleted, create an empty linear constraint */
1807 if( SCIPconsIsDeleted(sourceslackcons) )
1808 {
1809 SCIPdebugMsg(scip, "slack constraint <%s> deleted; creating empty linear constraint\n",
1810 SCIPconsGetName(sourceslackcons));
1811
1812 SCIP_CALL( SCIPcreateConsLinear(scip, &targetslackcons, "dummy", 0, NULL, NULL, 0.0, SCIPinfinity(scip),
1814
1815 SCIP_CALL( SCIPaddCons(scip, targetslackcons) );
1816 }
1817 else
1818 {
1819 /* get copied version of slack constraint */
1820 conshdlrslack = SCIPconsGetHdlr(sourceslackcons);
1821 assert(conshdlrslack != NULL);
1822
1823 /* if copying scip after transforming the original instance before presolving, we need to correct the slack
1824 * constraint pointer
1825 */
1826 assert(!SCIPisTransformed(sourcescip) || SCIPconsIsTransformed(sourceslackcons));
1827 if( SCIPisTransformed(sourcescip) && !SCIPconsIsTransformed(sourceslackcons) )
1828 {
1829 SCIP_CONS* transslackcons;
1830
1831 SCIP_CALL( SCIPgetTransformedCons(sourcescip, sourceslackcons, &transslackcons) );
1832 assert(transslackcons != NULL);
1833 SCIP_CALL( SCIPreleaseCons(sourcescip, &sourceconsdata->slackcons) );
1834 SCIP_CALL( SCIPcaptureCons(sourcescip, transslackcons) );
1835
1836 sourceconsdata->slackcons = transslackcons;
1837 sourceslackcons = transslackcons;
1838 }
1839
1840 SCIP_CALL( SCIPgetConsCopy(sourcescip, scip, sourceslackcons, &targetslackcons, conshdlrslack, varmap, consmap,
1841 SCIPconsGetName(sourceslackcons), SCIPconsIsInitial(sourceslackcons), SCIPconsIsSeparated(sourceslackcons),
1842 SCIPconsIsEnforced(sourceslackcons), SCIPconsIsChecked(sourceslackcons), SCIPconsIsPropagated(sourceslackcons),
1843 SCIPconsIsLocal(sourceslackcons), SCIPconsIsModifiable(sourceslackcons), SCIPconsIsDynamic(sourceslackcons),
1844 SCIPconsIsRemovable(sourceslackcons), SCIPconsIsStickingAtNode(sourceslackcons), global, valid) );
1845 }
1846
1847 /* find copied variable corresponding to binvar */
1848 if( *valid )
1849 {
1850 SCIP_VAR* sourcebinvar;
1851
1852 sourcebinvar = sourceconsdata->binvar;
1853 assert(sourcebinvar != NULL);
1854
1855 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, sourcebinvar, &targetbinvar, varmap, consmap, global, valid) );
1856 }
1857 else
1858 targetbinvar = NULL;
1859
1860 /* create superindicator constraint */
1861 if( *valid )
1862 {
1863 assert(targetslackcons != NULL);
1864 assert(targetbinvar != NULL);
1865 assert(!modifiable);
1866
1867 SCIP_CALL( SCIPcreateConsSuperindicator(scip, cons, consname, targetbinvar, targetslackcons,
1868 initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode) );
1869 }
1870
1871 /* relase slack constraint */
1872 if( targetslackcons != NULL )
1873 {
1874 SCIP_CALL( SCIPreleaseCons(scip, &targetslackcons) );
1875 }
1876
1877 if( !(*valid) )
1878 {
1879 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "could not copy superindicator constraint <%s>\n", SCIPconsGetName(sourcecons));
1880 }
1881
1882 return SCIP_OKAY;
1883}
1884
1885/** constraint parsing method of constraint handler */
1886static
1887SCIP_DECL_CONSPARSE(consParseSuperindicator)
1888{ /*lint --e{715}*/
1889 SCIP_VAR* binvar;
1890 SCIP_CONS* slackcons;
1891 char binvarname[1024];
1892 const char* slackstr;
1893 int zeroone;
1894 int nargs;
1895
1896 assert(cons != NULL);
1897 assert(scip != NULL);
1898 assert(success != NULL);
1899 assert(str != NULL);
1900 assert(name != NULL);
1901
1902 *success = FALSE;
1903
1904 /* extract binary variable name and value which triggers slack constraint */
1905 /* coverity[secure_coding] */
1906 nargs = sscanf(str, " <%1023[^>]>[B] = %d", binvarname, &zeroone);
1907
1908 if( nargs != 2 || (zeroone != 0 && zeroone != 1) )
1909 {
1910 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error: expected the following form: <var> = [0|1] -> <cons>\n");
1911 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "got: %s\n", str);
1912 return SCIP_OKAY;
1913 }
1914
1915 /* extract string describing slack constraint */
1916 slackstr = strstr(str, "->");
1917
1918 if( slackstr == NULL )
1919 {
1920 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error: expected the following form: <var> = [0|1] -> <cons>\n");
1921 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "got: %s\n", str);
1922 return SCIP_OKAY;
1923 }
1924
1925 slackstr = strstr(slackstr, "[");
1926
1927 if( slackstr == NULL )
1928 {
1929 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error: expected the following form: <var> = [0|1] -> <cons>\n");
1930 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "got: %s\n", str);
1931 return SCIP_OKAY;
1932 }
1933
1934 SCIPdebugMsg(scip, "binvarname=%s, zeroone=%d, slackstr=%s\n", binvarname, zeroone, slackstr);
1935
1936 /* get binary variable */
1937 binvar = SCIPfindVar(scip, binvarname);
1938 if( binvar == NULL )
1939 {
1940 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "unknown variable <%s>\n", binvarname);
1941 return SCIP_OKAY;
1942 }
1943
1944 /* resolve negation if necessary */
1945 if( zeroone == 0 )
1946 {
1947 SCIP_CALL( SCIPgetNegatedVar(scip, binvar, &binvar) );
1948 }
1949
1950 /**@todo get slack constraint name and check whether constraint already exists; however, using only SCIPfindCons() is
1951 * not sufficient since slack constraints are not added to the problem; do we need something like
1952 * SCIPfindConsInConshdlr()?; currently, if there are two superindicator constraints with same slack constraint
1953 * (binvars may be different), then after writing and reading, the slack constraint will be created twice with
1954 * identical constraint name; this is not incorrect, but might consume more memory or time
1955 */
1956
1957 /* parse slack constraint string */
1958 SCIP_CALL( SCIPparseCons(scip, &slackcons, slackstr, initial, separate, enforce, check, propagate, local, modifiable,
1959 dynamic, removable, stickingatnode, success) );
1960
1961 if( *success )
1962 {
1963 assert(binvar != NULL);
1964 assert(slackcons != NULL);
1965
1966 /* create the superindicator constraint */
1967 SCIP_CALL( SCIPcreateConsSuperindicator(scip, cons, name, binvar, slackcons,
1968 initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode) );
1969
1970 /* the new superindicator constraint captured the slack constraint, so we can release it now */
1971 SCIP_CALL( SCIPreleaseCons(scip, &slackcons) );
1972 }
1973
1974 return SCIP_OKAY;
1975}
1976
1977/** constraint method of constraint handler which returns the variables (if possible) */
1978static
1979SCIP_DECL_CONSGETVARS(consGetVarsSuperindicator)
1980{ /*lint --e{715}*/
1981 SCIP_CONSDATA* consdata;
1982
1983 consdata = SCIPconsGetData(cons);
1984 assert(consdata != NULL);
1985
1986 /* must be ready to hold at least the binary variable */
1987 if( varssize <= 0 )
1988 *success = FALSE;
1989 else
1990 {
1991 /* add binary variable */
1992 vars[0] = consdata->binvar;
1993
1994 /* add variables of slack constraint */
1995 SCIP_CALL( SCIPgetConsVars(scip, consdata->slackcons, &(vars[1]), varssize-1, success) );
1996 }
1997
1998 return SCIP_OKAY;
1999}
2000
2001/** constraint method of constraint handler which returns the number of variables (if possible) */
2002static
2003SCIP_DECL_CONSGETNVARS(consGetNVarsSuperindicator)
2004{ /*lint --e{715}*/
2005 SCIP_CONSDATA* consdata;
2006
2007 consdata = SCIPconsGetData(cons);
2008 assert(consdata != NULL);
2009
2010 /* get number of variables in slack constraint */
2011 SCIP_CALL( SCIPgetConsNVars(scip, consdata->slackcons, nvars, success) );
2012
2013 /* add binary variable */
2014 if( *success )
2015 (*nvars)++;
2016
2017 return SCIP_OKAY;
2018}
2019
2020
2021/** constraint handler method which returns the permutation symmetry detection graph of a constraint */
2022static
2023SCIP_DECL_CONSGETPERMSYMGRAPH(consGetPermsymGraphSuperindicator)
2024{ /*lint --e{715}*/
2025 SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_PERM, cons, graph, success) );
2026
2027 return SCIP_OKAY;
2028}
2029
2030
2031/** constraint handler method which returns the signed permutation symmetry detection graph of a constraint */
2032static
2033SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH(consGetSignedPermsymGraphSuperindicator)
2034{ /*lint --e{715}*/
2035 SCIP_CALL( addSymmetryInformation(scip, SYM_SYMTYPE_SIGNPERM, cons, graph, success) );
2036
2037 return SCIP_OKAY;
2038}
2039
2040
2041/*
2042 * constraint specific interface methods
2043 */
2044
2045/** creates the handler for superindicator constraints and includes it in SCIP */
2047 SCIP* scip /**< SCIP data structure */
2048 )
2049{
2050 SCIP_CONSHDLRDATA* conshdlrdata;
2051 SCIP_CONSHDLR* conshdlr;
2052 SCIP_DIALOG* root;
2053 SCIP_DIALOG* changemenu;
2054 SCIP_DIALOG* dialog;
2055
2056 /* create superindicator constraint handler data */
2057 SCIP_CALL( SCIPallocBlockMemory(scip, &conshdlrdata) );
2058
2059 conshdlrdata->nrejects = 0;
2060
2061 /* include constraint handler */
2064 consEnfolpSuperindicator, consEnfopsSuperindicator, consCheckSuperindicator, consLockSuperindicator,
2065 conshdlrdata) );
2066
2067 assert(conshdlr != NULL);
2068
2069 /* set non-fundamental callbacks via specific setter functions */
2070 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopySuperindicator, consCopySuperindicator) );
2071 SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteSuperindicator) );
2072 SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeSuperindicator) );
2073 SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsSuperindicator) );
2074 SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsSuperindicator) );
2075 SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpSuperindicator) );
2076 SCIP_CALL( SCIPsetConshdlrInitpre(scip, conshdlr, consInitpreSuperindicator) );
2077 SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseSuperindicator) );
2078 SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolSuperindicator, CONSHDLR_MAXPREROUNDS, CONSHDLR_PRESOLTIMING) );
2079 SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintSuperindicator) );
2081 SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropSuperindicator) );
2082 SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpSuperindicator, consSepasolSuperindicator, CONSHDLR_SEPAFREQ, CONSHDLR_SEPAPRIORITY, CONSHDLR_DELAYSEPA) );
2083 SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransSuperindicator) );
2084 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxSuperindicator) );
2085 SCIP_CALL( SCIPsetConshdlrGetPermsymGraph(scip, conshdlr, consGetPermsymGraphSuperindicator) );
2086 SCIP_CALL( SCIPsetConshdlrGetSignedPermsymGraph(scip, conshdlr, consGetSignedPermsymGraphSuperindicator) );
2087
2088 /* add dialogs if they are not disabled */
2089 root = SCIPgetRootDialog(scip);
2090 if( root != NULL )
2091 {
2092 /* find change menu */
2093 if( !SCIPdialogHasEntry(root, "change") )
2094 {
2095 SCIP_CALL( SCIPincludeDialog(scip, &changemenu,
2096 NULL,
2097 SCIPdialogExecMenu, NULL, NULL,
2098 "change", "change the problem", TRUE, NULL) );
2099 SCIP_CALL( SCIPaddDialogEntry(scip, root, changemenu) );
2100 SCIP_CALL( SCIPreleaseDialog(scip, &changemenu) );
2101 }
2102
2103 if( SCIPdialogFindEntry(root, "change", &changemenu) != 1 )
2104 {
2105 SCIPerrorMessage("change sub menu not found\n");
2106 return SCIP_PLUGINNOTFOUND;
2107 }
2108
2109 /* add minuc dialog */
2110 if( !SCIPdialogHasEntry(changemenu, "minuc") )
2111 {
2113 NULL,
2114 SCIPdialogExecChangeMinUC, NULL, NULL,
2115 "minuc", "transforms the current problem into a MinUC problem minimizing the number of unsatisfied constraints",
2116 FALSE, NULL) );
2117 SCIP_CALL( SCIPaddDialogEntry(scip, changemenu, dialog) );
2118 SCIP_CALL( SCIPreleaseDialog(scip, &dialog) );
2119 }
2120 }
2121
2122 /* add constraint handler parameters */
2124 "constraints/" CONSHDLR_NAME "/checkslacktype",
2125 "should type of slack constraint be checked when creating superindicator constraint?",
2126 &conshdlrdata->checkslacktype, TRUE, DEFAULT_CHECKSLACKTYPE, NULL, NULL) );
2127
2129 "constraints/" CONSHDLR_NAME "/maxupgdcoeflinear",
2130 "maximum big-M coefficient of binary variable in upgrade to a linear constraint (relative to smallest coefficient)",
2131 &conshdlrdata->maxupgdcoeflinear, TRUE, DEFAULT_MAXUPGDCOEFLINEAR, 0.0, 1e15, NULL, NULL) );
2132
2134 "constraints/" CONSHDLR_NAME "/upgdprioindicator",
2135 "priority for upgrading to an indicator constraint (-1: never)",
2136 &conshdlrdata->upgdprioindicator, TRUE, DEFAULT_UPGDPRIOINDICATOR, -1, INT_MAX, NULL, NULL) );
2137
2139 "constraints/" CONSHDLR_NAME "/upgdpriolinear",
2140 "priority for upgrading to an indicator constraint (-1: never)",
2141 &conshdlrdata->upgdpriolinear, TRUE, DEFAULT_UPGDPRIOLINEAR, -1, INT_MAX, NULL, NULL) );
2142
2143 return SCIP_OKAY;
2144}
2145
2146/** creates and captures a superindicator constraint
2147 *
2148 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
2149 */
2151 SCIP* scip, /**< SCIP data structure */
2152 SCIP_CONS** cons, /**< pointer to hold the created constraint */
2153 const char* name, /**< name of constraint */
2154 SCIP_VAR* binvar, /**< pointer to the indicator constraint */
2155 SCIP_CONS* slackcons, /**< constraint corresponding to the handled constraint */
2156 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
2157 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
2158 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
2159 * Usually set to TRUE. */
2160 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
2161 * TRUE for model constraints, FALSE for additional, redundant constraints. */
2162 SCIP_Bool check, /**< should the constraint be checked for feasibility?
2163 * TRUE for model constraints, FALSE for additional, redundant constraints. */
2164 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
2165 * Usually set to TRUE. */
2166 SCIP_Bool local, /**< is constraint only valid locally?
2167 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
2168 SCIP_Bool dynamic, /**< is constraint subject to aging?
2169 * Usually set to FALSE. Set to TRUE for own cuts which
2170 * are separated as constraints. */
2171 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
2172 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
2173 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
2174 * if it may be moved to a more global node?
2175 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
2176 )
2177{
2178 SCIP_CONSHDLRDATA* conshdlrdata;
2179 SCIP_CONSHDLR* conshdlr;
2180 SCIP_CONSDATA* consdata;
2181 SCIP_Bool modifiable;
2182
2183 assert(scip != NULL);
2184 assert(cons != NULL);
2185 assert(name != NULL);
2186 assert(binvar != NULL);
2187 assert(slackcons != NULL);
2188
2189 modifiable = FALSE;
2190
2191 /* find the superindicator constraint handler */
2192 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2193 if( conshdlr == NULL )
2194 {
2195 SCIPerrorMessage("superindicator constraint handler not found\n");
2196 return SCIP_PLUGINNOTFOUND;
2197 }
2198
2199 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2200 assert(conshdlrdata != NULL);
2201
2202 /* only allow types of slack constraints that can be handled */
2203 if( conshdlrdata->checkslacktype &&
2204 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "and") != 0 &&
2205 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "bounddisjunction") != 0 &&
2206 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "conjunction") != 0 &&
2207 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "disjunction") != 0 &&
2208 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "knapsack") != 0 &&
2209 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "linear") != 0 &&
2210 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "linking") != 0 &&
2211 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "logicor") != 0 &&
2212 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "nonlinear") != 0 &&
2213 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "or") != 0 &&
2214 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "SOS1") != 0 &&
2215 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "SOS2") != 0 &&
2216 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "cumulative") != 0 &&
2217 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "varbound") != 0 &&
2218 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "superindicator") != 0
2219 )
2220 {
2221 if( conshdlrdata->nrejects < 5 )
2222 {
2223 SCIPwarningMessage(scip, "rejected creation of superindicator with slack constraint <%s> of type <%s> "
2224 "(use parameter <checkslacktype> to disable check)\n",
2225 SCIPconsGetName(slackcons), SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)));
2226 conshdlrdata->nrejects++;
2227 }
2228
2229 if( conshdlrdata->nrejects == 5 )
2230 {
2231 SCIPwarningMessage(scip, "suppressing further warning messages of this type\n");
2232 conshdlrdata->nrejects++;
2233 }
2234
2235 return SCIP_INVALIDCALL;
2236 }
2237
2238 /* create constraint data */
2239 SCIP_CALL( consdataCreateSuperindicator(scip, &consdata, binvar, slackcons) );
2240 assert(consdata != NULL);
2241
2242 /* create constraint */
2243 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
2244 local, modifiable, dynamic, removable, stickingatnode) );
2245
2246 return SCIP_OKAY;
2247}
2248
2249/** creates and captures a superindicator constraint
2250 * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
2251 * method SCIPcreateConsSuperindicator(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
2252 *
2253 * @see SCIPcreateConsSuperindicator() for information about the basic constraint flag configuration
2254 *
2255 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
2256 */
2258 SCIP* scip, /**< SCIP data structure */
2259 SCIP_CONS** cons, /**< pointer to hold the created constraint */
2260 const char* name, /**< name of constraint */
2261 SCIP_VAR* binvar, /**< pointer to the indicator constraint */
2262 SCIP_CONS* slackcons /**< constraint corresponding to the handled constraint */
2263 )
2264{
2265 assert(scip != NULL);
2266 assert(cons != NULL);
2267 assert(name != NULL);
2268 assert(binvar != NULL);
2269 assert(slackcons != NULL);
2270
2271 SCIP_CALL( SCIPcreateConsSuperindicator(scip, cons, name, binvar, slackcons,
2273
2274 return SCIP_OKAY;
2275}
2276
2277
2278/** gets binary variable corresponding to the general indicator constraint */
2280 SCIP_CONS* cons /**< superindicator constraint */
2281 )
2282{
2283 assert(cons != NULL);
2284 assert(SCIPconsGetData(cons) != NULL);
2285
2287
2288 return SCIPconsGetData(cons)->binvar;
2289}
2290
2291/** gets the slack constraint corresponding to the general indicator constraint */
2293 SCIP_CONS* cons /**< superindicator constraint */
2294 )
2295{
2296 assert(cons != NULL);
2297 assert(SCIPconsGetData(cons) != NULL);
2298
2300
2301 return SCIPconsGetData(cons)->slackcons;
2302}
2303
2304
2305/*
2306 * constraint-dependent SCIP methods
2307 */
2308
2309/** transforms the current problem into a MinUC problem (minimizing the number of unsatisfied constraints),
2310 * a CIP generalization of the MinULR (min. unsatisfied linear relations) problem
2311 */
2313 SCIP* scip, /**< SCIP data structure */
2314 SCIP_Bool* success /**< pointer to store whether all constraints could be transformed */
2315 )
2316{
2317 SCIP_CONS** conss;
2318 SCIP_CONS** probconss;
2319 SCIP_VAR** vars;
2320 char consname[SCIP_MAXSTRLEN];
2321 char varname[SCIP_MAXSTRLEN];
2322 int maxbranchprio;
2323 int ntransconss;
2324 int nconss;
2325 int nvars;
2326 int i;
2327
2328 assert(scip != NULL);
2329 assert(success != NULL);
2330
2331 *success = FALSE;
2332
2334 {
2335 SCIPerrorMessage("method <SCIPtransformMinUC> can only be called in problem stage\n");
2336 return SCIP_INVALIDCALL;
2337 }
2338
2339 /* get variable data */
2341
2342 /* copy the conss array because it changes when adding and deleting constraints */
2343 nconss = SCIPgetNConss(scip);
2344 probconss = SCIPgetConss(scip);
2345 SCIP_CALL( SCIPduplicateBufferArray(scip, &conss, probconss, nconss) );
2346
2347 /* clear objective function and compute maximal branching priority */
2348 maxbranchprio = 0;
2349 for( i = nvars-1; i >= 0; i-- )
2350 {
2351 SCIP_CALL( SCIPchgVarObj(scip, vars[i], 0.0) );
2352
2353 if( SCIPvarGetBranchPriority(vars[i]) > maxbranchprio )
2354 maxbranchprio = SCIPvarGetBranchPriority(vars[i]);
2355 }
2356
2357 maxbranchprio++;
2358
2359 /* transform each constraint to slack constraint in a newly created superindicator constraint; note that we also need
2360 * to transform superindicator constraints, since their binary variable might have down-locks
2361 */
2362 ntransconss = 0;
2363 for( i = 0; i < nconss; ++i )
2364 {
2365 SCIP_CONS* cons;
2366 SCIP_CONS* supindcons;
2367 SCIP_VAR* binvar;
2368 SCIP_VAR* negbinvar;
2369 SCIP_RETCODE retcode;
2370
2371 cons = conss[i];
2372 assert(cons != NULL);
2373
2374 /* create a new binary variable with objective coefficient one */
2375 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "%s_master", SCIPconsGetName(cons));
2376
2377 SCIP_CALL( SCIPcreateVar(scip, &binvar, varname, 0.0, 1.0, 1.0, SCIP_VARTYPE_BINARY,
2378 TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
2379
2380 /* get negated variable, since we want to minimize the number of violated constraints */
2381 SCIP_CALL( SCIPgetNegatedVar(scip, binvar, &negbinvar) );
2382
2383 /* create superindicator constraint */
2384 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_super", SCIPconsGetName(cons));
2385
2386 retcode = SCIPcreateConsSuperindicator(scip, &supindcons, consname, negbinvar, cons,
2390
2391 if( retcode == SCIP_OKAY )
2392 {
2393 /* add binary variable and increase its branching priority */
2394 SCIP_CALL( SCIPaddVar(scip, binvar) );
2395 SCIP_CALL( SCIPchgVarBranchPriority(scip, binvar, maxbranchprio) );
2396
2397 /* add superindicator constraint */
2398 SCIP_CALL( SCIPaddCons(scip, supindcons) );
2399
2400 /* release binary variable and superindicator constraint */
2401 SCIP_CALL( SCIPreleaseVar(scip, &binvar) );
2402 SCIP_CALL( SCIPreleaseCons(scip, &supindcons) );
2403
2404 /* delete slack constraint; it is still captured by the superindicator constraint */
2405 SCIP_CALL( SCIPdelCons(scip, cons) );
2406
2407 ntransconss++;
2408 }
2409 else if( retcode == SCIP_INVALIDCALL )
2410 {
2411 SCIPdebugMsg(scip, "constraint <%s> of type <%s> could not be transformed to superindicator and was removed\n",
2413
2414 /* release binary variable */
2415 SCIP_CALL( SCIPreleaseVar(scip, &binvar) );
2416
2417 /* delete slack constraint; this is necessary, because, e.g., the indicator expects its linear slack constraint
2418 * present in the problem, but this has just be transformed; hence, it cannot function any more and we have to
2419 * remove it
2420 */
2421 SCIP_CALL( SCIPdelCons(scip, cons) );
2422 }
2423 else
2424 {
2425 /* return all other error codes */
2426 SCIP_CALL( retcode );
2427 }
2428 }
2429
2430 if( ntransconss == nconss )
2431 *success = TRUE;
2432
2433 /* minimize the number of violated constraints */
2435
2436 /* free the allocated memory for the copied constraint array */
2437 SCIPfreeBufferArray(scip, &conss);
2438
2439 return SCIP_OKAY;
2440}
2441
2442
2443/*
2444 * constraint-dependent dialog entries
2445 */
2446
2447/** dialog execution method for the SCIPtransformMinUC() method */
2448SCIP_DECL_DIALOGEXEC(SCIPdialogExecChangeMinUC)
2449{ /*lint --e{715}*/
2450 SCIP_Bool success;
2451
2452 SCIP_CALL( SCIPdialoghdlrAddHistory(dialoghdlr, dialog, NULL, FALSE) );
2453 SCIPdialogMessage(scip, NULL, "\n");
2454
2455 switch( SCIPgetStage(scip) )
2456 {
2457 case SCIP_STAGE_INIT:
2458 SCIPdialogMessage(scip, NULL, "no problem exists\n");
2459 break;
2460 case SCIP_STAGE_PROBLEM:
2461 SCIPdialogMessage(scip, NULL, "change problem to MinUC\n");
2462 SCIPdialogMessage(scip, NULL, "==============\n");
2463
2464 SCIP_CALL( SCIPtransformMinUC(scip, &success) );
2465
2466 if( !success )
2467 {
2468 SCIPdialogMessage(scip, NULL, "some constraints could not be transformed to superindicator constraints and were removed\n");
2469 }
2470
2471 SCIPdialogMessage(scip, NULL, "\n");
2472 SCIPdialogMessage(scip, NULL, "changed problem has %d variables (%d bin, %d int, %d cont) and %d constraints\n",
2476
2477 SCIPdialogMessage(scip, NULL, "increased branching priority of new binary variables");
2478
2479 break;
2485 case SCIP_STAGE_SOLVING:
2486 case SCIP_STAGE_SOLVED:
2491 case SCIP_STAGE_FREE:
2492 SCIPdialogMessage(scip, NULL, "problem has to be in problem stage to create MinUC problem\n");
2493 break;
2494 default:
2495 SCIPerrorMessage("invalid SCIP stage\n");
2496 return SCIP_INVALIDCALL;
2497 } /*lint --e{616}*/
2498
2499 SCIPdialogMessage(scip, NULL, "\n");
2500 *nextdialog = SCIPdialoghdlrGetRoot(dialoghdlr);
2501
2502 return SCIP_OKAY;
2503}
#define CONSHDLR_NEEDSCONS
Definition cons_and.c:96
#define CONSHDLR_SEPAFREQ
Definition cons_and.c:89
#define CONSHDLR_CHECKPRIORITY
Definition cons_and.c:88
#define CONSHDLR_DESC
Definition cons_and.c:85
#define CONSHDLR_PROP_TIMING
Definition cons_and.c:99
#define CONSHDLR_MAXPREROUNDS
Definition cons_and.c:93
#define CONSHDLR_SEPAPRIORITY
Definition cons_and.c:86
#define CONSHDLR_PROPFREQ
Definition cons_and.c:90
#define CONSHDLR_PRESOLTIMING
Definition cons_and.c:98
#define CONSHDLR_EAGERFREQ
Definition cons_and.c:91
#define CONSHDLR_ENFOPRIORITY
Definition cons_and.c:87
#define CONSHDLR_DELAYSEPA
Definition cons_and.c:94
#define CONSHDLR_NAME
Definition cons_and.c:84
#define CONSHDLR_DELAYPROP
Definition cons_and.c:95
constraint handler for indicator constraints
Constraint handler for linear constraints in their most general form, .
#define DEFAULT_MAXUPGDCOEFLINEAR
#define DEFAULT_UPGDPRIOLINEAR
#define DEFAULT_CHECKSLACKTYPE
static SCIP_RETCODE upgradeLinearSuperindicator(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success, SCIP_Bool *deleted)
static SCIP_RETCODE enforceConstraint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_CONS **conss, int nconss, int nusefulconss, SCIP_SOL *sol, SCIP_Bool solinfeasible, SCIP_RESULT *result)
static void extractLinearValues(SCIP *scip, SCIP_CONS *cons, SCIP_Real *minactivity, SCIP_Real *maxactivity, SCIP_Real *minabscoef)
#define DEFAULT_UPGDPRIOINDICATOR
static SCIP_RETCODE upgradeSuperindicator(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success, SCIP_Bool *deleted)
static SCIP_RETCODE addSymmetryInformation(SCIP *scip, SYM_SYMTYPE symtype, SCIP_CONS *cons, SYM_GRAPH *graph, SCIP_Bool *success)
static SCIP_RETCODE upgradeIndicatorSuperindicator(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success, SCIP_Bool *deleted)
static SCIP_RETCODE consdataCheckSuperindicator(SCIP *scip, SCIP_CONSDATA *consdata, SCIP_SOL *sol, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_RESULT *result)
static SCIP_RETCODE consdataCreateSuperindicator(SCIP *scip, SCIP_CONSDATA **consdata, SCIP_VAR *binvar, SCIP_CONS *slackcons)
constraint handler for indicator constraints over arbitrary constraint types
#define NULL
Definition def.h:257
#define SCIP_MAXSTRLEN
Definition def.h:278
#define SCIP_Bool
Definition def.h:100
#define SCIP_STRINGEQ(name, reference, retcode)
Definition def.h:454
#define SCIP_Real
Definition def.h:165
#define TRUE
Definition def.h:102
#define FALSE
Definition def.h:103
#define SCIP_CALL(x)
Definition def.h:364
default user interface dialog
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_VAR * SCIPgetBinaryVarSuperindicator(SCIP_CONS *cons)
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Real SCIPgetLhsLinear(SCIP *scip, SCIP_CONS *cons)
int SCIPgetNVarsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPcreateConsIndicator(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, int nvars, SCIP_VAR **vars, SCIP_Real *vals, SCIP_Real rhs, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_CONS * SCIPgetSlackConsSuperindicator(SCIP_CONS *cons)
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 SCIPcreateConsSuperindicator(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, SCIP_CONS *slackcons, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
SCIP_RETCODE SCIPcreateConsBasicSuperindicator(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_VAR *binvar, SCIP_CONS *slackcons)
SCIP_RETCODE SCIPincludeConshdlrSuperindicator(SCIP *scip)
SCIP_RETCODE SCIPgetConsCopy(SCIP *sourcescip, SCIP *targetscip, SCIP_CONS *sourcecons, SCIP_CONS **targetcons, SCIP_CONSHDLR *sourceconshdlr, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, const char *name, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode, SCIP_Bool global, SCIP_Bool *valid)
Definition scip_copy.c:1581
SCIP_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)
SCIP_STAGE SCIPgetStage(SCIP *scip)
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition scip_prob.c:1907
int SCIPgetNIntVars(SCIP *scip)
Definition scip_prob.c:2340
int SCIPgetNContVars(SCIP *scip)
Definition scip_prob.c:2569
int SCIPgetNBinImplVars(SCIP *scip)
Definition scip_prob.c:2432
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition scip_prob.c:2115
SCIP_CONS ** SCIPgetConss(SCIP *scip)
Definition scip_prob.c:3666
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
int SCIPgetNConss(SCIP *scip)
Definition scip_prob.c:3620
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition scip_prob.c:2201
int SCIPgetNIntImplVars(SCIP *scip)
Definition scip_prob.c:2477
int SCIPgetNContImplVars(SCIP *scip)
Definition scip_prob.c:2522
SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
Definition scip_prob.c:1417
int SCIPgetNBinVars(SCIP *scip)
Definition scip_prob.c:2293
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition scip_prob.c:3189
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
#define SCIPdebugMsgPrint
#define SCIPdebugMsg
void SCIPdialogMessage(SCIP *scip, FILE *file, const char *formatstr,...)
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
SCIP_RETCODE SCIPaddIntParam(SCIP *scip, const char *name, const char *desc, int *valueptr, SCIP_Bool isadvanced, int defaultvalue, int minvalue, int maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:83
SCIP_RETCODE SCIPaddRealParam(SCIP *scip, const char *name, const char *desc, SCIP_Real *valueptr, SCIP_Bool isadvanced, SCIP_Real defaultvalue, SCIP_Real minvalue, SCIP_Real maxvalue, SCIP_DECL_PARAMCHGD((*paramchgd)), SCIP_PARAMDATA *paramdata)
Definition scip_param.c:139
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)
void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
Definition cons.c:4350
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:372
SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
Definition scip_cons.c:540
SCIP_RETCODE SCIPsetConshdlrInitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
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 SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:323
SCIP_RETCODE SCIPincludeConshdlrBasic(SCIP *scip, SCIP_CONSHDLR **conshdlrptr, const char *name, const char *desc, int enfopriority, int chckpriority, int eagerfreq, SCIP_Bool needscons, SCIP_DECL_CONSENFOLP((*consenfolp)), SCIP_DECL_CONSENFOPS((*consenfops)), SCIP_DECL_CONSCHECK((*conscheck)), SCIP_DECL_CONSLOCK((*conslock)), SCIP_CONSHDLRDATA *conshdlrdata)
Definition scip_cons.c:181
SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:808
SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:831
SCIP_Bool SCIPconshdlrSupportsSignedPermsymDetection(SCIP_CONSHDLR *conshdlr)
Definition cons.c:5460
SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:785
SCIP_RETCODE SCIPsetConshdlrGetSignedPermsymGraph(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:924
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4320
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)),)
Definition scip_cons.c:347
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition scip_cons.c:940
SCIP_RETCODE SCIPsetConshdlrGetPermsymGraph(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:900
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:578
SCIP_Bool SCIPconshdlrSupportsPermsymDetection(SCIP_CONSHDLR *conshdlr)
Definition cons.c:5450
SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
Definition cons.c:4340
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:601
SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:647
SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:624
SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr,)
Definition scip_cons.c:854
SCIP_RETCODE SCIPgetConsNVars(SCIP *scip, SCIP_CONS *cons, int *nvars, SCIP_Bool *success)
Definition scip_cons.c:2621
SCIP_RETCODE SCIPgetConsSignedPermsymGraph(SCIP *scip, SCIP_CONS *cons, SYM_GRAPH *graph, SCIP_Bool *success)
Definition scip_cons.c:2687
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition cons.c:8423
SCIP_RETCODE SCIPenfopsCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool solinfeasible, SCIP_Bool objinfeasible, SCIP_RESULT *result)
Definition scip_cons.c:2163
SCIP_RETCODE SCIPcheckCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool checkintegrality, SCIP_Bool checklprows, SCIP_Bool printreason, SCIP_RESULT *result)
Definition scip_cons.c:2135
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition cons.c:8652
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition cons.c:8413
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition cons.c:8562
SCIP_RETCODE SCIPenfolpCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool solinfeasible, SCIP_RESULT *result)
Definition scip_cons.c:2194
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition scip_cons.c:2536
SCIP_RETCODE SCIPpropCons(SCIP *scip, SCIP_CONS *cons, SCIP_PROPTIMING proptiming, SCIP_RESULT *result)
Definition scip_cons.c:2340
SCIP_RETCODE SCIPgetConsPermsymGraph(SCIP *scip, SCIP_CONS *cons, SYM_GRAPH *graph, SCIP_Bool *success)
Definition scip_cons.c:2654
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition cons.c:8592
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition cons.c:8522
SCIP_RETCODE SCIPsepalpCons(SCIP *scip, SCIP_CONS *cons, SCIP_RESULT *result)
Definition scip_cons.c:2283
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition cons.c:8702
SCIP_RETCODE SCIPgetConsVars(SCIP *scip, SCIP_CONS *cons, SCIP_VAR **vars, int varssize, SCIP_Bool *success)
Definition scip_cons.c:2577
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition cons.c:8582
SCIP_RETCODE SCIPcreateCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_CONSHDLR *conshdlr, SCIP_CONSDATA *consdata, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition scip_cons.c:997
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition cons.c:8612
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition cons.c:8632
SCIP_RETCODE SCIPaddConsLocksType(SCIP *scip, SCIP_CONS *cons, SCIP_LOCKTYPE locktype, int nlockspos, int nlocksneg)
Definition scip_cons.c:2072
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition cons.c:8393
SCIP_RETCODE SCIPinitlpCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible)
Definition scip_cons.c:2256
SCIP_RETCODE SCIPrespropCons(SCIP *scip, SCIP_CONS *cons, SCIP_VAR *infervar, int inferinfo, SCIP_BOUNDTYPE boundtype, SCIP_BDCHGIDX *bdchgidx, SCIP_Real relaxedbd, SCIP_RESULT *result)
Definition scip_cons.c:2371
SCIP_RETCODE SCIPsetConsLocal(SCIP *scip, SCIP_CONS *cons, SCIP_Bool local)
Definition scip_cons.c:1398
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition cons.c:8642
SCIP_RETCODE SCIPgetTransformedCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **transcons)
Definition scip_cons.c:1674
SCIP_RETCODE SCIPenforelaxCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool solinfeasible, SCIP_RESULT *result)
Definition scip_cons.c:2224
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition cons.c:8672
SCIP_RETCODE SCIPparseCons(SCIP *scip, SCIP_CONS **cons, const char *str, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode, SCIP_Bool *success)
Definition scip_cons.c:1081
SCIP_RETCODE SCIPsepasolCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_RESULT *result)
Definition scip_cons.c:2310
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition scip_cons.c:1173
SCIP_RETCODE SCIPtransformCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **transcons)
Definition scip_cons.c:1584
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition cons.c:8572
SCIP_RETCODE SCIPcaptureCons(SCIP *scip, SCIP_CONS *cons)
Definition scip_cons.c:1138
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition cons.c:8662
SCIP_RETCODE SCIPreleaseDialog(SCIP *scip, SCIP_DIALOG **dialog)
SCIP_DIALOG * SCIPdialoghdlrGetRoot(SCIP_DIALOGHDLR *dialoghdlr)
Definition dialog.c:436
SCIP_Bool SCIPdialogHasEntry(SCIP_DIALOG *dialog, const char *entryname)
Definition dialog.c:1013
SCIP_RETCODE SCIPdialoghdlrAddHistory(SCIP_DIALOGHDLR *dialoghdlr, SCIP_DIALOG *dialog, const char *command, SCIP_Bool escapecommand)
Definition dialog.c:725
SCIP_RETCODE SCIPincludeDialog(SCIP *scip, SCIP_DIALOG **dialog, SCIP_DECL_DIALOGCOPY((*dialogcopy)), SCIP_DECL_DIALOGEXEC((*dialogexec)), SCIP_DECL_DIALOGDESC((*dialogdesc)), SCIP_DECL_DIALOGFREE((*dialogfree)), const char *name, const char *desc, SCIP_Bool issubmenu, SCIP_DIALOGDATA *dialogdata)
Definition scip_dialog.c:59
SCIP_RETCODE SCIPaddDialogEntry(SCIP *scip, SCIP_DIALOG *dialog, SCIP_DIALOG *subdialog)
SCIP_DIALOG * SCIPgetRootDialog(SCIP *scip)
int SCIPdialogFindEntry(SCIP_DIALOG *dialog, const char *entryname, SCIP_DIALOG **subdialog)
Definition dialog.c:1046
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition heur.c:1467
SCIP_RETCODE SCIPtransformMinUC(SCIP *scip, SCIP_Bool *success)
#define SCIPallocBufferArray(scip, ptr, num)
Definition scip_mem.h:124
#define SCIPfreeBufferArray(scip, ptr)
Definition scip_mem.h:136
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition scip_mem.h:132
#define SCIPfreeBlockMemory(scip, ptr)
Definition scip_mem.h:108
#define SCIPallocBlockMemory(scip, ptr)
Definition scip_mem.h:89
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
Definition scip_sol.c:2351
SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
Definition sol.c:4274
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition scip_sol.c:1763
SCIP_Real SCIPinfinity(SCIP *scip)
SCIP_Bool SCIPisGE(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 SCIPisPositive(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisInfinity(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
SCIP_Bool SCIPisZero(SCIP *scip, SCIP_Real val)
SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
Definition var.c:23900
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition var.c:23418
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition var.c:24174
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition scip_var.c:5118
SCIP_RETCODE SCIPchgVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition scip_var.c:9917
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:23299
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition scip_var.c:1887
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition scip_var.c:2166
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition var.c:24266
int SCIPvarGetBranchPriority(SCIP_VAR *var)
Definition var.c:24494
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:24152
SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
Definition scip_var.c:361
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition scip_var.c:5372
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition scip_var.c:2078
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition misc.c:10827
SCIP_RETCODE SCIPaddSymgraphEdge(SCIP *scip, SYM_GRAPH *graph, int first, int second, SCIP_Bool hasval, SCIP_Real val)
SCIP_RETCODE SCIPfreeSymgraph(SCIP *scip, SYM_GRAPH **graph)
SCIP_RETCODE SCIPaddSymgraphOpnode(SCIP *scip, SYM_GRAPH *graph, int op, int *nodeidx)
SCIP_RETCODE SCIPgetSymActiveVariables(SCIP *scip, SYM_SYMTYPE symtype, SCIP_VAR ***vars, SCIP_Real **scalars, int *nvars, SCIP_Real *constant, SCIP_Bool transformed)
SCIP_RETCODE SCIPcreateSymgraph(SCIP *scip, SYM_SYMTYPE symtype, SYM_GRAPH **graph, SCIP_VAR **symvars, int nsymvars, int nopnodes, int nvalnodes, int nconsnodes, int nedges)
int SCIPgetSymgraphVarnodeidx(SCIP *scip, SYM_GRAPH *graph, SCIP_VAR *var)
SCIP_RETCODE SCIPcopySymgraphAsSubgraph(SCIP *scip, SYM_GRAPH *sourcegraph, SYM_GRAPH *targetgraph, SCIP_CONS *sourcecons, int *rootidx)
SCIP_RETCODE SCIPaddSymgraphConsnode(SCIP *scip, SYM_GRAPH *graph, SCIP_CONS *cons, SCIP_Real lhs, SCIP_Real rhs, int *nodeidx)
SCIP_RETCODE SCIPaddSymgraphVarAggregation(SCIP *scip, SYM_GRAPH *graph, int rootidx, SCIP_VAR **vars, SCIP_Real *vals, int nvars, SCIP_Real constant)
int SCIPgetSymgraphNegatedVarnodeidx(SCIP *scip, SYM_GRAPH *graph, SCIP_VAR *var)
return SCIP_OKAY
int c
static SCIP_SOL * sol
assert(minobj< SCIPgetCutoffbound(scip))
int nvars
static SCIP_Bool propagate
static SCIP_VAR ** vars
memory allocation routines
public methods for managing constraints
public methods for user interface dialog
public methods for primal heuristics
public methods for message output
#define SCIPerrorMessage
Definition pub_message.h:64
#define SCIPdebug(x)
Definition pub_message.h:93
#define SCIPdebugPrintf
Definition pub_message.h:99
public data structures and miscellaneous methods
public methods for primal CIP solutions
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 dialog handler plugins
general public methods
public methods for memory management
public methods for message handling
public methods for numerical tolerances
public methods for SCIP parameter handling
public methods for global and local (sub)problems
public methods for solutions
public methods for SCIP variables
static SCIP_RETCODE separate(SCIP *scip, SCIP_SEPA *sepa, SCIP_SOL *sol, SCIP_RESULT *result)
Main separation function.
methods for dealing with symmetry detection graphs
#define SCIP_DECL_CONSGETSIGNEDPERMSYMGRAPH(x)
Definition type_cons.h:956
#define SCIP_DECL_CONSGETPERMSYMGRAPH(x)
Definition type_cons.h:938
#define SCIP_DECL_CONSENFOLP(x)
Definition type_cons.h:363
#define SCIP_DECL_CONSINITPRE(x)
Definition type_cons.h:156
#define SCIP_DECL_CONSDELETE(x)
Definition type_cons.h:229
struct SCIP_Cons SCIP_CONS
Definition type_cons.h:63
#define SCIP_DECL_CONSGETVARS(x)
Definition type_cons.h:867
#define SCIP_DECL_CONSPRINT(x)
Definition type_cons.h:769
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition type_cons.h:64
#define SCIP_DECL_CONSSEPALP(x)
Definition type_cons.h:288
struct SYM_Graph SYM_GRAPH
Definition type_cons.h:68
#define SCIP_DECL_CONSENFORELAX(x)
Definition type_cons.h:388
#define SCIP_DECL_CONSPROP(x)
Definition type_cons.h:506
#define SCIP_DECL_CONSGETNVARS(x)
Definition type_cons.h:885
#define SCIP_DECL_CONSRESPROP(x)
Definition type_cons.h:612
#define SCIP_DECL_CONSENFOPS(x)
Definition type_cons.h:431
#define SCIP_DECL_CONSPARSE(x)
Definition type_cons.h:845
#define SCIP_DECL_CONSTRANS(x)
Definition type_cons.h:239
#define SCIP_DECL_CONSPRESOL(x)
Definition type_cons.h:561
#define SCIP_DECL_CONSINITLP(x)
Definition type_cons.h:259
#define SCIP_DECL_CONSLOCK(x)
Definition type_cons.h:676
struct SCIP_Conshdlr SCIP_CONSHDLR
Definition type_cons.h:62
#define SCIP_DECL_CONSCOPY(x)
Definition type_cons.h:810
struct SCIP_ConsData SCIP_CONSDATA
Definition type_cons.h:65
#define SCIP_DECL_CONSCHECK(x)
Definition type_cons.h:474
#define SCIP_DECL_CONSHDLRCOPY(x)
Definition type_cons.h:108
#define SCIP_DECL_CONSFREE(x)
Definition type_cons.h:116
#define SCIP_DECL_CONSSEPASOL(x)
Definition type_cons.h:320
struct SCIP_Dialog SCIP_DIALOG
Definition type_dialog.h:50
#define SCIP_DECL_DIALOGEXEC(x)
Definition type_dialog.h:96
@ SCIP_VERBLEVEL_MINIMAL
@ SCIP_OBJSENSE_MINIMIZE
Definition type_prob.h:48
@ SCIP_DIDNOTRUN
Definition type_result.h:42
@ SCIP_CUTOFF
Definition type_result.h:48
@ SCIP_FEASIBLE
Definition type_result.h:45
@ SCIP_DELAYED
Definition type_result.h:43
@ SCIP_REDUCEDDOM
Definition type_result.h:51
@ SCIP_DIDNOTFIND
Definition type_result.h:44
@ SCIP_CONSADDED
Definition type_result.h:52
@ SCIP_UNBOUNDED
Definition type_result.h:47
@ SCIP_BRANCHED
Definition type_result.h:54
@ SCIP_SEPARATED
Definition type_result.h:49
@ SCIP_SOLVELP
Definition type_result.h:55
@ SCIP_NEWROUND
Definition type_result.h:50
@ 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_INVALIDRESULT
@ SCIP_PLUGINNOTFOUND
@ SCIP_INVALIDCALL
enum SCIP_Retcode SCIP_RETCODE
struct Scip SCIP
Definition type_scip.h:39
@ SCIP_STAGE_PROBLEM
Definition type_set.h:45
@ SCIP_STAGE_INITPRESOLVE
Definition type_set.h:48
@ SCIP_STAGE_SOLVED
Definition type_set.h:54
@ SCIP_STAGE_PRESOLVING
Definition type_set.h:49
@ SCIP_STAGE_TRANSFORMED
Definition type_set.h:47
@ SCIP_STAGE_INITSOLVE
Definition type_set.h:52
@ SCIP_STAGE_EXITPRESOLVE
Definition type_set.h:50
@ SCIP_STAGE_EXITSOLVE
Definition type_set.h:55
@ SCIP_STAGE_INIT
Definition type_set.h:44
@ SCIP_STAGE_FREE
Definition type_set.h:57
@ SCIP_STAGE_FREETRANS
Definition type_set.h:56
@ SCIP_STAGE_SOLVING
Definition type_set.h:53
@ SCIP_STAGE_TRANSFORMING
Definition type_set.h:46
@ SCIP_STAGE_PRESOLVED
Definition type_set.h:51
struct SCIP_Sol SCIP_SOL
Definition type_sol.h:57
enum SYM_Symtype SYM_SYMTYPE
@ SYM_CONSOPTYPE_SUM
@ SYM_SYMTYPE_SIGNPERM
@ SYM_SYMTYPE_PERM
struct SCIP_Var SCIP_VAR
Definition type_var.h:166
@ SCIP_VARTYPE_BINARY
Definition type_var.h:64
@ SCIP_VARSTATUS_NEGATED
Definition type_var.h:57
@ SCIP_LOCKTYPE_MODEL
Definition type_var.h:141