1 /* 2 * Copyright 2007-2008, Christof Lutteroth, lutteroth@cs.auckland.ac.nz 3 * Copyright 2007-2008, James Kim, jkim202@ec.auckland.ac.nz 4 * Copyright 2010, Clemens Zeidler <haiku@clemens-zeidler.de> 5 * Distributed under the terms of the MIT License. 6 */ 7 8 9 #include "Variable.h" 10 11 #include <float.h> // for DBL_MAX 12 13 #include <File.h> 14 15 #include "Constraint.h" 16 #include "LinearSpec.h" 17 18 // Toggle debug output 19 //#define DEBUG_VARIABLE 20 21 #ifdef DEBUG_VARIABLE 22 # define STRACE(x) debug_printf x 23 #else 24 # define STRACE(x) ; 25 #endif 26 27 28 /** 29 * Gets index of the variable. 30 * 31 * @return the index of the variable 32 */ 33 int32 34 Variable::Index() const 35 { 36 return fLS->IndexOf(this); 37 } 38 39 40 int32 41 Variable::GlobalIndex() const 42 { 43 return fLS->GlobalIndexOf(this); 44 } 45 46 47 /** 48 * Gets the current linear specification. 49 * 50 * @return the current linear specification 51 */ 52 LinearSpec* 53 Variable::LS() const 54 { 55 return fLS; 56 } 57 58 59 /** 60 * Gets the value. 61 * 62 * @return the value 63 */ 64 double 65 Variable::Value() const 66 { 67 return fValue; 68 } 69 70 71 /** 72 * Sets the value. 73 * 74 * @param value the value 75 */ 76 void 77 Variable::SetValue(double value) 78 { 79 fValue = value; 80 } 81 82 83 /** 84 * Gets the minimum value of the variable. 85 * 86 * @return the minimum value of variable 87 */ 88 double 89 Variable::Min() const 90 { 91 return fMin; 92 } 93 94 95 /** 96 * Sets the minimum value of the variable. 97 * 98 * @param min minimum value 99 */ 100 void 101 Variable::SetMin(double min) 102 { 103 SetRange(min, fMax); 104 } 105 106 107 /** 108 * Gets the maximum value of the variable. 109 * 110 * @return the maximum value of variable 111 */ 112 double 113 Variable::Max() const 114 { 115 return fMax; 116 } 117 118 119 /** 120 * Sets the maximum value of the variable. 121 * 122 * @param max maximum value 123 */ 124 void 125 Variable::SetMax(double max) 126 { 127 SetRange(fMin, max); 128 } 129 130 131 /** 132 * Sets the minimum and maximum values of the variable. 133 * 134 * @param min minimum value 135 * @param max maximum value 136 */ 137 void 138 Variable::SetRange(double min, double max) 139 { 140 if (!fIsValid) 141 return; 142 143 fMin = min; 144 fMax = max; 145 fLS->UpdateRange(this); 146 } 147 148 149 const char* 150 Variable::Label() 151 { 152 return fLabel.String(); 153 } 154 155 156 void 157 Variable::SetLabel(const char* label) 158 { 159 fLabel = label; 160 } 161 162 163 /** 164 * Returns index of the variable as String. 165 * E.g. "Var2" 166 * 167 * @return the <code>String</code> index of the variable 168 */ 169 BString 170 Variable::ToString() const 171 { 172 BString string; 173 if (fLabel) { 174 string << fLabel; 175 if (!fIsValid) 176 string << "(invalid)"; 177 } else { 178 string << "Variable "; 179 if (!fIsValid) 180 string << "(invalid," << (int32)this << ")"; 181 else 182 string << Index(); 183 } 184 return string; 185 } 186 187 188 /** 189 * Adds a constraint that sets this variable equal to the given one. 190 * 191 * @param var variable that should have the same value 192 * @return the new equality constraint 193 */ 194 Constraint* 195 Variable::IsEqual(Variable* var) 196 { 197 if (!fIsValid) 198 return NULL; 199 200 return fLS->AddConstraint(1.0, this, -1.0, var, kEQ, 0.0); 201 } 202 203 204 /** 205 * Adds a constraint that sets this variable smaller or equal to the given one. 206 * 207 * @param var variable that should have a larger or equal value 208 * @return the new constraint 209 */ 210 Constraint* 211 Variable::IsSmallerOrEqual(Variable* var) 212 { 213 if (!fIsValid) 214 return NULL; 215 216 return fLS->AddConstraint(1.0, this, -1.0, var, kLE, 0.0); 217 } 218 219 220 /** 221 * Adds a constraint that sets this variable greater or equal to the given one. 222 * 223 * @param var variable that should have a smaller or equal value 224 * @return the new constraint 225 */ 226 Constraint* 227 Variable::IsGreaterOrEqual(Variable* var) 228 { 229 if (!fIsValid) 230 return NULL; 231 232 return fLS->AddConstraint(-1.0, var, 1.0, this, kGE, 0.0); 233 } 234 235 236 Constraint* 237 Variable::IsEqual(Variable* var, double penaltyNeg, double penaltyPos) 238 { 239 if (!fIsValid) 240 return NULL; 241 242 return fLS->AddConstraint(1.0, this, -1.0, var, kEQ, 0.0, 243 penaltyNeg, penaltyPos); 244 } 245 246 247 Constraint* 248 Variable::IsSmallerOrEqual(Variable* var, double penaltyNeg, double penaltyPos) 249 { 250 if (!fIsValid) 251 return NULL; 252 253 return fLS->AddConstraint(1.0, this, -1.0, var, kLE, 0.0, penaltyNeg, 254 penaltyPos); 255 } 256 257 258 Constraint* 259 Variable::IsGreaterOrEqual(Variable* var, double penaltyNeg, double penaltyPos) 260 { 261 if (!fIsValid) 262 return NULL; 263 264 return fLS->AddConstraint(-1.0, var, 1.0, this, kGE, 0.0, penaltyNeg, 265 penaltyPos); 266 } 267 268 269 bool 270 Variable::IsValid() 271 { 272 return fIsValid; 273 } 274 275 276 void 277 Variable::Invalidate() 278 { 279 STRACE(("Variable::Invalidate() on %s\n", BString(*this).String())); 280 281 if (!fIsValid) 282 return; 283 284 fIsValid = false; 285 fLS->RemoveVariable(this, false); 286 } 287 288 289 /** 290 * Constructor. 291 */ 292 Variable::Variable(LinearSpec* ls) 293 : 294 fLS(ls), 295 fValue(NAN), 296 fMin(-20000), 297 fMax(20000), 298 fLabel(NULL), 299 fIsValid(false), 300 fReferenceCount(0) 301 { 302 303 } 304 305 306 int32 307 Variable::AddReference() 308 { 309 fReferenceCount++; 310 return fReferenceCount; 311 } 312 313 314 int32 315 Variable::RemoveReference() 316 { 317 fReferenceCount--; 318 return fReferenceCount; 319 } 320 321 322 /** 323 * Destructor. 324 * Removes the variable from its specification. 325 */ 326 Variable::~Variable() 327 { 328 fLS->RemoveVariable(this, false); 329 } 330 331