xref: /haiku/src/libs/linprog/Variable.cpp (revision 5c6260dc232fcb2d4d5d1103c1623dba9663b753)
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