1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2 /* */
3 /* This file is part of the class library */
4 /* SoPlex --- the Sequential object-oriented simPlex. */
5 /* */
6 /* Copyright (c) 1996-2023 Zuse Institute Berlin (ZIB) */
7 /* */
8 /* Licensed under the Apache License, Version 2.0 (the "License"); */
9 /* you may not use this file except in compliance with the License. */
10 /* You may obtain a copy of the License at */
11 /* */
12 /* http://www.apache.org/licenses/LICENSE-2.0 */
13 /* */
14 /* Unless required by applicable law or agreed to in writing, software */
15 /* distributed under the License is distributed on an "AS IS" BASIS, */
16 /* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
17 /* See the License for the specific language governing permissions and */
18 /* limitations under the License. */
19 /* */
20 /* You should have received a copy of the Apache-2.0 license */
21 /* along with SoPlex; see the file LICENSE. If not email to soplex@zib.de. */
22 /* */
23 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
24
25 /**@file solbase.h
26 * @brief Class for storing a primal-dual solution with basis information
27 */
28 #ifndef _SOLBASE_H_
29 #define _SOLBASE_H_
30
31 /* undefine SOPLEX_DEBUG flag from including files; if SOPLEX_DEBUG should be defined in this file, do so below */
32 #ifdef SOPLEX_DEBUG
33 #define SOPLEX_DEBUG_SOLBASE
34 #undef SOPLEX_DEBUG
35 #endif
36
37 #include <assert.h>
38 #include <string.h>
39 #include <math.h>
40 #include <iostream>
41
42 #include "soplex/basevectors.h"
43 #include "soplex/spxsolver.h" // needed for basis information
44
45 namespace soplex
46 {
47 /**@class SolBase
48 * @brief Class for storing a primal-dual solution with basis information
49 * @ingroup Algo
50 */
51 template <class R>
(1) Event rule_of_three_violation: |
Class "soplex::SolBase<double>" has a user definition for at least one special function (copy constructor, copy assignment, destructor) but not all. If one of these functions requires a user definition then the others likely do as well. |
(2) Event remediation: |
Add user-definition for a copy constructor. |
(4) Event remediation: |
Add user-definition for a destructor. |
Also see events: |
[copy_assign] |
52 class SolBase
53 {
54 template <class T> friend class SoPlexBase;
55 // Why do we need the following? This is at least used in the operator=
56 // When Rational solution needs to be copied into Real, the private member
57 // _objVal is accessed.
58 template <class S> friend class SolBase;
59
60 public:
61 /// is the stored solution primal feasible?
62 bool isPrimalFeasible() const
63 {
64 return _isPrimalFeasible;
65 }
66
67 /// gets the primal solution vector; returns true on success
68 bool getPrimalSol(VectorBase<R>& vector) const
69 {
70 vector = _primal;
71
72 return _isPrimalFeasible;
73 }
74
75 /// gets the vector of slack values; returns true on success
76 bool getSlacks(VectorBase<R>& vector) const
77 {
78 vector = _slacks;
79
80 return _isPrimalFeasible;
81 }
82
83 /// is a primal unbounded ray available?
84 bool hasPrimalRay() const
85 {
86 return _hasPrimalRay;
87 }
88
89 /// gets the primal unbounded ray if available; returns true on success
90 bool getPrimalRaySol(VectorBase<R>& vector) const
91 {
92 if(_hasPrimalRay)
93 vector = _primalRay;
94
95 return _hasPrimalRay;
96 }
97
98 /// is a dual solution available?
99 bool isDualFeasible() const
100 {
101 return _isDualFeasible;
102 }
103
104 /// gets the dual solution vector; returns true on success
105 bool getDualSol(VectorBase<R>& vector) const
106 {
107 vector = _dual;
108
109 return _isDualFeasible;
110 }
111
112 /// gets the vector of reduced cost values if available; returns true on success
113 bool getRedCostSol(VectorBase<R>& vector) const
114 {
115 vector = _redCost;
116
117 return _isDualFeasible;
118 }
119
120 /// is a dual farkas ray available?
121 bool hasDualFarkas() const
122 {
123 return _hasDualFarkas;
124 }
125
126 /// gets the Farkas proof if available; returns true on success
127 bool getDualFarkasSol(VectorBase<R>& vector) const
128 {
129 if(_hasDualFarkas)
130 vector = _dualFarkas;
131
132 return _hasDualFarkas;
133 }
134
135 /// returns total size of primal solution
136 int totalSizePrimal(const int base = 2) const
137 {
138 int size = 0;
139
140 if(_isPrimalFeasible)
141 size += totalSizeRational(_primal.get_const_ptr(), _primal.dim(), base);
142
143 if(_hasPrimalRay)
144 size += totalSizeRational(_primalRay.get_const_ptr(), _primalRay.dim(), base);
145
146 return size;
147 }
148
149 /// returns total size of dual solution
150 int totalSizeDual(const int base = 2) const
151 {
152 int size = 0;
153
154 if(_isDualFeasible)
155 size += totalSizeRational(_dual.get_const_ptr(), _dual.dim(), base);
156
157 if(_hasDualFarkas)
158 size += totalSizeRational(_dualFarkas.get_const_ptr(), _dualFarkas.dim(), base);
159
160 return size;
161 }
162
163 /// returns size of least common multiple of denominators in primal solution
164 int dlcmSizePrimal(const int base = 2) const
165 {
166 int size = 0;
167
168 if(_isPrimalFeasible)
169 size += dlcmSizeRational(_primal.get_const_ptr(), _primal.dim(), base);
170
171 if(_hasPrimalRay)
172 size += dlcmSizeRational(_primalRay.get_const_ptr(), _primalRay.dim(), base);
173
174 return size;
175 }
176
177 /// returns size of least common multiple of denominators in dual solution
178 int dlcmSizeDual(const int base = 2) const
179 {
180 int size = 0;
181
182 if(_isDualFeasible)
183 size += dlcmSizeRational(_dual.get_const_ptr(), _dual.dim(), base);
184
185 if(_hasDualFarkas)
186 size += dlcmSizeRational(_dualFarkas.get_const_ptr(), _dualFarkas.dim(), base);
187
188 return size;
189 }
190
191 /// returns size of largest denominator in primal solution
192 int dmaxSizePrimal(const int base = 2) const
193 {
194 int size = 0;
195
196 if(_isPrimalFeasible)
197 size += dmaxSizeRational(_primal.get_const_ptr(), _primal.dim(), base);
198
199 if(_hasPrimalRay)
200 size += dmaxSizeRational(_primalRay.get_const_ptr(), _primalRay.dim(), base);
201
202 return size;
203 }
204
205 /// returns size of largest denominator in dual solution
206 int dmaxSizeDual(const int base = 2) const
207 {
208 int size = 0;
209
210 if(_isDualFeasible)
211 size += dmaxSizeRational(_dual.get_const_ptr(), _dual.dim(), base);
212
213 if(_hasDualFarkas)
214 size += dmaxSizeRational(_dualFarkas.get_const_ptr(), _dualFarkas.dim(), base);
215
216 return size;
217 }
218
219 /// invalidate solution
220 void invalidate()
221 {
222 _isPrimalFeasible = false;
223 _hasPrimalRay = false;
224 _isDualFeasible = false;
225 _hasDualFarkas = false;
226 }
227
228 private:
229 VectorBase<R> _primal;
230 VectorBase<R> _slacks;
231 VectorBase<R> _primalRay;
232 VectorBase<R> _dual;
233 VectorBase<R> _redCost;
234 VectorBase<R> _dualFarkas;
235
236 R _objVal;
237
238 unsigned int _isPrimalFeasible: 1;
239 unsigned int _hasPrimalRay: 1;
240 unsigned int _isDualFeasible: 1;
241 unsigned int _hasDualFarkas: 1;
242
243 /// default constructor only for friends
244 SolBase()
245 : _objVal(0)
246 {
247 invalidate();
248 }
249
250 /// assignment operator only for friends
251 SolBase<R>& operator=(const SolBase<R>& sol)
252 {
253 if(this != &sol)
254 {
255
256 _isPrimalFeasible = sol._isPrimalFeasible;
257 _primal = sol._primal;
258 _slacks = sol._slacks;
259 _objVal = sol._objVal;
260
261 _hasPrimalRay = sol._hasPrimalRay;
262
263 if(_hasPrimalRay)
264 _primalRay = sol._primalRay;
265
266 _isDualFeasible = sol._isDualFeasible;
267 _dual = sol._dual;
268 _redCost = sol._redCost;
269
270 _hasDualFarkas = sol._hasDualFarkas;
271
272 if(_hasDualFarkas)
273 _dualFarkas = sol._dualFarkas;
274 }
275
276 return *this;
277 }
278
279 /// assignment operator only for friends
280 template <class S>
281 SolBase<R>& operator=(const SolBase<S>& sol)
282 {
283 if((SolBase<S>*)this != &sol)
284 {
285
286 _isPrimalFeasible = sol._isPrimalFeasible;
287 _primal = sol._primal;
288 _slacks = sol._slacks;
289
290 _objVal = R(sol._objVal);
291
292 _hasPrimalRay = sol._hasPrimalRay;
293
294 if(_hasPrimalRay)
295 _primalRay = sol._primalRay;
296
297 _isDualFeasible = sol._isDualFeasible;
298 _dual = sol._dual;
299 _redCost = sol._redCost;
300
301 _hasDualFarkas = sol._hasDualFarkas;
302
303 if(_hasDualFarkas)
304 _dualFarkas = sol._dualFarkas;
305 }
306
307 return *this;
308 }
309
310 };
311 } // namespace soplex
312
313 /* reset the SOPLEX_DEBUG flag to its original value */
314 #undef SOPLEX_DEBUG
315 #ifdef SOPLEX_DEBUG_SOLBASE
316 #define SOPLEX_DEBUG
317 #undef SOPLEX_DEBUG_SOLBASE
318 #endif
319
320 #endif // _SOLBASE_H_
321