Changeset 482:ed54c0d13df0 in lemon for lemon/lp_soplex.cc
- Timestamp:
- 12/02/08 22:48:28 (15 years ago)
- Branch:
- default
- Children:
- 483:76ec7bd57026, 547:17cabb114d52
- Phase:
- public
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
lemon/lp_soplex.cc
r481 r482 17 17 */ 18 18 19 #include <iostream>20 #include <lemon/lp_soplex.h>19 #include <iostream> 20 #include <lemon/lp_soplex.h> 21 21 22 22 #include <soplex/soplex.h> … … 27 27 namespace lemon { 28 28 29 LpSoplex::LpSoplex() : LpSolverBase() { 30 rows.setIdHandler(relocateIdHandler); 31 cols.setIdHandler(relocateIdHandler); 29 LpSoplex::LpSoplex() { 32 30 soplex = new soplex::SoPlex; 33 solved = false;34 31 } 35 32 … … 38 35 } 39 36 40 LpSoplex::LpSoplex(const LpSoplex& lp) : LpSolverBase(){37 LpSoplex::LpSoplex(const LpSoplex& lp) { 41 38 rows = lp.rows; 42 rows.setIdHandler(relocateIdHandler);43 44 39 cols = lp.cols; 45 cols.setIdHandler(relocateIdHandler);46 40 47 41 soplex = new soplex::SoPlex; 48 42 (*static_cast<soplex::SPxLP*>(soplex)) = *(lp.soplex); 49 43 50 colNames = lp.colNames; 51 invColNames = lp.invColNames; 52 53 primal_value = lp.primal_value; 54 dual_value = lp.dual_value; 55 56 } 57 58 LpSolverBase* LpSoplex::_newLp() { 44 _col_names = lp._col_names; 45 _col_names_ref = lp._col_names_ref; 46 47 _row_names = lp._row_names; 48 _row_names_ref = lp._row_names_ref; 49 50 } 51 52 void LpSoplex::_clear_temporals() { 53 _primal_values.clear(); 54 _dual_values.clear(); 55 } 56 57 LpSoplex* LpSoplex::_newSolver() const { 59 58 LpSoplex* newlp = new LpSoplex(); 60 59 return newlp; 61 60 } 62 61 63 LpSo lverBase* LpSoplex::_copyLp(){62 LpSoplex* LpSoplex::_cloneSolver() const { 64 63 LpSoplex* newlp = new LpSoplex(*this); 65 64 return newlp; 66 65 } 66 67 const char* LpSoplex::_solverName() const { return "LpSoplex"; } 67 68 68 69 int LpSoplex::_addCol() { … … 72 73 soplex->addCol(c); 73 74 74 colNames.push_back(std::string()); 75 primal_value.push_back(0.0); 76 solved = false; 75 _col_names.push_back(std::string()); 77 76 78 77 return soplex->nCols() - 1; … … 85 84 soplex->addRow(r); 86 85 87 dual_value.push_back(0.0); 88 solved = false; 86 _row_names.push_back(std::string()); 89 87 90 88 return soplex->nRows() - 1; … … 94 92 void LpSoplex::_eraseCol(int i) { 95 93 soplex->removeCol(i); 96 invColNames.erase(colNames[i]); 97 colNames[i] = colNames.back(); 98 invColNames[colNames.back()] = i; 99 colNames.pop_back(); 100 primal_value[i] = primal_value.back(); 101 primal_value.pop_back(); 102 solved = false; 94 _col_names_ref.erase(_col_names[i]); 95 _col_names[i] = _col_names.back(); 96 _col_names_ref[_col_names.back()] = i; 97 _col_names.pop_back(); 103 98 } 104 99 105 100 void LpSoplex::_eraseRow(int i) { 106 101 soplex->removeRow(i); 107 dual_value[i] = dual_value.back(); 108 dual_value.pop_back(); 109 solved = false; 102 _row_names_ref.erase(_row_names[i]); 103 _row_names[i] = _row_names.back(); 104 _row_names_ref[_row_names.back()] = i; 105 _row_names.pop_back(); 106 } 107 108 void LpSoplex::_eraseColId(int i) { 109 cols.eraseIndex(i); 110 cols.relocateIndex(i, cols.maxIndex()); 111 } 112 void LpSoplex::_eraseRowId(int i) { 113 rows.eraseIndex(i); 114 rows.relocateIndex(i, rows.maxIndex()); 110 115 } 111 116 112 117 void LpSoplex::_getColName(int c, std::string &name) const { 113 name = colNames[c];118 name = _col_names[c]; 114 119 } 115 120 116 121 void LpSoplex::_setColName(int c, const std::string &name) { 117 invColNames.erase(colNames[c]);118 colNames[c] = name;122 _col_names_ref.erase(_col_names[c]); 123 _col_names[c] = name; 119 124 if (!name.empty()) { 120 invColNames.insert(std::make_pair(name, c));125 _col_names_ref.insert(std::make_pair(name, c)); 121 126 } 122 127 } … … 124 129 int LpSoplex::_colByName(const std::string& name) const { 125 130 std::map<std::string, int>::const_iterator it = 126 invColNames.find(name);127 if (it != invColNames.end()) {131 _col_names_ref.find(name); 132 if (it != _col_names_ref.end()) { 128 133 return it->second; 129 134 } else { … … 132 137 } 133 138 134 135 void LpSoplex::_setRowCoeffs(int i, ConstRowIterator b, ConstRowIterator e) { 139 void LpSoplex::_getRowName(int r, std::string &name) const { 140 name = _row_names[r]; 141 } 142 143 void LpSoplex::_setRowName(int r, const std::string &name) { 144 _row_names_ref.erase(_row_names[r]); 145 _row_names[r] = name; 146 if (!name.empty()) { 147 _row_names_ref.insert(std::make_pair(name, r)); 148 } 149 } 150 151 int LpSoplex::_rowByName(const std::string& name) const { 152 std::map<std::string, int>::const_iterator it = 153 _row_names_ref.find(name); 154 if (it != _row_names_ref.end()) { 155 return it->second; 156 } else { 157 return -1; 158 } 159 } 160 161 162 void LpSoplex::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) { 136 163 for (int j = 0; j < soplex->nCols(); ++j) { 137 164 soplex->changeElement(i, j, 0.0); 138 165 } 139 for( ConstRowIterator it = b; it != e; ++it) {166 for(ExprIterator it = b; it != e; ++it) { 140 167 soplex->changeElement(i, it->first, it->second); 141 168 } 142 solved = false; 143 } 144 145 void LpSoplex::_getRowCoeffs(int i, RowIterator b) const { 169 } 170 171 void LpSoplex::_getRowCoeffs(int i, InsertIterator b) const { 146 172 const soplex::SVector& vec = soplex->rowVector(i); 147 173 for (int k = 0; k < vec.size(); ++k) { … … 151 177 } 152 178 153 void LpSoplex::_setColCoeffs(int j, ConstColIterator b, ConstColIterator e) {179 void LpSoplex::_setColCoeffs(int j, ExprIterator b, ExprIterator e) { 154 180 for (int i = 0; i < soplex->nRows(); ++i) { 155 181 soplex->changeElement(i, j, 0.0); 156 182 } 157 for( ConstColIterator it = b; it != e; ++it) {183 for(ExprIterator it = b; it != e; ++it) { 158 184 soplex->changeElement(it->first, j, it->second); 159 185 } 160 solved = false; 161 } 162 163 void LpSoplex::_getColCoeffs(int i, ColIterator b) const { 186 } 187 188 void LpSoplex::_getColCoeffs(int i, InsertIterator b) const { 164 189 const soplex::SVector& vec = soplex->colVector(i); 165 190 for (int k = 0; k < vec.size(); ++k) { … … 171 196 void LpSoplex::_setCoeff(int i, int j, Value value) { 172 197 soplex->changeElement(i, j, value); 173 solved = false;174 198 } 175 199 … … 179 203 180 204 void LpSoplex::_setColLowerBound(int i, Value value) { 205 LEMON_ASSERT(value != INF, "Invalid bound"); 181 206 soplex->changeLower(i, value != -INF ? value : -soplex::infinity); 182 solved = false;183 207 } 184 208 … … 189 213 190 214 void LpSoplex::_setColUpperBound(int i, Value value) { 215 LEMON_ASSERT(value != -INF, "Invalid bound"); 191 216 soplex->changeUpper(i, value != INF ? value : soplex::infinity); 192 solved = false;193 217 } 194 218 … … 198 222 } 199 223 200 void LpSoplex::_setRowBounds(int i, Value lb, Value ub) { 201 soplex->changeRange(i, lb != -INF ? lb : -soplex::infinity, 202 ub != INF ? ub : soplex::infinity); 203 solved = false; 204 } 205 void LpSoplex::_getRowBounds(int i, Value &lower, Value &upper) const { 206 lower = soplex->lhs(i); 207 if (lower == -soplex::infinity) lower = -INF; 208 upper = soplex->rhs(i); 209 if (upper == -soplex::infinity) upper = INF; 224 void LpSoplex::_setRowLowerBound(int i, Value lb) { 225 LEMON_ASSERT(lb != INF, "Invalid bound"); 226 soplex->changeRange(i, lb != -INF ? lb : -soplex::infinity, soplex->rhs(i)); 227 } 228 229 LpSoplex::Value LpSoplex::_getRowLowerBound(int i) const { 230 double res = soplex->lhs(i); 231 return res == -soplex::infinity ? -INF : res; 232 } 233 234 void LpSoplex::_setRowUpperBound(int i, Value ub) { 235 LEMON_ASSERT(ub != -INF, "Invalid bound"); 236 soplex->changeRange(i, soplex->lhs(i), ub != INF ? ub : soplex::infinity); 237 } 238 239 LpSoplex::Value LpSoplex::_getRowUpperBound(int i) const { 240 double res = soplex->rhs(i); 241 return res == soplex::infinity ? INF : res; 242 } 243 244 void LpSoplex::_setObjCoeffs(ExprIterator b, ExprIterator e) { 245 for (int j = 0; j < soplex->nCols(); ++j) { 246 soplex->changeObj(j, 0.0); 247 } 248 for (ExprIterator it = b; it != e; ++it) { 249 soplex->changeObj(it->first, it->second); 250 } 251 } 252 253 void LpSoplex::_getObjCoeffs(InsertIterator b) const { 254 for (int j = 0; j < soplex->nCols(); ++j) { 255 Value coef = soplex->obj(j); 256 if (coef != 0.0) { 257 *b = std::make_pair(j, coef); 258 ++b; 259 } 260 } 210 261 } 211 262 212 263 void LpSoplex::_setObjCoeff(int i, Value obj_coef) { 213 264 soplex->changeObj(i, obj_coef); 214 solved = false;215 265 } 216 266 … … 219 269 } 220 270 221 void LpSoplex::_clearObj() {222 for (int i = 0; i < soplex->nCols(); ++i) {223 soplex->changeObj(i, 0.0);224 }225 solved = false;226 }227 228 271 LpSoplex::SolveExitStatus LpSoplex::_solve() { 272 273 _clear_temporals(); 274 229 275 soplex::SPxSolver::Status status = soplex->solve(); 230 231 soplex::Vector pv(primal_value.size(), &primal_value[0]);232 soplex->getPrimal(pv);233 234 soplex::Vector dv(dual_value.size(), &dual_value[0]);235 soplex->getDual(dv);236 276 237 277 switch (status) { … … 239 279 case soplex::SPxSolver::INFEASIBLE: 240 280 case soplex::SPxSolver::UNBOUNDED: 241 solved = true;242 281 return SOLVED; 243 282 default: … … 247 286 248 287 LpSoplex::Value LpSoplex::_getPrimal(int i) const { 249 return primal_value[i]; 288 if (_primal_values.empty()) { 289 _primal_values.resize(soplex->nCols()); 290 soplex::Vector pv(_primal_values.size(), &_primal_values.front()); 291 soplex->getPrimal(pv); 292 } 293 return _primal_values[i]; 250 294 } 251 295 252 296 LpSoplex::Value LpSoplex::_getDual(int i) const { 253 return dual_value[i]; 297 if (_dual_values.empty()) { 298 _dual_values.resize(soplex->nRows()); 299 soplex::Vector dv(_dual_values.size(), &_dual_values.front()); 300 soplex->getDual(dv); 301 } 302 return _dual_values[i]; 254 303 } 255 304 … … 258 307 } 259 308 260 bool LpSoplex::_isBasicCol(int i) const { 261 return soplex->getBasisColStatus(i) == soplex::SPxSolver::BASIC; 262 } 263 264 LpSoplex::SolutionStatus LpSoplex::_getPrimalStatus() const { 265 if (!solved) return UNDEFINED; 309 LpSoplex::VarStatus LpSoplex::_getColStatus(int i) const { 310 switch (soplex->getBasisColStatus(i)) { 311 case soplex::SPxSolver::BASIC: 312 return BASIC; 313 case soplex::SPxSolver::ON_UPPER: 314 return UPPER; 315 case soplex::SPxSolver::ON_LOWER: 316 return LOWER; 317 case soplex::SPxSolver::FIXED: 318 return FIXED; 319 case soplex::SPxSolver::ZERO: 320 return FREE; 321 default: 322 LEMON_ASSERT(false, "Wrong column status"); 323 return VarStatus(); 324 } 325 } 326 327 LpSoplex::VarStatus LpSoplex::_getRowStatus(int i) const { 328 switch (soplex->getBasisRowStatus(i)) { 329 case soplex::SPxSolver::BASIC: 330 return BASIC; 331 case soplex::SPxSolver::ON_UPPER: 332 return UPPER; 333 case soplex::SPxSolver::ON_LOWER: 334 return LOWER; 335 case soplex::SPxSolver::FIXED: 336 return FIXED; 337 case soplex::SPxSolver::ZERO: 338 return FREE; 339 default: 340 LEMON_ASSERT(false, "Wrong row status"); 341 return VarStatus(); 342 } 343 } 344 345 LpSoplex::Value LpSoplex::_getPrimalRay(int i) const { 346 if (_primal_ray.empty()) { 347 _primal_ray.resize(soplex->nCols()); 348 soplex::Vector pv(_primal_ray.size(), &_primal_ray.front()); 349 soplex->getDualfarkas(pv); 350 } 351 return _primal_ray[i]; 352 } 353 354 LpSoplex::Value LpSoplex::_getDualRay(int i) const { 355 if (_dual_ray.empty()) { 356 _dual_ray.resize(soplex->nRows()); 357 soplex::Vector dv(_dual_ray.size(), &_dual_ray.front()); 358 soplex->getDualfarkas(dv); 359 } 360 return _dual_ray[i]; 361 } 362 363 LpSoplex::ProblemType LpSoplex::_getPrimalType() const { 266 364 switch (soplex->status()) { 267 365 case soplex::SPxSolver::OPTIMAL: 268 366 return OPTIMAL; 269 367 case soplex::SPxSolver::UNBOUNDED: 270 return INFINITE;368 return UNBOUNDED; 271 369 case soplex::SPxSolver::INFEASIBLE: 272 370 return INFEASIBLE; … … 276 374 } 277 375 278 LpSoplex::SolutionStatus LpSoplex::_getDualStatus() const { 279 if (!solved) return UNDEFINED; 376 LpSoplex::ProblemType LpSoplex::_getDualType() const { 280 377 switch (soplex->status()) { 281 378 case soplex::SPxSolver::OPTIMAL: 282 379 return OPTIMAL; 283 380 case soplex::SPxSolver::UNBOUNDED: 381 return UNBOUNDED; 382 case soplex::SPxSolver::INFEASIBLE: 284 383 return INFEASIBLE; 285 384 default: … … 288 387 } 289 388 290 LpSoplex::ProblemTypes LpSoplex::_getProblemType() const { 291 if (!solved) return UNKNOWN; 292 switch (soplex->status()) { 293 case soplex::SPxSolver::OPTIMAL: 294 return PRIMAL_DUAL_FEASIBLE; 295 case soplex::SPxSolver::UNBOUNDED: 296 return PRIMAL_FEASIBLE_DUAL_INFEASIBLE; 297 default: 298 return UNKNOWN; 299 } 300 } 301 302 void LpSoplex::_setMax() { 303 soplex->changeSense(soplex::SPxSolver::MAXIMIZE); 304 solved = false; 305 } 306 void LpSoplex::_setMin() { 307 soplex->changeSense(soplex::SPxSolver::MINIMIZE); 308 solved = false; 309 } 310 bool LpSoplex::_isMax() const { 311 return soplex->spxSense() == soplex::SPxSolver::MAXIMIZE; 312 } 313 389 void LpSoplex::_setSense(Sense sense) { 390 switch (sense) { 391 case MIN: 392 soplex->changeSense(soplex::SPxSolver::MINIMIZE); 393 break; 394 case MAX: 395 soplex->changeSense(soplex::SPxSolver::MAXIMIZE); 396 } 397 } 398 399 LpSoplex::Sense LpSoplex::_getSense() const { 400 switch (soplex->spxSense()) { 401 case soplex::SPxSolver::MAXIMIZE: 402 return MAX; 403 case soplex::SPxSolver::MINIMIZE: 404 return MIN; 405 default: 406 LEMON_ASSERT(false, "Wrong sense."); 407 return LpSoplex::Sense(); 408 } 409 } 410 411 void LpSoplex::_clear() { 412 soplex->clear(); 413 _col_names.clear(); 414 _col_names_ref.clear(); 415 _row_names.clear(); 416 _row_names_ref.clear(); 417 cols.clear(); 418 rows.clear(); 419 _clear_temporals(); 420 } 314 421 315 422 } //namespace lemon
Note: See TracChangeset
for help on using the changeset viewer.