Scippy

SCIP

Solving Constraint Integer Programs

presol_inttobinary.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-2014 Konrad-Zuse-Zentrum */
7 /* fuer Informationstechnik Berlin */
8 /* */
9 /* SCIP is distributed under the terms of the ZIB Academic License. */
10 /* */
11 /* You should have received a copy of the ZIB Academic License */
12 /* along with SCIP; see the file COPYING. If not email to scip@zib.de. */
13 /* */
14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
15 
16 /**@file presol_inttobinary.c
17  * @brief presolver that converts integer variables with domain [a,a+1] to binaries
18  * @author Tobias Achterberg
19  */
20 
21 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/
22 
23 #include <assert.h>
24 #include <string.h>
25 
27 
28 
29 #define PRESOL_NAME "inttobinary"
30 #define PRESOL_DESC "converts integer variables with domain [a,a+1] to binaries"
31 #define PRESOL_PRIORITY +7000000 /**< priority of the presolver (>= 0: before, < 0: after constraint handlers) */
32 #define PRESOL_MAXROUNDS -1 /**< maximal number of presolving rounds the presolver participates in (-1: no limit) */
33 #define PRESOL_DELAY FALSE /**< should presolver be delayed, if other presolvers found reductions? */
34 
35 
36 /*
37  * Callback methods of presolver
38  */
39 
40 /** copy method for constraint handler plugins (called when SCIP copies plugins) */
41 static
42 SCIP_DECL_PRESOLCOPY(presolCopyInttobinary)
43 { /*lint --e{715}*/
44  assert(scip != NULL);
45  assert(presol != NULL);
46  assert(strcmp(SCIPpresolGetName(presol), PRESOL_NAME) == 0);
47 
48  /* call inclusion method of presolver */
50 
51  return SCIP_OKAY;
52 }
53 
54 
55 /** presolving execution method */
56 static
57 SCIP_DECL_PRESOLEXEC(presolExecInttobinary)
58 { /*lint --e{715}*/
59  SCIP_VAR** scipvars;
60  SCIP_VAR** vars;
61  int nbinvars;
62  int nintvars;
63  int v;
64 
65  assert(result != NULL);
66 
67  *result = SCIP_DIDNOTRUN;
68 
69  if( SCIPdoNotAggr(scip) )
70  return SCIP_OKAY;
71 
72  /* get the problem variables */
73  scipvars = SCIPgetVars(scip);
74  nbinvars = SCIPgetNBinVars(scip);
75  nintvars = SCIPgetNIntVars(scip);
76  if( nintvars == 0 )
77  return SCIP_OKAY;
78 
79  *result = SCIP_DIDNOTFIND;
80 
81  /* copy the integer variables into an own array, since adding binary variables affects the left-most slots in the
82  * array and thereby interferes with our search loop
83  */
84  SCIP_CALL( SCIPduplicateBufferArray(scip, &vars, &scipvars[nbinvars], nintvars) );
85 
86  /* scan the integer variables for possible conversion into binaries;
87  * we have to collect the variables first in an own
88  */
89  for( v = 0; v < nintvars; ++v )
90  {
91  SCIP_Real lb;
92  SCIP_Real ub;
93 
94  assert(SCIPvarGetType(vars[v]) == SCIP_VARTYPE_INTEGER);
95 
96  /* get variable's bounds */
97  lb = SCIPvarGetLbGlobal(vars[v]);
98  ub = SCIPvarGetUbGlobal(vars[v]);
99 
100  /* check if bounds are exactly one apart */
101  if( SCIPisEQ(scip, lb, ub - 1.0) )
102  {
103  SCIP_VAR* binvar;
104  char binvarname[SCIP_MAXSTRLEN];
105  SCIP_Bool infeasible;
106  SCIP_Bool redundant;
107  SCIP_Bool aggregated;
108 
109  SCIPdebugMessage("converting <%s>[%g,%g] into binary variable\n", SCIPvarGetName(vars[v]), lb, ub);
110 
111  /* create binary variable */
112  (void) SCIPsnprintf(binvarname, SCIP_MAXSTRLEN, "%s_bin", SCIPvarGetName(vars[v]));
113  SCIP_CALL( SCIPcreateVar(scip, &binvar, binvarname, 0.0, 1.0, 0.0, SCIP_VARTYPE_BINARY,
114  SCIPvarIsInitial(vars[v]), SCIPvarIsRemovable(vars[v]), NULL, NULL, NULL, NULL, NULL) );
115  SCIP_CALL( SCIPaddVar(scip, binvar) );
116 
117  /* aggregate integer and binary variable */
118  SCIP_CALL( SCIPaggregateVars(scip, vars[v], binvar, 1.0, -1.0, lb, &infeasible, &redundant, &aggregated) );
119 
120  /* release binary variable */
121  SCIP_CALL( SCIPreleaseVar(scip, &binvar) );
122 
123  /* it can be the case that this aggregation detects an infeasibility; for example, during the copy of the
124  * variable bounds from the integer variable to the binary variable, infeasibility can be detected; this can
125  * happen because an upper bound or a lower bound of such a variable bound variable was "just" changed and the
126  * varbound constraint handler, who would detect that infeasibility (since it was creating it from a varbound
127  * constraint), was called before that bound change was detected due to the presolving priorities;
128  */
129  if( infeasible )
130  {
131  *result = SCIP_CUTOFF;
132  break;
133  }
134 
135  assert(redundant);
136  assert(aggregated);
137  (*nchgvartypes)++;
138  ++(*naggrvars);
139  *result = SCIP_SUCCESS;
140  }
141  }
142 
143  /* free temporary memory */
144  SCIPfreeBufferArray(scip, &vars);
145 
146  return SCIP_OKAY;
147 }
148 
149 
150 /*
151  * presolver specific interface methods
152  */
153 
154 /** creates the inttobinary presolver and includes it in SCIP */
156  SCIP* scip /**< SCIP data structure */
157  )
158 {
159  SCIP_PRESOLDATA* presoldata;
160  SCIP_PRESOL* presolptr;
161 
162  /* create inttobinary presolver data */
163  presoldata = NULL;
164 
165  /* include presolver */
167  presolExecInttobinary,
168  presoldata) );
169 
170  assert(presolptr != NULL);
171 
172  SCIP_CALL( SCIPsetPresolCopy(scip, presolptr, presolCopyInttobinary) );
173 
174  return SCIP_OKAY;
175 }
SCIP_Bool SCIPisEQ(SCIP *scip, SCIP_Real val1, SCIP_Real val2)
Definition: scip.c:38254
struct SCIP_PresolData SCIP_PRESOLDATA
Definition: type_presol.h:37
const char * SCIPvarGetName(SCIP_VAR *var)
Definition: var.c:15788
SCIP_RETCODE SCIPaggregateVars(SCIP *scip, SCIP_VAR *varx, SCIP_VAR *vary, SCIP_Real scalarx, SCIP_Real scalary, SCIP_Real rhs, SCIP_Bool *infeasible, SCIP_Bool *redundant, SCIP_Bool *aggregated)
Definition: scip.c:20892
SCIP_RETCODE SCIPaddVar(SCIP *scip, SCIP_VAR *var)
Definition: scip.c:9751
SCIP_RETCODE SCIPcreateVar(SCIP *scip, SCIP_VAR **var, const char *name, SCIP_Real lb, SCIP_Real ub, SCIP_Real obj, SCIP_VARTYPE vartype, SCIP_Bool initial, SCIP_Bool removable, SCIP_DECL_VARDELORIG((*vardelorig)), SCIP_DECL_VARTRANS((*vartrans)), SCIP_DECL_VARDELTRANS((*vardeltrans)), SCIP_DECL_VARCOPY((*varcopy)), SCIP_VARDATA *vardata)
Definition: scip.c:13986
SCIP_VAR ** SCIPgetVars(SCIP *scip)
Definition: scip.c:10026
#define SCIP_MAXSTRLEN
Definition: def.h:196
#define PRESOL_DESC
#define NULL
Definition: lpi_spx.cpp:129
SCIP_RETCODE SCIPsetPresolCopy(SCIP *scip, SCIP_PRESOL *presol, SCIP_DECL_PRESOLCOPY((*presolcopy)))
Definition: scip.c:5948
SCIP_Real SCIPvarGetUbGlobal(SCIP_VAR *var)
Definition: var.c:16380
const char * SCIPpresolGetName(SCIP_PRESOL *presol)
Definition: presol.c:551
int SCIPgetNBinVars(SCIP *scip)
Definition: scip.c:10116
int SCIPsnprintf(char *t, int len, const char *s,...)
Definition: misc.c:7579
enum SCIP_Retcode SCIP_RETCODE
Definition: type_retcode.h:53
#define PRESOL_DELAY
#define SCIPdebugMessage
Definition: pub_message.h:77
static SCIP_DECL_PRESOLEXEC(presolExecInttobinary)
#define SCIPfreeBufferArray(scip, ptr)
Definition: scip.h:19221
SCIP_Bool SCIPdoNotAggr(SCIP *scip)
Definition: scip.c:21051
SCIP_Bool SCIPvarIsInitial(SCIP_VAR *var)
Definition: var.c:15989
SCIP_Bool SCIPvarIsRemovable(SCIP_VAR *var)
Definition: var.c:15999
#define SCIP_CALL(x)
Definition: def.h:258
SCIP_RETCODE SCIPreleaseVar(SCIP *scip, SCIP_VAR **var)
Definition: scip.c:15130
SCIP_RETCODE SCIPincludePresolInttobinary(SCIP *scip)
#define SCIP_Bool
Definition: def.h:49
#define PRESOL_NAME
#define PRESOL_PRIORITY
SCIP_VARTYPE SCIPvarGetType(SCIP_VAR *var)
Definition: var.c:15953
SCIP_Real SCIPvarGetLbGlobal(SCIP_VAR *var)
Definition: var.c:16370
int SCIPgetNIntVars(SCIP *scip)
Definition: scip.c:10161
#define SCIPduplicateBufferArray(scip, ptr, source, num)
Definition: scip.h:19217
#define PRESOL_MAXROUNDS
static SCIP_DECL_PRESOLCOPY(presolCopyInttobinary)
#define SCIP_Real
Definition: def.h:123
presolver that converts integer variables with domain [a,a+1] to binaries
SCIP_RETCODE SCIPincludePresolBasic(SCIP *scip, SCIP_PRESOL **presolptr, const char *name, const char *desc, int priority, int maxrounds, SCIP_Bool delay, SCIP_DECL_PRESOLEXEC((*presolexec)), SCIP_PRESOLDATA *presoldata)
Definition: scip.c:5913