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 lprowbase.h 26 * @brief (In)equality for LPs. 27 */ 28 #ifndef _LPROWBASE_H_ 29 #define _LPROWBASE_H_ 30 31 #include <assert.h> 32 33 #include "soplex/spxdefines.h" 34 #include "soplex/basevectors.h" 35 36 namespace soplex 37 { 38 /**@brief (In)equality for LPs. 39 * @ingroup Algo 40 * 41 * Class LPRowBase provides constraints for linear programs in the form \f[ l \le a^Tx \le r, \f] where \em a is a 42 * DSVector. \em l is referred to as %left hand side, \em r as %right hand side and \em a as \em row \em vector or the 43 * constraint vector. \em l and \em r may also take values \f$\pm\f$ #R(infinity). This static member is predefined, but 44 * may be overridden to meet the needs of the LP solver to be used. 45 * 46 * LPRowBases allow to specify regular inequalities of the form \f[ a^Tx \sim \alpha, \f] where \f$\sim\f$ can take any 47 * value of \f$\le, =, \ge\f$, by setting rhs and lhs to the same value or setting one of them to \f$\infty\f$. 48 * 49 * Since constraints in the regular form occur often, LPRowBases offers methods type() and value() for retreiving 50 * \f$\sim\f$ and \f$\alpha\f$ of an LPRowBase in this form, respectively. Also, a constructor for LPRowBases given in 51 * regular form is provided. 52 */ 53 template < class R > 54 class LPRowBase 55 { 56 template < class S > friend class LPRowBase; 57 58 private: 59 60 // ------------------------------------------------------------------------------------------------------------------ 61 /**@name Data */ 62 ///@{ 63 64 R left; ///< left-hand side of the constraint 65 R right; ///< right-hand side of the constraint 66 R object; ///< objective coefficient of corresponding slack variable s = vec times primal 67 DSVectorBase<R> vec; ///< the row vector 68 69 ///@} 70 71 public: 72 73 // ------------------------------------------------------------------------------------------------------------------ 74 /**@name Types */ 75 ///@{ 76 77 /// (In)Equality type of an LP row. 78 /** #LPRowBase%s may be of one of the following Types. This datatype may be used for constructing new #LPRowBase%s in the 79 * regular form. 80 */ 81 enum Type 82 { 83 LESS_EQUAL, ///< \f$a^Tx \le \alpha\f$. 84 EQUAL, ///< \f$a^Tx = \alpha\f$. 85 GREATER_EQUAL, ///< \f$a^Tx \ge \alpha\f$. 86 RANGE ///< \f$\lambda \le a^Tx \le \rho\f$. 87 }; 88 89 ///@} 90 91 // ------------------------------------------------------------------------------------------------------------------ 92 /**@name Construction / destruction */ 93 ///@{ 94 95 /// Constructs LPRowBase with a vector ready to hold \p defDim nonzeros. 96 explicit LPRowBase(int defDim = 0) 97 : left(0), right(R(infinity)), object(0), vec(defDim) 98 { 99 assert(isConsistent()); 100 } 101 102 /// Assignment operator. 103 LPRowBase<R>& operator=(const LPRowBase<R>& row) 104 { 105 if(this != &row) 106 { 107 left = row.left; 108 right = row.right; 109 object = row.object; 110 vec = row.vec; 111 } 112 113 assert(isConsistent()); 114 } 115 116 /// Copy constructor. 117 LPRowBase(const LPRowBase<R>& row) 118 : left(row.left), right(row.right), object(row.object), vec(row.vec) 119 { 120 assert(isConsistent()); 121 } 122 123 /// Copy constructor. 124 template < class S > 125 LPRowBase(const LPRowBase<S>& row) 126 : left(row.left), right(row.right), object(row.object), vec(row.vec) 127 { 128 assert(isConsistent()); 129 } 130 131 /// Constructs LPRowBase with the given left-hand side, right-hand side and rowVector. 132 LPRowBase(const R& p_lhs, const SVectorBase<R>& p_rowVector, const R& p_rhs, const R& p_obj = 0) 133 : left(p_lhs), right(p_rhs), object(p_obj), vec(p_rowVector) 134 { 135 assert(isConsistent()); 136 } 137 138 /// Constructs LPRowBase from passed \p rowVector, \p type and \p value. 139 LPRowBase(const SVectorBase<R>& p_rowVector, Type p_type, const R& p_value, const R& p_obj = 0) 140 : object(p_obj), vec(p_rowVector) 141 { 142 switch(p_type) 143 { 144 case LESS_EQUAL: 145 left = R(-infinity); 146 right = p_value; 147 break; 148 149 case EQUAL: 150 left = p_value; 151 right = p_value; 152 break; 153 154 case GREATER_EQUAL: 155 left = p_value; 156 right = R(infinity); 157 break; 158 159 default: 160 throw SPxInternalCodeException("XLPROW03 This should never happen."); 161 } 162 163 assert(isConsistent()); 164 } 165 166 /// Destructor. 167 ~LPRowBase() 168 {} 169 170 ///@} 171 172 // ------------------------------------------------------------------------------------------------------------------ 173 /**@name Access / modification */ 174 ///@{ 175 176 /// Gets type of row. 177 Type type() const 178 { 179 if(rhs() >= R(infinity)) 180 return GREATER_EQUAL; 181 182 if(lhs() <= R(-infinity)) 183 return LESS_EQUAL; 184 185 if(lhs() == rhs()) 186 return EQUAL; 187 188 return RANGE; 189 } 190 191 /// Sets type of (in)equality. 192 void setType(Type p_type) 193 { 194 switch(p_type) 195 { 196 case LESS_EQUAL: 197 left = R(-infinity); 198 break; 199 200 case EQUAL: 201 if(lhs() > R(-infinity)) 202 right = lhs(); 203 else 204 left = rhs(); 205 206 break; 207 208 case GREATER_EQUAL: 209 right = R(infinity); 210 break; 211 212 case RANGE: 213 SPX_MSG_ERROR(std::cerr << "ELPROW01 RANGE not supported in LPRow::setType()" 214 << std::endl;) 215 throw SPxInternalCodeException("XLPROW01 This should never happen."); 216 217 default: 218 throw SPxInternalCodeException("XLPROW02 This should never happen."); 219 } 220 } 221 222 /// Right hand side value of (in)equality. 223 /** This method returns \f$\alpha\f$ for a LPRowBase in regular form. However, value() may only be called for 224 * LPRowBase%s with type() != \c RANGE. 225 */ 226 R value() const 227 { 228 assert(type() != RANGE); 229 230 return (rhs() < R(infinity)) ? rhs() : lhs(); 231 } 232 233 /// Left-hand side value. 234 R lhs() const 235 { 236 return left; 237 } 238 239 /// Sets left-hand side value. 240 void setLhs(const R& p_left) 241 { 242 left = p_left; 243 } 244 245 /// Right-hand side value. 246 R rhs() const 247 { 248 return right; 249 } 250 251 /// Sets right-hand side value. 252 void setRhs(const R& p_right) 253 { 254 right = p_right; 255 } 256 257 /// Objective coefficient value. 258 R obj() const 259 { 260 return object; 261 } 262 263 /// Sets objective coefficient value. 264 void setObj(const R& p_obj) 265 { 266 object = p_obj; 267 } 268 269 /// Constraint row vector. 270 const SVectorBase<R>& rowVector() const 271 { 272 return vec; 273 } 274 275 /// access constraint row vector. 276 void setRowVector(const DSVectorBase<R>& p_vec) 277 { 278 vec = p_vec; 279 } 280 281 ///@} 282 283 // ------------------------------------------------------------------------------------------------------------------ 284 /**@name Consistency check */ 285 ///@{ 286 287 /// Checks consistency. 288 bool isConsistent() const 289 { 290 #ifdef ENABLE_CONSISTENCY_CHECKS 291 return vec.isConsistent(); 292 #else 293 return true; 294 #endif 295 } 296 297 ///@} 298 }; 299 300 } // namespace soplex 301 #endif // _LPROWBASE_H_ 302