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> 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