Scippy

SCIP

Solving Constraint Integer Programs

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-2024 Zuse Institute Berlin (ZIB) */
7/* */
8/* Licensed under the Apache License, Version 2.0 (the "License"); */
9/* you may not use this file except in compliance with the License. */
10/* You may obtain a copy of the License at */
11/* */
12/* http://www.apache.org/licenses/LICENSE-2.0 */
13/* */
14/* Unless required by applicable law or agreed to in writing, software */
15/* distributed under the License is distributed on an "AS IS" BASIS, */
16/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17/* See the License for the specific language governing permissions and */
18/* limitations under the License. */
19/* */
20/* You should have received a copy of the Apache-2.0 license */
21/* along with SCIP; see the file LICENSE. If not visit scipopt.org. */
22/* */
23/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25/**@file cons_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 <string.h>
69
70/* constraint handler properties */
71#define CONSHDLR_NAME "superindicator"
72#define CONSHDLR_DESC "constraint handler for indicator constraints over arbitrary constraint types"
73#define CONSHDLR_SEPAPRIORITY 0 /**< priority of the constraint handler for separation */
74#define CONSHDLR_ENFOPRIORITY -5000000 /**< priority of the constraint handler for constraint enforcing */
75#define CONSHDLR_CHECKPRIORITY -5000000 /**< priority of the constraint handler for checking feasibility */
76#define CONSHDLR_SEPAFREQ -1 /**< frequency for separating cuts; zero means to separate only in the root node */
77#define CONSHDLR_PROPFREQ 1 /**< frequency for propagating domains; zero means only preprocessing propagation */
78#define CONSHDLR_EAGERFREQ 100 /**< frequency for using all instead of only the useful constraints in separation,
79 * propagation and enforcement, -1 for no eager evaluations, 0 for first only */
80#define CONSHDLR_MAXPREROUNDS -1 /**< maximal number of presolving rounds the constraint handler
81 * participates in (-1: no limit) */
82#define CONSHDLR_DELAYSEPA FALSE /**< should separation method be delayed, if other separators found cuts? */
83#define CONSHDLR_DELAYPROP FALSE /**< should propagation method be delayed, if other propagators found reductions? */
84#define CONSHDLR_NEEDSCONS TRUE /**< should the constraint handler be skipped, if no constraints are available? */
85
86#define CONSHDLR_PROP_TIMING SCIP_PROPTIMING_BEFORELP /**< propagation timing mask of the constraint handler */
87#define CONSHDLR_PRESOLTIMING SCIP_PRESOLTIMING_MEDIUM /**< presolving timing of the constraint handler (fast, medium, or exhaustive) */
88
89#define DEFAULT_CHECKSLACKTYPE TRUE /**< should type of slack constraint be checked when creating superindicator constraint? */
90#define DEFAULT_UPGDPRIOINDICATOR 1 /**< priority for upgrading to an indicator constraint (-1: never) */
91#define DEFAULT_UPGDPRIOLINEAR 2 /**< priority for upgrading to a linear constraint (-1: never) */
92#define DEFAULT_MAXUPGDCOEFLINEAR 1e4 /**< maximum big-M coefficient of binary variable in upgrade to a linear constraint
93 * (relative to smallest coefficient) */
94
95
96/*
97 * Data structures
98 */
99
100/** constraint data for superindicator constraints */
101struct SCIP_ConsData
102{
103 SCIP_CONS* slackcons; /**< constraint corresponding to the handled constraint */
104 SCIP_VAR* binvar; /**< binary variable for indicator constraint */
105};
106
107/** constraint handler data */
108struct SCIP_ConshdlrData
109{
110 SCIP_Bool checkslacktype; /**< should type of slack constraint be checked when creating superindicator constraint? */
111 SCIP_Real maxupgdcoeflinear; /**< maximum big-M coefficient of binary variable in upgrade to a linear constraint
112 * (relative to smallest coefficient) */
113 int upgdprioindicator; /**< priority for upgrading to an indicator constraint (-1: never) */
114 int upgdpriolinear; /**< priority for upgrading to a linear constraint (-1: never) */
115 int nrejects; /**< number of rejected calls to create method */
116};
117
118/*
119 * Local methods
120 */
121
122/** creates superindicator constraint data */
123static
125 SCIP* scip, /**< SCIP data structure */
126 SCIP_CONSDATA** consdata, /**< pointer to constraint data */
127 SCIP_VAR* binvar, /**< binary variable */
128 SCIP_CONS* slackcons /**< slack constraint */
129 )
130{
131 assert(scip != NULL);
132
133 SCIP_CALL( SCIPallocBlockMemory(scip, consdata) );
134
135 (*consdata)->binvar = binvar;
136 (*consdata)->slackcons = slackcons;
137
139 {
140 SCIPdebugMsg(scip, "creating the transformed data\n");
141
142 /* do not capture the slack constraint when scip is in transformed mode; this automatically happens in
143 * SCIPtransformCons() if necessary
144 */
145 SCIP_CALL( SCIPtransformCons(scip, (*consdata)->slackcons, &(*consdata)->slackcons) );
146
147 /* get transformed binary variable */
148 SCIP_CALL( SCIPgetTransformedVar(scip, (*consdata)->binvar, &(*consdata)->binvar) );
149 }
150 else
151 {
152 /* we need to capture the constraint to avoid that SCIP deletes them since they are not (yet) added to the problem */
153 SCIP_CALL( SCIPcaptureCons(scip, slackcons) );
154 }
155
156 assert((*consdata)->slackcons != NULL);
157
158 return SCIP_OKAY;
159}
160
161/** checks the feasibility of a superindicator constraint */
162static
164 SCIP* scip, /**< SCIP data structure */
165 SCIP_CONSDATA* consdata, /**< pointer to superindicator constraint data */
166 SCIP_SOL* sol, /**< pointer to the solution to be checked */
167 SCIP_Bool checkintegrality, /**< Has integrality to be checked? */
168 SCIP_Bool checklprows, /**< Do constraints represented by rows in the current LP have to be checked? */
169 SCIP_Bool printreason, /**< Should the reason for the violation be printed? */
170 SCIP_RESULT* result /**< pointer to store the result of the test */
171 )
172{
173 SCIP_Real binval;
174
175 /* not to be called if infeasibility is already detected */
176 assert(*result == SCIP_FEASIBLE || *result == SCIP_DIDNOTRUN);
177
178 binval = SCIPgetSolVal(scip, sol, consdata->binvar);
179
180 /* check integrality of binary variable */
181 if( checkintegrality && !SCIPisIntegral(scip, binval) )
182 {
183 if( printreason )
184 {
185 SCIPinfoMessage(scip, NULL, "violation: binvar takes fractional value %.15g\n", binval);
186 }
187
188 *result = SCIP_INFEASIBLE;
189 }
190 /* if binvar is one, call SCIPcheckCons() for the slack constraint */
191 else if( binval > 0.5 )
192 {
193 assert(SCIPisFeasEQ(scip, binval, 1.0));
194
195 SCIP_CALL( SCIPcheckCons(scip, consdata->slackcons, sol, checkintegrality, checklprows, printreason, result) );
196
197 if( printreason && *result != SCIP_FEASIBLE )
198 {
199 SCIPinfoMessage(scip, NULL, "violation: SCIPcheckCons() for slack constraint <%s> returns infeasible while binvar <%s> == 1\n",
200 SCIPconsGetName(consdata->slackcons), SCIPvarGetName(consdata->binvar));
201 }
202
203#ifdef SCIP_DEBUG
204 {
205 /* checking in debug mode that different flags don't give us different results */
206 SCIP_RESULT testresultnotintegrality;
207 SCIP_RESULT testresultnotlprows;
208
209 SCIP_CALL( SCIPcheckCons(scip, consdata->slackcons, sol, checkintegrality, TRUE, TRUE, &testresultnotintegrality) );
210 SCIP_CALL( SCIPcheckCons(scip, consdata->slackcons, sol, TRUE, checklprows, TRUE, &testresultnotlprows) );
211
212 assert(*result == testresultnotintegrality);
213 assert(*result == testresultnotlprows);
214 }
215#endif
216
217 SCIPdebugMsg(scip, "binvar <%s> == 1, sol=%p --> SCIPcheckCons() on constraint <%s> --> %s\n",
218 SCIPvarGetName(consdata->binvar), (void*)sol, SCIPconsGetName(consdata->slackcons),
219 *result == SCIP_FEASIBLE ? "satisfied" : "violated");
220 }
221 /* if binval is zero, the superindicator constraint is feasible */
222 else
223 {
224 *result = SCIP_FEASIBLE;
225 }
226
227 return SCIP_OKAY;
228}
229
230/** computes the minactivity, maxactivity, and minimal absolute value of nonzero coefficients of a linear constraint
231 * with respect to its global bounds
232 */
233static
235 SCIP* scip, /**< SCIP data structure */
236 SCIP_CONS* cons, /**< pointer to linear constraint */
237 SCIP_Real* minactivity, /**< pointer to return the minimal activity */
238 SCIP_Real* maxactivity, /**< pointer to return the maximal activity */
239 SCIP_Real* minabscoef /**< pointer to return the minimal absolute value of the coefficients */
240 )
241{
242 SCIP_VAR** vars;
243 SCIP_Real* vals;
244 SCIP_Bool ismininfinity;
245 SCIP_Bool ismaxinfinity;
246 int nvars;
247 int i;
248
249 assert(scip != NULL);
250 assert(cons != NULL);
251 assert(minactivity != NULL);
252 assert(maxactivity != NULL);
253 assert(minabscoef != NULL);
254 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), "linear") == 0);
255
256 /* get nonzero elements */
257 vars = SCIPgetVarsLinear(scip, cons);
258 vals = SCIPgetValsLinear(scip, cons);
259 nvars = SCIPgetNVarsLinear(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];
278 lb = SCIPvarGetLbGlobal(vars[i]);
279 ub = SCIPvarGetUbGlobal(vars[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 */
397 SCIP_CALL( SCIPallocBufferArray(scip, &negvals, nvars) );
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 {
698 *result = SCIP_FEASIBLE;
699 return SCIP_OKAY;
700 }
701
702 SCIPdebugMsg(scip, "executing enforcement callback for %s solution\n", sol == NULL ? "LP" : "relaxation");
703
704 cont = TRUE;
705 *result = SCIP_FEASIBLE;
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:
755 assert(*result != SCIP_CUTOFF);
756 assert(*result != SCIP_BRANCHED);
757 *result = locresult;
758 cont = FALSE;
759 break;
760 case SCIP_CONSADDED:
761 assert(*result != SCIP_CUTOFF);
762 assert(*result != SCIP_BRANCHED);
763 if( *result != SCIP_CUTOFF )
764 *result = locresult;
765 break;
766 case SCIP_REDUCEDDOM:
767 assert(*result != SCIP_CUTOFF);
768 assert(*result != SCIP_BRANCHED);
769 if( *result != SCIP_CUTOFF
770 && *result != SCIP_CONSADDED )
771 *result = locresult;
772 break;
773 case SCIP_SEPARATED:
774 assert(*result != SCIP_CUTOFF);
775 assert(*result != SCIP_BRANCHED);
776 if( *result != SCIP_CUTOFF
777 && *result != SCIP_CONSADDED
778 && *result != SCIP_REDUCEDDOM )
779 *result = locresult;
780 break;
781 case SCIP_INFEASIBLE:
782 assert(*result != SCIP_CUTOFF);
783 assert(*result != SCIP_BRANCHED);
784 if( *result != SCIP_CUTOFF
785 && *result != SCIP_CONSADDED
786 && *result != SCIP_REDUCEDDOM
787 && *result != SCIP_SEPARATED
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/*
806 * Callback methods of constraint handler
807 */
808
809/** copy method for constraint handler plugins (called when SCIP copies plugins) */
810static
811SCIP_DECL_CONSHDLRCOPY(conshdlrCopySuperindicator)
812{ /*lint --e{715}*/
813 assert(scip != NULL);
814 assert(conshdlr != NULL);
815 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
816
817 /* call inclusion method of constraint handler */
819
820 *valid = TRUE;
821
822 return SCIP_OKAY;
823}
824
825/** destructor of constraint handler to free constraint handler data (called when SCIP is exiting) */
826static
827SCIP_DECL_CONSFREE(consFreeSuperindicator)
828{ /*lint --e{715}*/
829 SCIP_CONSHDLRDATA* conshdlrdata;
830
831 assert(conshdlr != NULL);
832 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
833 assert(scip != NULL);
834
835 SCIPdebugMsg(scip, "freeing superindicator constraint handler data\n");
836
837 /* free constraint handler data */
838 conshdlrdata = SCIPconshdlrGetData(conshdlr);
839 assert(conshdlrdata != NULL);
840
841 SCIPfreeBlockMemory(scip, &conshdlrdata);
842
843 SCIPconshdlrSetData(conshdlr, NULL);
844
845 return SCIP_OKAY;
846}
847
848/** presolving initialization method of constraint handler (called when presolving is about to begin) */
849static
850SCIP_DECL_CONSINITPRE(consInitpreSuperindicator)
851{ /*lint --e{715}*/
852 SCIP_CONSDATA* consdata;
853 int i;
854
855 SCIPdebugMsg(scip, "initializing presolving\n");
856
857 for( i = nconss-1; i >= 0; i-- )
858 {
859 consdata = SCIPconsGetData(conss[i]);
860 assert(consdata != NULL);
861
862 /* make the constraint local to avoid wrong propagation */
863 SCIP_CALL( SCIPsetConsLocal(scip, consdata->slackcons, TRUE) );
864 }
865
866 return SCIP_OKAY;
867}
868
869/** frees specific constraint data */
870static
871SCIP_DECL_CONSDELETE(consDeleteSuperindicator)
872{ /*lint --e{715}*/
873 assert(conshdlr != NULL);
874 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
875 assert(consdata != NULL);
876 assert(*consdata != NULL);
877 assert((*consdata)->slackcons != NULL);
878
879 SCIPdebugMsg(scip, "deleting constraint <%s>\n", SCIPconsGetName(cons));
880
881 /* we have to release the slack constraint also in case we transformed it manually since it is captured automatically
882 * in SCIPtransformCons()
883 */
884 SCIP_CALL( SCIPreleaseCons(scip, &((*consdata)->slackcons)) );
885
886 /* free memory */
887 SCIPfreeBlockMemory(scip, consdata);
888
889 return SCIP_OKAY;
890}
891
892/** transforms constraint data into data belonging to the transformed problem */
893static
894SCIP_DECL_CONSTRANS(consTransSuperindicator)
895{ /*lint --e{715}*/
896 SCIP_CONSDATA* sourcedata;
897 SCIP_CONSDATA* targetdata;
898 char newname[SCIP_MAXSTRLEN];
899
900 SCIPdebugMsg(scip, "transforming superindicator constraint <%s>\n", SCIPconsGetName(sourcecons));
901
902 /* get constraint data of source constraint */
903 sourcedata = SCIPconsGetData(sourcecons);
904 assert(sourcedata != NULL);
905
906 (void) SCIPsnprintf(newname, SCIP_MAXSTRLEN, "t_%s", SCIPconsGetName(sourcecons) );
907 SCIP_CALL( consdataCreateSuperindicator(scip, &targetdata, sourcedata->binvar, sourcedata->slackcons) );
908
909 /* create target constraint and capture it at the same time */
910 SCIP_CALL( SCIPcreateCons(scip, targetcons, newname, conshdlr, targetdata,
911 SCIPconsIsInitial(sourcecons), SCIPconsIsSeparated(sourcecons), SCIPconsIsEnforced(sourcecons),
912 SCIPconsIsChecked(sourcecons), SCIPconsIsPropagated(sourcecons), SCIPconsIsLocal(sourcecons),
913 SCIPconsIsModifiable(sourcecons), SCIPconsIsDynamic(sourcecons), SCIPconsIsRemovable(sourcecons),
914 SCIPconsIsStickingAtNode(sourcecons)) );
915
916 return SCIP_OKAY;
917}
918
919/** LP initialization method of constraint handler */
920static
921SCIP_DECL_CONSINITLP(consInitlpSuperindicator)
922{
923 int c;
924
925 assert(scip != NULL);
926 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
927 assert(infeasible != NULL);
928
929 *infeasible = FALSE;
930
931 SCIPdebugMsg(scip, "executing initlp callback\n");
932
933 for( c = nconss-1; c >= 0 && !(*infeasible); c-- )
934 {
935 SCIP_CONSDATA* consdata;
936
937 consdata = SCIPconsGetData(conss[c]);
938
939 assert(consdata != NULL);
940 assert(SCIPconsIsInitial(conss[c]));
941
942 if( SCIPvarGetLbLocal(consdata->binvar) > 0.5 )
943 {
944 assert(SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->binvar), 1.0));
945
946 SCIPdebugMsg(scip, "binvar <%s> == 1 --> SCIPinitlpCons() on constraint <%s>\n",
947 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
948
949 SCIP_CALL( SCIPinitlpCons(scip, consdata->slackcons, infeasible) );
950 }
951 }
952
953 return SCIP_OKAY;
954}
955
956/** separation method of constraint handler for LP solutions */
957static
958SCIP_DECL_CONSSEPALP(consSepalpSuperindicator)
959{ /*lint --e{715}*/
960 int c;
961
962 assert(conshdlr != NULL);
963 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
964 assert(conss != NULL);
965 assert(result != NULL);
966
967 *result = SCIP_DELAYED;
968
969 SCIPdebugMsg(scip, "executing sepalp callback\n");
970
971#ifdef SCIP_OUTPUT
973#endif
974
975 /* check all useful constraints */
976 for( c = nusefulconss-1; c >= 0 && *result != SCIP_CUTOFF; c-- )
977 {
978 SCIP_CONSDATA* consdata;
979 SCIP_RESULT locresult;
980
981 consdata = SCIPconsGetData(conss[c]);
982 assert(consdata != NULL);
983
984 locresult = SCIP_DELAYED;
985
986 /* separate only if binvar is fixed to one */
987 if( SCIPvarGetLbLocal(consdata->binvar) > 0.5 )
988 {
989 assert(SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->binvar), 1.0));
990
991 SCIPdebugMsg(scip, "binvar <%s> == 1 --> SCIPsepalpCons() on constraint <%s>\n",
992 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
993
994 SCIP_CALL( SCIPsepalpCons(scip, consdata->slackcons, &locresult) );
995
996 SCIPdebugMsgPrint(scip, " --> locresult=%d\n", locresult);
997 }
998
999 /* evaluate result value */
1000 switch( locresult )
1001 {
1002 case SCIP_CUTOFF:
1003 case SCIP_CONSADDED:
1004 assert(*result != SCIP_CUTOFF);
1005 *result = locresult;
1006 break;
1007 case SCIP_REDUCEDDOM:
1008 assert(*result != SCIP_CUTOFF);
1009 if( *result != SCIP_CONSADDED )
1010 *result = locresult;
1011 break;
1012 case SCIP_SEPARATED:
1013 assert(*result != SCIP_CUTOFF);
1014 if( *result != SCIP_CONSADDED
1015 && *result != SCIP_REDUCEDDOM )
1016 *result = locresult;
1017 break;
1018 case SCIP_NEWROUND:
1019 assert(*result != SCIP_CUTOFF);
1020 if( *result != SCIP_CONSADDED
1021 && *result != SCIP_REDUCEDDOM
1022 && *result != SCIP_SEPARATED )
1023 *result = locresult;
1024 break;
1025 case SCIP_DIDNOTFIND:
1026 assert(*result != SCIP_CUTOFF);
1027 if( *result != SCIP_CONSADDED
1028 && *result != SCIP_REDUCEDDOM
1029 && *result != SCIP_NEWROUND
1030 && *result != SCIP_SEPARATED )
1031 *result = locresult;
1032 break;
1033 case SCIP_DIDNOTRUN:
1034 assert(*result != SCIP_CUTOFF);
1035 if( *result != SCIP_CONSADDED
1036 && *result != SCIP_REDUCEDDOM
1037 && *result != SCIP_NEWROUND
1038 && *result != SCIP_SEPARATED
1039 && *result != SCIP_DIDNOTFIND )
1040 *result = locresult;
1041 break;
1042 case SCIP_INFEASIBLE:
1043 assert(*result != SCIP_CUTOFF);
1044 if( *result != SCIP_CONSADDED
1045 && *result != SCIP_REDUCEDDOM
1046 && *result != SCIP_SEPARATED
1047 && *result != SCIP_DIDNOTFIND
1048 && *result != SCIP_DIDNOTRUN
1049 && *result != SCIP_NEWROUND )
1050 *result = locresult;
1051 break;
1052 case SCIP_DELAYED:
1053 break;
1054 default:
1055 SCIPerrorMessage("invalid SCIP result %d\n", locresult);
1056 return SCIP_INVALIDRESULT;
1057 } /*lint !e788*/
1058 }
1059
1060 SCIPdebugMsg(scip, "sepalp result=%d\n", *result);
1061
1062 return SCIP_OKAY;
1063}
1064
1065/** separation method of constraint handler for arbitrary primal solutions */
1066static
1067SCIP_DECL_CONSSEPASOL(consSepasolSuperindicator)
1068{ /*lint --e{715}*/
1069 int c;
1070
1071 assert(conshdlr != NULL);
1072 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
1073 assert(conss != NULL);
1074 assert(result != NULL);
1075
1076 *result = SCIP_DELAYED;
1077
1078 SCIPdebugMsg(scip, "executing sepasol callback\n");
1079
1080#ifdef SCIP_OUTPUT
1082#endif
1083
1084 /* check all the useful constraint */
1085 for( c = 0; c < nusefulconss && *result != SCIP_CUTOFF; ++c )
1086 {
1087 SCIP_CONSDATA* consdata;
1088 SCIP_RESULT locresult;
1089
1090 consdata = SCIPconsGetData(conss[c]);
1091 assert(consdata != NULL);
1092
1093 locresult = SCIP_DELAYED;
1094
1095 /* separate only if binvar is fixed to one */
1096 if( SCIPvarGetLbLocal(consdata->binvar) > 0.5 )
1097 {
1098 assert(SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->binvar), 1.0));
1099
1100 SCIPdebugMsg(scip, "binvar <%s> == 0 --> SCIPsepasolCons() on constraint <%s>\n",
1101 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
1102
1103 SCIP_CALL( SCIPsepasolCons(scip, consdata->slackcons, sol, &locresult) );
1104
1105 SCIPdebugMsgPrint(scip, " --> result=%d\n", locresult);
1106 }
1107
1108 /* evaluate result value */
1109 switch( locresult )
1110 {
1111 case SCIP_CUTOFF:
1112 case SCIP_CONSADDED:
1113 assert(*result != SCIP_CUTOFF);
1114 *result = locresult;
1115 break;
1116 case SCIP_REDUCEDDOM:
1117 assert(*result != SCIP_CUTOFF);
1118 if( *result != SCIP_CONSADDED )
1119 *result = locresult;
1120 break;
1121 case SCIP_SEPARATED:
1122 assert(*result != SCIP_CUTOFF);
1123 if( *result != SCIP_CONSADDED
1124 && *result != SCIP_REDUCEDDOM )
1125 *result = locresult;
1126 break;
1127 case SCIP_NEWROUND:
1128 assert(*result != SCIP_CUTOFF);
1129 if( *result != SCIP_CONSADDED
1130 && *result != SCIP_REDUCEDDOM
1131 && *result != SCIP_SEPARATED )
1132 *result = locresult;
1133 break;
1134 case SCIP_DIDNOTFIND:
1135 assert(*result != SCIP_CUTOFF);
1136 if( *result != SCIP_CONSADDED
1137 && *result != SCIP_REDUCEDDOM
1138 && *result != SCIP_NEWROUND
1139 && *result != SCIP_SEPARATED )
1140 *result = locresult;
1141 break;
1142 case SCIP_DIDNOTRUN:
1143 assert(*result != SCIP_CUTOFF);
1144 if( *result != SCIP_CONSADDED
1145 && *result != SCIP_REDUCEDDOM
1146 && *result != SCIP_NEWROUND
1147 && *result != SCIP_SEPARATED
1148 && *result != SCIP_DIDNOTFIND )
1149 *result = locresult;
1150 break;
1151 case SCIP_INFEASIBLE:
1152 assert(*result != SCIP_CUTOFF);
1153 if( *result != SCIP_CONSADDED
1154 && *result != SCIP_REDUCEDDOM
1155 && *result != SCIP_SEPARATED
1156 && *result != SCIP_DIDNOTFIND
1157 && *result != SCIP_DIDNOTRUN
1158 && *result != SCIP_NEWROUND )
1159 *result = locresult;
1160 break;
1161 case SCIP_DELAYED:
1162 break;
1163 default:
1164 SCIPerrorMessage("invalid SCIP result %d\n", locresult);
1165 return SCIP_INVALIDRESULT;
1166 } /*lint !e788*/
1167 }
1168
1169 SCIPdebugMsg(scip, "sepa sol result=%d\n", *result);
1170
1171 return SCIP_OKAY;
1172}
1173
1174/** constraint enforcing method of constraint handler for LP solutions */
1175static
1176SCIP_DECL_CONSENFOLP(consEnfolpSuperindicator)
1177{ /*lint --e{715}*/
1178 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, NULL, solinfeasible, result) );
1179
1180 return SCIP_OKAY;
1181}
1182
1183/** constraint enforcing method of constraint handler for relaxation solutions */
1184static
1185SCIP_DECL_CONSENFORELAX(consEnforelaxSuperindicator)
1186{ /*lint --e{715}*/
1187 SCIP_CALL( enforceConstraint(scip, conshdlr, conss, nconss, nusefulconss, sol, solinfeasible, result) );
1188
1189 return SCIP_OKAY;
1190}
1191
1192/** constraint enforcing method of constraint handler for pseudo solutions */
1193static
1194SCIP_DECL_CONSENFOPS(consEnfopsSuperindicator)
1195{ /*lint --e{715}*/
1196 SCIP_Bool cont;
1197 int i;
1198
1199 assert(scip != NULL);
1200 assert(conshdlr != NULL);
1201 assert(result != NULL);
1202
1203 /* if the solution is infeasible anyway, skip the enforcement */
1204 if( solinfeasible )
1205 {
1206 *result = SCIP_FEASIBLE;
1207 return SCIP_OKAY;
1208 }
1209 else if( objinfeasible )
1210 {
1211 *result = SCIP_DIDNOTRUN;
1212 return SCIP_OKAY;
1213 }
1214
1215 SCIPdebugMsg(scip, "executing enfops callback\n");
1216
1217 *result = SCIP_FEASIBLE;
1218 cont = TRUE;
1219
1220 /* check all contraints */
1221 for( i = nconss-1; i >= 0 && cont; i-- )
1222 {
1223 SCIP_CONSDATA* consdata;
1224 SCIP_RESULT locresult;
1225
1226 consdata = SCIPconsGetData(conss[i]);
1227 assert(consdata != NULL);
1228
1229 locresult = SCIP_DIDNOTRUN;
1230
1231 /* enforce only if binvar is fixed to one */
1232 if( SCIPvarGetLbLocal(consdata->binvar) > 0.5 )
1233 {
1234 assert(SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->binvar), 1.0));
1235
1236 SCIPdebugMsg(scip, "binvar <%s> == 1 locally --> SCIPenfopsCons() on constraint <%s>\n",
1237 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
1238
1239 SCIP_CALL( SCIPenfopsCons(scip, consdata->slackcons, solinfeasible, objinfeasible, &locresult) );
1240
1241 SCIPdebugMsgPrint(scip, " --> %slocresult=%d\n", locresult == SCIP_FEASIBLE ? "satisfied, " : "", locresult);
1242 }
1243 /* otherwise check if we have not yet detected infeasibility */
1244 else if( *result == SCIP_FEASIBLE || *result == SCIP_DIDNOTRUN )
1245 {
1246 SCIP_CALL( consdataCheckSuperindicator(scip, consdata, NULL, TRUE, FALSE, FALSE, &locresult) );
1247 }
1248
1249 /* evaluate result value */
1250 switch( locresult )
1251 {
1252 case SCIP_CUTOFF:
1253 case SCIP_BRANCHED:
1254 assert(*result != SCIP_CUTOFF);
1255 assert(*result != SCIP_BRANCHED);
1256 *result = locresult;
1257 cont = FALSE;
1258 break;
1259 case SCIP_CONSADDED:
1260 assert(*result != SCIP_CUTOFF);
1261 assert(*result != SCIP_BRANCHED);
1262 if( *result != SCIP_CUTOFF )
1263 *result = locresult;
1264 break;
1265 case SCIP_REDUCEDDOM:
1266 assert(*result != SCIP_CUTOFF);
1267 assert(*result != SCIP_BRANCHED);
1268 if( *result != SCIP_CUTOFF
1269 && *result != SCIP_CONSADDED )
1270 *result = locresult;
1271 break;
1272 case SCIP_SOLVELP:
1273 assert(*result != SCIP_CUTOFF);
1274 assert(*result != SCIP_BRANCHED);
1275 if( *result != SCIP_CUTOFF
1276 && *result != SCIP_CONSADDED
1277 && *result != SCIP_REDUCEDDOM
1278 && *result != SCIP_BRANCHED )
1279 *result = locresult;
1280 break;
1281 case SCIP_INFEASIBLE:
1282 assert(*result != SCIP_CUTOFF);
1283 assert(*result != SCIP_BRANCHED);
1284 if( *result != SCIP_CUTOFF
1285 && *result != SCIP_CONSADDED
1286 && *result != SCIP_REDUCEDDOM
1287 && *result != SCIP_BRANCHED
1288 && *result != SCIP_SOLVELP )
1289 *result = locresult;
1290 break;
1291 case SCIP_DIDNOTRUN:
1292 assert(*result != SCIP_CUTOFF);
1293 assert(*result != SCIP_BRANCHED);
1294 if( *result != SCIP_CUTOFF
1295 && *result != SCIP_CONSADDED
1296 && *result != SCIP_REDUCEDDOM
1297 && *result != SCIP_BRANCHED
1298 && *result != SCIP_SOLVELP
1299 && *result != SCIP_INFEASIBLE )
1300 *result = locresult;
1301 break;
1302 case SCIP_FEASIBLE:
1303 assert(*result != SCIP_CUTOFF);
1304 assert(*result != SCIP_BRANCHED);
1305 if( *result != SCIP_CUTOFF
1306 && *result != SCIP_CONSADDED
1307 && *result != SCIP_REDUCEDDOM
1308 && *result != SCIP_BRANCHED
1309 && *result != SCIP_SOLVELP
1310 && *result != SCIP_INFEASIBLE
1311 && *result != SCIP_DIDNOTRUN )
1312 *result = locresult;
1313 break;
1314 default:
1315 SCIPerrorMessage("invalid SCIP result %d\n", locresult);
1316 return SCIP_INVALIDRESULT;
1317 } /*lint !e788*/
1318 }
1319
1320 SCIPdebugMsg(scip, "enfops result=%d\n", *result);
1321
1322 return SCIP_OKAY;
1323}
1324
1325/** feasibility check method of constraint handler for integral solutions */
1326static
1327SCIP_DECL_CONSCHECK(consCheckSuperindicator)
1328{ /*lint --e{715}*/
1329 int i;
1330
1331 assert(scip != NULL);
1332 assert(conshdlr != NULL);
1333 assert(result != NULL);
1334 assert(sol != NULL);
1335
1336 *result = SCIP_FEASIBLE;
1337
1338 for( i = nconss-1; i >= 0 && (*result == SCIP_FEASIBLE || completely); i-- )
1339 {
1340 SCIP_CONSDATA* consdata;
1341
1342 consdata = SCIPconsGetData(conss[i]);
1343 SCIP_CALL( consdataCheckSuperindicator(scip, consdata, sol, checkintegrality, checklprows, printreason, result) );
1344 }
1345
1346 SCIPdebugMsg(scip, "checked solution from <%s> (checkintegrality=%u, checklprows=%u) --> result=%d (%sfeasible)\n",
1347 SCIPsolGetHeur(sol) == NULL ? "NULL" : SCIPheurGetName(SCIPsolGetHeur(sol)), checkintegrality, checklprows,
1348 *result, *result == SCIP_INFEASIBLE ? "in" : "");
1349
1350 return SCIP_OKAY;
1351}
1352
1353/** domain propagation method of constraint handler */
1354static
1355SCIP_DECL_CONSPROP(consPropSuperindicator)
1356{ /*lint --e{715}*/
1357 int i;
1358
1359 assert(scip != NULL);
1360 assert(conshdlr != NULL);
1361 assert(result != NULL);
1362
1363 *result = SCIP_DIDNOTRUN;
1364
1365 SCIPdebugMsg(scip, "executing prop callback\n");
1366
1367 /* loop over all useful contraints */
1368 for( i = nusefulconss-1; i >= 0 && *result != SCIP_CUTOFF; i-- )
1369 {
1370 SCIP_CONSDATA* consdata;
1371 SCIP_RESULT locresult;
1372
1373 consdata = SCIPconsGetData(conss[i]);
1374 assert(consdata != NULL);
1375
1376 locresult = SCIP_DIDNOTRUN;
1377
1378 /* propagate only if binvar is fixed to one */
1379 if( SCIPvarGetLbGlobal(consdata->binvar) > 0.5 )
1380 {
1381 assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(consdata->binvar), 1.0));
1382
1383 SCIPdebugMsg(scip, "binvar <%s> == 1 globally --> deleting superindicator and adding slack constraint <%s>\n",
1384 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
1385
1386 SCIP_CALL( SCIPsetConsLocal(scip, consdata->slackcons, FALSE) );
1387 SCIP_CALL( SCIPaddCons(scip, consdata->slackcons) );
1388 SCIP_CALL( SCIPdelCons(scip, conss[i]) );
1389
1390 locresult = SCIP_DIDNOTFIND;
1391 }
1392 else if( SCIPvarGetLbLocal(consdata->binvar) > 0.5 )
1393 {
1394 assert(SCIPisFeasEQ(scip, SCIPvarGetLbLocal(consdata->binvar), 1.0));
1395
1396 SCIPdebugMsg(scip, "binvar <%s> == 1 locally --> propagating slack constraint <%s>\n",
1397 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
1398
1399 SCIP_CALL( SCIPpropCons(scip, consdata->slackcons, proptiming, &locresult) );
1400
1401 SCIPdebugMsgPrint(scip, " --> locresult=%d\n", locresult);
1402 }
1403 /**@todo else propagate the domain of the binvar as well: start probing mode, fix binvar to one, propagate
1404 * constraint, and see whether we become infeasible; if this is implemented, the resprop callback must be
1405 * updated
1406 */
1407
1408 /* evaluate result value */
1409 switch( locresult )
1410 {
1411 case SCIP_CUTOFF:
1412 case SCIP_DELAYED:
1413 /* if propagation of one constraint is delayed, we want to propagate again unless the node is cut off */
1414 assert(*result != SCIP_CUTOFF);
1415 *result = locresult;
1416 break;
1417 case SCIP_REDUCEDDOM:
1418 assert(*result != SCIP_CUTOFF);
1419 if( *result != SCIP_DELAYED )
1420 *result = locresult;
1421 break;
1422 case SCIP_DIDNOTFIND:
1423 assert(*result != SCIP_CUTOFF);
1424 if( *result != SCIP_REDUCEDDOM
1425 && *result != SCIP_DELAYED )
1426 *result = locresult;
1427 break;
1428 case SCIP_DIDNOTRUN:
1429 assert(*result != SCIP_CUTOFF);
1430 if( *result != SCIP_REDUCEDDOM
1431 && *result != SCIP_DIDNOTFIND
1432 && *result != SCIP_DELAYED )
1433 *result = locresult;
1434 break;
1435 default:
1436 SCIPerrorMessage("invalid SCIP result %d\n", locresult);
1437 return SCIP_INVALIDRESULT;
1438 } /*lint !e788*/
1439 }
1440
1441 SCIPdebugMsg(scip, "prop result=%d\n", *result);
1442
1443 return SCIP_OKAY;
1444}
1445
1446/** presolving method of constraint handler */
1447static
1448SCIP_DECL_CONSPRESOL(consPresolSuperindicator)
1449{ /*lint --e{715}*/
1450 int i;
1451
1452 assert(scip != NULL);
1453 assert(conss != NULL);
1454 assert(conshdlr != NULL);
1455
1456 *result = SCIP_DIDNOTRUN;
1457
1458 SCIPdebugMsg(scip, "executing presol callback\n");
1459
1460 for( i = nconss-1; i >= 0 && *result != SCIP_CUTOFF; i-- )
1461 {
1462 SCIP_CONSDATA* consdata;
1463 SCIP_RESULT locresult;
1464
1465 consdata = SCIPconsGetData(conss[i]);
1466 assert(consdata != NULL);
1467
1468 locresult = SCIP_DIDNOTFIND;
1469
1470 /**@todo check whether the slack constraint is added to SCIP; in this case the superindicator can be deleted */
1471
1472 /**@todo check whether the slack constraint is a superindicator constraint and presolve */
1473
1474 /* if binvar is globally fixed to 1, we add the slack constraint and remove the superindicator */
1475 if( SCIPvarGetLbGlobal(consdata->binvar) > 0.5 )
1476 {
1477 assert(SCIPisFeasEQ(scip, SCIPvarGetLbGlobal(consdata->binvar), 1.0));
1478
1479 SCIPdebugMsg(scip, "binvar <%s> == 1 globally --> deleting superindicator and adding slack constraint <%s>\n",
1480 SCIPvarGetName(consdata->binvar), SCIPconsGetName(consdata->slackcons));
1481
1482 SCIP_CALL( SCIPsetConsLocal(scip, consdata->slackcons, FALSE) );
1483 SCIP_CALL( SCIPaddCons(scip, consdata->slackcons) );
1484 SCIP_CALL( SCIPdelCons(scip, conss[i]) );
1485
1486 locresult = SCIP_SUCCESS;
1487 }
1488 /* otherwise try upgrading */
1489 else
1490 {
1491 SCIP_Bool success;
1492 SCIP_Bool deleted;
1493
1494 SCIP_CALL( upgradeSuperindicator(scip, conss[i], &success, &deleted) );
1495
1496 /* update statistics */
1497 if( deleted )
1498 (*ndelconss)++;
1499 else if( success )
1500 (*nupgdconss)++;
1501
1502 /**@todo mark if upgrading failed to avoid trying too often; however, since upgrading might fail only due to
1503 * large domains, we may want to try again later, e.g., if SCIPisPresolveFinished() is TRUE
1504 */
1505
1506 if( deleted || success )
1507 locresult = SCIP_SUCCESS;
1508 }
1509 /**@todo else propagate the domain of the binvar as well: start probing mode, fix binvar to one, propagate
1510 * constraint, and see whether we become infeasible
1511 */
1512
1513 /* evaluate result value */
1514 switch( locresult )
1515 {
1516 case SCIP_SUCCESS:
1517 assert(*result != SCIP_CUTOFF);
1518 if( *result != SCIP_DELAYED )
1519 *result = locresult;
1520 break;
1521 default:
1522 assert(locresult == SCIP_DIDNOTFIND);
1523 assert(*result != SCIP_CUTOFF);
1524 if( *result != SCIP_UNBOUNDED && *result != SCIP_DELAYED && *result != SCIP_SUCCESS )
1525 *result = locresult;
1526 break;
1527 } /*lint !e788*/
1528 }
1529
1530 SCIPdebugMsg(scip, "presol result=%d\n", *result);
1531
1532 return SCIP_OKAY;
1533}
1534
1535/** propagation conflict resolving method of constraint handler */
1536static
1537SCIP_DECL_CONSRESPROP(consRespropSuperindicator)
1538{ /*lint --e{715}*/
1539 SCIP_CONSDATA* consdata;
1540
1541 assert(scip != NULL);
1542 assert(cons != NULL);
1543 assert(infervar != NULL);
1544 assert(bdchgidx != NULL);
1545 assert(result != NULL);
1546
1547 SCIPdebugMsg(scip, "executing resprop callback for constraint <%s>\n", SCIPconsGetName(cons));
1548
1549 consdata = SCIPconsGetData(cons);
1550 assert(consdata != NULL);
1551
1552 *result = SCIP_DIDNOTFIND;
1553
1554 /* check that we only propagated if the binvar is fixed to one */
1555 assert(SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, consdata->binvar, bdchgidx, TRUE), 1.0));
1556
1557 /* add tightened lower bound on binvar to conflict set */
1558 SCIP_CALL( SCIPaddConflictLb(scip, consdata->binvar, bdchgidx) );
1559
1560 /* call propagation conflict resolving method for the slack constraint */
1561 SCIP_CALL( SCIPrespropCons(scip, consdata->slackcons, infervar, inferinfo, boundtype, bdchgidx, relaxedbd, result) );
1562
1563 SCIPdebugMsgPrint(scip, " --> result=%d\n", *result);
1564
1565 return SCIP_OKAY;
1566}
1567
1568/** variable rounding lock method of constraint handler */
1569static
1570SCIP_DECL_CONSLOCK(consLockSuperindicator)
1571{ /*lint --e{715}*/
1572 SCIP_CONSDATA* consdata;
1573
1574 assert(scip != NULL);
1575 assert(locktype == SCIP_LOCKTYPE_MODEL);
1576
1577 SCIPdebugMsg(scip, "locking variables for constraint <%s>\n", SCIPconsGetName(cons));
1578
1579 consdata = SCIPconsGetData(cons);
1580 assert(consdata != NULL);
1581
1582 /* lock binvar up */
1583 SCIP_CALL( SCIPaddVarLocksType(scip, consdata->binvar, locktype, nlocksneg, nlockspos) );
1584
1585 /* call lock method for the slack constraint */
1586 SCIP_CALL( SCIPaddConsLocksType(scip, consdata->slackcons, locktype, nlockspos, nlocksneg) );
1587
1588 return SCIP_OKAY;
1589}
1590
1591
1592/** constraint display method of constraint handler */
1593static
1594SCIP_DECL_CONSPRINT(consPrintSuperindicator)
1595{ /*lint --e{715}*/
1596 SCIP_CONSDATA* consdata;
1597 SCIP_VAR* binvar;
1598 int zeroone;
1599
1600 assert(scip != NULL);
1601 assert(conshdlr != NULL);
1602 assert(cons != NULL);
1603 assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
1604
1605 consdata = SCIPconsGetData(cons);
1606 assert(consdata != NULL);
1607
1608 /* get binary variable */
1609 binvar = consdata->binvar;
1610 assert(binvar != NULL);
1611
1612 /* resolve negation if necessary */
1613 zeroone = 1;
1615 {
1616 zeroone = 0;
1617 binvar = SCIPvarGetNegatedVar(binvar);
1618 assert(binvar != NULL);
1619 }
1620
1621 /* print name of the binary variable */
1622 SCIP_CALL( SCIPwriteVarName(scip, file, binvar, TRUE) );
1623
1624 /* print implication */
1625 SCIPinfoMessage(scip, file, " = %d ->", zeroone);
1626
1627 /* print slack constraint */
1628 assert(consdata->slackcons != NULL);
1629 SCIP_CALL( SCIPprintCons(scip, consdata->slackcons, file) );
1630
1631 return SCIP_OKAY;
1632}
1633
1634/** constraint copying method of constraint handler */
1635static
1636SCIP_DECL_CONSCOPY(consCopySuperindicator)
1637{ /*lint --e{715}*/
1638 SCIP_CONSHDLR* conshdlrslack;
1639 SCIP_CONSDATA* sourceconsdata;
1640 SCIP_CONS* sourceslackcons;
1641 SCIP_CONS* targetslackcons;
1642 SCIP_VAR* targetbinvar;
1643 const char* consname;
1644
1645 assert(scip != NULL);
1646 assert(sourcescip != NULL);
1647 assert(sourcecons != NULL);
1648 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(sourcecons)), CONSHDLR_NAME) == 0);
1649
1650 *valid = TRUE;
1651
1652 if( name != NULL )
1653 consname = name;
1654 else
1655 consname = SCIPconsGetName(sourcecons);
1656
1657 SCIPdebugMsg(scip, "copying superindicator constraint <%s> to <%s>\n", SCIPconsGetName(sourcecons), consname);
1658
1659 if( modifiable )
1660 {
1661 SCIPwarningMessage(scip, "cannot create modifiable superindicator constraint when trying to copy constraint <%s>\n",
1662 SCIPconsGetName(sourcecons));
1663 *valid = FALSE;
1664 return SCIP_OKAY;
1665 }
1666
1667 sourceconsdata = SCIPconsGetData(sourcecons);
1668 assert(sourceconsdata != NULL);
1669
1670 /* get slack constraint */
1671 sourceslackcons = sourceconsdata->slackcons;
1672 assert(sourceslackcons != NULL);
1673
1674 /* if the slack constraint has been deleted, create an empty linear constraint */
1675 if( SCIPconsIsDeleted(sourceslackcons) )
1676 {
1677 SCIPdebugMsg(scip, "slack constraint <%s> deleted; creating empty linear constraint\n",
1678 SCIPconsGetName(sourceslackcons));
1679
1680 SCIP_CALL( SCIPcreateConsLinear(scip, &targetslackcons, "dummy", 0, NULL, NULL, 0.0, SCIPinfinity(scip),
1682
1683 SCIP_CALL( SCIPaddCons(scip, targetslackcons) );
1684 }
1685 else
1686 {
1687 /* get copied version of slack constraint */
1688 conshdlrslack = SCIPconsGetHdlr(sourceslackcons);
1689 assert(conshdlrslack != NULL);
1690
1691 /* if copying scip after transforming the original instance before presolving, we need to correct the slack
1692 * constraint pointer
1693 */
1694 assert(!SCIPisTransformed(sourcescip) || SCIPconsIsTransformed(sourceslackcons));
1695 if( SCIPisTransformed(sourcescip) && !SCIPconsIsTransformed(sourceslackcons) )
1696 {
1697 SCIP_CONS* transslackcons;
1698
1699 SCIP_CALL( SCIPgetTransformedCons(sourcescip, sourceslackcons, &transslackcons) );
1700 assert(transslackcons != NULL);
1701 SCIP_CALL( SCIPreleaseCons(sourcescip, &sourceconsdata->slackcons) );
1702 SCIP_CALL( SCIPcaptureCons(sourcescip, transslackcons) );
1703
1704 sourceconsdata->slackcons = transslackcons;
1705 sourceslackcons = transslackcons;
1706 }
1707
1708 SCIP_CALL( SCIPgetConsCopy(sourcescip, scip, sourceslackcons, &targetslackcons, conshdlrslack, varmap, consmap,
1709 SCIPconsGetName(sourceslackcons), SCIPconsIsInitial(sourceslackcons), SCIPconsIsSeparated(sourceslackcons),
1710 SCIPconsIsEnforced(sourceslackcons), SCIPconsIsChecked(sourceslackcons), SCIPconsIsPropagated(sourceslackcons),
1711 SCIPconsIsLocal(sourceslackcons), SCIPconsIsModifiable(sourceslackcons), SCIPconsIsDynamic(sourceslackcons),
1712 SCIPconsIsRemovable(sourceslackcons), SCIPconsIsStickingAtNode(sourceslackcons), global, valid) );
1713 }
1714
1715 /* find copied variable corresponding to binvar */
1716 if( *valid )
1717 {
1718 SCIP_VAR* sourcebinvar;
1719
1720 sourcebinvar = sourceconsdata->binvar;
1721 assert(sourcebinvar != NULL);
1722
1723 SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, sourcebinvar, &targetbinvar, varmap, consmap, global, valid) );
1724 }
1725 else
1726 targetbinvar = NULL;
1727
1728 /* create superindicator constraint */
1729 if( *valid )
1730 {
1731 assert(targetslackcons != NULL);
1732 assert(targetbinvar != NULL);
1733 assert(!modifiable);
1734
1735 SCIP_CALL( SCIPcreateConsSuperindicator(scip, cons, consname, targetbinvar, targetslackcons,
1736 initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode) );
1737 }
1738
1739 /* relase slack constraint */
1740 if( targetslackcons != NULL )
1741 {
1742 SCIP_CALL( SCIPreleaseCons(scip, &targetslackcons) );
1743 }
1744
1745 if( !(*valid) )
1746 {
1747 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "could not copy superindicator constraint <%s>\n", SCIPconsGetName(sourcecons));
1748 }
1749
1750 return SCIP_OKAY;
1751}
1752
1753/** constraint parsing method of constraint handler */
1754static
1755SCIP_DECL_CONSPARSE(consParseSuperindicator)
1756{ /*lint --e{715}*/
1757 SCIP_VAR* binvar;
1758 SCIP_CONS* slackcons;
1759 char binvarname[1024];
1760 const char* slackstr;
1761 int zeroone;
1762 int nargs;
1763
1764 assert(cons != NULL);
1765 assert(scip != NULL);
1766 assert(success != NULL);
1767 assert(str != NULL);
1768 assert(name != NULL);
1769
1770 *success = FALSE;
1771
1772 /* extract binary variable name and value which triggers slack constraint */
1773 /* coverity[secure_coding] */
1774 nargs = sscanf(str, " <%1023[^>]>[B] = %d", binvarname, &zeroone);
1775
1776 if( nargs != 2 || (zeroone != 0 && zeroone != 1) )
1777 {
1778 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error: expected the following form: <var> = [0|1] -> <cons>\n");
1779 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "got: %s\n", str);
1780 return SCIP_OKAY;
1781 }
1782
1783 /* extract string describing slack constraint */
1784 slackstr = strstr(str, "->");
1785
1786 if( slackstr == NULL )
1787 {
1788 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error: expected the following form: <var> = [0|1] -> <cons>\n");
1789 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "got: %s\n", str);
1790 return SCIP_OKAY;
1791 }
1792
1793 slackstr = strstr(slackstr, "[");
1794
1795 if( slackstr == NULL )
1796 {
1797 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error: expected the following form: <var> = [0|1] -> <cons>\n");
1798 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "got: %s\n", str);
1799 return SCIP_OKAY;
1800 }
1801
1802 SCIPdebugMsg(scip, "binvarname=%s, zeroone=%d, slackstr=%s\n", binvarname, zeroone, slackstr);
1803
1804 /* get binary variable */
1805 binvar = SCIPfindVar(scip, binvarname);
1806 if( binvar == NULL )
1807 {
1808 SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "unknown variable <%s>\n", binvarname);
1809 return SCIP_OKAY;
1810 }
1811
1812 /* resolve negation if necessary */
1813 if( zeroone == 0 )
1814 {
1815 SCIP_CALL( SCIPgetNegatedVar(scip, binvar, &binvar) );
1816 }
1817
1818 /**@todo get slack constraint name and check whether constraint already exists; however, using only SCIPfindCons() is
1819 * not sufficient since slack constraints are not added to the problem; do we need something like
1820 * SCIPfindConsInConshdlr()?; currently, if there are two superindicator constraints with same slack constraint
1821 * (binvars may be different), then after writing and reading, the slack constraint will be created twice with
1822 * identical constraint name; this is not incorrect, but might consume more memory or time
1823 */
1824
1825 /* parse slack constraint string */
1826 SCIP_CALL( SCIPparseCons(scip, &slackcons, slackstr, initial, separate, enforce, check, propagate, local, modifiable,
1827 dynamic, removable, stickingatnode, success) );
1828
1829 if( *success )
1830 {
1831 assert(binvar != NULL);
1832 assert(slackcons != NULL);
1833
1834 /* create the superindicator constraint */
1835 SCIP_CALL( SCIPcreateConsSuperindicator(scip, cons, name, binvar, slackcons,
1836 initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode) );
1837
1838 /* the new superindicator constraint captured the slack constraint, so we can release it now */
1839 SCIP_CALL( SCIPreleaseCons(scip, &slackcons) );
1840 }
1841
1842 return SCIP_OKAY;
1843}
1844
1845/** constraint method of constraint handler which returns the variables (if possible) */
1846static
1847SCIP_DECL_CONSGETVARS(consGetVarsSuperindicator)
1848{ /*lint --e{715}*/
1849 SCIP_CONSDATA* consdata;
1850
1851 consdata = SCIPconsGetData(cons);
1852 assert(consdata != NULL);
1853
1854 /* must be ready to hold at least the binary variable */
1855 if( varssize <= 0 )
1856 *success = FALSE;
1857 else
1858 {
1859 /* add binary variable */
1860 vars[0] = consdata->binvar;
1861
1862 /* add variables of slack constraint */
1863 SCIP_CALL( SCIPgetConsVars(scip, consdata->slackcons, &(vars[1]), varssize-1, success) );
1864 }
1865
1866 return SCIP_OKAY;
1867}
1868
1869/** constraint method of constraint handler which returns the number of variables (if possible) */
1870static
1871SCIP_DECL_CONSGETNVARS(consGetNVarsSuperindicator)
1872{ /*lint --e{715}*/
1873 SCIP_CONSDATA* consdata;
1874
1875 consdata = SCIPconsGetData(cons);
1876 assert(consdata != NULL);
1877
1878 /* get number of variables in slack constraint */
1879 SCIP_CALL( SCIPgetConsNVars(scip, consdata->slackcons, nvars, success) );
1880
1881 /* add binary variable */
1882 if( *success )
1883 (*nvars)++;
1884
1885 return SCIP_OKAY;
1886}
1887
1888
1889/*
1890 * constraint specific interface methods
1891 */
1892
1893/** creates the handler for superindicator constraints and includes it in SCIP */
1895 SCIP* scip /**< SCIP data structure */
1896 )
1897{
1898 SCIP_CONSHDLRDATA* conshdlrdata;
1899 SCIP_CONSHDLR* conshdlr;
1900 SCIP_DIALOG* root;
1901 SCIP_DIALOG* changemenu;
1902 SCIP_DIALOG* dialog;
1903
1904 /* create superindicator constraint handler data */
1905 SCIP_CALL( SCIPallocBlockMemory(scip, &conshdlrdata) );
1906
1907 conshdlrdata->nrejects = 0;
1908
1909 /* include constraint handler */
1912 consEnfolpSuperindicator, consEnfopsSuperindicator, consCheckSuperindicator, consLockSuperindicator,
1913 conshdlrdata) );
1914
1915 assert(conshdlr != NULL);
1916
1917 /* set non-fundamental callbacks via specific setter functions */
1918 SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopySuperindicator, consCopySuperindicator) );
1919 SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteSuperindicator) );
1920 SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeSuperindicator) );
1921 SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsSuperindicator) );
1922 SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsSuperindicator) );
1923 SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpSuperindicator) );
1924 SCIP_CALL( SCIPsetConshdlrInitpre(scip, conshdlr, consInitpreSuperindicator) );
1925 SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseSuperindicator) );
1926 SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolSuperindicator, CONSHDLR_MAXPREROUNDS, CONSHDLR_PRESOLTIMING) );
1927 SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintSuperindicator) );
1929 SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropSuperindicator) );
1930 SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpSuperindicator, consSepasolSuperindicator, CONSHDLR_SEPAFREQ, CONSHDLR_SEPAPRIORITY, CONSHDLR_DELAYSEPA) );
1931 SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransSuperindicator) );
1932 SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxSuperindicator) );
1933
1934 /* add dialogs if they are not disabled */
1935 root = SCIPgetRootDialog(scip);
1936 if( root != NULL )
1937 {
1938 /* find change menu */
1939 if( !SCIPdialogHasEntry(root, "change") )
1940 {
1941 SCIP_CALL( SCIPincludeDialog(scip, &changemenu,
1942 NULL,
1943 SCIPdialogExecMenu, NULL, NULL,
1944 "change", "change the problem", TRUE, NULL) );
1945 SCIP_CALL( SCIPaddDialogEntry(scip, root, changemenu) );
1946 SCIP_CALL( SCIPreleaseDialog(scip, &changemenu) );
1947 }
1948
1949 if( SCIPdialogFindEntry(root, "change", &changemenu) != 1 )
1950 {
1951 SCIPerrorMessage("change sub menu not found\n");
1952 return SCIP_PLUGINNOTFOUND;
1953 }
1954
1955 /* add minuc dialog */
1956 if( !SCIPdialogHasEntry(changemenu, "minuc") )
1957 {
1959 NULL,
1960 SCIPdialogExecChangeMinUC, NULL, NULL,
1961 "minuc", "transforms the current problem into a MinUC problem minimizing the number of unsatisfied constraints",
1962 FALSE, NULL) );
1963 SCIP_CALL( SCIPaddDialogEntry(scip, changemenu, dialog) );
1964 SCIP_CALL( SCIPreleaseDialog(scip, &dialog) );
1965 }
1966 }
1967
1968 /* add constraint handler parameters */
1970 "constraints/" CONSHDLR_NAME "/checkslacktype",
1971 "should type of slack constraint be checked when creating superindicator constraint?",
1972 &conshdlrdata->checkslacktype, TRUE, DEFAULT_CHECKSLACKTYPE, NULL, NULL) );
1973
1975 "constraints/" CONSHDLR_NAME "/maxupgdcoeflinear",
1976 "maximum big-M coefficient of binary variable in upgrade to a linear constraint (relative to smallest coefficient)",
1977 &conshdlrdata->maxupgdcoeflinear, TRUE, DEFAULT_MAXUPGDCOEFLINEAR, 0.0, 1e15, NULL, NULL) );
1978
1980 "constraints/" CONSHDLR_NAME "/upgdprioindicator",
1981 "priority for upgrading to an indicator constraint (-1: never)",
1982 &conshdlrdata->upgdprioindicator, TRUE, DEFAULT_UPGDPRIOINDICATOR, -1, INT_MAX, NULL, NULL) );
1983
1985 "constraints/" CONSHDLR_NAME "/upgdpriolinear",
1986 "priority for upgrading to an indicator constraint (-1: never)",
1987 &conshdlrdata->upgdpriolinear, TRUE, DEFAULT_UPGDPRIOLINEAR, -1, INT_MAX, NULL, NULL) );
1988
1989 return SCIP_OKAY;
1990}
1991
1992/** creates and captures a superindicator constraint
1993 *
1994 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
1995 */
1997 SCIP* scip, /**< SCIP data structure */
1998 SCIP_CONS** cons, /**< pointer to hold the created constraint */
1999 const char* name, /**< name of constraint */
2000 SCIP_VAR* binvar, /**< pointer to the indicator constraint */
2001 SCIP_CONS* slackcons, /**< constraint corresponding to the handled constraint */
2002 SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
2003 * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
2004 SCIP_Bool separate, /**< should the constraint be separated during LP processing?
2005 * Usually set to TRUE. */
2006 SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
2007 * TRUE for model constraints, FALSE for additional, redundant constraints. */
2008 SCIP_Bool check, /**< should the constraint be checked for feasibility?
2009 * TRUE for model constraints, FALSE for additional, redundant constraints. */
2010 SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
2011 * Usually set to TRUE. */
2012 SCIP_Bool local, /**< is constraint only valid locally?
2013 * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
2014 SCIP_Bool dynamic, /**< is constraint subject to aging?
2015 * Usually set to FALSE. Set to TRUE for own cuts which
2016 * are separated as constraints. */
2017 SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
2018 * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
2019 SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
2020 * if it may be moved to a more global node?
2021 * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
2022 )
2023{
2024 SCIP_CONSHDLRDATA* conshdlrdata;
2025 SCIP_CONSHDLR* conshdlr;
2026 SCIP_CONSDATA* consdata;
2027 SCIP_Bool modifiable;
2028
2029 assert(scip != NULL);
2030 assert(cons != NULL);
2031 assert(name != NULL);
2032 assert(binvar != NULL);
2033 assert(slackcons != NULL);
2034
2035 modifiable = FALSE;
2036
2037 /* find the superindicator constraint handler */
2038 conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2039 if( conshdlr == NULL )
2040 {
2041 SCIPerrorMessage("superindicator constraint handler not found\n");
2042 return SCIP_PLUGINNOTFOUND;
2043 }
2044
2045 conshdlrdata = SCIPconshdlrGetData(conshdlr);
2046 assert(conshdlrdata != NULL);
2047
2048 /* only allow types of slack constraints that can be handled */
2049 if( conshdlrdata->checkslacktype &&
2050 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "and") != 0 &&
2051 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "bounddisjunction") != 0 &&
2052 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "conjunction") != 0 &&
2053 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "disjunction") != 0 &&
2054 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "knapsack") != 0 &&
2055 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "linear") != 0 &&
2056 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "linking") != 0 &&
2057 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "logicor") != 0 &&
2058 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "nonlinear") != 0 &&
2059 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "or") != 0 &&
2060 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "SOS1") != 0 &&
2061 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "SOS2") != 0 &&
2062 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "cumulative") != 0 &&
2063 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "varbound") != 0 &&
2064 strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "superindicator") != 0
2065 )
2066 {
2067 if( conshdlrdata->nrejects < 5 )
2068 {
2069 SCIPwarningMessage(scip, "rejected creation of superindicator with slack constraint <%s> of type <%s> "
2070 "(use parameter <checkslacktype> to disable check)\n",
2071 SCIPconsGetName(slackcons), SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)));
2072 conshdlrdata->nrejects++;
2073 }
2074
2075 if( conshdlrdata->nrejects == 5 )
2076 {
2077 SCIPwarningMessage(scip, "suppressing further warning messages of this type\n");
2078 conshdlrdata->nrejects++;
2079 }
2080
2081 return SCIP_INVALIDCALL;
2082 }
2083
2084 /* create constraint data */
2085 SCIP_CALL( consdataCreateSuperindicator(scip, &consdata, binvar, slackcons) );
2086 assert(consdata != NULL);
2087
2088 /* create constraint */
2089 SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
2090 local, modifiable, dynamic, removable, stickingatnode) );
2091
2092 return SCIP_OKAY;
2093}
2094
2095/** creates and captures a superindicator constraint
2096 * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
2097 * method SCIPcreateConsSuperindicator(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
2098 *
2099 * @see SCIPcreateConsSuperindicator() for information about the basic constraint flag configuration
2100 *
2101 * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
2102 */
2104 SCIP* scip, /**< SCIP data structure */
2105 SCIP_CONS** cons, /**< pointer to hold the created constraint */
2106 const char* name, /**< name of constraint */
2107 SCIP_VAR* binvar, /**< pointer to the indicator constraint */
2108 SCIP_CONS* slackcons /**< constraint corresponding to the handled constraint */
2109 )
2110{
2111 assert(scip != NULL);
2112 assert(cons != NULL);
2113 assert(name != NULL);
2114 assert(binvar != NULL);
2115 assert(slackcons != NULL);
2116
2117 SCIP_CALL( SCIPcreateConsSuperindicator(scip, cons, name, binvar, slackcons,
2119
2120 return SCIP_OKAY;
2121}
2122
2123
2124/** gets binary variable corresponding to the general indicator constraint */
2126 SCIP_CONS* cons /**< superindicator constraint */
2127 )
2128{
2129 assert(cons != NULL);
2130 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
2131 assert(SCIPconsGetData(cons) != NULL);
2132
2133 return SCIPconsGetData(cons)->binvar;
2134}
2135
2136/** gets the slack constraint corresponding to the general indicator constraint */
2138 SCIP_CONS* cons /**< superindicator constraint */
2139 )
2140{
2141 assert(cons != NULL);
2142 assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
2143 assert(SCIPconsGetData(cons) != NULL);
2144
2145 return SCIPconsGetData(cons)->slackcons;
2146}
2147
2148
2149/*
2150 * constraint-dependent SCIP methods
2151 */
2152
2153/** transforms the current problem into a MinUC problem (minimizing the number of unsatisfied constraints),
2154 * a CIP generalization of the MinULR (min. unsatisfied linear relations) problem
2155 */
2157 SCIP* scip, /**< SCIP data structure */
2158 SCIP_Bool* success /**< pointer to store whether all constraints could be transformed */
2159 )
2160{
2161 SCIP_CONS** conss;
2162 SCIP_CONS** probconss;
2163 SCIP_VAR** vars;
2164 char consname[SCIP_MAXSTRLEN];
2165 char varname[SCIP_MAXSTRLEN];
2166 int maxbranchprio;
2167 int ntransconss;
2168 int nconss;
2169 int nvars;
2170 int i;
2171
2172 assert(scip != NULL);
2173 assert(success != NULL);
2174
2175 *success = FALSE;
2176
2178 {
2179 SCIPerrorMessage("method <SCIPtransformMinUC> can only be called in problem stage\n");
2180 return SCIP_INVALIDCALL;
2181 }
2182
2183 /* get variable data */
2184 SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
2185
2186 /* copy the conss array because it changes when adding and deleting constraints */
2187 nconss = SCIPgetNConss(scip);
2188 probconss = SCIPgetConss(scip);
2189 SCIP_CALL( SCIPduplicateBufferArray(scip, &conss, probconss, nconss) );
2190
2191 /* clear objective function and compute maximal branching priority */
2192 maxbranchprio = 0;
2193 for( i = nvars-1; i >= 0; i-- )
2194 {
2195 SCIP_CALL( SCIPchgVarObj(scip, vars[i], 0.0) );
2196
2197 if( SCIPvarGetBranchPriority(vars[i]) > maxbranchprio )
2198 maxbranchprio = SCIPvarGetBranchPriority(vars[i]);
2199 }
2200
2201 maxbranchprio++;
2202
2203 /* transform each constraint to slack constraint in a newly created superindicator constraint; note that we also need
2204 * to transform superindicator constraints, since their binary variable might have down-locks
2205 */
2206 ntransconss = 0;
2207 for( i = 0; i < nconss; ++i )
2208 {
2209 SCIP_CONS* cons;
2210 SCIP_CONS* supindcons;
2211 SCIP_VAR* binvar;
2212 SCIP_VAR* negbinvar;
2213 SCIP_RETCODE retcode;
2214
2215 cons = conss[i];
2216 assert(cons != NULL);
2217
2218 /* create a new binary variable with objective coefficient one */
2219 (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "%s_master", SCIPconsGetName(cons));
2220
2221 SCIP_CALL( SCIPcreateVar(scip, &binvar, varname, 0.0, 1.0, 1.0, SCIP_VARTYPE_BINARY,
2222 TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
2223
2224 /* get negated variable, since we want to minimize the number of violated constraints */
2225 SCIP_CALL( SCIPgetNegatedVar(scip, binvar, &negbinvar) );
2226
2227 /* create superindicator constraint */
2228 (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_super", SCIPconsGetName(cons));
2229
2230 retcode = SCIPcreateConsSuperindicator(scip, &supindcons, consname, negbinvar, cons,
2234
2235 if( retcode == SCIP_OKAY )
2236 {
2237 /* add binary variable and increase its branching priority */
2238 SCIP_CALL( SCIPaddVar(scip, binvar) );
2239 SCIP_CALL( SCIPchgVarBranchPriority(scip, binvar, maxbranchprio) );
2240
2241 /* add superindicator constraint */
2242 SCIP_CALL( SCIPaddCons(scip, supindcons) );
2243
2244 /* release binary variable and superindicator constraint */
2245 SCIP_CALL( SCIPreleaseVar(scip, &binvar) );
2246 SCIP_CALL( SCIPreleaseCons(scip, &supindcons) );
2247
2248 /* delete slack constraint; it is still captured by the superindicator constraint */
2249 SCIP_CALL( SCIPdelCons(scip, cons) );
2250
2251 ntransconss++;
2252 }
2253 else if( retcode == SCIP_INVALIDCALL )
2254 {
2255 SCIPdebugMsg(scip, "constraint <%s> of type <%s> could not be transformed to superindicator and was removed\n",
2257
2258 /* release binary variable */
2259 SCIP_CALL( SCIPreleaseVar(scip, &binvar) );
2260
2261 /* delete slack constraint; this is necessary, because, e.g., the indicator expects its linear slack constraint
2262 * present in the problem, but this has just be transformed; hence, it cannot function any more and we have to
2263 * remove it
2264 */
2265 SCIP_CALL( SCIPdelCons(scip, cons) );
2266 }
2267 else
2268 {
2269 /* return all other error codes */
2270 SCIP_CALL( retcode );
2271 }
2272 }
2273
2274 if( ntransconss == nconss )
2275 *success = TRUE;
2276
2277 /* minimize the number of violated constraints */
2279
2280 /* free the allocated memory for the copied constraint array */
2281 SCIPfreeBufferArray(scip, &conss);
2282
2283 return SCIP_OKAY;
2284}
2285
2286
2287/*
2288 * constraint-dependent dialog entries
2289 */
2290
2291/** dialog execution method for the SCIPtransformMinUC() method */
2292SCIP_DECL_DIALOGEXEC(SCIPdialogExecChangeMinUC)
2293{ /*lint --e{715}*/
2294 SCIP_Bool success;
2295
2296 SCIP_CALL( SCIPdialoghdlrAddHistory(dialoghdlr, dialog, NULL, FALSE) );
2297 SCIPdialogMessage(scip, NULL, "\n");
2298
2299 switch( SCIPgetStage(scip) )
2300 {
2301 case SCIP_STAGE_INIT:
2302 SCIPdialogMessage(scip, NULL, "no problem exists\n");
2303 break;
2304 case SCIP_STAGE_PROBLEM:
2305 SCIPdialogMessage(scip, NULL, "change problem to MinUC\n");
2306 SCIPdialogMessage(scip, NULL, "==============\n");
2307
2308 SCIP_CALL( SCIPtransformMinUC(scip, &success) );
2309
2310 if( !success )
2311 {
2312 SCIPdialogMessage(scip, NULL, "some constraints could not be transformed to superindicator constraints and were removed\n");
2313 }
2314
2315 SCIPdialogMessage(scip, NULL, "\n");
2316 SCIPdialogMessage(scip, NULL, "changed problem has %d variables (%d bin, %d int, %d impl, %d cont) and %d constraints\n",
2319
2320 SCIPdialogMessage(scip, NULL, "increased branching priority of new binary variables");
2321
2322 break;
2328 case SCIP_STAGE_SOLVING:
2329 case SCIP_STAGE_SOLVED:
2334 case SCIP_STAGE_FREE:
2335 SCIPdialogMessage(scip, NULL, "problem has to be in problem stage to create MinUC problem\n");
2336 break;
2337 default:
2338 SCIPerrorMessage("invalid SCIP stage\n");
2339 return SCIP_INVALIDCALL;
2340 } /*lint --e{616}*/
2341
2342 SCIPdialogMessage(scip, NULL, "\n");
2343 *nextdialog = SCIPdialoghdlrGetRoot(dialoghdlr);
2344
2345 return SCIP_OKAY;
2346}
constraint handler for indicator constraints
Constraint handler for linear constraints in their most general form, .
static SCIP_DECL_CONSENFORELAX(consEnforelaxSuperindicator)
#define DEFAULT_MAXUPGDCOEFLINEAR
#define CONSHDLR_NEEDSCONS
#define CONSHDLR_SEPAFREQ
#define CONSHDLR_CHECKPRIORITY
#define DEFAULT_UPGDPRIOLINEAR
#define CONSHDLR_DESC
static SCIP_DECL_CONSRESPROP(consRespropSuperindicator)
static SCIP_DECL_CONSINITPRE(consInitpreSuperindicator)
#define CONSHDLR_PROP_TIMING
static SCIP_DECL_CONSFREE(consFreeSuperindicator)
#define CONSHDLR_MAXPREROUNDS
#define DEFAULT_CHECKSLACKTYPE
static SCIP_RETCODE upgradeLinearSuperindicator(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success, SCIP_Bool *deleted)
static SCIP_DECL_CONSLOCK(consLockSuperindicator)
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 SCIP_DECL_CONSHDLRCOPY(conshdlrCopySuperindicator)
static SCIP_DECL_CONSSEPALP(consSepalpSuperindicator)
#define CONSHDLR_SEPAPRIORITY
static void extractLinearValues(SCIP *scip, SCIP_CONS *cons, SCIP_Real *minactivity, SCIP_Real *maxactivity, SCIP_Real *minabscoef)
#define DEFAULT_UPGDPRIOINDICATOR
static SCIP_DECL_CONSPRINT(consPrintSuperindicator)
static SCIP_DECL_CONSDELETE(consDeleteSuperindicator)
static SCIP_DECL_CONSSEPASOL(consSepasolSuperindicator)
static SCIP_RETCODE upgradeSuperindicator(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success, SCIP_Bool *deleted)
static SCIP_DECL_CONSGETVARS(consGetVarsSuperindicator)
static SCIP_RETCODE upgradeIndicatorSuperindicator(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *success, SCIP_Bool *deleted)
static SCIP_DECL_CONSPARSE(consParseSuperindicator)
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_DECL_CONSGETNVARS(consGetNVarsSuperindicator)
static SCIP_DECL_CONSINITLP(consInitlpSuperindicator)
#define CONSHDLR_PROPFREQ
static SCIP_RETCODE consdataCreateSuperindicator(SCIP *scip, SCIP_CONSDATA **consdata, SCIP_VAR *binvar, SCIP_CONS *slackcons)
static SCIP_DECL_CONSCOPY(consCopySuperindicator)
#define CONSHDLR_PRESOLTIMING
#define CONSHDLR_EAGERFREQ
static SCIP_DECL_CONSCHECK(consCheckSuperindicator)
#define CONSHDLR_ENFOPRIORITY
static SCIP_DECL_CONSENFOLP(consEnfolpSuperindicator)
#define CONSHDLR_DELAYSEPA
static SCIP_DECL_CONSPRESOL(consPresolSuperindicator)
static SCIP_DECL_CONSTRANS(consTransSuperindicator)
static SCIP_DECL_CONSENFOPS(consEnfopsSuperindicator)
#define CONSHDLR_NAME
static SCIP_DECL_CONSPROP(consPropSuperindicator)
#define CONSHDLR_DELAYPROP
constraint handler for indicator constraints over arbitrary constraint types
#define NULL
Definition: def.h:267
#define SCIP_MAXSTRLEN
Definition: def.h:288
#define SCIP_Bool
Definition: def.h:91
#define SCIP_Real
Definition: def.h:173
#define TRUE
Definition: def.h:93
#define FALSE
Definition: def.h:94
#define SCIP_CALL(x)
Definition: def.h:374
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_DECL_DIALOGEXEC(SCIPdialogExecChangeMinUC)
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_RETCODE SCIPtransformMinUC(SCIP *scip, SCIP_Bool *success)
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:1591
SCIP_RETCODE SCIPgetVarCopy(SCIP *sourcescip, SCIP *targetscip, SCIP_VAR *sourcevar, SCIP_VAR **targetvar, SCIP_HASHMAP *varmap, SCIP_HASHMAP *consmap, SCIP_Bool global, SCIP_Bool *success)
Definition: scip_copy.c:711
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip_general.c:596
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip_general.c:380
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip_prob.c:1668
int SCIPgetNIntVars(SCIP *scip)
Definition: scip_prob.c:2082
int SCIPgetNImplVars(SCIP *scip)
Definition: scip_prob.c:2127
int SCIPgetNContVars(SCIP *scip)
Definition: scip_prob.c:2172
SCIP_RETCODE SCIPgetVarsData(SCIP *scip, SCIP_VAR ***vars, int *nvars, int *nbinvars, int *nintvars, int *nimplvars, int *ncontvars)
Definition: scip_prob.c:1866
SCIP_CONS ** SCIPgetConss(SCIP *scip)
Definition: scip_prob.c:3088
int SCIPgetNVars(SCIP *scip)
Definition: scip_prob.c:1992
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2770
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_prob.c:2843
int SCIPgetNConss(SCIP *scip)
Definition: scip_prob.c:3042
SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
Definition: scip_prob.c:1242
int SCIPgetNBinVars(SCIP *scip)
Definition: scip_prob.c:2037
SCIP_VAR * SCIPfindVar(SCIP *scip, const char *name)
Definition: scip_prob.c:2685
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:208
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip_message.c:225
#define SCIPdebugMsgPrint
Definition: scip_message.h:79
#define SCIPdebugMsg
Definition: scip_message.h:78
void SCIPdialogMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip_message.c:191
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip_message.c:120
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)
SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
Definition: scip_cons.c:808
void SCIPconshdlrSetData(SCIP_CONSHDLR *conshdlr, SCIP_CONSHDLRDATA *conshdlrdata)
Definition: cons.c:4227
SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
Definition: scip_cons.c:540
SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETVARS((*consgetvars)))
Definition: scip_cons.c:831
SCIP_RETCODE SCIPsetConshdlrInitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITPRE((*consinitpre)))
Definition: scip_cons.c:492
SCIP_RETCODE SCIPsetConshdlrSepa(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSSEPALP((*conssepalp)), SCIP_DECL_CONSSEPASOL((*conssepasol)), int sepafreq, int sepapriority, SCIP_Bool delaysepa)
Definition: scip_cons.c:235
SCIP_RETCODE SCIPsetConshdlrProp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPROP((*consprop)), int propfreq, SCIP_Bool delayprop, SCIP_PROPTIMING proptiming)
Definition: scip_cons.c:281
SCIP_RETCODE SCIPincludeConshdlrBasic(SCIP *scip, SCIP_CONSHDLR **conshdlrptr, const char *name, const char *desc, int enfopriority, int chckpriority, int eagerfreq, SCIP_Bool needscons, SCIP_DECL_CONSENFOLP((*consenfolp)), SCIP_DECL_CONSENFOPS((*consenfops)), SCIP_DECL_CONSCHECK((*conscheck)), SCIP_DECL_CONSLOCK((*conslock)), SCIP_CONSHDLRDATA *conshdlrdata)
Definition: scip_cons.c:181
SCIP_RETCODE SCIPsetConshdlrDelete(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSDELETE((*consdelete)))
Definition: scip_cons.c:578
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
Definition: scip_cons.c:372
SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
Definition: scip_cons.c:323
const char * SCIPconshdlrGetName(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4197
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
Definition: scip_cons.c:347
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip_cons.c:941
SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
Definition: scip_cons.c:624
SCIP_CONSHDLRDATA * SCIPconshdlrGetData(SCIP_CONSHDLR *conshdlr)
Definition: cons.c:4217
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
Definition: scip_cons.c:601
SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
Definition: scip_cons.c:647
SCIP_RETCODE SCIPsetConshdlrGetNVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETNVARS((*consgetnvars)))
Definition: scip_cons.c:854
SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
Definition: scip_cons.c:785
SCIP_RETCODE SCIPgetConsNVars(SCIP *scip, SCIP_CONS *cons, int *nvars, SCIP_Bool *success)
Definition: scip_cons.c:2622
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition: cons.c:8244
SCIP_RETCODE SCIPenfopsCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool solinfeasible, SCIP_Bool objinfeasible, SCIP_RESULT *result)
Definition: scip_cons.c:2164
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:2136
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:8473
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:8234
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:8383
SCIP_RETCODE SCIPenfolpCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool solinfeasible, SCIP_RESULT *result)
Definition: scip_cons.c:2195
SCIP_RETCODE SCIPprintCons(SCIP *scip, SCIP_CONS *cons, FILE *file)
Definition: scip_cons.c:2537
SCIP_RETCODE SCIPpropCons(SCIP *scip, SCIP_CONS *cons, SCIP_PROPTIMING proptiming, SCIP_RESULT *result)
Definition: scip_cons.c:2341
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8413
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition: cons.c:8343
SCIP_RETCODE SCIPsepalpCons(SCIP *scip, SCIP_CONS *cons, SCIP_RESULT *result)
Definition: scip_cons.c:2284
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:8523
SCIP_RETCODE SCIPgetConsVars(SCIP *scip, SCIP_CONS *cons, SCIP_VAR **vars, int varssize, SCIP_Bool *success)
Definition: scip_cons.c:2578
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:8403
SCIP_RETCODE SCIPcreateCons(SCIP *scip, SCIP_CONS **cons, const char *name, SCIP_CONSHDLR *conshdlr, SCIP_CONSDATA *consdata, SCIP_Bool initial, SCIP_Bool separate, SCIP_Bool enforce, SCIP_Bool check, SCIP_Bool propagate, SCIP_Bool local, SCIP_Bool modifiable, SCIP_Bool dynamic, SCIP_Bool removable, SCIP_Bool stickingatnode)
Definition: scip_cons.c:998
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:8433
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8453
SCIP_RETCODE SCIPaddConsLocksType(SCIP *scip, SCIP_CONS *cons, SCIP_LOCKTYPE locktype, int nlockspos, int nlocksneg)
Definition: scip_cons.c:2073
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:8214
SCIP_RETCODE SCIPinitlpCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible)
Definition: scip_cons.c:2257
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:2372
SCIP_RETCODE SCIPsetConsLocal(SCIP *scip, SCIP_CONS *cons, SCIP_Bool local)
Definition: scip_cons.c:1399
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8463
SCIP_RETCODE SCIPgetTransformedCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **transcons)
Definition: scip_cons.c:1675
SCIP_RETCODE SCIPenforelaxCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_Bool solinfeasible, SCIP_RESULT *result)
Definition: scip_cons.c:2225
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition: cons.c:8493
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:1082
SCIP_RETCODE SCIPsepasolCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_RESULT *result)
Definition: scip_cons.c:2311
SCIP_RETCODE SCIPreleaseCons(SCIP *scip, SCIP_CONS **cons)
Definition: scip_cons.c:1174
SCIP_RETCODE SCIPtransformCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **transcons)
Definition: scip_cons.c:1585
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8393
SCIP_RETCODE SCIPcaptureCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip_cons.c:1139
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:8483
SCIP_RETCODE SCIPreleaseDialog(SCIP *scip, SCIP_DIALOG **dialog)
Definition: scip_dialog.c:124
SCIP_DIALOG * SCIPdialoghdlrGetRoot(SCIP_DIALOGHDLR *dialoghdlr)
Definition: dialog.c:436
SCIP_Bool SCIPdialogHasEntry(SCIP_DIALOG *dialog, const char *entryname)
Definition: dialog.c:995
SCIP_RETCODE SCIPdialoghdlrAddHistory(SCIP_DIALOGHDLR *dialoghdlr, SCIP_DIALOG *dialog, const char *command, SCIP_Bool escapecommand)
Definition: dialog.c:726
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)
Definition: scip_dialog.c:171
SCIP_DIALOG * SCIPgetRootDialog(SCIP *scip)
Definition: scip_dialog.c:157
int SCIPdialogFindEntry(SCIP_DIALOG *dialog, const char *entryname, SCIP_DIALOG **subdialog)
Definition: dialog.c:1028
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1453
#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:1631
SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
Definition: sol.c:2804
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip_sol.c:1217
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_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
Definition: var.c:17894
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:17538
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:18088
SCIP_RETCODE SCIPaddVarLocksType(SCIP *scip, SCIP_VAR *var, SCIP_LOCKTYPE locktype, int nlocksdown, int nlocksup)
Definition: scip_var.c:4259
SCIP_RETCODE SCIPchgVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip_var.c:7980
SCIP_Real SCIPgetVarUbAtIndex(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx, SCIP_Bool after)
Definition: scip_var.c:2128
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:17419
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip_var.c:1248
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip_var.c:1527
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:18134
int SCIPvarGetBranchPriority(SCIP_VAR *var)
Definition: var.c:18250
SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: scip_var.c:114
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:18078
SCIP_RETCODE SCIPwriteVarName(SCIP *scip, FILE *file, SCIP_VAR *var, SCIP_Bool type)
Definition: scip_var.c:230
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip_var.c:4513
SCIP_RETCODE SCIPgetTransformedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **transvar)
Definition: scip_var.c:1439
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:10877
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
struct SCIP_ConshdlrData SCIP_CONSHDLRDATA
Definition: type_cons.h:64
struct SCIP_ConsData SCIP_CONSDATA
Definition: type_cons.h:65
@ SCIP_VERBLEVEL_MINIMAL
Definition: type_message.h:54
@ 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
Definition: type_retcode.h:53
@ SCIP_PLUGINNOTFOUND
Definition: type_retcode.h:54
@ SCIP_OKAY
Definition: type_retcode.h:42
@ SCIP_INVALIDCALL
Definition: type_retcode.h:51
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:63
@ 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
@ SCIP_VARTYPE_BINARY
Definition: type_var.h:62
@ SCIP_VARSTATUS_NEGATED
Definition: type_var.h:55
@ SCIP_LOCKTYPE_MODEL
Definition: type_var.h:97