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