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