A year has passed again.
2 #ifndef LEMON_LP_SOLVER_BASE_H
3 #define LEMON_LP_SOLVER_BASE_H
26 #include <lemon/invalid.h>
27 #include <expression.h>
29 //#include <lemon/max_flow.h>
30 //#include <augmenting_flow.h>
31 //#include <iter_map.h>
42 /// \brief A partitioned vector with iterable classes.
44 /// This class implements a container in which the data is stored in an
45 /// stl vector, the range is partitioned into sets and each set is
46 /// doubly linked in a list.
47 /// That is, each class is iterable by lemon iterators, and any member of
48 /// the vector can bo moved to an other class.
50 class IterablePartition {
54 int prev; //invalid az -1
57 std::vector<Node> nodes;
62 std::vector<Tip> tips;
64 /// The classes are indexed by integers from \c 0 to \c classNum()-1.
65 int classNum() const { return tips.size(); }
66 /// This lemon style iterator iterates through a class.
68 /// Constructor. The number of classes is to be given which is fixed
69 /// over the life of the container.
70 /// The partition classes are indexed from 0 to class_num-1.
71 IterablePartition(int class_num) {
72 for (int i=0; i<class_num; ++i) {
79 void befuz(Class it, int class_id) {
80 if (tips[class_id].first==-1) {
81 if (tips[class_id].last==-1) {
82 nodes[it.i].prev=nodes[it.i].next=-1;
83 tips[class_id].first=tips[class_id].last=it.i;
86 nodes[it.i].prev=tips[class_id].last;
88 nodes[tips[class_id].last].next=it.i;
89 tips[class_id].last=it.i;
92 void kifuz(Class it, int class_id) {
93 if (tips[class_id].first==it.i) {
94 if (tips[class_id].last==it.i) {
95 tips[class_id].first=tips[class_id].last=-1;
97 tips[class_id].first=nodes[it.i].next;
98 nodes[nodes[it.i].next].prev=-1;
101 if (tips[class_id].last==it.i) {
102 tips[class_id].last=nodes[it.i].prev;
103 nodes[nodes[it.i].prev].next=-1;
105 nodes[nodes[it.i].next].prev=nodes[it.i].prev;
106 nodes[nodes[it.i].prev].next=nodes[it.i].next;
111 /// A new element with data \c t is pushed into the vector and into class
113 Class push_back(const T& t, int class_id) {
117 int i=nodes.size()-1;
121 /// A member is moved to an other class.
122 void set(Class it, int old_class_id, int new_class_id) {
123 kifuz(it.i, old_class_id);
124 befuz(it.i, new_class_id);
126 /// Returns the data pointed by \c it.
127 T& operator[](Class it) { return nodes[it.i].data; }
128 /// Returns the data pointed by \c it.
129 const T& operator[](Class it) const { return nodes[it.i].data; }
132 friend class IterablePartition;
136 /// Default constructor.
138 /// This constructor constructs an iterator which points
139 /// to the member of th container indexed by the integer _i.
140 Class(const int& _i) : i(_i) { }
141 /// Invalid constructor.
142 Class(const Invalid&) : i(-1) { }
143 friend bool operator<(const Class& x, const Class& y);
144 friend std::ostream& operator<<(std::ostream& os,
146 bool operator==(const Class& node) const {return i == node.i;}
147 bool operator!=(const Class& node) const {return i != node.i;}
149 friend bool operator<(const Class& x, const Class& y) {
152 friend std::ostream& operator<<(std::ostream& os,
157 /// First member of class \c class_id.
158 Class& first(Class& it, int class_id) const {
159 it.i=tips[class_id].first;
163 Class& next(Class& it) const {
164 it.i=nodes[it.i].next;
167 /// True iff the iterator is valid.
168 bool valid(const Class& it) const { return it.i!=-1; }
170 class ClassIt : public Class {
171 const IterablePartition* iterable_partition;
174 ClassIt(Invalid i) : Class(i) { }
175 ClassIt(const IterablePartition& _iterable_partition,
176 const int& i) : iterable_partition(&_iterable_partition) {
177 _iterable_partition.first(*this, i);
179 ClassIt(const IterablePartition& _iterable_partition,
180 const Class& _class) :
181 Class(_class), iterable_partition(&_iterable_partition) { }
182 ClassIt& operator++() {
183 iterable_partition->next(*this);
192 \todo kellenene uj iterable structure bele, mert ez nem az igazi
193 \todo A[x,y]-t cserel. Jobboldal, baloldal csere.
194 \todo LEKERDEZESEK!!!
195 \todo DOKSI!!!! Doxygen group!!!
196 The aim of this class is to give a general surface to different
197 solvers, i.e. it makes possible to write algorithms using LP's,
198 in which the solver can be changed to an other one easily.
201 template <typename _Value>
204 /*! @name Uncategorized functions and types (public members)
212 typedef IterablePartition<int> Rows;
214 typedef IterablePartition<int> Cols;
216 typedef _Value Value;
218 typedef Rows::Class Row;
220 typedef Cols::Class Col;
223 IterablePartition<int> row_iter_map;
225 IterablePartition<int> col_iter_map;
227 std::vector<Row> int_row_map;
229 std::vector<Col> int_col_map;
231 const int VALID_CLASS;
233 const int INVALID_CLASS;
235 static const _Value INF;
238 LPSolverBase() : row_iter_map(2),
240 VALID_CLASS(0), INVALID_CLASS(1) { }
242 virtual ~LPSolverBase() { }
245 /*! @name Medium level interface (public members)
246 These functions appear in the low level and also in the high level
247 interfaces thus these each of these functions have to be implemented
248 only once in the different interfaces.
249 This means that these functions have to be reimplemented for all of the
250 different lp solvers. These are basic functions, and have the same
251 parameter lists in the low and high level interfaces.
256 //UNCATEGORIZED FUNCTIONS
259 virtual void setMinimize() = 0;
261 virtual void setMaximize() = 0;
266 virtual void solveSimplex() = 0;
268 virtual void solvePrimalSimplex() = 0;
270 virtual void solveDualSimplex() = 0;
272 //SOLUTION RETRIEVING
275 virtual _Value getObjVal() = 0;
280 virtual int rowNum() const = 0;
282 virtual int colNum() const = 0;
284 virtual int warmUp() = 0;
286 virtual void printWarmUpStatus(int i) = 0;
288 virtual int getPrimalStatus() = 0;
290 virtual void printPrimalStatus(int i) = 0;
292 virtual int getDualStatus() = 0;
294 virtual void printDualStatus(int i) = 0;
295 /// Returns the status of the slack variable assigned to row \c row.
296 virtual int getRowStat(const Row& row) = 0;
298 virtual void printRowStatus(int i) = 0;
299 /// Returns the status of the variable assigned to column \c col.
300 virtual int getColStat(const Col& col) = 0;
302 virtual void printColStatus(int i) = 0;
306 /*! @name Low level interface (protected members)
307 Problem manipulating functions in the low level interface
312 //MATRIX MANIPULATING FUNCTIONS
315 virtual int _addCol() = 0;
317 virtual int _addRow() = 0;
319 virtual void _eraseCol(int i) = 0;
321 virtual void _eraseRow(int i) = 0;
323 virtual void _setRowCoeffs(int i,
324 const std::vector<std::pair<int, _Value> >& coeffs) = 0;
326 /// This routine modifies \c coeffs only by the \c push_back method.
327 virtual void _getRowCoeffs(int i,
328 std::vector<std::pair<int, _Value> >& coeffs) = 0;
330 virtual void _setColCoeffs(int i,
331 const std::vector<std::pair<int, _Value> >& coeffs) = 0;
333 /// This routine modifies \c coeffs only by the \c push_back method.
334 virtual void _getColCoeffs(int i,
335 std::vector<std::pair<int, _Value> >& coeffs) = 0;
337 virtual void _setCoeff(int col, int row, _Value value) = 0;
339 virtual _Value _getCoeff(int col, int row) = 0;
342 // enum Bound { FREE, LOWER, UPPER, DOUBLE, FIXED };
345 /// The lower bound of a variable (column) have to be given by an
346 /// extended number of type _Value, i.e. a finite number of type
348 virtual void _setColLowerBound(int i, _Value value) = 0;
350 /// The lower bound of a variable (column) is an
351 /// extended number of type _Value, i.e. a finite number of type
353 virtual _Value _getColLowerBound(int i) = 0;
355 /// The upper bound of a variable (column) have to be given by an
356 /// extended number of type _Value, i.e. a finite number of type
358 virtual void _setColUpperBound(int i, _Value value) = 0;
360 /// The upper bound of a variable (column) is an
361 /// extended number of type _Value, i.e. a finite number of type
363 virtual _Value _getColUpperBound(int i) = 0;
365 /// The lower bound of a linear expression (row) have to be given by an
366 /// extended number of type _Value, i.e. a finite number of type
368 virtual void _setRowLowerBound(int i, _Value value) = 0;
370 /// The lower bound of a linear expression (row) is an
371 /// extended number of type _Value, i.e. a finite number of type
373 virtual _Value _getRowLowerBound(int i) = 0;
375 /// The upper bound of a linear expression (row) have to be given by an
376 /// extended number of type _Value, i.e. a finite number of type
378 virtual void _setRowUpperBound(int i, _Value value) = 0;
380 /// The upper bound of a linear expression (row) is an
381 /// extended number of type _Value, i.e. a finite number of type
383 virtual _Value _getRowUpperBound(int i) = 0;
385 virtual void _setObjCoeff(int i, _Value obj_coef) = 0;
387 virtual _Value _getObjCoeff(int i) = 0;
389 //SOLUTION RETRIEVING
392 virtual _Value _getPrimal(int i) = 0;
395 /*! @name High level interface (public members)
396 Problem manipulating functions in the high level interface
401 //MATRIX MANIPULATING FUNCTIONS
407 col_iter_map.first(col, INVALID_CLASS);
408 if (col_iter_map.valid(col)) { //van hasznalhato hely
409 col_iter_map.set(col, INVALID_CLASS, VALID_CLASS);
411 } else { //a cucc vegere kell inzertalni mert nincs szabad hely
412 col=col_iter_map.push_back(i, VALID_CLASS);
414 int_col_map.push_back(col);
421 row_iter_map.first(row, INVALID_CLASS);
422 if (row_iter_map.valid(row)) { //van hasznalhato hely
423 row_iter_map.set(row, INVALID_CLASS, VALID_CLASS);
425 } else { //a cucc vegere kell inzertalni mert nincs szabad hely
426 row=row_iter_map.push_back(i, VALID_CLASS);
428 int_row_map.push_back(row);
432 void eraseCol(const Col& col) {
433 col_iter_map.set(col, VALID_CLASS, INVALID_CLASS);
435 cols[1]=col_iter_map[col];
437 col_iter_map[col]=0; //glpk specifikus, de kell ez??
439 for (col_iter_map.first(it, VALID_CLASS);
440 col_iter_map.valid(it); col_iter_map.next(it)) {
441 if (col_iter_map[it]>cols[1]) --col_iter_map[it];
443 int_col_map.erase(int_col_map.begin()+cols[1]);
446 void eraseRow(const Row& row) {
447 row_iter_map.set(row, VALID_CLASS, INVALID_CLASS);
449 rows[1]=row_iter_map[row];
451 row_iter_map[row]=0; //glpk specifikus, de kell ez??
453 for (row_iter_map.first(it, VALID_CLASS);
454 row_iter_map.valid(it); row_iter_map.next(it)) {
455 if (row_iter_map[it]>rows[1]) --row_iter_map[it];
457 int_row_map.erase(int_row_map.begin()+rows[1]);
460 void setCoeff(Col col, Row row, _Value value) {
461 _setCoeff(col_iter_map[col], row_iter_map[row], value);
464 _Value getCoeff(Col col, Row row) {
465 return _getCoeff(col_iter_map[col], row_iter_map[row], value);
468 void setColLowerBound(Col col, _Value lo) {
469 _setColLowerBound(col_iter_map[col], lo);
472 _Value getColLowerBound(Col col) {
473 return _getColLowerBound(col_iter_map[col]);
476 void setColUpperBound(Col col, _Value up) {
477 _setColUpperBound(col_iter_map[col], up);
480 _Value getColUpperBound(Col col) {
481 return _getColUpperBound(col_iter_map[col]);
484 void setRowLowerBound(Row row, _Value lo) {
485 _setRowLowerBound(row_iter_map[row], lo);
488 _Value getRowLowerBound(Row row) {
489 return _getRowLowerBound(row_iter_map[row]);
492 void setRowUpperBound(Row row, _Value up) {
493 _setRowUpperBound(row_iter_map[row], up);
496 _Value getRowUpperBound(Row row) {
497 return _getRowUpperBound(row_iter_map[row]);
500 void setObjCoeff(const Col& col, _Value obj_coef) {
501 _setObjCoeff(col_iter_map[col], obj_coef);
504 _Value getObjCoeff(const Col& col) {
505 return _getObjCoeff(col_iter_map[col]);
508 //SOLUTION RETRIEVING FUNCTIONS
511 _Value getPrimal(const Col& col) {
512 return _getPrimal(col_iter_map[col]);
517 /*! @name User friend interface
518 Problem manipulating functions in the user friend interface
525 typedef Expr<Col, _Value> Expression;
527 typedef Expr<Row, _Value> DualExpression;
529 typedef Constr<Col, _Value> Constraint;
531 //MATRIX MANIPULATING FUNCTIONS
534 void setRowCoeffs(Row row, const Expression& expr) {
535 std::vector<std::pair<int, _Value> > row_coeffs;
536 for(typename Expression::Data::const_iterator i=expr.data.begin();
537 i!=expr.data.end(); ++i) {
538 row_coeffs.push_back(std::make_pair
539 (col_iter_map[(*i).first], (*i).second));
541 _setRowCoeffs(row_iter_map[row], row_coeffs);
544 void setRow(Row row, const Constraint& constr) {
545 setRowCoeffs(row, constr.expr);
546 setRowLowerBound(row, constr.lo);
547 setRowUpperBound(row, constr.up);
550 Row addRow(const Constraint& constr) {
552 setRowCoeffs(row, constr.expr);
553 setRowLowerBound(row, constr.lo);
554 setRowUpperBound(row, constr.up);
558 /// This routine modifies \c expr by only adding to it.
559 void getRowCoeffs(Row row, Expression& expr) {
560 std::vector<std::pair<int, _Value> > row_coeffs;
561 _getRowCoeffs(row_iter_map[row], row_coeffs);
562 for(typename std::vector<std::pair<int, _Value> >::const_iterator
563 i=row_coeffs.begin(); i!=row_coeffs.end(); ++i) {
564 expr+= (*i).second*int_col_map[(*i).first];
568 void setColCoeffs(Col col, const DualExpression& expr) {
569 std::vector<std::pair<int, _Value> > col_coeffs;
570 for(typename DualExpression::Data::const_iterator i=expr.data.begin();
571 i!=expr.data.end(); ++i) {
572 col_coeffs.push_back(std::make_pair
573 (row_iter_map[(*i).first], (*i).second));
575 _setColCoeffs(col_iter_map[col], col_coeffs);
578 /// This routine modifies \c expr by only adding to it.
579 void getColCoeffs(Col col, DualExpression& expr) {
580 std::vector<std::pair<int, _Value> > col_coeffs;
581 _getColCoeffs(col_iter_map[col], col_coeffs);
582 for(typename std::vector<std::pair<int, _Value> >::const_iterator
583 i=col_coeffs.begin(); i!=col_coeffs.end(); ++i) {
584 expr+= (*i).second*int_row_map[(*i).first];
588 void setObjCoeffs(const Expression& expr) {
589 // writing zero everywhere
590 for(Cols::ClassIt it(col_iter_map, VALID_CLASS); it!=INVALID; ++it)
591 setObjCoeff(it, 0.0);
592 // writing the data needed
593 for(typename Expression::Data::const_iterator i=expr.data.begin();
594 i!=expr.data.end(); ++i) {
595 setObjCoeff((*i).first, (*i).second);
599 /// This routine modifies \c expr by only adding to it.
600 void getObjCoeffs(Expression& expr) {
601 for(Cols::ClassIt it(col_iter_map, VALID_CLASS); it!=INVALID; ++it)
602 expr+=getObjCoeff(it)*it;
607 /*! @name MIP functions and types (public members)
612 virtual void solveBandB() = 0;
614 virtual void setLP() = 0;
616 virtual void setMIP() = 0;
619 virtual void _setColCont(int i) = 0;
621 virtual void _setColInt(int i) = 0;
623 virtual _Value _getMIPPrimal(int i) = 0;
626 void setColCont(Col col) {
627 _setColCont(col_iter_map[col]);
630 void setColInt(Col col) {
631 _setColInt(col_iter_map[col]);
634 _Value getMIPPrimal(Col col) {
635 return _getMIPPrimal(col_iter_map[col]);
640 template <typename _Value>
641 const _Value LPSolverBase<_Value>::INF=std::numeric_limits<_Value>::infinity();
644 /// \brief Wrapper for GLPK solver
646 /// This class implements a lemon wrapper for GLPK.
647 class LPGLPK : public LPSolverBase<double> {
649 typedef LPSolverBase<double> Parent;
658 lp(lpx_create_prob()) {
659 int_row_map.push_back(Row());
660 int_col_map.push_back(Col());
661 lpx_set_int_parm(lp, LPX_K_DUAL, 1);
668 //MATRIX INDEPEDENT MANIPULATING FUNCTIONS
672 lpx_set_obj_dir(lp, LPX_MIN);
676 lpx_set_obj_dir(lp, LPX_MAX);
679 //LOW LEVEL INTERFACE, MATRIX MANIPULATING FUNCTIONS
684 int i=lpx_add_cols(lp, 1);
685 _setColLowerBound(i, -INF);
686 _setColUpperBound(i, INF);
691 int i=lpx_add_rows(lp, 1);
695 virtual void _setRowCoeffs(int i,
696 const std::vector<std::pair<int, double> >& coeffs) {
697 int mem_length=1+colNum();
698 int* indices = new int[mem_length];
699 double* doubles = new double[mem_length];
701 for (std::vector<std::pair<int, double> >::
702 const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) {
704 indices[length]=it->first;
705 doubles[length]=it->second;
707 lpx_set_mat_row(lp, i, length, indices, doubles);
712 virtual void _getRowCoeffs(int i,
713 std::vector<std::pair<int, double> >& coeffs) {
714 int mem_length=1+colNum();
715 int* indices = new int[mem_length];
716 double* doubles = new double[mem_length];
717 int length=lpx_get_mat_row(lp, i, indices, doubles);
718 for (int i=1; i<=length; ++i) {
719 coeffs.push_back(std::make_pair(indices[i], doubles[i]));
725 virtual void _setColCoeffs(int i,
726 const std::vector<std::pair<int, double> >& coeffs) {
727 int mem_length=1+rowNum();
728 int* indices = new int[mem_length];
729 double* doubles = new double[mem_length];
731 for (std::vector<std::pair<int, double> >::
732 const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) {
734 indices[length]=it->first;
735 doubles[length]=it->second;
737 lpx_set_mat_col(lp, i, length, indices, doubles);
742 virtual void _getColCoeffs(int i,
743 std::vector<std::pair<int, double> >& coeffs) {
744 int mem_length=1+rowNum();
745 int* indices = new int[mem_length];
746 double* doubles = new double[mem_length];
747 int length=lpx_get_mat_col(lp, i, indices, doubles);
748 for (int i=1; i<=length; ++i) {
749 coeffs.push_back(std::make_pair(indices[i], doubles[i]));
755 virtual void _eraseCol(int i) {
758 lpx_del_cols(lp, 1, cols);
760 virtual void _eraseRow(int i) {
763 lpx_del_rows(lp, 1, rows);
765 void _setCoeff(int col, int row, double value) {
766 /// FIXME not yet implemented
768 double _getCoeff(int col, int row) {
769 /// FIXME not yet implemented
772 virtual void _setColLowerBound(int i, double lo) {
776 int b=lpx_get_col_type(lp, i);
777 double up=lpx_get_col_ub(lp, i);
782 lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
788 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
797 lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
803 lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
805 lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
812 virtual double _getColLowerBound(int i) {
813 int b=lpx_get_col_type(lp, i);
818 return lpx_get_col_lb(lp, i);
823 return lpx_get_col_lb(lp, i);
829 virtual void _setColUpperBound(int i, double up) {
833 int b=lpx_get_col_type(lp, i);
834 double lo=lpx_get_col_lb(lp, i);
841 lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
845 lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
853 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
856 lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
858 lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
861 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
866 lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
868 lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
875 virtual double _getColUpperBound(int i) {
876 int b=lpx_get_col_type(lp, i);
884 return lpx_get_col_ub(lp, i);
890 virtual void _setRowLowerBound(int i, double lo) {
894 int b=lpx_get_row_type(lp, i);
895 double up=lpx_get_row_ub(lp, i);
900 lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
906 lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
915 lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
921 lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
923 lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
930 virtual double _getRowLowerBound(int i) {
931 int b=lpx_get_row_type(lp, i);
936 return lpx_get_row_lb(lp, i);
941 return lpx_get_row_lb(lp, i);
947 virtual void _setRowUpperBound(int i, double up) {
951 int b=lpx_get_row_type(lp, i);
952 double lo=lpx_get_row_lb(lp, i);
959 lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
963 lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
971 lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
974 lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
976 lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
979 lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
984 lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
986 lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
993 virtual double _getRowUpperBound(int i) {
994 int b=lpx_get_row_type(lp, i);
1002 return lpx_get_row_ub(lp, i);
1009 virtual double _getObjCoeff(int i) {
1010 return lpx_get_obj_coef(lp, i);
1013 virtual void _setObjCoeff(int i, double obj_coef) {
1014 lpx_set_obj_coef(lp, i, obj_coef);
1018 void solveSimplex() { lpx_simplex(lp); }
1020 void solvePrimalSimplex() { lpx_simplex(lp); }
1022 void solveDualSimplex() { lpx_simplex(lp); }
1024 virtual double _getPrimal(int i) {
1025 return lpx_get_col_prim(lp, i);
1029 double getObjVal() { return lpx_get_obj_val(lp); }
1031 int rowNum() const { return lpx_get_num_rows(lp); }
1033 int colNum() const { return lpx_get_num_cols(lp); }
1035 int warmUp() { return lpx_warm_up(lp); }
1037 void printWarmUpStatus(int i) {
1039 case LPX_E_OK: cout << "LPX_E_OK" << endl; break;
1040 case LPX_E_EMPTY: cout << "LPX_E_EMPTY" << endl; break;
1041 case LPX_E_BADB: cout << "LPX_E_BADB" << endl; break;
1042 case LPX_E_SING: cout << "LPX_E_SING" << endl; break;
1046 int getPrimalStatus() { return lpx_get_prim_stat(lp); }
1048 void printPrimalStatus(int i) {
1050 case LPX_P_UNDEF: cout << "LPX_P_UNDEF" << endl; break;
1051 case LPX_P_FEAS: cout << "LPX_P_FEAS" << endl; break;
1052 case LPX_P_INFEAS: cout << "LPX_P_INFEAS" << endl; break;
1053 case LPX_P_NOFEAS: cout << "LPX_P_NOFEAS" << endl; break;
1057 int getDualStatus() { return lpx_get_dual_stat(lp); }
1059 void printDualStatus(int i) {
1061 case LPX_D_UNDEF: cout << "LPX_D_UNDEF" << endl; break;
1062 case LPX_D_FEAS: cout << "LPX_D_FEAS" << endl; break;
1063 case LPX_D_INFEAS: cout << "LPX_D_INFEAS" << endl; break;
1064 case LPX_D_NOFEAS: cout << "LPX_D_NOFEAS" << endl; break;
1067 /// Returns the status of the slack variable assigned to row \c row.
1068 int getRowStat(const Row& row) {
1069 return lpx_get_row_stat(lp, row_iter_map[row]);
1072 void printRowStatus(int i) {
1074 case LPX_BS: cout << "LPX_BS" << endl; break;
1075 case LPX_NL: cout << "LPX_NL" << endl; break;
1076 case LPX_NU: cout << "LPX_NU" << endl; break;
1077 case LPX_NF: cout << "LPX_NF" << endl; break;
1078 case LPX_NS: cout << "LPX_NS" << endl; break;
1081 /// Returns the status of the variable assigned to column \c col.
1082 int getColStat(const Col& col) {
1083 return lpx_get_col_stat(lp, col_iter_map[col]);
1086 void printColStatus(int i) {
1088 case LPX_BS: cout << "LPX_BS" << endl; break;
1089 case LPX_NL: cout << "LPX_NL" << endl; break;
1090 case LPX_NU: cout << "LPX_NU" << endl; break;
1091 case LPX_NF: cout << "LPX_NF" << endl; break;
1092 case LPX_NS: cout << "LPX_NS" << endl; break;
1098 void solveBandB() { lpx_integer(lp); }
1100 void setLP() { lpx_set_class(lp, LPX_LP); }
1102 void setMIP() { lpx_set_class(lp, LPX_MIP); }
1105 void _setColCont(int i) { lpx_set_col_kind(lp, i, LPX_CV); }
1107 void _setColInt(int i) { lpx_set_col_kind(lp, i, LPX_IV); }
1109 double _getMIPPrimal(int i) { return lpx_mip_col_val(lp, i); }
1116 #endif //LEMON_LP_SOLVER_BASE_H