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-2017 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  case SCIP_DIDNOTFIND:
1499  assert(*result != SCIP_CUTOFF);
1500  if( *result != SCIP_UNBOUNDED
1501  && *result != SCIP_DELAYED
1502  && *result != SCIP_SUCCESS )
1503  *result = locresult;
1504  break;
1505  default:
1506  SCIPerrorMessage("invalid SCIP result %d\n", locresult);
1507  return SCIP_INVALIDRESULT;
1508  } /*lint !e788*/
1509  }
1510 
1511  SCIPdebugMsg(scip, "presol result=%d\n", *result);
1512 
1513  return SCIP_OKAY;
1514 }
1515 
1516 /** propagation conflict resolving method of constraint handler */
1517 static
1518 SCIP_DECL_CONSRESPROP(consRespropSuperindicator)
1519 { /*lint --e{715}*/
1520  SCIP_CONSDATA* consdata;
1522  assert(scip != NULL);
1523  assert(cons != NULL);
1524  assert(infervar != NULL);
1525  assert(bdchgidx != NULL);
1526  assert(result != NULL);
1527 
1528  SCIPdebugMsg(scip, "executing resprop callback for constraint <%s>\n", SCIPconsGetName(cons));
1529 
1530  consdata = SCIPconsGetData(cons);
1531  assert(consdata != NULL);
1532 
1533  *result = SCIP_DIDNOTFIND;
1534 
1535  /* check that we only propagated if the binvar is fixed to one */
1536  assert(SCIPisFeasEQ(scip, SCIPgetVarUbAtIndex(scip, consdata->binvar, bdchgidx, TRUE), 1.0));
1537 
1538  /* add tightened lower bound on binvar to conflict set */
1539  SCIP_CALL( SCIPaddConflictLb(scip, consdata->binvar, bdchgidx) );
1540 
1541  /* call propagation conflict resolving method for the slack constraint */
1542  SCIP_CALL( SCIPrespropCons(scip, consdata->slackcons, infervar, inferinfo, boundtype, bdchgidx, relaxedbd, result) );
1543 
1544  SCIPdebugMsgPrint(scip, " --> result=%d\n", *result);
1545 
1546  return SCIP_OKAY;
1547 }
1548 
1549 /** variable rounding lock method of constraint handler */
1550 static
1551 SCIP_DECL_CONSLOCK(consLockSuperindicator)
1552 { /*lint --e{715}*/
1553  SCIP_CONSDATA* consdata;
1555  assert(scip != NULL);
1556 
1557  SCIPdebugMsg(scip, "locking variables for constraint <%s>\n", SCIPconsGetName(cons));
1558 
1559  consdata = SCIPconsGetData(cons);
1560  assert(consdata != NULL);
1561 
1562  /* lock binvar up */
1563  SCIP_CALL( SCIPaddVarLocks(scip, consdata->binvar, nlocksneg, nlockspos) );
1564 
1565  /* call lock method for the slack constraint */
1566  SCIP_CALL( SCIPaddConsLocks(scip, consdata->slackcons, nlockspos, nlocksneg) );
1567 
1568  return SCIP_OKAY;
1569 }
1570 
1571 
1572 /** constraint display method of constraint handler */
1573 static
1574 SCIP_DECL_CONSPRINT(consPrintSuperindicator)
1575 { /*lint --e{715}*/
1576  SCIP_CONSDATA* consdata;
1577  SCIP_VAR* binvar;
1578  int zeroone;
1579 
1580  assert(scip != NULL);
1581  assert(conshdlr != NULL);
1582  assert(cons != NULL);
1583  assert(strcmp(SCIPconshdlrGetName(conshdlr), CONSHDLR_NAME) == 0);
1584 
1585  consdata = SCIPconsGetData(cons);
1586  assert(consdata != NULL);
1587 
1588  /* get binary variable */
1589  binvar = consdata->binvar;
1590  assert(binvar != NULL);
1591 
1592  /* resolve negation if necessary */
1593  zeroone = 1;
1594  if ( SCIPvarGetStatus(binvar) == SCIP_VARSTATUS_NEGATED )
1595  {
1596  zeroone = 0;
1597  binvar = SCIPvarGetNegatedVar(binvar);
1598  assert(binvar != NULL);
1599  }
1600 
1601  /* print name of the binary variable */
1602  SCIP_CALL( SCIPwriteVarName(scip, file, binvar, TRUE) );
1603 
1604  /* print implication */
1605  SCIPinfoMessage(scip, file, " = %d ->", zeroone);
1606 
1607  /* print slack constraint */
1608  assert(consdata->slackcons != NULL);
1609  SCIP_CALL( SCIPprintCons(scip, consdata->slackcons, file) );
1610 
1611  return SCIP_OKAY;
1612 }
1613 
1614 /** constraint copying method of constraint handler */
1615 static
1616 SCIP_DECL_CONSCOPY(consCopySuperindicator)
1617 { /*lint --e{715}*/
1618  SCIP_CONSHDLR* conshdlrslack;
1619  SCIP_CONSDATA* sourceconsdata;
1620  SCIP_CONS* sourceslackcons;
1621  SCIP_CONS* targetslackcons;
1622  SCIP_VAR* targetbinvar;
1623  const char* consname;
1624 
1625  assert(scip != NULL);
1626  assert(sourcescip != NULL);
1627  assert(sourcecons != NULL);
1628  assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(sourcecons)), CONSHDLR_NAME) == 0);
1629 
1630  *valid = TRUE;
1631 
1632  if( name != NULL )
1633  consname = name;
1634  else
1635  consname = SCIPconsGetName(sourcecons);
1636 
1637  SCIPdebugMsg(scip, "copying superindicator constraint <%s> to <%s>\n", SCIPconsGetName(sourcecons), consname);
1638 
1639  if( modifiable )
1640  {
1641  SCIPwarningMessage(scip, "cannot create modifiable superindicator constraint when trying to copy constraint <%s>\n",
1642  SCIPconsGetName(sourcecons));
1643  *valid = FALSE;
1644  return SCIP_OKAY;
1645  }
1646 
1647  sourceconsdata = SCIPconsGetData(sourcecons);
1648  assert(sourceconsdata != NULL);
1649 
1650  /* get slack constraint */
1651  sourceslackcons = sourceconsdata->slackcons;
1652  assert(sourceslackcons != NULL);
1653 
1654  /* if the slack constraint has been deleted, create an empty linear constraint */
1655  if( SCIPconsIsDeleted(sourceslackcons) )
1656  {
1657  SCIPdebugMsg(scip, "slack constraint <%s> deleted; creating empty linear constraint\n",
1658  SCIPconsGetName(sourceslackcons));
1659 
1660  SCIP_CALL( SCIPcreateConsLinear(scip, &targetslackcons, "dummy", 0, NULL, NULL, 0.0, SCIPinfinity(scip),
1662 
1663  SCIP_CALL( SCIPaddCons(scip, targetslackcons) );
1664  }
1665  else
1666  {
1667  /* get copied version of slack constraint */
1668  conshdlrslack = SCIPconsGetHdlr(sourceslackcons);
1669  assert(conshdlrslack != NULL);
1670 
1671  /* if copying scip after transforming the original instance before presolving, we need to correct the slack
1672  * constraint pointer
1673  */
1674  assert(!SCIPisTransformed(sourcescip) || SCIPconsIsTransformed(sourceslackcons));
1675  if( SCIPisTransformed(sourcescip) && !SCIPconsIsTransformed(sourceslackcons) )
1676  {
1677  SCIP_CONS* transslackcons;
1678 
1679  SCIP_CALL( SCIPgetTransformedCons(sourcescip, sourceslackcons, &transslackcons) );
1680  assert(transslackcons != NULL);
1681  SCIP_CALL( SCIPreleaseCons(sourcescip, &sourceconsdata->slackcons) );
1682  SCIP_CALL( SCIPcaptureCons(sourcescip, transslackcons) );
1683 
1684  sourceconsdata->slackcons = transslackcons;
1685  sourceslackcons = transslackcons;
1686  }
1687 
1688  SCIP_CALL( SCIPgetConsCopy(sourcescip, scip, sourceslackcons, &targetslackcons, conshdlrslack, varmap, consmap,
1689  SCIPconsGetName(sourceslackcons), SCIPconsIsInitial(sourceslackcons), SCIPconsIsSeparated(sourceslackcons),
1690  SCIPconsIsEnforced(sourceslackcons), SCIPconsIsChecked(sourceslackcons), SCIPconsIsPropagated(sourceslackcons),
1691  SCIPconsIsLocal(sourceslackcons), SCIPconsIsModifiable(sourceslackcons), SCIPconsIsDynamic(sourceslackcons),
1692  SCIPconsIsRemovable(sourceslackcons), SCIPconsIsStickingAtNode(sourceslackcons), global, valid) );
1693  }
1694 
1695  /* find copied variable corresponding to binvar */
1696  if( *valid )
1697  {
1698  SCIP_VAR* sourcebinvar;
1699 
1700  sourcebinvar = sourceconsdata->binvar;
1701  assert(sourcebinvar != NULL);
1702 
1703  SCIP_CALL( SCIPgetVarCopy(sourcescip, scip, sourcebinvar, &targetbinvar, varmap, consmap, global, valid) );
1704  }
1705  else
1706  targetbinvar = NULL;
1707 
1708  /* create superindicator constraint */
1709  if( *valid )
1710  {
1711  assert(targetslackcons != NULL);
1712  assert(targetbinvar != NULL);
1713  assert(!modifiable);
1714 
1715  SCIP_CALL( SCIPcreateConsSuperindicator(scip, cons, consname, targetbinvar, targetslackcons,
1716  initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode) );
1717  }
1718 
1719  /* relase slack constraint */
1720  if( targetslackcons != NULL )
1721  {
1722  SCIP_CALL( SCIPreleaseCons(scip, &targetslackcons) );
1723  }
1724 
1725  if( !(*valid) )
1726  {
1727  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "could not copy superindicator constraint <%s>\n", SCIPconsGetName(sourcecons));
1728  }
1729 
1730  return SCIP_OKAY;
1731 }
1732 
1733 /** constraint parsing method of constraint handler */
1734 static
1735 SCIP_DECL_CONSPARSE(consParseSuperindicator)
1736 { /*lint --e{715}*/
1737  SCIP_VAR* binvar;
1738  SCIP_CONS* slackcons;
1739  char binvarname[1024];
1740  const char* slackstr;
1741  int zeroone;
1742  int nargs;
1743 
1744  assert(cons != NULL);
1745  assert(scip != NULL);
1746  assert(success != NULL);
1747  assert(str != NULL);
1748  assert(name != NULL);
1749 
1750  *success = FALSE;
1751 
1752  /* extract binary variable name and value which triggers slack constraint */
1753  nargs = sscanf(str, " <%1023[^>]>[B] = %d", binvarname, &zeroone);
1754 
1755  if( nargs != 2 || (zeroone != 0 && zeroone != 1) )
1756  {
1757  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error: expected the following form: <var> = [0|1] -> <cons>\n");
1758  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "got: %s\n", str);
1759  return SCIP_OKAY;
1760  }
1761 
1762  /* extract string describing slack constraint */
1763  slackstr = strstr(str, "->");
1764 
1765  if( slackstr == NULL )
1766  {
1767  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error: expected the following form: <var> = [0|1] -> <cons>\n");
1768  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "got: %s\n", str);
1769  return SCIP_OKAY;
1770  }
1771 
1772  slackstr = strstr(slackstr, "[");
1773 
1774  if( slackstr == NULL )
1775  {
1776  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "Syntax error: expected the following form: <var> = [0|1] -> <cons>\n");
1777  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "got: %s\n", str);
1778  return SCIP_OKAY;
1779  }
1780 
1781  SCIPdebugMsg(scip, "binvarname=%s, zeroone=%d, slackstr=%s\n", binvarname, zeroone, slackstr);
1782 
1783  /* get binary variable */
1784  binvar = SCIPfindVar(scip, binvarname);
1785  if( binvar == NULL )
1786  {
1787  SCIPverbMessage(scip, SCIP_VERBLEVEL_MINIMAL, NULL, "unknown variable <%s>\n", binvarname);
1788  return SCIP_OKAY;
1789  }
1790 
1791  /* resolve negation if necessary */
1792  if( zeroone == 0 )
1793  {
1794  SCIP_CALL( SCIPgetNegatedVar(scip, binvar, &binvar) );
1795  }
1796 
1797  /**@todo get slack constraint name and check whether constraint already exists; however, using only SCIPfindCons() is
1798  * not sufficient since slack constraints are not added to the problem; do we need something like
1799  * SCIPfindConsInConshdlr()?; currently, if there are two superindicator constraints with same slack constraint
1800  * (binvars may be different), then after writing and reading, the slack constraint will be created twice with
1801  * identical constraint name; this is not incorrect, but might consume more memory or time
1802  */
1803 
1804  /* parse slack constraint string */
1805  SCIP_CALL( SCIPparseCons(scip, &slackcons, slackstr, initial, separate, enforce, check, propagate, local, modifiable,
1806  dynamic, removable, stickingatnode, success) );
1807 
1808  if( *success )
1809  {
1810  assert(binvar != NULL);
1811  assert(slackcons != NULL);
1812 
1813  /* create the superindicator constraint */
1814  SCIP_CALL( SCIPcreateConsSuperindicator(scip, cons, name, binvar, slackcons,
1815  initial, separate, enforce, check, propagate, local, dynamic, removable, stickingatnode) );
1816 
1817  /* the new superindicator constraint captured the slack constraint, so we can release it now */
1818  SCIP_CALL( SCIPreleaseCons(scip, &slackcons) );
1819  }
1820 
1821  return SCIP_OKAY;
1822 }
1823 
1824 /** constraint method of constraint handler which returns the variables (if possible) */
1825 static
1826 SCIP_DECL_CONSGETVARS(consGetVarsSuperindicator)
1827 { /*lint --e{715}*/
1828  SCIP_CONSDATA* consdata;
1830  consdata = SCIPconsGetData(cons);
1831  assert(consdata != NULL);
1832 
1833  /* must be ready to hold at least the binary variable */
1834  if( varssize <= 0 )
1835  *success = FALSE;
1836  else
1837  {
1838  /* add binary variable */
1839  vars[0] = consdata->binvar;
1840 
1841  /* add variables of slack constraint */
1842  SCIP_CALL( SCIPgetConsVars(scip, consdata->slackcons, &(vars[1]), varssize-1, success) );
1843  }
1844 
1845  return SCIP_OKAY;
1846 }
1847 
1848 /** constraint method of constraint handler which returns the number of variables (if possible) */
1849 static
1850 SCIP_DECL_CONSGETNVARS(consGetNVarsSuperindicator)
1851 { /*lint --e{715}*/
1852  SCIP_CONSDATA* consdata;
1854  consdata = SCIPconsGetData(cons);
1855  assert(consdata != NULL);
1856 
1857  /* get number of variables in slack constraint */
1858  SCIP_CALL( SCIPgetConsNVars(scip, consdata->slackcons, nvars, success) );
1859 
1860  /* add binary variable */
1861  if( *success )
1862  (*nvars)++;
1863 
1864  return SCIP_OKAY;
1865 }
1866 
1867 
1868 /*
1869  * constraint specific interface methods
1870  */
1871 
1872 /** creates the handler for superindicator constraints and includes it in SCIP */
1874  SCIP* scip /**< SCIP data structure */
1875  )
1877  SCIP_CONSHDLRDATA* conshdlrdata;
1878  SCIP_CONSHDLR* conshdlr;
1879  SCIP_DIALOG* root;
1880  SCIP_DIALOG* changemenu;
1881  SCIP_DIALOG* dialog;
1882 
1883  /* create superindicator constraint handler data */
1884  SCIP_CALL( SCIPallocBlockMemory(scip, &conshdlrdata) );
1885 
1886  conshdlrdata->nrejects = 0;
1887 
1888  /* include constraint handler */
1891  consEnfolpSuperindicator, consEnfopsSuperindicator, consCheckSuperindicator, consLockSuperindicator,
1892  conshdlrdata) );
1893 
1894  assert(conshdlr != NULL);
1895 
1896  /* set non-fundamental callbacks via specific setter functions */
1897  SCIP_CALL( SCIPsetConshdlrCopy(scip, conshdlr, conshdlrCopySuperindicator, consCopySuperindicator) );
1898  SCIP_CALL( SCIPsetConshdlrDelete(scip, conshdlr, consDeleteSuperindicator) );
1899  SCIP_CALL( SCIPsetConshdlrFree(scip, conshdlr, consFreeSuperindicator) );
1900  SCIP_CALL( SCIPsetConshdlrGetVars(scip, conshdlr, consGetVarsSuperindicator) );
1901  SCIP_CALL( SCIPsetConshdlrGetNVars(scip, conshdlr, consGetNVarsSuperindicator) );
1902  SCIP_CALL( SCIPsetConshdlrInitlp(scip, conshdlr, consInitlpSuperindicator) );
1903  SCIP_CALL( SCIPsetConshdlrInitpre(scip, conshdlr, consInitpreSuperindicator) );
1904  SCIP_CALL( SCIPsetConshdlrParse(scip, conshdlr, consParseSuperindicator) );
1905  SCIP_CALL( SCIPsetConshdlrPresol(scip, conshdlr, consPresolSuperindicator, CONSHDLR_MAXPREROUNDS, CONSHDLR_PRESOLTIMING) );
1906  SCIP_CALL( SCIPsetConshdlrPrint(scip, conshdlr, consPrintSuperindicator) );
1907  SCIP_CALL( SCIPsetConshdlrProp(scip, conshdlr, consPropSuperindicator, CONSHDLR_PROPFREQ, CONSHDLR_DELAYPROP, CONSHDLR_PROP_TIMING) );
1908  SCIP_CALL( SCIPsetConshdlrResprop(scip, conshdlr, consRespropSuperindicator) );
1909  SCIP_CALL( SCIPsetConshdlrSepa(scip, conshdlr, consSepalpSuperindicator, consSepasolSuperindicator, CONSHDLR_SEPAFREQ, CONSHDLR_SEPAPRIORITY, CONSHDLR_DELAYSEPA) );
1910  SCIP_CALL( SCIPsetConshdlrTrans(scip, conshdlr, consTransSuperindicator) );
1911  SCIP_CALL( SCIPsetConshdlrEnforelax(scip, conshdlr, consEnforelaxSuperindicator) );
1912 
1913  /* includes or updates the default dialog menus in SCIP */
1915 
1916  root = SCIPgetRootDialog(scip);
1917  assert(root != NULL);
1918 
1919  /* find change menu */
1920  if( !SCIPdialogHasEntry(root, "change") )
1921  {
1922  SCIP_CALL( SCIPincludeDialog(scip, &changemenu,
1923  NULL,
1924  SCIPdialogExecMenu, NULL, NULL,
1925  "change", "change the problem", TRUE, NULL) );
1926  SCIP_CALL( SCIPaddDialogEntry(scip, root, changemenu) );
1927  SCIP_CALL( SCIPreleaseDialog(scip, &changemenu) );
1928  }
1929 
1930  if( SCIPdialogFindEntry(root, "change", &changemenu) != 1 )
1931  {
1932  SCIPerrorMessage("change sub menu not found\n");
1933  return SCIP_PLUGINNOTFOUND;
1934  }
1935 
1936  /* add minuc dialog */
1937  if( !SCIPdialogHasEntry(changemenu, "minuc") )
1938  {
1939  SCIP_CALL( SCIPincludeDialog(scip, &dialog,
1940  NULL,
1941  SCIPdialogExecChangeMinUC, NULL, NULL,
1942  "minuc", "transforms the current problem into a MinUC problem minimizing the number of unsatisfied constraints",
1943  FALSE, NULL) );
1944  SCIP_CALL( SCIPaddDialogEntry(scip, changemenu, dialog) );
1945  SCIP_CALL( SCIPreleaseDialog(scip, &dialog) );
1946  }
1947 
1948  /* add constraint handler parameters */
1950  "constraints/" CONSHDLR_NAME "/checkslacktype",
1951  "should type of slack constraint be checked when creating superindicator constraint?",
1952  &conshdlrdata->checkslacktype, TRUE, DEFAULT_CHECKSLACKTYPE, NULL, NULL) );
1953 
1955  "constraints/" CONSHDLR_NAME "/maxupgdcoeflinear",
1956  "maximum big-M coefficient of binary variable in upgrade to a linear constraint (relative to smallest coefficient)",
1957  &conshdlrdata->maxupgdcoeflinear, TRUE, DEFAULT_MAXUPGDCOEFLINEAR, 0.0, 1e15, NULL, NULL) );
1958 
1959  SCIP_CALL( SCIPaddIntParam(scip,
1960  "constraints/" CONSHDLR_NAME "/upgdprioindicator",
1961  "priority for upgrading to an indicator constraint (-1: never)",
1962  &conshdlrdata->upgdprioindicator, TRUE, DEFAULT_UPGDPRIOINDICATOR, -1, INT_MAX, NULL, NULL) );
1963 
1964  SCIP_CALL( SCIPaddIntParam(scip,
1965  "constraints/" CONSHDLR_NAME "/upgdpriolinear",
1966  "priority for upgrading to an indicator constraint (-1: never)",
1967  &conshdlrdata->upgdpriolinear, TRUE, DEFAULT_UPGDPRIOLINEAR, -1, INT_MAX, NULL, NULL) );
1968 
1969  return SCIP_OKAY;
1970 }
1971 
1972 /** creates and captures a superindicator constraint
1973  *
1974  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
1975  */
1977  SCIP* scip, /**< SCIP data structure */
1978  SCIP_CONS** cons, /**< pointer to hold the created constraint */
1979  const char* name, /**< name of constraint */
1980  SCIP_VAR* binvar, /**< pointer to the indicator constraint */
1981  SCIP_CONS* slackcons, /**< constraint corresponding to the handled constraint */
1982  SCIP_Bool initial, /**< should the LP relaxation of constraint be in the initial LP?
1983  * Usually set to TRUE. Set to FALSE for 'lazy constraints'. */
1984  SCIP_Bool separate, /**< should the constraint be separated during LP processing?
1985  * Usually set to TRUE. */
1986  SCIP_Bool enforce, /**< should the constraint be enforced during node processing?
1987  * TRUE for model constraints, FALSE for additional, redundant constraints. */
1988  SCIP_Bool check, /**< should the constraint be checked for feasibility?
1989  * TRUE for model constraints, FALSE for additional, redundant constraints. */
1990  SCIP_Bool propagate, /**< should the constraint be propagated during node processing?
1991  * Usually set to TRUE. */
1992  SCIP_Bool local, /**< is constraint only valid locally?
1993  * Usually set to FALSE. Has to be set to TRUE, e.g., for branching constraints. */
1994  SCIP_Bool dynamic, /**< is constraint subject to aging?
1995  * Usually set to FALSE. Set to TRUE for own cuts which
1996  * are separated as constraints. */
1997  SCIP_Bool removable, /**< should the relaxation be removed from the LP due to aging or cleanup?
1998  * Usually set to FALSE. Set to TRUE for 'lazy constraints' and 'user cuts'. */
1999  SCIP_Bool stickingatnode /**< should the constraint always be kept at the node where it was added, even
2000  * if it may be moved to a more global node?
2001  * Usually set to FALSE. Set to TRUE to for constraints that represent node data. */
2002  )
2003 {
2004  SCIP_CONSHDLRDATA* conshdlrdata;
2005  SCIP_CONSHDLR* conshdlr;
2006  SCIP_CONSDATA* consdata;
2007  SCIP_Bool modifiable;
2008 
2009  assert(scip != NULL);
2010  assert(cons != NULL);
2011  assert(name != NULL);
2012  assert(binvar != NULL);
2013  assert(slackcons != NULL);
2014 
2015  modifiable = FALSE;
2016 
2017  /* find the superindicator constraint handler */
2018  conshdlr = SCIPfindConshdlr(scip, CONSHDLR_NAME);
2019  if( conshdlr == NULL )
2020  {
2021  SCIPerrorMessage("superindicator constraint handler not found\n");
2022  return SCIP_PLUGINNOTFOUND;
2023  }
2024 
2025  conshdlrdata = SCIPconshdlrGetData(conshdlr);
2026  assert(conshdlrdata != NULL);
2027 
2028  /* only allow types of slack constraints that can be handled */
2029  if( conshdlrdata->checkslacktype &&
2030  strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "abspower") != 0 &&
2031  strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "and") != 0 &&
2032  strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "bivariate") != 0 &&
2033  strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "bounddisjunction") != 0 &&
2034  strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "conjunction") != 0 &&
2035  strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "disjunction") != 0 &&
2036  strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "knapsack") != 0 &&
2037  strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "linear") != 0 &&
2038  strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "linking") != 0 &&
2039  strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "logicor") != 0 &&
2040  strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "nonlinear") != 0 &&
2041  strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "or") != 0 &&
2042  strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "quadratic") != 0 &&
2043  strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "soc") != 0 &&
2044  strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "SOS1") != 0 &&
2045  strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "SOS2") != 0 &&
2046  strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "cumulative") != 0 &&
2047  strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "varbound") != 0 &&
2048  strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)), "superindicator") != 0
2049  )
2050  {
2051  if( conshdlrdata->nrejects < 5 )
2052  {
2053  SCIPwarningMessage(scip, "rejected creation of superindicator with slack constraint <%s> of type <%s> "
2054  "(use parameter <checkslacktype> to disable check)\n",
2055  SCIPconsGetName(slackcons), SCIPconshdlrGetName(SCIPconsGetHdlr(slackcons)));
2056  conshdlrdata->nrejects++;
2057  }
2058 
2059  if( conshdlrdata->nrejects == 5 )
2060  {
2061  SCIPwarningMessage(scip, "suppressing further warning messages of this type\n");
2062  conshdlrdata->nrejects++;
2063  }
2064 
2065  return SCIP_INVALIDCALL;
2066  }
2067 
2068  /* create constraint data */
2069  SCIP_CALL( consdataCreateSuperindicator(scip, &consdata, binvar, slackcons) );
2070  assert(consdata != NULL);
2071 
2072  /* create constraint */
2073  SCIP_CALL( SCIPcreateCons(scip, cons, name, conshdlr, consdata, initial, separate, enforce, check, propagate,
2074  local, modifiable, dynamic, removable, stickingatnode) );
2075 
2076  return SCIP_OKAY;
2077 }
2078 
2079 /** creates and captures a superindicator constraint
2080  * in its most basic version, i. e., all constraint flags are set to their basic value as explained for the
2081  * method SCIPcreateConsSuperindicator(); all flags can be set via SCIPsetConsFLAGNAME-methods in scip.h
2082  *
2083  * @see SCIPcreateConsSuperindicator() for information about the basic constraint flag configuration
2084  *
2085  * @note the constraint gets captured, hence at one point you have to release it using the method SCIPreleaseCons()
2086  */
2088  SCIP* scip, /**< SCIP data structure */
2089  SCIP_CONS** cons, /**< pointer to hold the created constraint */
2090  const char* name, /**< name of constraint */
2091  SCIP_VAR* binvar, /**< pointer to the indicator constraint */
2092  SCIP_CONS* slackcons /**< constraint corresponding to the handled constraint */
2093  )
2094 {
2095  assert(scip != NULL);
2096  assert(cons != NULL);
2097  assert(name != NULL);
2098  assert(binvar != NULL);
2099  assert(slackcons != NULL);
2100 
2101  SCIP_CALL( SCIPcreateConsSuperindicator(scip, cons, name, binvar, slackcons,
2102  TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE) );
2103 
2104  return SCIP_OKAY;
2105 }
2106 
2107 
2108 /** gets binary variable corresponding to the general indicator constraint */
2110  SCIP_CONS* cons /**< superindicator constraint */
2111  )
2113  assert(cons != NULL);
2114  assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
2115  assert(SCIPconsGetData(cons) != NULL);
2116 
2117  return SCIPconsGetData(cons)->binvar;
2118 }
2119 
2120 /** gets the slack constraint corresponding to the general indicator constraint */
2122  SCIP_CONS* cons /**< superindicator constraint */
2123  )
2125  assert(cons != NULL);
2126  assert(strcmp(SCIPconshdlrGetName(SCIPconsGetHdlr(cons)), CONSHDLR_NAME) == 0);
2127  assert(SCIPconsGetData(cons) != NULL);
2128 
2129  return SCIPconsGetData(cons)->slackcons;
2130 }
2131 
2132 
2133 /*
2134  * constraint-dependent SCIP methods
2135  */
2136 
2137 /** transforms the current problem into a MinUC problem (minimizing the number of unsatisfied constraints),
2138  * a CIP generalization of the MinULR (min. unsatisfied linear relations) problem
2139  */
2141  SCIP* scip, /**< SCIP data structure */
2142  SCIP_Bool* success /**< pointer to store whether all constraints could be transformed */
2143  )
2144 {
2145  SCIP_CONS** conss;
2146  SCIP_VAR** vars;
2147  char consname[SCIP_MAXSTRLEN];
2148  char varname[SCIP_MAXSTRLEN];
2149  int maxbranchprio;
2150  int ntransconss;
2151  int nconss;
2152  int nvars;
2153  int i;
2154 
2155  assert(scip != NULL);
2156  assert(success != NULL);
2157 
2158  *success = FALSE;
2159 
2160  if( SCIPgetStage(scip) != SCIP_STAGE_PROBLEM )
2161  {
2162  SCIPerrorMessage("method <SCIPtransformMinUC> can only be called in problem stage\n");
2163  return SCIP_INVALIDCALL;
2164  }
2165 
2166  /* get variable data */
2167  SCIP_CALL( SCIPgetVarsData(scip, &vars, &nvars, NULL, NULL, NULL, NULL) );
2168 
2169  /* copy the conss array because it changes when adding and deleting constraints */
2170  nconss = SCIPgetNConss(scip);
2171  SCIP_CALL( SCIPduplicateBufferArray(scip, &conss, SCIPgetConss(scip), nconss) );
2172 
2173  /* clear objective function and compute maximal branching priority */
2174  maxbranchprio = 0;
2175  for( i = nvars-1; i >= 0; i-- )
2176  {
2177  SCIP_CALL( SCIPchgVarObj(scip, vars[i], 0.0) );
2178 
2179  if( SCIPvarGetBranchPriority(vars[i]) > maxbranchprio )
2180  maxbranchprio = SCIPvarGetBranchPriority(vars[i]);
2181  }
2182 
2183  maxbranchprio++;
2184 
2185  /* transform each constraint to slack constraint in a newly created superindicator constraint; note that we also need
2186  * to transform superindicator constraints, since their binary variable might have down-locks
2187  */
2188  ntransconss = 0;
2189  for( i = 0; i < nconss; ++i )
2190  {
2191  SCIP_CONS* cons;
2192  SCIP_CONS* supindcons;
2193  SCIP_VAR* binvar;
2194  SCIP_VAR* negbinvar;
2195  SCIP_RETCODE retcode;
2196 
2197  cons = conss[i];
2198  assert(cons != NULL);
2199 
2200  /* create a new binary variable with objective coefficient one */
2201  (void) SCIPsnprintf(varname, SCIP_MAXSTRLEN, "%s_master", SCIPconsGetName(cons));
2202 
2203  SCIP_CALL( SCIPcreateVar(scip, &binvar, varname, 0.0, 1.0, 1.0, SCIP_VARTYPE_BINARY,
2204  TRUE, FALSE, NULL, NULL, NULL, NULL, NULL) );
2205 
2206  /* get negated variable, since we want to minimize the number of violated constraints */
2207  SCIP_CALL( SCIPgetNegatedVar(scip, binvar, &negbinvar) );
2208 
2209  /* create superindicator constraint */
2210  (void) SCIPsnprintf(consname, SCIP_MAXSTRLEN, "%s_super", SCIPconsGetName(cons));
2211 
2212  retcode = SCIPcreateConsSuperindicator(scip, &supindcons, consname, negbinvar, cons,
2215  SCIPconsIsStickingAtNode(cons));
2216 
2217  if( retcode == SCIP_OKAY )
2218  {
2219  /* add binary variable and increase its branching priority */
2220  SCIP_CALL( SCIPaddVar(scip, binvar) );
2221  SCIP_CALL( SCIPchgVarBranchPriority(scip, binvar, maxbranchprio) );
2222 
2223  /* add superindicator constraint */
2224  SCIP_CALL( SCIPaddCons(scip, supindcons) );
2225 
2226  /* release binary variable and superindicator constraint */
2227  SCIP_CALL( SCIPreleaseVar(scip, &binvar) );
2228  SCIP_CALL( SCIPreleaseCons(scip, &supindcons) );
2229 
2230  /* delete slack constraint; it is still captured by the superindicator constraint */
2231  SCIP_CALL( SCIPdelCons(scip, cons) );
2232 
2233  ntransconss++;
2234  }
2235  else if( retcode == SCIP_INVALIDCALL )
2236  {
2237  SCIPdebugMsg(scip, "constraint <%s> of type <%s> could not be transformed to superindicator and was removed\n",
2239 
2240  /* release binary variable */
2241  SCIP_CALL( SCIPreleaseVar(scip, &binvar) );
2242 
2243  /* delete slack constraint; this is necessary, because, e.g., the indicator expects its linear slack constraint
2244  * present in the problem, but this has just be transformed; hence, it cannot function any more and we have to
2245  * remove it
2246  */
2247  SCIP_CALL( SCIPdelCons(scip, cons) );
2248  }
2249  else
2250  {
2251  /* return all other error codes */
2252  SCIP_CALL( retcode );
2253  }
2254  }
2255 
2256  if( ntransconss == nconss )
2257  *success = TRUE;
2258 
2259  /* minimize the number of violated constraints */
2261 
2262  /* free the allocated memory for the copied constraint array */
2263  SCIPfreeBufferArray(scip, &conss);
2264 
2265  return SCIP_OKAY;
2266 }
2267 
2268 
2269 /*
2270  * constraint-dependent dialog entries
2271  */
2272 
2273 /** dialog execution method for the SCIPtransformMinUC() method */
2274 SCIP_DECL_DIALOGEXEC(SCIPdialogExecChangeMinUC)
2275 { /*lint --e{715}*/
2276  SCIP_Bool success;
2278  SCIP_CALL( SCIPdialoghdlrAddHistory(dialoghdlr, dialog, NULL, FALSE) );
2279  SCIPdialogMessage(scip, NULL, "\n");
2280 
2281  switch( SCIPgetStage(scip) )
2282  {
2283  case SCIP_STAGE_INIT:
2284  SCIPdialogMessage(scip, NULL, "no problem exists\n");
2285  break;
2286  case SCIP_STAGE_PROBLEM:
2287  SCIPdialogMessage(scip, NULL, "change problem to MinUC\n");
2288  SCIPdialogMessage(scip, NULL, "==============\n");
2289 
2290  SCIP_CALL( SCIPtransformMinUC(scip, &success) );
2291 
2292  if( !success )
2293  {
2294  SCIPdialogMessage(scip, NULL, "some constraints could not be transformed to superindicator constraints and were removed\n");
2295  }
2296 
2297  SCIPdialogMessage(scip, NULL, "\n");
2298  SCIPdialogMessage(scip, NULL, "changed problem has %d variables (%d bin, %d int, %d impl, %d cont) and %d constraints\n",
2300  SCIPgetNConss(scip));
2301 
2302  SCIPdialogMessage(scip, NULL, "increased branching priority of new binary variables");
2303 
2304  break;
2307  case SCIP_STAGE_PRESOLVING:
2309  case SCIP_STAGE_PRESOLVED:
2310  case SCIP_STAGE_SOLVING:
2311  case SCIP_STAGE_SOLVED:
2313  case SCIP_STAGE_INITSOLVE:
2314  case SCIP_STAGE_EXITSOLVE:
2315  case SCIP_STAGE_FREETRANS:
2316  case SCIP_STAGE_FREE:
2317  SCIPdialogMessage(scip, NULL, "problem has to be in problem stage to create MinUC problem\n");
2318  break;
2319  default:
2320  SCIPerrorMessage("invalid SCIP stage\n");
2321  return SCIP_INVALIDCALL;
2322  } /*lint --e{616}*/
2323 
2324  SCIPdialogMessage(scip, NULL, "\n");
2325  *nextdialog = SCIPdialoghdlrGetRoot(dialoghdlr);
2326 
2327  return SCIP_OKAY;
2328 }
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:28488
enum SCIP_Result SCIP_RESULT
Definition: type_result.h:52
int SCIPgetNIntVars(SCIP *scip)
Definition: scip.c:11721
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:6228
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:19263
static SCIP_DECL_CONSENFOPS(consEnfopsSuperindicator)
SCIP_Bool SCIPisFeasEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:46086
SCIP_STAGE SCIPgetStage(SCIP *scip)
Definition: scip.c:814
SCIP_Bool SCIPconsIsDynamic(SCIP_CONS *cons)
Definition: cons.c:8140
SCIP_RETCODE SCIPsetConshdlrTrans(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSTRANS((*constrans)))
Definition: scip.c:6251
void SCIPdialogMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip.c:1319
SCIP_RETCODE SCIPaddDialogEntry(SCIP *scip, SCIP_DIALOG *dialog, SCIP_DIALOG *subdialog)
Definition: scip.c:9669
SCIP_CONSHDLR * SCIPfindConshdlr(SCIP *scip, const char *name)
Definition: scip.c:6541
#define CONSHDLR_SEPAPRIORITY
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:17166
SCIP_RETCODE SCIPsetConshdlrGetVars(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSGETVARS((*consgetvars)))
Definition: scip.c:6481
#define SCIP_MAXSTRLEN
Definition: def.h:215
SCIP_RETCODE SCIPsetConshdlrEnforelax(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSENFORELAX((*consenforelax)))
Definition: scip.c:5973
SCIP_RETCODE SCIPdelCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:12481
static SCIP_DECL_CONSGETVARS(consGetVarsSuperindicator)
SCIP_Bool SCIPisPositive(SCIP *scip, SCIP_Real val)
Definition: scip.c:45876
SCIP_Real SCIPvarGetLbLocal(SCIP_VAR *var)
Definition: var.c:17222
SCIP_Bool SCIPisGE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:45803
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:18575
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:18384
#define CONSHDLR_MAXPREROUNDS
SCIP_RETCODE SCIPsetConshdlrInitpre(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITPRE((*consinitpre)))
Definition: scip.c:6142
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:11505
#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:5831
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:27230
SCIP_Real SCIPinfinity(SCIP *scip)
Definition: scip.c:45816
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:9340
SCIP_Bool SCIPisNegative(SCIP *scip, SCIP_Real val)
Definition: scip.c:45888
#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:21255
SCIP_Bool SCIPconsIsStickingAtNode(SCIP_CONS *cons)
Definition: cons.c:8160
int SCIPdialogFindEntry(SCIP_DIALOG *dialog, const char *entryname, SCIP_DIALOG **subdialog)
Definition: dialog.c:1021
SCIP_Bool SCIPconsIsTransformed(SCIP_CONS *cons)
Definition: cons.c:8190
#define SCIPfreeBlockMemory(scip, ptr)
Definition: scip.h:21907
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:5885
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip.h:21933
SCIP_CONS ** SCIPgetConss(SCIP *scip)
Definition: scip.c:12725
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:21937
#define SCIPallocBlockMemory(scip, ptr)
Definition: scip.h:21890
SCIP_Bool SCIPisTransformed(SCIP *scip)
Definition: scip.c:1010
SCIP_Bool SCIPconsIsRemovable(SCIP_CONS *cons)
Definition: cons.c:8150
SCIP_RETCODE SCIPsetConshdlrInitlp(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSINITLP((*consinitlp)))
Definition: scip.c:6274
void SCIPwarningMessage(SCIP *scip, const char *formatstr,...)
Definition: scip.c:1260
#define SCIPdebugMsgPrint
Definition: scip.h:452
#define SCIPdebugMsg
Definition: scip.h:451
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:4202
SCIP_Real SCIPgetRhsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_RETCODE SCIPsetConshdlrParse(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPARSE((*consparse)))
Definition: scip.c:6458
void SCIPinfoMessage(SCIP *scip, FILE *file, const char *formatstr,...)
Definition: scip.c:1336
int SCIPgetNContVars(SCIP *scip)
Definition: scip.c:11811
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:27146
SCIP_RETCODE SCIPaddConflictLb(SCIP *scip, SCIP_VAR *var, SCIP_BDCHGIDX *bdchgidx)
Definition: scip.c:26746
static SCIP_DECL_CONSTRANS(consTransSuperindicator)
SCIP_VAR * SCIPvarGetNegatedVar(SCIP_VAR *var)
Definition: var.c:16982
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:12325
#define CONSHDLR_NAME
SCIP_DIALOG * SCIPgetRootDialog(SCIP *scip)
Definition: scip.c:9655
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:17176
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:9557
SCIP_RETCODE SCIPsetObjsense(SCIP *scip, SCIP_OBJSENSE objsense)
Definition: scip.c:10898
static SCIP_DECL_CONSCHECK(consCheckSuperindicator)
SCIP_RETCODE SCIPsetConshdlrCopy(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSHDLRCOPY((*conshdlrcopy)), SCIP_DECL_CONSCOPY((*conscopy)))
Definition: scip.c:5997
#define CONSHDLR_SEPAFREQ
const char * SCIPheurGetName(SCIP_HEUR *heur)
Definition: heur.c:1181
#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:28737
SCIP_RETCODE SCIPaddCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:12410
#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:28252
const char * SCIPconsGetName(SCIP_CONS *cons)
Definition: cons.c:7881
SCIP_Bool SCIPconsIsPropagated(SCIP_CONS *cons)
Definition: cons.c:8100
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:16552
SCIP_RETCODE SCIPsetConshdlrFree(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSFREE((*consfree)))
Definition: scip.c:6022
#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:28341
#define NULL
Definition: lpi_spx1.cpp:137
SCIP_HEUR * SCIPsolGetHeur(SCIP_SOL *sol)
Definition: sol.c:2382
SCIP_DECL_DIALOGEXEC(SCIPdialogExecChangeMinUC)
SCIP_RETCODE SCIPtransformCons(SCIP *scip, SCIP_CONS *cons, SCIP_CONS **transcons)
Definition: scip.c:27734
#define SCIP_CALL(x)
Definition: def.h:306
void SCIPverbMessage(SCIP *scip, SCIP_VERBLEVEL msgverblevel, FILE *file, const char *formatstr,...)
Definition: scip.c:1353
SCIP_Bool SCIPconsIsLocal(SCIP_CONS *cons)
Definition: cons.c:8120
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:27824
SCIP_RETCODE SCIPcaptureCons(SCIP *scip, SCIP_CONS *cons)
Definition: scip.c:27288
SCIP_RETCODE SCIPsetConshdlrResprop(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSRESPROP((*consresprop)))
Definition: scip.c:6297
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:28693
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:2524
SCIP_RETCODE SCIPchgVarObj(SCIP *scip, SCIP_VAR *var, SCIP_Real newobj)
Definition: scip.c:21448
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:28457
#define SCIPallocBufferArray(scip, ptr, num)
Definition: scip.h:21925
#define DEFAULT_UPGDPRIOINDICATOR
#define SCIP_Bool
Definition: def.h:61
SCIP_RETCODE SCIPsetConsLocal(SCIP *scip, SCIP_CONS *cons, SCIP_Bool local)
Definition: scip.c:27548
int SCIPgetNImplVars(SCIP *scip)
Definition: scip.c:11766
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:17338
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:28652
SCIP_CONSHDLR * SCIPconsGetHdlr(SCIP_CONS *cons)
Definition: cons.c:7901
static SCIP_DECL_CONSCOPY(consCopySuperindicator)
SCIP_Bool SCIPconsIsDeleted(SCIP_CONS *cons)
Definition: cons.c:8010
SCIP_Bool SCIPconsIsChecked(SCIP_CONS *cons)
Definition: cons.c:8080
SCIP_Bool SCIPconsIsInitial(SCIP_CONS *cons)
Definition: cons.c:8050
#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:17237
SCIP_RETCODE SCIPsepasolCons(SCIP *scip, SCIP_CONS *cons, SCIP_SOL *sol, SCIP_RESULT *result)
Definition: scip.c:28427
SCIP_RETCODE SCIPchgVarBranchPriority(SCIP *scip, SCIP_VAR *var, int branchpriority)
Definition: scip.c:24851
#define CONSHDLR_DELAYPROP
SCIP_RETCODE SCIPenfolpCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool solinfeasible, SCIP_RESULT *result)
Definition: scip.c:28311
SCIP_RETCODE SCIPsetConshdlrPrint(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRINT((*consprint)))
Definition: scip.c:6435
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:45827
SCIP_RETCODE SCIPdialoghdlrAddHistory(SCIP_DIALOGHDLR *dialoghdlr, SCIP_DIALOG *dialog, const char *command, SCIP_Bool escapecommand)
Definition: dialog.c:717
int SCIPgetNBinVars(SCIP *scip)
Definition: scip.c:11676
#define CONSHDLR_DESC
int SCIPgetNVars(SCIP *scip)
Definition: scip.c:11631
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:425
static SCIP_DECL_CONSENFORELAX(consEnforelaxSuperindicator)
SCIP_Bool SCIPisIntegral(SCIP *scip, SCIP_Real val)
Definition: scip.c:45900
SCIP_RETCODE SCIPenfopsCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool solinfeasible, SCIP_Bool objinfeasible, SCIP_RESULT *result)
Definition: scip.c:28280
SCIP_RETCODE SCIPsepalpCons(SCIP *scip, SCIP_CONS *cons, SCIP_RESULT *result)
Definition: scip.c:28400
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:1911
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:11311
SCIP_VAR ** SCIPgetVarsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_CONSDATA * SCIPconsGetData(SCIP_CONS *cons)
Definition: cons.c:7911
static SCIP_DECL_CONSDELETE(consDeleteSuperindicator)
int SCIPgetNConss(SCIP *scip)
Definition: scip.c:12679
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:27323
#define CONSHDLR_DELAYSEPA
SCIP_RETCODE SCIPsetConshdlrPresol(SCIP *scip, SCIP_CONSHDLR *conshdlr, SCIP_DECL_CONSPRESOL((*conspresol)), int maxprerounds, SCIP_PRESOLTIMING presoltiming)
Definition: scip.c:6190
SCIP_CONS * SCIPgetSlackConsSuperindicator(SCIP_CONS *cons)
#define CONSHDLR_PROP_TIMING
SCIP_VARSTATUS SCIPvarGetStatus(SCIP_VAR *var)
Definition: var.c:16671
default user interface dialog
#define SCIP_Real
Definition: def.h:135
SCIP_Bool SCIPconsIsModifiable(SCIP_CONS *cons)
Definition: cons.c:8130
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:6504
static SCIP_DECL_CONSPRINT(consPrintSuperindicator)
SCIP_Bool SCIPconsIsEnforced(SCIP_CONS *cons)
Definition: cons.c:8070
SCIP_Bool SCIPconsIsSeparated(SCIP_CONS *cons)
Definition: cons.c:8060
SCIP_RETCODE SCIPaddConsLocks(SCIP *scip, SCIP_CONS *cons, int nlockspos, int nlocksneg)
Definition: scip.c:28222
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:9622
SCIP_Real * SCIPgetValsLinear(SCIP *scip, SCIP_CONS *cons)
SCIP_Bool SCIPisLE(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:45777
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:17353
SCIP_Real SCIPgetSolVal(SCIP *scip, SCIP_SOL *sol, SCIP_VAR *var)
Definition: scip.c:38007
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:4258
SCIP_RETCODE SCIPincludeConshdlrSuperindicator(SCIP *scip)
SCIP_RETCODE SCIPgetNegatedVar(SCIP *scip, SCIP_VAR *var, SCIP_VAR **negvar)
Definition: scip.c:18663
#define CONSHDLR_PRESOLTIMING
SCIP_RETCODE SCIPinitlpCons(SCIP *scip, SCIP_CONS *cons, SCIP_Bool *infeasible)
Definition: scip.c:28373
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:4176
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:5931
SCIP_RETCODE SCIPprintSol(SCIP *scip, SCIP_SOL *sol, FILE *file, SCIP_Bool printzeros)
Definition: scip.c:38421