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 fMin = min; 141 fMax = max; 142 if (fIsValid) 143 fLS->UpdateRange(this); 144 } 145 146 147 const char* 148 Variable::Label() 149 { 150 return fLabel.String(); 151 } 152 153 154 void 155 Variable::SetLabel(const char* label) 156 { 157 fLabel = label; 158 } 159 160 161 /** 162 * Returns index of the variable as String. 163 * E.g. "Var2" 164 * 165 * @return the <code>String</code> index of the variable 166 */ 167 BString 168 Variable::ToString() const 169 { 170 BString string; 171 if (fLabel) { 172 string << fLabel; 173 if (!fIsValid) 174 string << "(invalid)"; 175 } else { 176 string << "Variable "; 177 if (!fIsValid) 178 string << "(invalid," << (int32)this << ")"; 179 else 180 string << Index(); 181 } 182 return string; 183 } 184 185 186 /** 187 * Adds a constraint that sets this variable equal to the given one. 188 * 189 * @param var variable that should have the same value 190 * @return the new equality constraint 191 */ 192 Constraint* 193 Variable::IsEqual(Variable* var) 194 { 195 if (!fIsValid) 196 return NULL; 197 198 return fLS->AddConstraint(1.0, this, -1.0, var, kEQ, 0.0); 199 } 200 201 202 /** 203 * Adds a constraint that sets this variable smaller or equal to the given one. 204 * 205 * @param var variable that should have a larger or equal value 206 * @return the new constraint 207 */ 208 Constraint* 209 Variable::IsSmallerOrEqual(Variable* var) 210 { 211 if (!fIsValid) 212 return NULL; 213 214 return fLS->AddConstraint(1.0, this, -1.0, var, kLE, 0.0); 215 } 216 217 218 /** 219 * Adds a constraint that sets this variable greater or equal to the given one. 220 * 221 * @param var variable that should have a smaller or equal value 222 * @return the new constraint 223 */ 224 Constraint* 225 Variable::IsGreaterOrEqual(Variable* var) 226 { 227 if (!fIsValid) 228 return NULL; 229 230 return fLS->AddConstraint(-1.0, var, 1.0, this, kGE, 0.0); 231 } 232 233 234 Constraint* 235 Variable::IsEqual(Variable* var, double penaltyNeg, double penaltyPos) 236 { 237 if (!fIsValid) 238 return NULL; 239 240 return fLS->AddConstraint(1.0, this, -1.0, var, kEQ, 0.0, 241 penaltyNeg, penaltyPos); 242 } 243 244 245 Constraint* 246 Variable::IsSmallerOrEqual(Variable* var, double penaltyNeg, double penaltyPos) 247 { 248 if (!fIsValid) 249 return NULL; 250 251 return fLS->AddConstraint(1.0, this, -1.0, var, kLE, 0.0, penaltyNeg, 252 penaltyPos); 253 } 254 255 256 Constraint* 257 Variable::IsGreaterOrEqual(Variable* var, double penaltyNeg, double penaltyPos) 258 { 259 if (!fIsValid) 260 return NULL; 261 262 return fLS->AddConstraint(-1.0, var, 1.0, this, kGE, 0.0, penaltyNeg, 263 penaltyPos); 264 } 265 266 267 bool 268 Variable::IsValid() 269 { 270 return fIsValid; 271 } 272 273 274 void 275 Variable::Invalidate() 276 { 277 STRACE(("Variable::Invalidate() on %s\n", BString(*this).String())); 278 279 if (!fIsValid) 280 return; 281 282 fIsValid = false; 283 fLS->RemoveVariable(this, false); 284 } 285 286 287 /** 288 * Constructor. 289 */ 290 Variable::Variable(LinearSpec* ls) 291 : 292 fLS(ls), 293 fValue(NAN), 294 fMin(-20000), 295 fMax(20000), 296 fLabel(NULL), 297 fIsValid(false), 298 fReferenceCount(0) 299 { 300 301 } 302 303 304 int32 305 Variable::AddReference() 306 { 307 fReferenceCount++; 308 return fReferenceCount; 309 } 310 311 312 int32 313 Variable::RemoveReference() 314 { 315 fReferenceCount--; 316 return fReferenceCount; 317 } 318 319 320 /** 321 * Destructor. 322 * Removes the variable from its specification. 323 */ 324 Variable::~Variable() 325 { 326 if (fLS) 327 fLS->RemoveVariable(this, false); 328 } 329 330