Scippy

SoPlex

Sequential object-oriented simPlex

solbase.h
Go to the documentation of this file.
1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the class library */
4 /* SoPlex --- the Sequential object-oriented simPlex. */
5 /* */
6 /* Copyright (C) 1996 Roland Wunderling */
7 /* 1996-2015 Konrad-Zuse-Zentrum */
8 /* fuer Informationstechnik Berlin */
9 /* */
10 /* SoPlex is distributed under the terms of the ZIB Academic Licence. */
11 /* */
12 /* You should have received a copy of the ZIB Academic License */
13 /* along with SoPlex; see the file COPYING. If not email to soplex@zib.de. */
14 /* */
15 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
16 
17 /**@file solbase.h
18  * @brief Class for storing a primal-dual solution with basis information
19  */
20 #ifndef _SOLBASE_H_
21 #define _SOLBASE_H_
22 
23 /* undefine SOPLEX_DEBUG flag from including files; if SOPLEX_DEBUG should be defined in this file, do so below */
24 #ifdef SOPLEX_DEBUG
25 #define SOPLEX_DEBUG_SOLBASE
26 #undef SOPLEX_DEBUG
27 #endif
28 
29 #include <assert.h>
30 #include <string.h>
31 #include <math.h>
32 #include <iostream>
33 
34 #include "basevectors.h"
35 #include "spxsolver.h" // needed for basis information
36 
37 namespace soplex
38 {
39 /**@class SolBase
40  * @brief Class for storing a primal-dual solution with basis information
41  * @ingroup Algo
42  */
43 template< class R >
44 class SolBase
45 {
46  friend class SoPlex;
47  template < class S > friend class SolBase;
48 
49 public:
50  /// is a primal feasible solution available?
51  bool hasPrimal() const
52  {
53  return _hasPrimal;
54  }
55 
56  /// gets the primal solution vector if available; returns true on success
57  bool getPrimal(VectorBase<R>& vector) const
58  {
59  if( _hasPrimal )
60  vector = _primal;
61 
62  return _hasPrimal;
63  }
64 
65  /// gets the vector of slack values if available; returns true on success
66  bool getSlacks(VectorBase<R>& vector) const
67  {
68  if( _hasPrimal )
69  vector = _slacks;
70 
71  return _hasPrimal;
72  }
73 
74  /// is a primal unbounded ray available?
75  bool hasPrimalRay() const
76  {
77  return _hasPrimalRay;
78  }
79 
80  /// gets the primal unbounded ray if available; returns true on success
81  bool getPrimalRay(VectorBase<R>& vector) const
82  {
83  if( _hasPrimalRay )
84  vector = _primalRay;
85 
86  return _hasPrimalRay;
87  }
88 
89  /// is a dual solution available?
90  bool hasDual() const
91  {
92  return _hasDual;
93  }
94 
95  /// gets the dual solution vector if available; returns true on success
96  bool getDual(VectorBase<R>& vector) const
97  {
98  if( _hasDual )
99  vector = _dual;
100 
101  return _hasDual;
102  }
103 
104  /// gets the vector of reduced cost values if available; returns true on success
105  bool getRedCost(VectorBase<R>& vector) const
106  {
107  if( _hasDual )
108  vector = _redCost;
109 
110  return _hasDual;
111  }
112 
113  /// is a dual farkas ray available?
114  bool hasDualFarkas() const
115  {
116  return _hasDualFarkas;
117  }
118 
119  /// gets the Farkas proof if available; returns true on success
120  bool getDualFarkas(VectorBase<R>& vector) const
121  {
122  if( _hasDualFarkas )
123  vector = _dualFarkas;
124 
125  return _hasDualFarkas;
126  }
127 
128  /// returns total size of primal solution
129  int totalSizePrimal(const int base = 2) const
130  {
131  int size = 0;
132 
133  if( _hasPrimal )
134  size += totalSizeRational(_primal.get_const_ptr(), _primal.dim(), base);
135 
136  if( _hasPrimalRay )
137  size += totalSizeRational(_primalRay.get_const_ptr(), _primalRay.dim(), base);
138 
139  return size;
140  }
141 
142  /// returns total size of dual solution
143  int totalSizeDual(const int base = 2) const
144  {
145  int size = 0;
146 
147  if( _hasDual )
148  size += totalSizeRational(_dual.get_const_ptr(), _dual.dim(), base);
149 
150  if( _hasDualFarkas )
151  size += totalSizeRational(_dualFarkas.get_const_ptr(), _dualFarkas.dim(), base);
152 
153  return size;
154  }
155 
156  /// returns size of least common multiple of denominators in primal solution
157  int dlcmSizePrimal(const int base = 2) const
158  {
159  int size = 0;
160 
161  if( _hasPrimal )
162  size += dlcmSizeRational(_primal.get_const_ptr(), _primal.dim(), base);
163 
164  if( _hasPrimalRay )
165  size += dlcmSizeRational(_primalRay.get_const_ptr(), _primalRay.dim(), base);
166 
167  return size;
168  }
169 
170  /// returns size of least common multiple of denominators in dual solution
171  int dlcmSizeDual(const int base = 2) const
172  {
173  int size = 0;
174 
175  if( _hasDual )
176  size += dlcmSizeRational(_dual.get_const_ptr(), _dual.dim(), base);
177 
178  if( _hasDualFarkas )
179  size += dlcmSizeRational(_dualFarkas.get_const_ptr(), _dualFarkas.dim(), base);
180 
181  return size;
182  }
183 
184  /// returns size of largest denominator in primal solution
185  int dmaxSizePrimal(const int base = 2) const
186  {
187  int size = 0;
188 
189  if( _hasPrimal )
190  size += dmaxSizeRational(_primal.get_const_ptr(), _primal.dim(), base);
191 
192  if( _hasPrimalRay )
193  size += dmaxSizeRational(_primalRay.get_const_ptr(), _primalRay.dim(), base);
194 
195  return size;
196  }
197 
198  /// returns size of largest denominator in dual solution
199  int dmaxSizeDual(const int base = 2) const
200  {
201  int size = 0;
202 
203  if( _hasDual )
204  size += dmaxSizeRational(_dual.get_const_ptr(), _dual.dim(), base);
205 
206  if( _hasDualFarkas )
207  size += dmaxSizeRational(_dualFarkas.get_const_ptr(), _dualFarkas.dim(), base);
208 
209  return size;
210  }
211 
212  /// invalidate solution
213  void invalidate()
214  {
215  _hasPrimal = false;
216  _hasPrimalRay = false;
217  _hasDual = false;
218  _hasDualFarkas = false;
219  }
220 
221 private:
228 
231 
232  unsigned int _hasPrimal:1;
233  unsigned int _hasPrimalRay:1;
234  unsigned int _hasDual:1;
235  unsigned int _hasDualFarkas:1;
236 
237  /// default constructor only for friends
239  : _primalObjVal(0)
240  , _dualObjVal(0)
241  {
242  invalidate();
243  }
244 
245  /// assignment operator only for friends
247  {
248  if( this != &sol )
249  {
250 
251  _hasPrimal = sol._hasPrimal;
252  if( _hasPrimal )
253  {
254  _primal = sol._primal;
255  _slacks = sol._slacks;
257  }
258 
260  if( _hasPrimalRay )
261  _primalRay = sol._primalRay;
262 
263  _hasDual = sol._hasDual;
264  if( _hasDual )
265  {
266  _dual = sol._dual;
267  _redCost = sol._redCost;
268  _dualObjVal = sol._dualObjVal;
269  }
270 
272  if( _hasDualFarkas )
273  _dualFarkas = sol._dualFarkas;
274  }
275 
276  return *this;
277  }
278 
279  /// assignment operator only for friends
280  template < class S >
282  {
283  if( (SolBase<S>*)this != &sol )
284  {
285 
286  _hasPrimal = sol._hasPrimal;
287  if( _hasPrimal )
288  {
289  _primal = sol._primal;
290  _slacks = sol._slacks;
291  _primalObjVal = R(sol._primalObjVal);
292  }
293 
295  if( _hasPrimalRay )
296  _primalRay = sol._primalRay;
297 
298  _hasDual = sol._hasDual;
299  if( _hasDual )
300  {
301  _dual = sol._dual;
302  _redCost = sol._redCost;
303  _dualObjVal = R(sol._dualObjVal);
304  }
305 
307  if( _hasDualFarkas )
308  _dualFarkas = sol._dualFarkas;
309  }
310 
311  return *this;
312  }
313 };
314 } // namespace soplex
315 
316 /* reset the SOPLEX_DEBUG flag to its original value */
317 #undef SOPLEX_DEBUG
318 #ifdef SOPLEX_DEBUG_SOLBASE
319 #define SOPLEX_DEBUG
320 #undef SOPLEX_DEBUG_SOLBASE
321 #endif
322 
323 #endif // _SOLBASE_H_