# HG changeset patch
# User Balazs Dezso <deba@inf.elte.hu>
# Date 1228725809 -3600
# Node ID 473d56c5aec86b15eea488c31d84a060426a40d1
# Parent 9347462c31067ff85c7691347bb28585967daf09
Documentation improvements, minor bug fix and renaming
- Lot of documentation improvements
- Rename shiftIndexes() to shiftIndices()
- Remove redundant column type settings
- Fix row status retrieval in LP
diff -r 9347462c3106 -r 473d56c5aec8 lemon/lp_base.h
|
a
|
b
|
|
| 38 | 38 | |
| 39 | 39 | ///Common base class for LP and MIP solvers |
| 40 | 40 | |
| 41 | | ///\todo Much more docs |
| | 41 | ///Usually this class is not used directly, please use one of the concrete |
| | 42 | ///implementations of the solver interface. |
| 42 | 43 | ///\ingroup lp_group |
| 43 | 44 | class LpBase { |
| 44 | 45 | |
| … |
… |
|
| 87 | 88 | ///Its value remains valid and correct even after the addition or erase of |
| 88 | 89 | ///other columns. |
| 89 | 90 | /// |
| 90 | | ///\todo Document what can one do with a Col (INVALID, comparing, |
| 91 | | ///it is similar to Node/Edge) |
| | 91 | ///\note This class is similar to other Item types in LEMON, like |
| | 92 | ///Node and Arc types in digraph. |
| 92 | 93 | class Col { |
| 93 | 94 | friend class LpBase; |
| 94 | 95 | protected: |
| … |
… |
|
| 96 | 97 | explicit Col(int id) : _id(id) {} |
| 97 | 98 | public: |
| 98 | 99 | typedef Value ExprValue; |
| 99 | | typedef True LpSolverCol; |
| | 100 | typedef True LpCol; |
| | 101 | /// Default constructor |
| | 102 | |
| | 103 | /// \warning The default constructor sets the Col to an |
| | 104 | /// undefined value. |
| 100 | 105 | Col() {} |
| | 106 | /// Invalid constructor \& conversion. |
| | 107 | |
| | 108 | /// This constructor initializes the Col to be invalid. |
| | 109 | /// \sa Invalid for more details. |
| 101 | 110 | Col(const Invalid&) : _id(-1) {} |
| | 111 | /// Equality operator |
| | 112 | |
| | 113 | /// Two \ref Col "Col"s are equal if and only if they point to |
| | 114 | /// the same LP column or both are invalid. |
| | 115 | bool operator==(Col c) const {return _id == c._id;} |
| | 116 | /// Inequality operator |
| | 117 | |
| | 118 | /// \sa operator==(Col c) |
| | 119 | /// |
| | 120 | bool operator!=(Col c) const {return _id != c._id;} |
| | 121 | /// Artificial ordering operator. |
| | 122 | |
| | 123 | /// To allow the use of this object in std::map or similar |
| | 124 | /// associative container we require this. |
| | 125 | /// |
| | 126 | /// \note This operator only have to define some strict ordering of |
| | 127 | /// the items; this order has nothing to do with the iteration |
| | 128 | /// ordering of the items. |
| 102 | 129 | bool operator<(Col c) const {return _id < c._id;} |
| 103 | | bool operator==(Col c) const {return _id == c._id;} |
| 104 | | bool operator!=(Col c) const {return _id != c._id;} |
| 105 | 130 | }; |
| 106 | 131 | |
| | 132 | ///Iterator for iterate over the columns of an LP problem |
| | 133 | |
| | 134 | /// Its usage is quite simple, for example you can count the number |
| | 135 | /// of columns in an LP \c lp: |
| | 136 | ///\code |
| | 137 | /// int count=0; |
| | 138 | /// for (LpBase::ColIt c(lp); c!=INVALID; ++c) ++count; |
| | 139 | ///\endcode |
| 107 | 140 | class ColIt : public Col { |
| 108 | 141 | const LpBase *_solver; |
| 109 | 142 | public: |
| | 143 | /// Default constructor |
| | 144 | |
| | 145 | /// \warning The default constructor sets the iterator |
| | 146 | /// to an undefined value. |
| 110 | 147 | ColIt() {} |
| | 148 | /// Sets the iterator to the first Col |
| | 149 | |
| | 150 | /// Sets the iterator to the first Col. |
| | 151 | /// |
| 111 | 152 | ColIt(const LpBase &solver) : _solver(&solver) |
| 112 | 153 | { |
| 113 | 154 | _solver->cols.firstItem(_id); |
| 114 | 155 | } |
| | 156 | /// Invalid constructor \& conversion |
| | 157 | |
| | 158 | /// Initialize the iterator to be invalid. |
| | 159 | /// \sa Invalid for more details. |
| 115 | 160 | ColIt(const Invalid&) : Col(INVALID) {} |
| | 161 | /// Next column |
| | 162 | |
| | 163 | /// Assign the iterator to the next column. |
| | 164 | /// |
| 116 | 165 | ColIt &operator++() |
| 117 | 166 | { |
| 118 | 167 | _solver->cols.nextItem(_id); |
| … |
… |
|
| 120 | 169 | } |
| 121 | 170 | }; |
| 122 | 171 | |
| | 172 | /// \brief Returns the ID of the column. |
| 123 | 173 | static int id(const Col& col) { return col._id; } |
| | 174 | /// \brief Returns the column with the given ID. |
| | 175 | /// |
| | 176 | /// \pre The argument should be a valid column ID in the LP problem. |
| 124 | 177 | static Col colFromId(int id) { return Col(id); } |
| 125 | 178 | |
| 126 | 179 | ///Refer to a row of the LP. |
| … |
… |
|
| 130 | 183 | ///Its value remains valid and correct even after the addition or erase of |
| 131 | 184 | ///other rows. |
| 132 | 185 | /// |
| 133 | | ///\todo Document what can one do with a Row (INVALID, comparing, |
| 134 | | ///it is similar to Node/Edge) |
| | 186 | ///\note This class is similar to other Item types in LEMON, like |
| | 187 | ///Node and Arc types in digraph. |
| 135 | 188 | class Row { |
| 136 | 189 | friend class LpBase; |
| 137 | 190 | protected: |
| … |
… |
|
| 139 | 192 | explicit Row(int id) : _id(id) {} |
| 140 | 193 | public: |
| 141 | 194 | typedef Value ExprValue; |
| 142 | | typedef True LpSolverRow; |
| | 195 | typedef True LpRow; |
| | 196 | /// Default constructor |
| | 197 | |
| | 198 | /// \warning The default constructor sets the Row to an |
| | 199 | /// undefined value. |
| 143 | 200 | Row() {} |
| | 201 | /// Invalid constructor \& conversion. |
| | 202 | |
| | 203 | /// This constructor initializes the Row to be invalid. |
| | 204 | /// \sa Invalid for more details. |
| 144 | 205 | Row(const Invalid&) : _id(-1) {} |
| | 206 | /// Equality operator |
| 145 | 207 | |
| 146 | | bool operator<(Row c) const {return _id < c._id;} |
| 147 | | bool operator==(Row c) const {return _id == c._id;} |
| 148 | | bool operator!=(Row c) const {return _id != c._id;} |
| | 208 | /// Two \ref Row "Row"s are equal if and only if they point to |
| | 209 | /// the same LP row or both are invalid. |
| | 210 | bool operator==(Row r) const {return _id == r._id;} |
| | 211 | /// Inequality operator |
| | 212 | |
| | 213 | /// \sa operator==(Row r) |
| | 214 | /// |
| | 215 | bool operator!=(Row r) const {return _id != r._id;} |
| | 216 | /// Artificial ordering operator. |
| | 217 | |
| | 218 | /// To allow the use of this object in std::map or similar |
| | 219 | /// associative container we require this. |
| | 220 | /// |
| | 221 | /// \note This operator only have to define some strict ordering of |
| | 222 | /// the items; this order has nothing to do with the iteration |
| | 223 | /// ordering of the items. |
| | 224 | bool operator<(Row r) const {return _id < r._id;} |
| 149 | 225 | }; |
| 150 | 226 | |
| | 227 | ///Iterator for iterate over the rows of an LP problem |
| | 228 | |
| | 229 | /// Its usage is quite simple, for example you can count the number |
| | 230 | /// of rows in an LP \c lp: |
| | 231 | ///\code |
| | 232 | /// int count=0; |
| | 233 | /// for (LpBase::RowIt c(lp); c!=INVALID; ++c) ++count; |
| | 234 | ///\endcode |
| 151 | 235 | class RowIt : public Row { |
| 152 | 236 | const LpBase *_solver; |
| 153 | 237 | public: |
| | 238 | /// Default constructor |
| | 239 | |
| | 240 | /// \warning The default constructor sets the iterator |
| | 241 | /// to an undefined value. |
| 154 | 242 | RowIt() {} |
| | 243 | /// Sets the iterator to the first Row |
| | 244 | |
| | 245 | /// Sets the iterator to the first Row. |
| | 246 | /// |
| 155 | 247 | RowIt(const LpBase &solver) : _solver(&solver) |
| 156 | 248 | { |
| 157 | 249 | _solver->rows.firstItem(_id); |
| 158 | 250 | } |
| | 251 | /// Invalid constructor \& conversion |
| | 252 | |
| | 253 | /// Initialize the iterator to be invalid. |
| | 254 | /// \sa Invalid for more details. |
| 159 | 255 | RowIt(const Invalid&) : Row(INVALID) {} |
| | 256 | /// Next row |
| | 257 | |
| | 258 | /// Assign the iterator to the next row. |
| | 259 | /// |
| 160 | 260 | RowIt &operator++() |
| 161 | 261 | { |
| 162 | 262 | _solver->rows.nextItem(_id); |
| … |
… |
|
| 164 | 264 | } |
| 165 | 265 | }; |
| 166 | 266 | |
| | 267 | /// \brief Returns the ID of the row. |
| 167 | 268 | static int id(const Row& row) { return row._id; } |
| | 269 | /// \brief Returns the row with the given ID. |
| | 270 | /// |
| | 271 | /// \pre The argument should be a valid row ID in the LP problem. |
| 168 | 272 | static Row rowFromId(int id) { return Row(id); } |
| 169 | 273 | |
| 170 | 274 | public: |
| … |
… |
|
| 196 | 300 | ///2*v-3.12*(v-w/2)+2 |
| 197 | 301 | ///v*2.1+(3*v+(v*12+w+6)*3)/2 |
| 198 | 302 | ///\endcode |
| 199 | | ///are valid \ref Expr "Expr"essions. |
| | 303 | ///are valid expressions. |
| 200 | 304 | ///The usual assignment operations are also defined. |
| 201 | 305 | ///\code |
| 202 | 306 | ///e=v+w; |
| … |
… |
|
| 204 | 308 | ///e*=3.4; |
| 205 | 309 | ///e/=5; |
| 206 | 310 | ///\endcode |
| 207 | | ///- The constant member can be set and read by \ref operator*() |
| | 311 | ///- The constant member can be set and read by dereference |
| | 312 | /// operator (unary *) |
| | 313 | /// |
| 208 | 314 | ///\code |
| 209 | 315 | ///*e=12; |
| 210 | 316 | ///double c=*e; |
| 211 | 317 | ///\endcode |
| 212 | 318 | /// |
| 213 | | ///\note \ref clear() not only sets all coefficients to 0 but also |
| 214 | | ///clears the constant components. |
| 215 | | /// |
| 216 | 319 | ///\sa Constr |
| 217 | | /// |
| 218 | 320 | class Expr { |
| 219 | 321 | friend class LpBase; |
| 220 | 322 | public: |
| | 323 | /// The key type of the expression |
| 221 | 324 | typedef LpBase::Col Key; |
| | 325 | /// The value type of the expression |
| 222 | 326 | typedef LpBase::Value Value; |
| 223 | 327 | |
| 224 | 328 | protected: |
| … |
… |
|
| 227 | 331 | |
| 228 | 332 | public: |
| 229 | 333 | typedef True SolverExpr; |
| 230 | | ///\e |
| | 334 | /// Default constructor |
| | 335 | |
| | 336 | /// Construct an empty expression, the coefficients and |
| | 337 | /// the constant component are initialized to zero. |
| 231 | 338 | Expr() : const_comp(0) {} |
| 232 | | ///\e |
| 233 | | Expr(const Key &k) : const_comp(0) { |
| | 339 | /// Construct an expression from a column |
| | 340 | |
| | 341 | /// Construct an expression, which has a term with \c c variable |
| | 342 | /// and 1.0 coefficient. |
| | 343 | Expr(const Col &c) : const_comp(0) { |
| 234 | 344 | typedef std::map<int, Value>::value_type pair_type; |
| 235 | | comps.insert(pair_type(id(k), 1)); |
| | 345 | comps.insert(pair_type(id(c), 1)); |
| 236 | 346 | } |
| 237 | | ///\e |
| | 347 | /// Construct an expression from a constant |
| | 348 | |
| | 349 | /// Construct an expression, which's constant component is \c v. |
| | 350 | /// |
| 238 | 351 | Expr(const Value &v) : const_comp(v) {} |
| 239 | | ///\e |
| 240 | | Value operator[](const Key& k) const { |
| 241 | | std::map<int, Value>::const_iterator it=comps.find(id(k)); |
| | 352 | /// Returns the coefficient of the column |
| | 353 | Value operator[](const Col& c) const { |
| | 354 | std::map<int, Value>::const_iterator it=comps.find(id(c)); |
| 242 | 355 | if (it != comps.end()) { |
| 243 | 356 | return it->second; |
| 244 | 357 | } else { |
| 245 | 358 | return 0; |
| 246 | 359 | } |
| 247 | 360 | } |
| 248 | | ///\e |
| 249 | | Value& operator[](const Key& k) { |
| 250 | | return comps[id(k)]; |
| | 361 | /// Returns the coefficient of the column |
| | 362 | Value& operator[](const Col& c) { |
| | 363 | return comps[id(c)]; |
| 251 | 364 | } |
| 252 | | ///\e |
| 253 | | void set(const Key &k, const Value &v) { |
| | 365 | /// Sets the coefficient of the column |
| | 366 | void set(const Col &c, const Value &v) { |
| 254 | 367 | if (v != 0.0) { |
| 255 | 368 | typedef std::map<int, Value>::value_type pair_type; |
| 256 | | comps.insert(pair_type(id(k), v)); |
| | 369 | comps.insert(pair_type(id(c), v)); |
| 257 | 370 | } else { |
| 258 | | comps.erase(id(k)); |
| | 371 | comps.erase(id(c)); |
| 259 | 372 | } |
| 260 | 373 | } |
| 261 | | |
| 262 | | ///\e |
| | 374 | /// Returns the constant component of the expression |
| 263 | 375 | Value& operator*() { return const_comp; } |
| 264 | | ///\e |
| | 376 | /// Returns the constant component of the expression |
| 265 | 377 | const Value& operator*() const { return const_comp; } |
| 266 | | |
| 267 | | ///Removes the coefficients closer to zero than \c epsilon. |
| | 378 | /// \brief Removes the coefficients which's absolute value does |
| | 379 | /// not exceed \c epsilon. It also sets to zero the constant |
| | 380 | /// component, if it does not exceed epsilon in absolute value. |
| 268 | 381 | void simplify(Value epsilon = 0.0) { |
| 269 | 382 | std::map<int, Value>::iterator it=comps.begin(); |
| 270 | 383 | while (it != comps.end()) { |
| … |
… |
|
| 286 | 399 | const_comp=0; |
| 287 | 400 | } |
| 288 | 401 | |
| 289 | | ///\e |
| | 402 | ///Compound assignment |
| 290 | 403 | Expr &operator+=(const Expr &e) { |
| 291 | 404 | for (std::map<int, Value>::const_iterator it=e.comps.begin(); |
| 292 | 405 | it!=e.comps.end(); ++it) |
| … |
… |
|
| 294 | 407 | const_comp+=e.const_comp; |
| 295 | 408 | return *this; |
| 296 | 409 | } |
| 297 | | ///\e |
| | 410 | ///Compound assignment |
| 298 | 411 | Expr &operator-=(const Expr &e) { |
| 299 | 412 | for (std::map<int, Value>::const_iterator it=e.comps.begin(); |
| 300 | 413 | it!=e.comps.end(); ++it) |
| … |
… |
|
| 302 | 415 | const_comp-=e.const_comp; |
| 303 | 416 | return *this; |
| 304 | 417 | } |
| 305 | | ///\e |
| 306 | | Expr &operator*=(const Value &c) { |
| | 418 | ///Multiply with a constant |
| | 419 | Expr &operator*=(const Value &v) { |
| 307 | 420 | for (std::map<int, Value>::iterator it=comps.begin(); |
| 308 | 421 | it!=comps.end(); ++it) |
| 309 | | it->second*=c; |
| 310 | | const_comp*=c; |
| | 422 | it->second*=v; |
| | 423 | const_comp*=v; |
| 311 | 424 | return *this; |
| 312 | 425 | } |
| 313 | | ///\e |
| | 426 | ///Division with a constant |
| 314 | 427 | Expr &operator/=(const Value &c) { |
| 315 | 428 | for (std::map<int, Value>::iterator it=comps.begin(); |
| 316 | 429 | it!=comps.end(); ++it) |
| … |
… |
|
| 319 | 432 | return *this; |
| 320 | 433 | } |
| 321 | 434 | |
| | 435 | ///Iterator over the expression |
| | 436 | |
| | 437 | ///The iterator iterates over the terms of the expression. |
| | 438 | /// |
| | 439 | ///\code |
| | 440 | ///double s=0; |
| | 441 | ///for(LpBase::Expr::CoeffIt i(e);i!=INVALID;++i) |
| | 442 | /// s+= *i * primal(i); |
| | 443 | ///\endcode |
| 322 | 444 | class CoeffIt { |
| 323 | 445 | private: |
| 324 | 446 | |
| … |
… |
|
| 326 | 448 | |
| 327 | 449 | public: |
| 328 | 450 | |
| | 451 | /// Sets the iterator to the first term |
| | 452 | |
| | 453 | /// Sets the iterator to the first term of the expression. |
| | 454 | /// |
| 329 | 455 | CoeffIt(Expr& e) |
| 330 | 456 | : _it(e.comps.begin()), _end(e.comps.end()){} |
| 331 | 457 | |
| | 458 | /// Convert the iterator to the column of the term |
| 332 | 459 | operator Col() const { |
| 333 | 460 | return colFromId(_it->first); |
| 334 | 461 | } |
| 335 | 462 | |
| | 463 | /// Returns the coefficient of the term |
| 336 | 464 | Value& operator*() { return _it->second; } |
| | 465 | |
| | 466 | /// Returns the coefficient of the term |
| 337 | 467 | const Value& operator*() const { return _it->second; } |
| 338 | | |
| | 468 | /// Next term |
| | 469 | |
| | 470 | /// Assign the iterator to the next term. |
| | 471 | /// |
| 339 | 472 | CoeffIt& operator++() { ++_it; return *this; } |
| 340 | 473 | |
| | 474 | /// Equality operator |
| 341 | 475 | bool operator==(Invalid) const { return _it == _end; } |
| | 476 | /// Inequality operator |
| 342 | 477 | bool operator!=(Invalid) const { return _it != _end; } |
| 343 | 478 | }; |
| 344 | 479 | |
| | 480 | /// Const iterator over the expression |
| | 481 | |
| | 482 | ///The iterator iterates over the terms of the expression. |
| | 483 | /// |
| | 484 | ///\code |
| | 485 | ///double s=0; |
| | 486 | ///for(LpBase::Expr::ConstCoeffIt i(e);i!=INVALID;++i) |
| | 487 | /// s+=*i * primal(i); |
| | 488 | ///\endcode |
| 345 | 489 | class ConstCoeffIt { |
| 346 | 490 | private: |
| 347 | 491 | |
| … |
… |
|
| 349 | 493 | |
| 350 | 494 | public: |
| 351 | 495 | |
| | 496 | /// Sets the iterator to the first term |
| | 497 | |
| | 498 | /// Sets the iterator to the first term of the expression. |
| | 499 | /// |
| 352 | 500 | ConstCoeffIt(const Expr& e) |
| 353 | 501 | : _it(e.comps.begin()), _end(e.comps.end()){} |
| 354 | 502 | |
| | 503 | /// Convert the iterator to the column of the term |
| 355 | 504 | operator Col() const { |
| 356 | 505 | return colFromId(_it->first); |
| 357 | 506 | } |
| 358 | 507 | |
| | 508 | /// Returns the coefficient of the term |
| 359 | 509 | const Value& operator*() const { return _it->second; } |
| 360 | 510 | |
| | 511 | /// Next term |
| | 512 | |
| | 513 | /// Assign the iterator to the next term. |
| | 514 | /// |
| 361 | 515 | ConstCoeffIt& operator++() { ++_it; return *this; } |
| 362 | 516 | |
| | 517 | /// Equality operator |
| 363 | 518 | bool operator==(Invalid) const { return _it == _end; } |
| | 519 | /// Inequality operator |
| 364 | 520 | bool operator!=(Invalid) const { return _it != _end; } |
| 365 | 521 | }; |
| 366 | 522 | |
| … |
… |
|
| 478 | 634 | ///2*v-3.12*(v-w/2) |
| 479 | 635 | ///v*2.1+(3*v+(v*12+w)*3)/2 |
| 480 | 636 | ///\endcode |
| 481 | | ///are valid \ref DualExpr "DualExpr"essions. |
| | 637 | ///are valid \ref DualExpr dual expressions. |
| 482 | 638 | ///The usual assignment operations are also defined. |
| 483 | 639 | ///\code |
| 484 | 640 | ///e=v+w; |
| … |
… |
|
| 488 | 644 | ///\endcode |
| 489 | 645 | /// |
| 490 | 646 | ///\sa Expr |
| 491 | | /// |
| 492 | 647 | class DualExpr { |
| 493 | 648 | friend class LpBase; |
| 494 | 649 | public: |
| | 650 | /// The key type of the expression |
| 495 | 651 | typedef LpBase::Row Key; |
| | 652 | /// The value type of the expression |
| 496 | 653 | typedef LpBase::Value Value; |
| 497 | 654 | |
| 498 | 655 | protected: |
| … |
… |
|
| 500 | 657 | |
| 501 | 658 | public: |
| 502 | 659 | typedef True SolverExpr; |
| 503 | | ///\e |
| | 660 | /// Default constructor |
| | 661 | |
| | 662 | /// Construct an empty expression, the coefficients are |
| | 663 | /// initialized to zero. |
| 504 | 664 | DualExpr() {} |
| 505 | | ///\e |
| 506 | | DualExpr(const Key &k) { |
| | 665 | /// Construct an expression from a row |
| | 666 | |
| | 667 | /// Construct an expression, which has a term with \c r dual |
| | 668 | /// variable and 1.0 coefficient. |
| | 669 | DualExpr(const Row &r) { |
| 507 | 670 | typedef std::map<int, Value>::value_type pair_type; |
| 508 | | comps.insert(pair_type(id(k), 1)); |
| | 671 | comps.insert(pair_type(id(r), 1)); |
| 509 | 672 | } |
| 510 | | ///\e |
| 511 | | Value operator[](const Key& k) const { |
| 512 | | std::map<int, Value>::const_iterator it = comps.find(id(k)); |
| | 673 | /// Returns the coefficient of the row |
| | 674 | Value operator[](const Row& r) const { |
| | 675 | std::map<int, Value>::const_iterator it = comps.find(id(r)); |
| 513 | 676 | if (it != comps.end()) { |
| 514 | 677 | return it->second; |
| 515 | 678 | } else { |
| 516 | 679 | return 0; |
| 517 | 680 | } |
| 518 | 681 | } |
| 519 | | ///\e |
| 520 | | Value& operator[](const Key& k) { |
| 521 | | return comps[id(k)]; |
| | 682 | /// Returns the coefficient of the row |
| | 683 | Value& operator[](const Row& r) { |
| | 684 | return comps[id(r)]; |
| 522 | 685 | } |
| 523 | | ///\e |
| 524 | | void set(const Key &k, const Value &v) { |
| | 686 | /// Sets the coefficient of the row |
| | 687 | void set(const Row &r, const Value &v) { |
| 525 | 688 | if (v != 0.0) { |
| 526 | 689 | typedef std::map<int, Value>::value_type pair_type; |
| 527 | | comps.insert(pair_type(id(k), v)); |
| | 690 | comps.insert(pair_type(id(r), v)); |
| 528 | 691 | } else { |
| 529 | | comps.erase(id(k)); |
| | 692 | comps.erase(id(r)); |
| 530 | 693 | } |
| 531 | 694 | } |
| 532 | | |
| 533 | | ///Removes the coefficients closer to zero than \c epsilon. |
| | 695 | /// \brief Removes the coefficients which's absolute value does |
| | 696 | /// not exceed \c epsilon. |
| 534 | 697 | void simplify(Value epsilon = 0.0) { |
| 535 | 698 | std::map<int, Value>::iterator it=comps.begin(); |
| 536 | 699 | while (it != comps.end()) { |
| … |
… |
|
| 549 | 712 | void clear() { |
| 550 | 713 | comps.clear(); |
| 551 | 714 | } |
| 552 | | |
| 553 | | ///\e |
| | 715 | ///Compound assignment |
| 554 | 716 | DualExpr &operator+=(const DualExpr &e) { |
| 555 | 717 | for (std::map<int, Value>::const_iterator it=e.comps.begin(); |
| 556 | 718 | it!=e.comps.end(); ++it) |
| 557 | 719 | comps[it->first]+=it->second; |
| 558 | 720 | return *this; |
| 559 | 721 | } |
| 560 | | ///\e |
| | 722 | ///Compound assignment |
| 561 | 723 | DualExpr &operator-=(const DualExpr &e) { |
| 562 | 724 | for (std::map<int, Value>::const_iterator it=e.comps.begin(); |
| 563 | 725 | it!=e.comps.end(); ++it) |
| 564 | 726 | comps[it->first]-=it->second; |
| 565 | 727 | return *this; |
| 566 | 728 | } |
| 567 | | ///\e |
| 568 | | DualExpr &operator*=(const Value &c) { |
| | 729 | ///Multiply with a constant |
| | 730 | DualExpr &operator*=(const Value &v) { |
| 569 | 731 | for (std::map<int, Value>::iterator it=comps.begin(); |
| 570 | 732 | it!=comps.end(); ++it) |
| 571 | | it->second*=c; |
| | 733 | it->second*=v; |
| 572 | 734 | return *this; |
| 573 | 735 | } |
| 574 | | ///\e |
| 575 | | DualExpr &operator/=(const Value &c) { |
| | 736 | ///Division with a constant |
| | 737 | DualExpr &operator/=(const Value &v) { |
| 576 | 738 | for (std::map<int, Value>::iterator it=comps.begin(); |
| 577 | 739 | it!=comps.end(); ++it) |
| 578 | | it->second/=c; |
| | 740 | it->second/=v; |
| 579 | 741 | return *this; |
| 580 | 742 | } |
| 581 | 743 | |
| | 744 | ///Iterator over the expression |
| | 745 | |
| | 746 | ///The iterator iterates over the terms of the expression. |
| | 747 | /// |
| | 748 | ///\code |
| | 749 | ///double s=0; |
| | 750 | ///for(LpBase::DualExpr::CoeffIt i(e);i!=INVALID;++i) |
| | 751 | /// s+= *i * dual(i); |
| | 752 | ///\endcode |
| 582 | 753 | class CoeffIt { |
| 583 | 754 | private: |
| 584 | 755 | |
| … |
… |
|
| 586 | 757 | |
| 587 | 758 | public: |
| 588 | 759 | |
| | 760 | /// Sets the iterator to the first term |
| | 761 | |
| | 762 | /// Sets the iterator to the first term of the expression. |
| | 763 | /// |
| 589 | 764 | CoeffIt(DualExpr& e) |
| 590 | 765 | : _it(e.comps.begin()), _end(e.comps.end()){} |
| 591 | 766 | |
| | 767 | /// Convert the iterator to the row of the term |
| 592 | 768 | operator Row() const { |
| 593 | 769 | return rowFromId(_it->first); |
| 594 | 770 | } |
| 595 | 771 | |
| | 772 | /// Returns the coefficient of the term |
| 596 | 773 | Value& operator*() { return _it->second; } |
| | 774 | |
| | 775 | /// Returns the coefficient of the term |
| 597 | 776 | const Value& operator*() const { return _it->second; } |
| 598 | 777 | |
| | 778 | /// Next term |
| | 779 | |
| | 780 | /// Assign the iterator to the next term. |
| | 781 | /// |
| 599 | 782 | CoeffIt& operator++() { ++_it; return *this; } |
| 600 | 783 | |
| | 784 | /// Equality operator |
| 601 | 785 | bool operator==(Invalid) const { return _it == _end; } |
| | 786 | /// Inequality operator |
| 602 | 787 | bool operator!=(Invalid) const { return _it != _end; } |
| 603 | 788 | }; |
| 604 | 789 | |
| | 790 | ///Iterator over the expression |
| | 791 | |
| | 792 | ///The iterator iterates over the terms of the expression. |
| | 793 | /// |
| | 794 | ///\code |
| | 795 | ///double s=0; |
| | 796 | ///for(LpBase::DualExpr::ConstCoeffIt i(e);i!=INVALID;++i) |
| | 797 | /// s+= *i * dual(i); |
| | 798 | ///\endcode |
| 605 | 799 | class ConstCoeffIt { |
| 606 | 800 | private: |
| 607 | 801 | |
| … |
… |
|
| 609 | 803 | |
| 610 | 804 | public: |
| 611 | 805 | |
| | 806 | /// Sets the iterator to the first term |
| | 807 | |
| | 808 | /// Sets the iterator to the first term of the expression. |
| | 809 | /// |
| 612 | 810 | ConstCoeffIt(const DualExpr& e) |
| 613 | 811 | : _it(e.comps.begin()), _end(e.comps.end()){} |
| 614 | 812 | |
| | 813 | /// Convert the iterator to the row of the term |
| 615 | 814 | operator Row() const { |
| 616 | 815 | return rowFromId(_it->first); |
| 617 | 816 | } |
| 618 | 817 | |
| | 818 | /// Returns the coefficient of the term |
| 619 | 819 | const Value& operator*() const { return _it->second; } |
| 620 | 820 | |
| | 821 | /// Next term |
| | 822 | |
| | 823 | /// Assign the iterator to the next term. |
| | 824 | /// |
| 621 | 825 | ConstCoeffIt& operator++() { ++_it; return *this; } |
| 622 | 826 | |
| | 827 | /// Equality operator |
| 623 | 828 | bool operator==(Invalid) const { return _it == _end; } |
| | 829 | /// Inequality operator |
| 624 | 830 | bool operator!=(Invalid) const { return _it != _end; } |
| 625 | 831 | }; |
| 626 | 832 | }; |
| … |
… |
|
| 774 | 980 | //Constant component of the objective function |
| 775 | 981 | Value obj_const_comp; |
| 776 | 982 | |
| | 983 | LpBase() : rows(), cols(), obj_const_comp(0) {} |
| | 984 | |
| 777 | 985 | public: |
| 778 | 986 | |
| 779 | | ///\e |
| 780 | | LpBase() : rows(), cols(), obj_const_comp(0) { |
| 781 | | } |
| 782 | | |
| 783 | | ///\e |
| | 987 | /// Virtual destructor |
| 784 | 988 | virtual ~LpBase() {} |
| 785 | 989 | |
| 786 | 990 | ///Creates a new LP problem |
| … |
… |
|
| 798 | 1002 | ///Add a new empty column (i.e a new variable) to the LP |
| 799 | 1003 | Col addCol() { Col c; c._id = _addColId(_addCol()); return c;} |
| 800 | 1004 | |
| 801 | | ///\brief Adds several new columns |
| 802 | | ///(i.e a variables) at once |
| | 1005 | ///\brief Adds several new columns (i.e variables) at once |
| 803 | 1006 | /// |
| 804 | | ///This magic function takes a container as its argument |
| 805 | | ///and fills its elements |
| 806 | | ///with new columns (i.e. variables) |
| | 1007 | ///This magic function takes a container as its argument and fills |
| | 1008 | ///its elements with new columns (i.e. variables) |
| 807 | 1009 | ///\param t can be |
| 808 | 1010 | ///- a standard STL compatible iterable container with |
| 809 | | ///\ref Col as its \c values_type |
| 810 | | ///like |
| | 1011 | ///\ref Col as its \c values_type like |
| 811 | 1012 | ///\code |
| 812 | 1013 | ///std::vector<LpBase::Col> |
| 813 | 1014 | ///std::list<LpBase::Col> |
| 814 | 1015 | ///\endcode |
| 815 | 1016 | ///- a standard STL compatible iterable container with |
| 816 | | ///\ref Col as its \c mapped_type |
| 817 | | ///like |
| | 1017 | ///\ref Col as its \c mapped_type like |
| 818 | 1018 | ///\code |
| 819 | 1019 | ///std::map<AnyType,LpBase::Col> |
| 820 | 1020 | ///\endcode |
| … |
… |
|
| 829 | 1029 | int addColSet(T &t) { return 0;} |
| 830 | 1030 | #else |
| 831 | 1031 | template<class T> |
| 832 | | typename enable_if<typename T::value_type::LpSolverCol,int>::type |
| | 1032 | typename enable_if<typename T::value_type::LpCol,int>::type |
| 833 | 1033 | addColSet(T &t,dummy<0> = 0) { |
| 834 | 1034 | int s=0; |
| 835 | 1035 | for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addCol();s++;} |
| 836 | 1036 | return s; |
| 837 | 1037 | } |
| 838 | 1038 | template<class T> |
| 839 | | typename enable_if<typename T::value_type::second_type::LpSolverCol, |
| | 1039 | typename enable_if<typename T::value_type::second_type::LpCol, |
| 840 | 1040 | int>::type |
| 841 | 1041 | addColSet(T &t,dummy<1> = 1) { |
| 842 | 1042 | int s=0; |
| … |
… |
|
| 847 | 1047 | return s; |
| 848 | 1048 | } |
| 849 | 1049 | template<class T> |
| 850 | | typename enable_if<typename T::MapIt::Value::LpSolverCol, |
| | 1050 | typename enable_if<typename T::MapIt::Value::LpCol, |
| 851 | 1051 | int>::type |
| 852 | 1052 | addColSet(T &t,dummy<2> = 2) { |
| 853 | 1053 | int s=0; |
| … |
… |
|
| 873 | 1073 | |
| 874 | 1074 | ///Get a column (i.e a dual constraint) of the LP |
| 875 | 1075 | |
| 876 | | ///\param r is the column to get |
| | 1076 | ///\param c is the column to get |
| 877 | 1077 | ///\return the dual expression associated to the column |
| 878 | 1078 | DualExpr col(Col c) const { |
| 879 | 1079 | DualExpr e; |
| … |
… |
|
| 884 | 1084 | ///Add a new column to the LP |
| 885 | 1085 | |
| 886 | 1086 | ///\param e is a dual linear expression (see \ref DualExpr) |
| 887 | | ///\param obj is the corresponding component of the objective |
| | 1087 | ///\param o is the corresponding component of the objective |
| 888 | 1088 | ///function. It is 0 by default. |
| 889 | 1089 | ///\return The created column. |
| 890 | 1090 | Col addCol(const DualExpr &e, Value o = 0) { |
| … |
… |
|
| 900 | 1100 | ///\return The created row |
| 901 | 1101 | Row addRow() { Row r; r._id = _addRowId(_addRow()); return r;} |
| 902 | 1102 | |
| 903 | | ///\brief Add several new rows |
| 904 | | ///(i.e a constraints) at once |
| | 1103 | ///\brief Add several new rows (i.e constraints) at once |
| 905 | 1104 | /// |
| 906 | | ///This magic function takes a container as its argument |
| 907 | | ///and fills its elements |
| 908 | | ///with new row (i.e. variables) |
| | 1105 | ///This magic function takes a container as its argument and fills |
| | 1106 | ///its elements with new row (i.e. variables) |
| 909 | 1107 | ///\param t can be |
| 910 | 1108 | ///- a standard STL compatible iterable container with |
| 911 | | ///\ref Row as its \c values_type |
| 912 | | ///like |
| | 1109 | ///\ref Row as its \c values_type like |
| 913 | 1110 | ///\code |
| 914 | 1111 | ///std::vector<LpBase::Row> |
| 915 | 1112 | ///std::list<LpBase::Row> |
| 916 | 1113 | ///\endcode |
| 917 | 1114 | ///- a standard STL compatible iterable container with |
| 918 | | ///\ref Row as its \c mapped_type |
| 919 | | ///like |
| | 1115 | ///\ref Row as its \c mapped_type like |
| 920 | 1116 | ///\code |
| 921 | 1117 | ///std::map<AnyType,LpBase::Row> |
| 922 | 1118 | ///\endcode |
| … |
… |
|
| 931 | 1127 | int addRowSet(T &t) { return 0;} |
| 932 | 1128 | #else |
| 933 | 1129 | template<class T> |
| 934 | | typename enable_if<typename T::value_type::LpSolverRow,int>::type |
| | 1130 | typename enable_if<typename T::value_type::LpRow,int>::type |
| 935 | 1131 | addRowSet(T &t, dummy<0> = 0) { |
| 936 | 1132 | int s=0; |
| 937 | 1133 | for(typename T::iterator i=t.begin();i!=t.end();++i) {*i=addRow();s++;} |
| 938 | 1134 | return s; |
| 939 | 1135 | } |
| 940 | 1136 | template<class T> |
| 941 | | typename enable_if<typename T::value_type::second_type::LpSolverRow, |
| 942 | | int>::type |
| | 1137 | typename enable_if<typename T::value_type::second_type::LpRow, int>::type |
| 943 | 1138 | addRowSet(T &t, dummy<1> = 1) { |
| 944 | 1139 | int s=0; |
| 945 | 1140 | for(typename T::iterator i=t.begin();i!=t.end();++i) { |
| … |
… |
|
| 949 | 1144 | return s; |
| 950 | 1145 | } |
| 951 | 1146 | template<class T> |
| 952 | | typename enable_if<typename T::MapIt::Value::LpSolverRow, |
| 953 | | int>::type |
| | 1147 | typename enable_if<typename T::MapIt::Value::LpRow, int>::type |
| 954 | 1148 | addRowSet(T &t, dummy<2> = 2) { |
| 955 | 1149 | int s=0; |
| 956 | 1150 | for(typename T::MapIt i(t); i!=INVALID; ++i) |
| … |
… |
|
| 1020 | 1214 | ///Erase a column (i.e a variable) from the LP |
| 1021 | 1215 | |
| 1022 | 1216 | ///\param c is the column to be deleted |
| 1023 | | ///\todo Please check this |
| 1024 | 1217 | void erase(Col c) { |
| 1025 | 1218 | _eraseCol(cols(id(c))); |
| 1026 | 1219 | _eraseColId(cols(id(c))); |
| … |
… |
|
| 1028 | 1221 | ///Erase a row (i.e a constraint) from the LP |
| 1029 | 1222 | |
| 1030 | 1223 | ///\param r is the row to be deleted |
| 1031 | | ///\todo Please check this |
| 1032 | 1224 | void erase(Row r) { |
| 1033 | 1225 | _eraseRow(rows(id(r))); |
| 1034 | 1226 | _eraseRowId(rows(id(r))); |
| … |
… |
|
| 1099 | 1291 | |
| 1100 | 1292 | /// Get an element of the coefficient matrix of the LP |
| 1101 | 1293 | |
| 1102 | | ///\param r is the row of the element in question |
| 1103 | | ///\param c is the column of the element in question |
| | 1294 | ///\param r is the row of the element |
| | 1295 | ///\param c is the column of the element |
| 1104 | 1296 | ///\return the corresponding coefficient |
| 1105 | 1297 | Value coeff(Row r, Col c) const { |
| 1106 | 1298 | return _getCoeff(rows(id(r)),cols(id(c))); |
| … |
… |
|
| 1117 | 1309 | |
| 1118 | 1310 | /// Get the lower bound of a column (i.e a variable) |
| 1119 | 1311 | |
| 1120 | | /// This function returns the lower bound for column (variable) \t c |
| | 1312 | /// This function returns the lower bound for column (variable) \c c |
| 1121 | 1313 | /// (this might be -\ref INF as well). |
| 1122 | | ///\return The lower bound for column \t c |
| | 1314 | ///\return The lower bound for column \c c |
| 1123 | 1315 | Value colLowerBound(Col c) const { |
| 1124 | 1316 | return _getColLowerBound(cols(id(c))); |
| 1125 | 1317 | } |
| 1126 | 1318 | |
| 1127 | 1319 | ///\brief Set the lower bound of several columns |
| 1128 | | ///(i.e a variables) at once |
| | 1320 | ///(i.e variables) at once |
| 1129 | 1321 | /// |
| 1130 | 1322 | ///This magic function takes a container as its argument |
| 1131 | 1323 | ///and applies the function on all of its elements. |
| 1132 | | /// The lower bound of a variable (column) has to be given by an |
| 1133 | | /// extended number of type Value, i.e. a finite number of type |
| 1134 | | /// Value or -\ref INF. |
| | 1324 | ///The lower bound of a variable (column) has to be given by an |
| | 1325 | ///extended number of type Value, i.e. a finite number of type |
| | 1326 | ///Value or -\ref INF. |
| 1135 | 1327 | #ifdef DOXYGEN |
| 1136 | 1328 | template<class T> |
| 1137 | 1329 | void colLowerBound(T &t, Value value) { return 0;} |
| 1138 | 1330 | #else |
| 1139 | 1331 | template<class T> |
| 1140 | | typename enable_if<typename T::value_type::LpSolverCol,void>::type |
| | 1332 | typename enable_if<typename T::value_type::LpCol,void>::type |
| 1141 | 1333 | colLowerBound(T &t, Value value,dummy<0> = 0) { |
| 1142 | 1334 | for(typename T::iterator i=t.begin();i!=t.end();++i) { |
| 1143 | 1335 | colLowerBound(*i, value); |
| 1144 | 1336 | } |
| 1145 | 1337 | } |
| 1146 | 1338 | template<class T> |
| 1147 | | typename enable_if<typename T::value_type::second_type::LpSolverCol, |
| | 1339 | typename enable_if<typename T::value_type::second_type::LpCol, |
| 1148 | 1340 | void>::type |
| 1149 | 1341 | colLowerBound(T &t, Value value,dummy<1> = 1) { |
| 1150 | 1342 | for(typename T::iterator i=t.begin();i!=t.end();++i) { |
| … |
… |
|
| 1152 | 1344 | } |
| 1153 | 1345 | } |
| 1154 | 1346 | template<class T> |
| 1155 | | typename enable_if<typename T::MapIt::Value::LpSolverCol, |
| | 1347 | typename enable_if<typename T::MapIt::Value::LpCol, |
| 1156 | 1348 | void>::type |
| 1157 | 1349 | colLowerBound(T &t, Value value,dummy<2> = 2) { |
| 1158 | 1350 | for(typename T::MapIt i(t); i!=INVALID; ++i){ |
| … |
… |
|
| 1172 | 1364 | |
| 1173 | 1365 | /// Get the upper bound of a column (i.e a variable) |
| 1174 | 1366 | |
| 1175 | | /// This function returns the upper bound for column (variable) \t c |
| | 1367 | /// This function returns the upper bound for column (variable) \c c |
| 1176 | 1368 | /// (this might be \ref INF as well). |
| 1177 | | ///\return The upper bound for column \t c |
| | 1369 | /// \return The upper bound for column \c c |
| 1178 | 1370 | Value colUpperBound(Col c) const { |
| 1179 | 1371 | return _getColUpperBound(cols(id(c))); |
| 1180 | 1372 | } |
| 1181 | 1373 | |
| 1182 | 1374 | ///\brief Set the upper bound of several columns |
| 1183 | | ///(i.e a variables) at once |
| | 1375 | ///(i.e variables) at once |
| 1184 | 1376 | /// |
| 1185 | 1377 | ///This magic function takes a container as its argument |
| 1186 | 1378 | ///and applies the function on all of its elements. |
| 1187 | | /// The upper bound of a variable (column) has to be given by an |
| 1188 | | /// extended number of type Value, i.e. a finite number of type |
| 1189 | | /// Value or \ref INF. |
| | 1379 | ///The upper bound of a variable (column) has to be given by an |
| | 1380 | ///extended number of type Value, i.e. a finite number of type |
| | 1381 | ///Value or \ref INF. |
| 1190 | 1382 | #ifdef DOXYGEN |
| 1191 | 1383 | template<class T> |
| 1192 | 1384 | void colUpperBound(T &t, Value value) { return 0;} |
| 1193 | 1385 | #else |
| 1194 | 1386 | template<class T> |
| 1195 | | typename enable_if<typename T::value_type::LpSolverCol,void>::type |
| | 1387 | typename enable_if<typename T::value_type::LpCol,void>::type |
| 1196 | 1388 | colUpperBound(T &t, Value value,dummy<0> = 0) { |
| 1197 | 1389 | for(typename T::iterator i=t.begin();i!=t.end();++i) { |
| 1198 | 1390 | colUpperBound(*i, value); |
| 1199 | 1391 | } |
| 1200 | 1392 | } |
| 1201 | 1393 | template<class T> |
| 1202 | | typename enable_if<typename T::value_type::second_type::LpSolverCol, |
| | 1394 | typename enable_if<typename T::value_type::second_type::LpCol, |
| 1203 | 1395 | void>::type |
| 1204 | 1396 | colUpperBound(T &t, Value value,dummy<1> = 1) { |
| 1205 | 1397 | for(typename T::iterator i=t.begin();i!=t.end();++i) { |
| … |
… |
|
| 1207 | 1399 | } |
| 1208 | 1400 | } |
| 1209 | 1401 | template<class T> |
| 1210 | | typename enable_if<typename T::MapIt::Value::LpSolverCol, |
| | 1402 | typename enable_if<typename T::MapIt::Value::LpCol, |
| 1211 | 1403 | void>::type |
| 1212 | 1404 | colUpperBound(T &t, Value value,dummy<2> = 2) { |
| 1213 | 1405 | for(typename T::MapIt i(t); i!=INVALID; ++i){ |
| … |
… |
|
| 1228 | 1420 | } |
| 1229 | 1421 | |
| 1230 | 1422 | ///\brief Set the lower and the upper bound of several columns |
| 1231 | | ///(i.e a variables) at once |
| | 1423 | ///(i.e variables) at once |
| 1232 | 1424 | /// |
| 1233 | 1425 | ///This magic function takes a container as its argument |
| 1234 | 1426 | ///and applies the function on all of its elements. |
| … |
… |
|
| 1241 | 1433 | void colBounds(T &t, Value lower, Value upper) { return 0;} |
| 1242 | 1434 | #else |
| 1243 | 1435 | template<class T> |
| 1244 | | typename enable_if<typename T::value_type::LpSolverCol,void>::type |
| | 1436 | typename enable_if<typename T::value_type::LpCol,void>::type |
| 1245 | 1437 | colBounds(T &t, Value lower, Value upper,dummy<0> = 0) { |
| 1246 | 1438 | for(typename T::iterator i=t.begin();i!=t.end();++i) { |
| 1247 | 1439 | colBounds(*i, lower, upper); |
| 1248 | 1440 | } |
| 1249 | 1441 | } |
| 1250 | 1442 | template<class T> |
| 1251 | | typename enable_if<typename T::value_type::second_type::LpSolverCol, |
| 1252 | | void>::type |
| | 1443 | typename enable_if<typename T::value_type::second_type::LpCol, void>::type |
| 1253 | 1444 | colBounds(T &t, Value lower, Value upper,dummy<1> = 1) { |
| 1254 | 1445 | for(typename T::iterator i=t.begin();i!=t.end();++i) { |
| 1255 | 1446 | colBounds(i->second, lower, upper); |
| 1256 | 1447 | } |
| 1257 | 1448 | } |
| 1258 | 1449 | template<class T> |
| 1259 | | typename enable_if<typename T::MapIt::Value::LpSolverCol, |
| 1260 | | void>::type |
| | 1450 | typename enable_if<typename T::MapIt::Value::LpCol, void>::type |
| 1261 | 1451 | colBounds(T &t, Value lower, Value upper,dummy<2> = 2) { |
| 1262 | 1452 | for(typename T::MapIt i(t); i!=INVALID; ++i){ |
| 1263 | 1453 | colBounds(*i, lower, upper); |
| … |
… |
|
| 1276 | 1466 | |
| 1277 | 1467 | /// Get the lower bound of a row (i.e a constraint) |
| 1278 | 1468 | |
| 1279 | | /// This function returns the lower bound for row (constraint) \t c |
| | 1469 | /// This function returns the lower bound for row (constraint) \c c |
| 1280 | 1470 | /// (this might be -\ref INF as well). |
| 1281 | | ///\return The lower bound for row \t r |
| | 1471 | ///\return The lower bound for row \c r |
| 1282 | 1472 | Value rowLowerBound(Row r) const { |
| 1283 | 1473 | return _getRowLowerBound(rows(id(r))); |
| 1284 | 1474 | } |
| … |
… |
|
| 1294 | 1484 | |
| 1295 | 1485 | /// Get the upper bound of a row (i.e a constraint) |
| 1296 | 1486 | |
| 1297 | | /// This function returns the upper bound for row (constraint) \t c |
| | 1487 | /// This function returns the upper bound for row (constraint) \c c |
| 1298 | 1488 | /// (this might be -\ref INF as well). |
| 1299 | | ///\return The upper bound for row \t r |
| | 1489 | ///\return The upper bound for row \c r |
| 1300 | 1490 | Value rowUpperBound(Row r) const { |
| 1301 | 1491 | return _getRowUpperBound(rows(id(r))); |
| 1302 | 1492 | } |
| … |
… |
|
| 1310 | 1500 | ///Set the objective function |
| 1311 | 1501 | |
| 1312 | 1502 | ///\param e is a linear expression of type \ref Expr. |
| | 1503 | /// |
| 1313 | 1504 | void obj(const Expr& e) { |
| 1314 | 1505 | _setObjCoeffs(ExprIterator(e.comps.begin(), cols), |
| 1315 | 1506 | ExprIterator(e.comps.end(), cols)); |
| … |
… |
|
| 1318 | 1509 | |
| 1319 | 1510 | ///Get the objective function |
| 1320 | 1511 | |
| 1321 | | ///\return the objective function as a linear expression of type \ref Expr. |
| | 1512 | ///\return the objective function as a linear expression of type |
| | 1513 | ///Expr. |
| 1322 | 1514 | Expr obj() const { |
| 1323 | 1515 | Expr e; |
| 1324 | 1516 | _getObjCoeffs(InsertIterator(e.comps, cols)); |
| … |
… |
|
| 1346 | 1538 | |
| 1347 | 1539 | }; |
| 1348 | 1540 | |
| | 1541 | /// Addition |
| | 1542 | |
| 1349 | 1543 | ///\relates LpBase::Expr |
| 1350 | 1544 | /// |
| 1351 | | inline LpBase::Expr operator+(const LpBase::Expr &a, |
| 1352 | | const LpBase::Expr &b) { |
| | 1545 | inline LpBase::Expr operator+(const LpBase::Expr &a, const LpBase::Expr &b) { |
| 1353 | 1546 | LpBase::Expr tmp(a); |
| 1354 | 1547 | tmp+=b; |
| 1355 | 1548 | return tmp; |
| 1356 | 1549 | } |
| 1357 | | ///\e |
| | 1550 | ///Substraction |
| 1358 | 1551 | |
| 1359 | 1552 | ///\relates LpBase::Expr |
| 1360 | 1553 | /// |
| 1361 | | inline LpBase::Expr operator-(const LpBase::Expr &a, |
| 1362 | | const LpBase::Expr &b) { |
| | 1554 | inline LpBase::Expr operator-(const LpBase::Expr &a, const LpBase::Expr &b) { |
| 1363 | 1555 | LpBase::Expr tmp(a); |
| 1364 | 1556 | tmp-=b; |
| 1365 | 1557 | return tmp; |
| 1366 | 1558 | } |
| 1367 | | ///\e |
| | 1559 | ///Multiply with constant |
| 1368 | 1560 | |
| 1369 | 1561 | ///\relates LpBase::Expr |
| 1370 | 1562 | /// |
| 1371 | | inline LpBase::Expr operator*(const LpBase::Expr &a, |
| 1372 | | const LpBase::Value &b) { |
| | 1563 | inline LpBase::Expr operator*(const LpBase::Expr &a, const LpBase::Value &b) { |
| 1373 | 1564 | LpBase::Expr tmp(a); |
| 1374 | 1565 | tmp*=b; |
| 1375 | 1566 | return tmp; |
| 1376 | 1567 | } |
| 1377 | 1568 | |
| 1378 | | ///\e |
| | 1569 | ///Multiply with constant |
| 1379 | 1570 | |
| 1380 | 1571 | ///\relates LpBase::Expr |
| 1381 | 1572 | /// |
| 1382 | | inline LpBase::Expr operator*(const LpBase::Value &a, |
| 1383 | | const LpBase::Expr &b) { |
| | 1573 | inline LpBase::Expr operator*(const LpBase::Value &a, const LpBase::Expr &b) { |
| 1384 | 1574 | LpBase::Expr tmp(b); |
| 1385 | 1575 | tmp*=a; |
| 1386 | 1576 | return tmp; |
| 1387 | 1577 | } |
| 1388 | | ///\e |
| | 1578 | ///Divide with constant |
| 1389 | 1579 | |
| 1390 | 1580 | ///\relates LpBase::Expr |
| 1391 | 1581 | /// |
| 1392 | | inline LpBase::Expr operator/(const LpBase::Expr &a, |
| 1393 | | const LpBase::Value &b) { |
| | 1582 | inline LpBase::Expr operator/(const LpBase::Expr &a, const LpBase::Value &b) { |
| 1394 | 1583 | LpBase::Expr tmp(a); |
| 1395 | 1584 | tmp/=b; |
| 1396 | 1585 | return tmp; |
| 1397 | 1586 | } |
| 1398 | 1587 | |
| 1399 | | ///\e |
| | 1588 | ///Create constraint |
| 1400 | 1589 | |
| 1401 | 1590 | ///\relates LpBase::Constr |
| 1402 | 1591 | /// |
| … |
… |
|
| 1405 | 1594 | return LpBase::Constr(0, f - e, LpBase::INF); |
| 1406 | 1595 | } |
| 1407 | 1596 | |
| 1408 | | ///\e |
| | 1597 | ///Create constraint |
| 1409 | 1598 | |
| 1410 | 1599 | ///\relates LpBase::Constr |
| 1411 | 1600 | /// |
| … |
… |
|
| 1414 | 1603 | return LpBase::Constr(e, f, LpBase::NaN); |
| 1415 | 1604 | } |
| 1416 | 1605 | |
| 1417 | | ///\e |
| | 1606 | ///Create constraint |
| 1418 | 1607 | |
| 1419 | 1608 | ///\relates LpBase::Constr |
| 1420 | 1609 | /// |
| … |
… |
|
| 1423 | 1612 | return LpBase::Constr(- LpBase::INF, e, f); |
| 1424 | 1613 | } |
| 1425 | 1614 | |
| 1426 | | ///\e |
| | 1615 | ///Create constraint |
| 1427 | 1616 | |
| 1428 | 1617 | ///\relates LpBase::Constr |
| 1429 | 1618 | /// |
| … |
… |
|
| 1433 | 1622 | } |
| 1434 | 1623 | |
| 1435 | 1624 | |
| 1436 | | ///\e |
| | 1625 | ///Create constraint |
| 1437 | 1626 | |
| 1438 | 1627 | ///\relates LpBase::Constr |
| 1439 | 1628 | /// |
| … |
… |
|
| 1443 | 1632 | } |
| 1444 | 1633 | |
| 1445 | 1634 | |
| 1446 | | ///\e |
| | 1635 | ///Create constraint |
| 1447 | 1636 | |
| 1448 | 1637 | ///\relates LpBase::Constr |
| 1449 | 1638 | /// |
| … |
… |
|
| 1452 | 1641 | return LpBase::Constr(f, e, LpBase::INF); |
| 1453 | 1642 | } |
| 1454 | 1643 | |
| 1455 | | ///\e |
| | 1644 | ///Create constraint |
| 1456 | 1645 | |
| 1457 | 1646 | ///\relates LpBase::Constr |
| 1458 | 1647 | /// |
| … |
… |
|
| 1461 | 1650 | return LpBase::Constr(f, e, f); |
| 1462 | 1651 | } |
| 1463 | 1652 | |
| 1464 | | ///\e |
| | 1653 | ///Create constraint |
| 1465 | 1654 | |
| 1466 | 1655 | ///\relates LpBase::Constr |
| 1467 | 1656 | /// |
| … |
… |
|
| 1470 | 1659 | return LpBase::Constr(0, f - e, 0); |
| 1471 | 1660 | } |
| 1472 | 1661 | |
| 1473 | | ///\e |
| | 1662 | ///Create constraint |
| 1474 | 1663 | |
| 1475 | 1664 | ///\relates LpBase::Constr |
| 1476 | 1665 | /// |
| … |
… |
|
| 1481 | 1670 | tmp.lowerBound()=n; |
| 1482 | 1671 | return tmp; |
| 1483 | 1672 | } |
| 1484 | | ///\e |
| | 1673 | ///Create constraint |
| 1485 | 1674 | |
| 1486 | 1675 | ///\relates LpBase::Constr |
| 1487 | 1676 | /// |
| … |
… |
|
| 1494 | 1683 | return tmp; |
| 1495 | 1684 | } |
| 1496 | 1685 | |
| 1497 | | ///\e |
| | 1686 | ///Create constraint |
| 1498 | 1687 | |
| 1499 | 1688 | ///\relates LpBase::Constr |
| 1500 | 1689 | /// |
| … |
… |
|
| 1505 | 1694 | tmp.upperBound()=n; |
| 1506 | 1695 | return tmp; |
| 1507 | 1696 | } |
| 1508 | | ///\e |
| | 1697 | ///Create constraint |
| 1509 | 1698 | |
| 1510 | 1699 | ///\relates LpBase::Constr |
| 1511 | 1700 | /// |
| … |
… |
|
| 1518 | 1707 | return tmp; |
| 1519 | 1708 | } |
| 1520 | 1709 | |
| 1521 | | ///\e |
| | 1710 | ///Addition |
| 1522 | 1711 | |
| 1523 | 1712 | ///\relates LpBase::DualExpr |
| 1524 | 1713 | /// |
| … |
… |
|
| 1528 | 1717 | tmp+=b; |
| 1529 | 1718 | return tmp; |
| 1530 | 1719 | } |
| 1531 | | ///\e |
| | 1720 | ///Substraction |
| 1532 | 1721 | |
| 1533 | 1722 | ///\relates LpBase::DualExpr |
| 1534 | 1723 | /// |
| … |
… |
|
| 1538 | 1727 | tmp-=b; |
| 1539 | 1728 | return tmp; |
| 1540 | 1729 | } |
| 1541 | | ///\e |
| | 1730 | ///Multiply with constant |
| 1542 | 1731 | |
| 1543 | 1732 | ///\relates LpBase::DualExpr |
| 1544 | 1733 | /// |
| … |
… |
|
| 1549 | 1738 | return tmp; |
| 1550 | 1739 | } |
| 1551 | 1740 | |
| 1552 | | ///\e |
| | 1741 | ///Multiply with constant |
| 1553 | 1742 | |
| 1554 | 1743 | ///\relates LpBase::DualExpr |
| 1555 | 1744 | /// |
| … |
… |
|
| 1559 | 1748 | tmp*=a; |
| 1560 | 1749 | return tmp; |
| 1561 | 1750 | } |
| 1562 | | ///\e |
| | 1751 | ///Divide with constant |
| 1563 | 1752 | |
| 1564 | 1753 | ///\relates LpBase::DualExpr |
| 1565 | 1754 | /// |
| … |
… |
|
| 1573 | 1762 | /// \ingroup lp_group |
| 1574 | 1763 | /// |
| 1575 | 1764 | /// \brief Common base class for LP solvers |
| 1576 | | /// \todo Much more docs |
| | 1765 | /// |
| | 1766 | /// This class is an abstract base class for LP solvers. This class |
| | 1767 | /// provides a full interface for set and modify an LP problem, |
| | 1768 | /// solve it and retrieve the solution. You can use one of the |
| | 1769 | /// descendants as a concrete implementation, or the \c Lp |
| | 1770 | /// default LP solver. However, if you would like to handle LP |
| | 1771 | /// solvers as reference or pointer in a generic way, you can use |
| | 1772 | /// this class directly. |
| 1577 | 1773 | class LpSolver : virtual public LpBase { |
| 1578 | 1774 | public: |
| 1579 | 1775 | |
| 1580 | | ///\e |
| | 1776 | /// The problem types for primal and dual problems |
| 1581 | 1777 | enum ProblemType { |
| 1582 | 1778 | ///Feasible solution hasn't been found (but may exist). |
| 1583 | 1779 | UNDEFINED = 0, |
| … |
… |
|
| 1591 | 1787 | UNBOUNDED = 4 |
| 1592 | 1788 | }; |
| 1593 | 1789 | |
| 1594 | | ///\e |
| | 1790 | ///The basis status of variables |
| 1595 | 1791 | enum VarStatus { |
| 1596 | 1792 | /// The variable is in the basis |
| 1597 | 1793 | BASIC, |
| … |
… |
|
| 1634 | 1830 | ///\return The result of the optimization procedure. Possible |
| 1635 | 1831 | ///values and their meanings can be found in the documentation of |
| 1636 | 1832 | ///\ref SolveExitStatus. |
| 1637 | | /// |
| 1638 | | ///\todo Which method is used to solve the problem |
| 1639 | 1833 | SolveExitStatus solve() { return _solve(); } |
| 1640 | 1834 | |
| 1641 | 1835 | ///@} |
| … |
… |
|
| 1654 | 1848 | return _getDualType(); |
| 1655 | 1849 | } |
| 1656 | 1850 | |
| 1657 | | ///\e |
| | 1851 | /// Return the primal value of the column |
| | 1852 | |
| | 1853 | /// Return the primal value of the column. |
| | 1854 | /// \pre The problem is solved. |
| 1658 | 1855 | Value primal(Col c) const { return _getPrimal(cols(id(c))); } |
| 1659 | | ///\e |
| | 1856 | |
| | 1857 | /// Return the primal value of the expression |
| | 1858 | |
| | 1859 | /// Return the primal value of the expression, i.e. the dot |
| | 1860 | /// product of the primal solution and the expression. |
| | 1861 | /// \pre The problem is solved. |
| 1660 | 1862 | Value primal(const Expr& e) const { |
| 1661 | 1863 | double res = *e; |
| 1662 | 1864 | for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) { |
| … |
… |
|
| 1664 | 1866 | } |
| 1665 | 1867 | return res; |
| 1666 | 1868 | } |
| 1667 | | ///\e |
| | 1869 | /// Returns a component of the primal ray |
| | 1870 | |
| | 1871 | /// The primal ray is solution of the modified primal problem, |
| | 1872 | /// where we change each finite bound to 0, and we looking for a |
| | 1873 | /// negative objective value in case of minimization, and positive |
| | 1874 | /// objective value for maximization. If there is such solution, |
| | 1875 | /// that proofs the unsolvability of the dual problem, and if a |
| | 1876 | /// feasible primal solution exists, then the unboundness of |
| | 1877 | /// primal problem. |
| | 1878 | /// |
| | 1879 | /// \pre The problem is solved and the dual problem is infeasible. |
| | 1880 | /// \note Some solvers does not provide primal ray calculation |
| | 1881 | /// functions. |
| 1668 | 1882 | Value primalRay(Col c) const { return _getPrimalRay(cols(id(c))); } |
| 1669 | 1883 | |
| 1670 | | ///\e |
| | 1884 | /// Return the dual value of the row |
| | 1885 | |
| | 1886 | /// Return the dual value of the row. |
| | 1887 | /// \pre The problem is solved. |
| 1671 | 1888 | Value dual(Row r) const { return _getDual(rows(id(r))); } |
| 1672 | | ///\e |
| | 1889 | |
| | 1890 | /// Return the dual value of the dual expression |
| | 1891 | |
| | 1892 | /// Return the dual value of the dual expression, i.e. the dot |
| | 1893 | /// product of the dual solution and the dual expression. |
| | 1894 | /// \pre The problem is solved. |
| 1673 | 1895 | Value dual(const DualExpr& e) const { |
| 1674 | 1896 | double res = 0.0; |
| 1675 | 1897 | for (DualExpr::ConstCoeffIt r(e); r != INVALID; ++r) { |
| … |
… |
|
| 1677 | 1899 | } |
| 1678 | 1900 | return res; |
| 1679 | 1901 | } |
| 1680 | | ///\e |
| | 1902 | |
| | 1903 | /// Returns a component of the dual ray |
| | 1904 | |
| | 1905 | /// The dual ray is solution of the modified primal problem, where |
| | 1906 | /// we change each finite bound to 0 (i.e. the objective function |
| | 1907 | /// coefficients in the primal problem), and we looking for a |
| | 1908 | /// ositive objective value. If there is such solution, that |
| | 1909 | /// proofs the unsolvability of the primal problem, and if a |
| | 1910 | /// feasible dual solution exists, then the unboundness of |
| | 1911 | /// dual problem. |
| | 1912 | /// |
| | 1913 | /// \pre The problem is solved and the primal problem is infeasible. |
| | 1914 | /// \note Some solvers does not provide dual ray calculation |
| | 1915 | /// functions. |
| 1681 | 1916 | Value dualRay(Row r) const { return _getDualRay(rows(id(r))); } |
| 1682 | 1917 | |
| 1683 | | ///\e |
| | 1918 | /// Return the basis status of the column |
| | 1919 | |
| | 1920 | /// \see VarStatus |
| 1684 | 1921 | VarStatus colStatus(Col c) const { return _getColStatus(cols(id(c))); } |
| 1685 | 1922 | |
| 1686 | | ///\e |
| 1687 | | VarStatus rowStatus(Col c) const { return _getRowStatus(cols(id(c))); } |
| | 1923 | /// Return the basis status of the row |
| 1688 | 1924 | |
| 1689 | | ///\e |
| | 1925 | /// \see VarStatus |
| | 1926 | VarStatus rowStatus(Row r) const { return _getRowStatus(rows(id(r))); } |
| | 1927 | |
| | 1928 | ///The value of the objective function |
| 1690 | 1929 | |
| 1691 | 1930 | ///\return |
| 1692 | 1931 | ///- \ref INF or -\ref INF means either infeasibility or unboundedness |
| … |
… |
|
| 1709 | 1948 | /// \ingroup lp_group |
| 1710 | 1949 | /// |
| 1711 | 1950 | /// \brief Common base class for MIP solvers |
| 1712 | | /// \todo Much more docs |
| | 1951 | /// |
| | 1952 | /// This class is an abstract base class for MIP solvers. This class |
| | 1953 | /// provides a full interface for set and modify an MIP problem, |
| | 1954 | /// solve it and retrieve the solution. You can use one of the |
| | 1955 | /// descendants as a concrete implementation, or the \c Lp |
| | 1956 | /// default MIP solver. However, if you would like to handle MIP |
| | 1957 | /// solvers as reference or pointer in a generic way, you can use |
| | 1958 | /// this class directly. |
| 1713 | 1959 | class MipSolver : virtual public LpBase { |
| 1714 | 1960 | public: |
| 1715 | 1961 | |
| 1716 | | ///\e |
| | 1962 | /// The problem types for MIP problems |
| 1717 | 1963 | enum ProblemType { |
| 1718 | 1964 | ///Feasible solution hasn't been found (but may exist). |
| 1719 | 1965 | UNDEFINED = 0, |
| … |
… |
|
| 1733 | 1979 | |
| 1734 | 1980 | ///@{ |
| 1735 | 1981 | |
| 1736 | | ///\e Solve the MIP problem at hand |
| | 1982 | /// Solve the MIP problem at hand |
| 1737 | 1983 | /// |
| 1738 | 1984 | ///\return The result of the optimization procedure. Possible |
| 1739 | 1985 | ///values and their meanings can be found in the documentation of |
| 1740 | 1986 | ///\ref SolveExitStatus. |
| 1741 | | /// |
| 1742 | | ///\todo Which method is used to solve the problem |
| 1743 | 1987 | SolveExitStatus solve() { return _solve(); } |
| 1744 | 1988 | |
| 1745 | 1989 | ///@} |
| … |
… |
|
| 1756 | 2000 | }; |
| 1757 | 2001 | |
| 1758 | 2002 | ///Sets the type of the given column to the given type |
| | 2003 | |
| | 2004 | ///Sets the type of the given column to the given type. |
| 1759 | 2005 | /// |
| 1760 | | ///Sets the type of the given column to the given type. |
| 1761 | 2006 | void colType(Col c, ColTypes col_type) { |
| 1762 | 2007 | _setColType(cols(id(c)),col_type); |
| 1763 | 2008 | } |
| 1764 | 2009 | |
| 1765 | 2010 | ///Gives back the type of the column. |
| | 2011 | |
| | 2012 | ///Gives back the type of the column. |
| 1766 | 2013 | /// |
| 1767 | | ///Gives back the type of the column. |
| 1768 | 2014 | ColTypes colType(Col c) const { |
| 1769 | 2015 | return _getColType(cols(id(c))); |
| 1770 | | } |
| 1771 | | |
| 1772 | | ///Sets the type of the given Col to integer. |
| 1773 | | /// |
| 1774 | | ///Sets the type of the given Col to integer. |
| 1775 | | void integer(Col c) { |
| 1776 | | colType(c, INTEGER); |
| 1777 | | } |
| 1778 | | |
| 1779 | | ///Gives back whether the type of the column is integer or not. |
| 1780 | | /// |
| 1781 | | ///Gives back the type of the column. |
| 1782 | | ///\return true if the column has integer type and false if not. |
| 1783 | | bool integer(Col c) const { |
| 1784 | | return (colType(c) == INTEGER); |
| 1785 | | } |
| 1786 | | |
| 1787 | | ///Sets the type of the given Col to continuous. |
| 1788 | | /// |
| 1789 | | ///Sets the type of the given Col to continuous. |
| 1790 | | void real(Col c) { |
| 1791 | | colType(c, REAL); |
| 1792 | | } |
| 1793 | | |
| 1794 | | ///Gives back whether the type of the column is continuous or not. |
| 1795 | | /// |
| 1796 | | ///Gives back the type of the column. |
| 1797 | | ///\return true if the column has continuous type and false if not. |
| 1798 | | bool real(Col c) const { |
| 1799 | | return (colType(c) == REAL); |
| 1800 | 2016 | } |
| 1801 | 2017 | ///@} |
| 1802 | 2018 | |
| … |
… |
|
| 1809 | 2025 | return _getType(); |
| 1810 | 2026 | } |
| 1811 | 2027 | |
| 1812 | | ///\e |
| | 2028 | /// Return the value of the row in the solution |
| | 2029 | |
| | 2030 | /// Return the value of the row in the solution. |
| | 2031 | /// \pre The problem is solved. |
| 1813 | 2032 | Value sol(Col c) const { return _getSol(cols(id(c))); } |
| 1814 | | ///\e |
| | 2033 | |
| | 2034 | /// Return the value of the expression in the solution |
| | 2035 | |
| | 2036 | /// Return the value of the expression in the solution, i.e. the |
| | 2037 | /// dot product of the solution and the expression. |
| | 2038 | /// \pre The problem is solved. |
| 1815 | 2039 | Value sol(const Expr& e) const { |
| 1816 | 2040 | double res = *e; |
| 1817 | 2041 | for (Expr::ConstCoeffIt c(e); c != INVALID; ++c) { |
| … |
… |
|
| 1819 | 2043 | } |
| 1820 | 2044 | return res; |
| 1821 | 2045 | } |
| | 2046 | ///The value of the objective function |
| | 2047 | |
| 1822 | 2048 | ///\return |
| 1823 | 2049 | ///- \ref INF or -\ref INF means either infeasibility or unboundedness |
| 1824 | 2050 | /// of the problem, depending on whether we minimize or maximize. |
diff -r 9347462c3106 -r 473d56c5aec8 lemon/lp_clp.cc
|
a
|
b
|
|
| 91 | 91 | |
| 92 | 92 | void LpClp::_eraseColId(int i) { |
| 93 | 93 | cols.eraseIndex(i); |
| 94 | | cols.shiftIndexes(i); |
| | 94 | cols.shiftIndices(i); |
| 95 | 95 | } |
| 96 | 96 | |
| 97 | 97 | void LpClp::_eraseRowId(int i) { |
| 98 | 98 | rows.eraseIndex(i); |
| 99 | | rows.shiftIndexes(i); |
| | 99 | rows.shiftIndices(i); |
| 100 | 100 | } |
| 101 | 101 | |
| 102 | 102 | void LpClp::_getColName(int c, std::string& name) const { |
diff -r 9347462c3106 -r 473d56c5aec8 lemon/lp_cplex.cc
|
a
|
b
|
|
| 119 | 119 | |
| 120 | 120 | void CplexBase::_eraseColId(int i) { |
| 121 | 121 | cols.eraseIndex(i); |
| 122 | | cols.shiftIndexes(i); |
| | 122 | cols.shiftIndices(i); |
| 123 | 123 | } |
| 124 | 124 | void CplexBase::_eraseRowId(int i) { |
| 125 | 125 | rows.eraseIndex(i); |
| 126 | | rows.shiftIndexes(i); |
| | 126 | rows.shiftIndices(i); |
| 127 | 127 | } |
| 128 | 128 | |
| 129 | 129 | void CplexBase::_getColName(int col, std::string &name) const { |
| … |
… |
|
| 395 | 395 | } |
| 396 | 396 | } |
| 397 | 397 | |
| 398 | | void CplexBase::_setObjCoeff(int i, CplexBase::Value obj_coef) |
| | 398 | void CplexBase::_setObjCoeff(int i, Value obj_coef) |
| 399 | 399 | { |
| 400 | 400 | CPXchgobj(cplexEnv(), _prob, 1, &i, &obj_coef); |
| 401 | 401 | } |
diff -r 9347462c3106 -r 473d56c5aec8 lemon/lp_glpk.cc
|
a
|
b
|
|
| 71 | 71 | |
| 72 | 72 | void GlpkBase::_eraseColId(int i) { |
| 73 | 73 | cols.eraseIndex(i); |
| 74 | | cols.shiftIndexes(i); |
| | 74 | cols.shiftIndices(i); |
| 75 | 75 | } |
| 76 | 76 | |
| 77 | 77 | void GlpkBase::_eraseRowId(int i) { |
| 78 | 78 | rows.eraseIndex(i); |
| 79 | | rows.shiftIndexes(i); |
| | 79 | rows.shiftIndices(i); |
| 80 | 80 | } |
| 81 | 81 | |
| 82 | 82 | void GlpkBase::_getColName(int c, std::string& name) const { |