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