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