1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 2 /* */ 3 /* This file is part of the program and library */ 4 /* SCIP --- Solving Constraint Integer Programs */ 5 /* */ 6 /* Copyright (C) 2002-2021 Konrad-Zuse-Zentrum */ 7 /* fuer Informationstechnik Berlin */ 8 /* */ 9 /* SCIP is distributed under the terms of the ZIB Academic License. */ 10 /* */ 11 /* You should have received a copy of the ZIB Academic License */ 12 /* along with SCIP; see the file COPYING. If not visit scipopt.org. */ 13 /* */ 14 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ 15 16 /**@file struct_var.h 17 * @ingroup INTERNALAPI 18 * @brief datastructures for problem variables 19 * @author Tobias Achterberg 20 */ 21 22 /*---+----1----+----2----+----3----+----4----+----5----+----6----+----7----+----8----+----9----+----0----+----1----+----2*/ 23 24 #ifndef __SCIP_STRUCT_VAR_H__ 25 #define __SCIP_STRUCT_VAR_H__ 26 27 28 #include "scip/def.h" 29 #include "scip/type_history.h" 30 #include "scip/type_event.h" 31 #include "scip/type_var.h" 32 #include "scip/type_implics.h" 33 #include "scip/type_cons.h" 34 #include "scip/type_prop.h" 35 #include "scip/type_lp.h" 36 37 #ifdef __cplusplus 38 extern "C" { 39 #endif 40 41 /** hole in a domain */ 42 struct SCIP_Hole 43 { 44 SCIP_Real left; /**< left bound of open interval defining the hole (left,right) */ 45 SCIP_Real right; /**< right bound of open interval defining the hole (left,right) */ 46 }; 47 48 /** list of domain holes */ 49 struct SCIP_Holelist 50 { 51 SCIP_HOLE hole; /**< this hole */ 52 SCIP_HOLELIST* next; /**< next hole in list */ 53 }; 54 55 /** change in a hole list */ 56 struct SCIP_HoleChg 57 { 58 SCIP_HOLELIST** ptr; /**< changed list pointer */ 59 SCIP_HOLELIST* newlist; /**< new value of list pointer */ 60 SCIP_HOLELIST* oldlist; /**< old value of list pointer */ 61 }; 62 63 /** data for branching decision bound changes */ 64 struct SCIP_BranchingData 65 { 66 SCIP_Real lpsolval; /**< sol val of var in last LP prior to bound change, or SCIP_INVALID if unknown */ 67 }; 68 69 /** data for infered bound changes */ 70 struct SCIP_InferenceData 71 { 72 SCIP_VAR* var; /**< variable that was changed (parent of var, or var itself) */ 73 union 74 { 75 SCIP_CONS* cons; /**< constraint that infered this bound change, or NULL */ 76 SCIP_PROP* prop; /**< propagator that infered this bound change, or NULL */ 77 } reason; 78 int info; /**< user information for inference to help resolving the conflict */ 79 }; 80 81 /** change in one bound of a variable */ 82 struct SCIP_BoundChg 83 { 84 SCIP_Real newbound; /**< new value for bound */ 85 union 86 { 87 SCIP_BRANCHINGDATA branchingdata; /**< data for branching decisions */ 88 SCIP_INFERENCEDATA inferencedata; /**< data for infered bound changes */ 89 } data; 90 SCIP_VAR* var; /**< active variable to change the bounds for */ 91 unsigned int boundchgtype:2; /**< bound change type: branching decision or infered bound change */ 92 unsigned int boundtype:1; /**< type of bound for var: lower or upper bound */ 93 unsigned int inferboundtype:1; /**< type of bound for inference var (see inference data): lower or upper bound */ 94 unsigned int applied:1; /**< was this bound change applied at least once? */ 95 unsigned int redundant:1; /**< is this bound change redundant? */ 96 }; 97 98 /** bound change index representing the time of the bound change in path from root to current node */ 99 struct SCIP_BdChgIdx 100 { 101 int depth; /**< depth of node where the bound change was created */ 102 int pos; /**< position of bound change in node's domchg array */ 103 }; 104 105 /** bound change information to track bound changes from root node to current node */ 106 struct SCIP_BdChgInfo 107 { 108 SCIP_Real oldbound; /**< old value for bound */ 109 SCIP_Real newbound; /**< new value for bound */ 110 SCIP_VAR* var; /**< active variable that changed the bounds */ 111 SCIP_INFERENCEDATA inferencedata; /**< data for infered bound changes */ 112 SCIP_BDCHGIDX bdchgidx; /**< bound change index in path from root to current node */ 113 unsigned int pos:27; /**< position in the variable domain change array */ 114 unsigned int boundchgtype:2; /**< bound change type: branching decision or infered bound change */ 115 unsigned int boundtype:1; /**< type of bound for var: lower or upper bound */ 116 unsigned int inferboundtype:1; /**< type of bound for inference var (see inference data): lower or upper bound */ 117 unsigned int redundant:1; /**< does the bound change info belong to a redundant bound change? */ 118 }; 119 120 /** tracks changes of the variables' domains (static arrays, bound changes only) */ 121 struct SCIP_DomChgBound 122 { 123 unsigned int nboundchgs:30; /**< number of bound changes (must be first structure entry!) */ 124 unsigned int domchgtype:2; /**< type of domain change data (must be first structure entry!) */ 125 SCIP_BOUNDCHG* boundchgs; /**< array with changes in bounds of variables */ 126 }; 127 128 /** tracks changes of the variables' domains (static arrays, bound and hole changes) */ 129 struct SCIP_DomChgBoth 130 { 131 unsigned int nboundchgs:30; /**< number of bound changes (must be first structure entry!) */ 132 unsigned int domchgtype:2; /**< type of domain change data (must be first structure entry!) */ 133 SCIP_BOUNDCHG* boundchgs; /**< array with changes in bounds of variables */ 134 SCIP_HOLECHG* holechgs; /**< array with changes in hole lists */ 135 int nholechgs; /**< number of hole list changes */ 136 }; 137 138 /** tracks changes of the variables' domains (dynamic arrays) */ 139 struct SCIP_DomChgDyn 140 { 141 unsigned int nboundchgs:30; /**< number of bound changes (must be first structure entry!) */ 142 unsigned int domchgtype:2; /**< type of domain change data (must be first structure entry!) */ 143 SCIP_BOUNDCHG* boundchgs; /**< array with changes in bounds of variables */ 144 SCIP_HOLECHG* holechgs; /**< array with changes in hole lists */ 145 int nholechgs; /**< number of hole list changes */ 146 int boundchgssize; /**< size of bound changes array */ 147 int holechgssize; /**< size of hole changes array */ 148 }; 149 150 /** tracks changes of the variables' domains */ 151 union SCIP_DomChg 152 { 153 SCIP_DOMCHGBOUND domchgbound; /**< bound changes */ 154 SCIP_DOMCHGBOTH domchgboth; /**< bound and hole changes */ 155 SCIP_DOMCHGDYN domchgdyn; /**< bound and hole changes with dynamic arrays */ 156 }; 157 158 /** domain of a variable */ 159 struct SCIP_Dom 160 { 161 SCIP_Real lb; /**< lower bounds of variables */ 162 SCIP_Real ub; /**< upper bounds of variables */ 163 SCIP_HOLELIST* holelist; /**< list of holes */ 164 }; 165 166 /** original variable information */ 167 struct SCIP_Original 168 { 169 SCIP_DOM origdom; /**< domain of variable in original problem */ 170 SCIP_VAR* transvar; /**< pointer to representing transformed variable */ 171 }; 172 173 /** aggregation information: x = a*y + c */ 174 struct SCIP_Aggregate 175 { 176 SCIP_Real scalar; /**< multiplier a in aggregation */ 177 SCIP_Real constant; /**< constant shift c in aggregation */ 178 SCIP_VAR* var; /**< variable y in aggregation */ 179 }; 180 181 /** multiple aggregation information: x = a_1*y_1 + ... + a_k*y_k + c */ 182 struct SCIP_Multaggr 183 { 184 SCIP_Real constant; /**< constant shift c in multiple aggregation */ 185 SCIP_Real* scalars; /**< multipliers a in multiple aggregation */ 186 SCIP_VAR** vars; /**< variables y in multiple aggregation */ 187 int nvars; /**< number of variables in aggregation */ 188 int varssize; /**< size of vars and scalars arrays */ 189 }; 190 191 /** negation information: x' = c - x */ 192 struct SCIP_Negate 193 { 194 SCIP_Real constant; /**< constant shift c in negation */ 195 }; 196 197 /** variable of the problem */ 198 struct SCIP_Var 199 { 200 SCIP_Real obj; /**< objective function value of variable (might be changed temporarily in probing mode)*/ 201 SCIP_Real unchangedobj; /**< unchanged objective function value of variable (ignoring temporary changes in probing mode) */ 202 SCIP_Real branchfactor; /**< factor to weigh variable's branching score with */ 203 SCIP_Real rootsol; /**< last primal solution of variable in root node, or zero */ 204 SCIP_Real bestrootsol; /**< best primal solution of variable in root node, or zero, w.r.t. root LP value and root reduced cost */ 205 SCIP_Real bestrootredcost; /**< best reduced costs of variable in root node, or zero, w.r.t. root LP value and root solution value */ 206 SCIP_Real bestrootlpobjval; /**< best root LP objective value, or SCIP_INVALID, w.r.t. root solution value and root reduced cost */ 207 SCIP_Real relaxsol; /**< primal solution of variable in current relaxation solution, or SCIP_INVALID */ 208 SCIP_Real nlpsol; /**< primal solution of variable in current NLP solution, or SCIP_INVALID */ 209 SCIP_Real primsolavg; /**< weighted average of all values of variable in primal feasible solutions */ 210 SCIP_Real conflictlb; /**< maximal lower bound of variable in the current conflict */ 211 SCIP_Real conflictub; /**< minimal upper bound of variable in the current conflict */ 212 SCIP_Real conflictrelaxedlb; /**< minimal relaxed lower bound of variable in the current conflict (conflictrelqxlb <= conflictlb) */ 213 SCIP_Real conflictrelaxedub; /**< minimal release upper bound of variable in the current conflict (conflictrelqxlb <= conflictlb) */ 214 SCIP_Real lazylb; /**< global lower bound that is ensured by constraints and has not to be added to the LP */ 215 SCIP_Real lazyub; /**< global upper bound that is ensured by constraints and has not to be added to the LP */ 216 SCIP_DOM glbdom; /**< domain of variable in global problem */ 217 SCIP_DOM locdom; /**< domain of variable in current subproblem */ 218 union 219 { 220 SCIP_ORIGINAL original; /**< original variable information */ 221 SCIP_COL* col; /**< LP column (for column variables) */ 222 SCIP_AGGREGATE aggregate; /**< aggregation information (for aggregated variables) */ 223 SCIP_MULTAGGR multaggr; /**< multiple aggregation information (for multiple aggregated variables) */ 224 SCIP_NEGATE negate; /**< negation information (for negated variables) */ 225 } data; 226 char* name; /**< name of the variable */ 227 SCIP_DECL_VARCOPY ((*varcopy)); /**< copies variable data if wanted to subscip, or NULL */ 228 SCIP_DECL_VARDELORIG ((*vardelorig)); /**< frees user data of original variable */ 229 SCIP_DECL_VARTRANS ((*vartrans)); /**< creates transformed user data by transforming original user data */ 230 SCIP_DECL_VARDELTRANS ((*vardeltrans)); /**< frees user data of transformed variable */ 231 SCIP_VARDATA* vardata; /**< user data for this specific variable */ 232 SCIP_VAR** parentvars; /**< parent variables in the aggregation tree */ 233 SCIP_VAR* negatedvar; /**< pointer to the variables negation: x' = lb + ub - x, or NULL if not created */ 234 SCIP_VBOUNDS* vlbs; /**< variable lower bounds x >= b*y + d */ 235 SCIP_VBOUNDS* vubs; /**< variable upper bounds x <= b*y + d */ 236 SCIP_IMPLICS* implics; /**< implications y >=/<= b following from x <= 0 and x >= 1 (x binary), or NULL if x is not binary */ 237 SCIP_CLIQUELIST* cliquelist; /**< list of cliques the variable and its negation is member of */ 238 SCIP_EVENTFILTER* eventfilter; /**< event filter for events concerning this variable; not for ORIGINAL vars */ 239 SCIP_BDCHGINFO* lbchginfos; /**< bound change informations for lower bound changes from root to current node */ 240 SCIP_BDCHGINFO* ubchginfos; /**< bound change informations for upper bound changes from root to current node */ 241 SCIP_HISTORY* history; /**< branching and inference history information */ 242 SCIP_HISTORY* historycrun; /**< branching and inference history information for current run */ 243 SCIP_VALUEHISTORY* valuehistory; /**< branching and inference history information which are value based, or NULL if not used */ 244 SCIP_Longint closestvblpcount; /**< LP count for which the closestvlbidx/closestvubidx entries are valid */ 245 int index; /**< consecutively numbered variable identifier */ 246 int probindex; /**< array position in problems vars array, or -1 if not assigned to a problem */ 247 int pseudocandindex; /**< array position in pseudo branching candidates array, or -1 */ 248 int eventqueueindexobj; /**< array position in event queue of objective change event, or -1 */ 249 int eventqueueindexlb; /**< array position in event queue of lower bound change event, or -1 */ 250 int eventqueueindexub; /**< array position in event queue of upper bound change event, or -1 */ 251 int parentvarssize; /**< available slots in parentvars array */ 252 int nparentvars; /**< number of parent variables in aggregation tree (used slots of parentvars) */ 253 int nuses; /**< number of times, this variable is referenced */ 254 int nlocksdown[NLOCKTYPES]; /**< array of variable locks for rounding down; if zero, rounding down is always feasible */ 255 int nlocksup[NLOCKTYPES]; /**< array of variable locks for rounding up; if zero, rounding up is always feasible */ 256 int branchpriority; /**< priority of the variable for branching */ 257 int lbchginfossize; /**< available slots in lbchginfos array */ 258 int nlbchginfos; /**< number of lower bound changes from root node to current node */ 259 int ubchginfossize; /**< available slots in ubchginfos array */ 260 int nubchginfos; /**< number of upper bound changes from root node to current node */ 261 int conflictlbcount; /**< number of last conflict, the lower bound was member of */ 262 int conflictubcount; /**< number of last conflict, the upper bound was member of */ 263 int closestvlbidx; /**< index of closest VLB variable in current LP solution, or -1 */ 264 int closestvubidx; /**< index of closest VUB variable in current LP solution, or -1 */ 265 unsigned int initial:1; /**< TRUE iff var's column should be present in the initial root LP */ 266 unsigned int removable:1; /**< TRUE iff var's column is removable from the LP (due to aging or cleanup) */ 267 unsigned int deletable:1; /**< TRUE iff the variable is removable from the problem */ 268 unsigned int deleted:1; /**< TRUE iff variable was marked for deletion from the problem */ 269 unsigned int donotaggr:1; /**< TRUE iff variable is not allowed to be aggregated */ 270 unsigned int donotmultaggr:1; /**< TRUE iff variable is not allowed to be multi-aggregated */ 271 unsigned int vartype:2; /**< type of variable: binary, integer, implicit integer, continuous */ 272 unsigned int varstatus:3; /**< status of variable: original, loose, column, fixed, aggregated, multiaggregated, negated */ 273 unsigned int pseudocostflag:2; /**< temporary flag used in pseudo cost update */ 274 unsigned int branchdirection:2; /**< preferred branching direction of the variable (downwards, upwards, auto) */ 275 unsigned int eventqueueimpl:1; /**< is an IMPLADDED event on this variable currently in the event queue? */ 276 unsigned int delglobalstructs:1; /**< is variable marked to be removed from global structures (cliques etc.)? */ 277 unsigned int relaxationonly:1; /**< TRUE if variable has been introduced only to define a relaxation */ 278 #ifndef NDEBUG 279 SCIP* scip; /**< SCIP data structure */ 280 #endif 281 }; 282 283 #ifdef __cplusplus 284 } 285 #endif 286 287 #endif 288