marci@1031: // -*- c++ -*- marci@1031: #ifndef LEMON_LP_SOLVER_WRAPPER_H marci@1031: #define LEMON_LP_SOLVER_WRAPPER_H marci@1031: marci@1031: ///\ingroup misc marci@1031: ///\file marci@1031: ///\brief Dijkstra algorithm. marci@1031: marci@1031: // #include marci@1031: #include marci@1097: #include marci@1097: #include marci@1031: // #include marci@1031: //#include marci@1031: extern "C" { marci@1031: #include "glpk.h" marci@1031: } marci@1031: marci@1031: #include marci@1031: #include marci@1031: #include marci@1031: #include marci@1031: #include marci@1031: #include marci@1031: marci@1031: //#include marci@1031: //#include marci@1031: //#include marci@1031: #include marci@1031: //#include marci@1031: //#include marci@1031: //#include marci@1031: //#include marci@1031: //#include marci@1031: marci@1031: using std::cout; marci@1031: using std::cin; marci@1031: using std::endl; marci@1031: marci@1031: namespace lemon { marci@1031: marci@1031: /// \addtogroup misc marci@1031: /// @{ marci@1031: marci@1031: /// \brief A partitioned vector with iterable classes. marci@1031: /// marci@1031: /// This class implements a container in which the data is stored in an marci@1031: /// stl vector, the range is partitioned into sets and each set is marci@1031: /// doubly linked in a list. marci@1031: /// That is, each class is iterable by lemon iterators, and any member of marci@1031: /// the vector can bo moved to an other class. marci@1031: template marci@1031: class IterablePartition { marci@1031: protected: marci@1031: struct Node { marci@1031: T data; marci@1031: int prev; //invalid az -1 marci@1031: int next; marci@1031: }; marci@1031: std::vector nodes; marci@1031: struct Tip { marci@1031: int first; marci@1031: int last; marci@1031: }; marci@1031: std::vector tips; marci@1031: public: marci@1031: /// The classes are indexed by integers from \c 0 to \c classNum()-1. marci@1031: int classNum() const { return tips.size(); } marci@1031: /// This lemon style iterator iterates through a class. marci@1031: class ClassIt; marci@1031: /// Constructor. The number of classes is to be given which is fixed marci@1031: /// over the life of the container. marci@1031: /// The partition classes are indexed from 0 to class_num-1. marci@1031: IterablePartition(int class_num) { marci@1031: for (int i=0; i marci@1097: class Expr; marci@1097: marci@1097: template marci@1097: class SmallExpr { marci@1097: template marci@1097: friend class Expr; marci@1097: protected: marci@1097: _Col col; marci@1097: _Value value; marci@1097: public: marci@1097: SmallExpr(_Col _col) : col(_col), value(1) { marci@1097: } marci@1097: SmallExpr& operator *= (_Value _value) { marci@1097: value*=_value; marci@1097: return *this; marci@1097: } marci@1097: // template marci@1097: // friend SmallExpr<_C, _V> operator* (_V _value, marci@1097: // const SmallExpr<_C, _V>& expr); marci@1097: template marci@1097: friend std::ostream& operator<<(std::ostream& os, marci@1097: const SmallExpr<_C, _V>& expr); marci@1097: }; marci@1097: marci@1097: template marci@1097: SmallExpr<_Col, _Value> marci@1097: operator* (_Value value, marci@1097: const SmallExpr<_Col, _Value>& expr) { marci@1097: SmallExpr<_Col, _Value> tmp; marci@1097: tmp=expr; marci@1097: tmp*=value; marci@1097: return tmp; marci@1097: } marci@1097: marci@1097: template marci@1097: std::ostream& operator<<(std::ostream& os, marci@1097: const SmallExpr<_Col, _Value>& expr) { marci@1097: os << expr.value << "*" << expr.col; marci@1097: return os; marci@1097: } marci@1097: marci@1097: template marci@1097: class Expr { marci@1097: protected: marci@1097: typedef marci@1097: typename std::map<_Col, _Value> Data; marci@1097: Data data; marci@1097: public: marci@1097: Expr() { } marci@1097: Expr(SmallExpr<_Col, _Value> expr) { marci@1097: data.insert(std::make_pair(expr.col, expr.value)); marci@1097: } marci@1097: // Expr(_Col col) { marci@1097: // data.insert(std::make_pair(col, 1)); marci@1097: // } marci@1097: Expr& operator*=(_Value _value) { marci@1097: for (typename Data::iterator i=data.begin(); marci@1097: i!=data.end(); ++i) { marci@1097: (*i).second *= _value; marci@1097: } marci@1097: return *this; marci@1097: } marci@1097: Expr& operator+=(SmallExpr<_Col, _Value> expr) { marci@1097: typename Data::iterator i=data.find(expr.col); marci@1097: if (i==data.end()) { marci@1097: data.insert(std::make_pair(expr.col, expr.value)); marci@1097: } else { marci@1097: (*i).second+=expr.value; marci@1097: } marci@1097: return *this; marci@1097: } marci@1097: // template marci@1097: // friend Expr<_C, _V> operator*(_V _value, const Expr<_C, _V>& expr); marci@1097: template marci@1097: friend std::ostream& operator<<(std::ostream& os, marci@1097: const Expr<_C, _V>& expr); marci@1097: }; marci@1097: marci@1097: template marci@1097: Expr<_Col, _Value> operator*(_Value _value, marci@1097: const Expr<_Col, _Value>& expr) { marci@1097: Expr<_Col, _Value> tmp; marci@1097: tmp=expr; marci@1097: tmp*=_value; marci@1097: return tmp; marci@1097: } marci@1097: marci@1097: template marci@1097: std::ostream& operator<<(std::ostream& os, marci@1097: const Expr<_Col, _Value>& expr) { marci@1097: for (typename Expr<_Col, _Value>::Data::const_iterator i= marci@1097: expr.data.begin(); marci@1097: i!=expr.data.end(); ++i) { marci@1097: os << (*i).second << "*" << (*i).first << " "; marci@1097: } marci@1097: return os; marci@1097: } marci@1097: marci@1031: /*! \e marci@1031: */ marci@1048: template marci@1031: class LPSolverBase { marci@1031: public: marci@1031: /// \e marci@1048: typedef _Value Value; marci@1048: /// \e marci@1031: typedef IterablePartition::ClassIt RowIt; marci@1031: /// \e marci@1031: typedef IterablePartition::ClassIt ColIt; marci@1074: public: marci@1031: /// \e marci@1031: IterablePartition row_iter_map; marci@1031: /// \e marci@1031: IterablePartition col_iter_map; marci@1031: /// \e marci@1074: const int VALID_CLASS; marci@1031: /// \e marci@1074: const int INVALID_CLASS; marci@1031: public: marci@1031: /// \e marci@1031: LPSolverBase() : row_iter_map(2), marci@1031: col_iter_map(2), marci@1074: VALID_CLASS(0), INVALID_CLASS(1) { } marci@1031: /// \e marci@1031: virtual ~LPSolverBase() { } marci@1081: marci@1081: //MATRIX INDEPEDENT MANIPULATING FUNCTIONS marci@1081: marci@1081: public: marci@1031: /// \e marci@1031: virtual void setMinimize() = 0; marci@1031: /// \e marci@1031: virtual void setMaximize() = 0; marci@1081: marci@1081: //LOW LEVEL INTERFACE, MATRIX MANIPULATING FUNCTIONS marci@1081: marci@1074: protected: marci@1031: /// \e marci@1074: virtual int _addRow() = 0; marci@1031: /// \e marci@1074: virtual int _addCol() = 0; marci@1081: /// \e marci@1081: virtual void _setRowCoeffs(int i, marci@1081: std::vector > coeffs) = 0; marci@1081: /// \e marci@1081: virtual void _setColCoeffs(int i, marci@1081: std::vector > coeffs) = 0; marci@1081: /// \e marci@1081: virtual void _eraseCol(int i) = 0; marci@1081: /// \e marci@1081: virtual void _eraseRow(int i) = 0; marci@1081: public: marci@1081: /// \e marci@1081: enum Bound { FREE, LOWER, UPPER, DOUBLE, FIXED }; marci@1081: protected: marci@1081: /// \e marci@1081: virtual void _setColBounds(int i, Bound bound, marci@1081: _Value lo, _Value up) = 0; marci@1081: /// \e marci@1081: virtual void _setRowBounds(int i, Bound bound, marci@1081: _Value lo, _Value up) = 0; marci@1081: /// \e marci@1081: virtual void _setObjCoef(int i, _Value obj_coef) = 0; marci@1081: /// \e marci@1081: virtual _Value _getObjCoef(int i) = 0; marci@1081: marci@1081: //LOW LEVEL, SOLUTION RETRIEVING FUNCTIONS marci@1081: marci@1081: protected: marci@1081: virtual _Value _getPrimal(int i) = 0; marci@1081: marci@1081: //HIGH LEVEL INTERFACE, MATRIX MANIPULATING FUNTIONS marci@1081: marci@1074: public: marci@1074: /// \e marci@1074: RowIt addRow() { marci@1074: int i=_addRow(); marci@1074: RowIt row_it; marci@1074: row_iter_map.first(row_it, INVALID_CLASS); marci@1074: if (row_iter_map.valid(row_it)) { //van hasznalhato hely marci@1074: row_iter_map.set(row_it, INVALID_CLASS, VALID_CLASS); marci@1074: row_iter_map[row_it]=i; marci@1074: } else { //a cucc vegere kell inzertalni mert nincs szabad hely marci@1074: row_it=row_iter_map.push_back(i, VALID_CLASS); marci@1074: } marci@1074: return row_it; marci@1074: } marci@1074: /// \e marci@1074: ColIt addCol() { marci@1074: int i=_addCol(); marci@1074: ColIt col_it; marci@1074: col_iter_map.first(col_it, INVALID_CLASS); marci@1074: if (col_iter_map.valid(col_it)) { //van hasznalhato hely marci@1074: col_iter_map.set(col_it, INVALID_CLASS, VALID_CLASS); marci@1074: col_iter_map[col_it]=i; marci@1074: } else { //a cucc vegere kell inzertalni mert nincs szabad hely marci@1074: col_it=col_iter_map.push_back(i, VALID_CLASS); marci@1074: } marci@1074: return col_it; marci@1074: } marci@1074: /// \e marci@1031: template marci@1031: void setRowCoeffs(RowIt row_it, Begin begin, End end) { marci@1074: std::vector > coeffs; marci@1031: for ( ; begin!=end; ++begin) { marci@1074: coeffs.push_back(std:: marci@1074: make_pair(col_iter_map[begin->first], begin->second)); marci@1031: } marci@1081: _setRowCoeffs(row_iter_map[row_it], coeffs); marci@1031: } marci@1031: /// \e marci@1031: template marci@1031: void setColCoeffs(ColIt col_it, Begin begin, End end) { marci@1074: std::vector > coeffs; marci@1031: for ( ; begin!=end; ++begin) { marci@1074: coeffs.push_back(std:: marci@1074: make_pair(row_iter_map[begin->first], begin->second)); marci@1031: } marci@1081: _setColCoeffs(col_iter_map[col_it], coeffs); marci@1074: } marci@1074: /// \e marci@1074: void eraseCol(const ColIt& col_it) { marci@1074: col_iter_map.set(col_it, VALID_CLASS, INVALID_CLASS); marci@1074: int cols[2]; marci@1074: cols[1]=col_iter_map[col_it]; marci@1074: _eraseCol(cols[1]); marci@1074: col_iter_map[col_it]=0; //glpk specifikus, de kell ez?? marci@1074: ColIt it; marci@1074: for (col_iter_map.first(it, VALID_CLASS); marci@1074: col_iter_map.valid(it); col_iter_map.next(it)) { marci@1074: if (col_iter_map[it]>cols[1]) --col_iter_map[it]; marci@1074: } marci@1031: } marci@1031: /// \e marci@1074: void eraseRow(const RowIt& row_it) { marci@1074: row_iter_map.set(row_it, VALID_CLASS, INVALID_CLASS); marci@1074: int rows[2]; marci@1074: rows[1]=row_iter_map[row_it]; marci@1074: _eraseRow(rows[1]); marci@1074: row_iter_map[row_it]=0; //glpk specifikus, de kell ez?? marci@1074: RowIt it; marci@1074: for (row_iter_map.first(it, VALID_CLASS); marci@1074: row_iter_map.valid(it); row_iter_map.next(it)) { marci@1074: if (row_iter_map[it]>rows[1]) --row_iter_map[it]; marci@1074: } marci@1074: } marci@1031: /// \e marci@1081: void setColBounds(const ColIt& col_it, Bound bound, marci@1081: _Value lo, _Value up) { marci@1081: _setColBounds(col_iter_map[col_it], bound, lo, up); marci@1081: } marci@1031: /// \e marci@1081: void setRowBounds(const RowIt& row_it, Bound bound, marci@1081: _Value lo, _Value up) { marci@1081: _setRowBounds(row_iter_map[row_it], bound, lo, up); marci@1081: } marci@1031: /// \e marci@1081: void setObjCoef(const ColIt& col_it, _Value obj_coef) { marci@1081: _setObjCoef(col_iter_map[col_it], obj_coef); marci@1081: } marci@1031: /// \e marci@1081: _Value getObjCoef(const ColIt& col_it) { marci@1081: return _getObjCoef(col_iter_map[col_it]); marci@1081: } marci@1081: marci@1081: //SOLVER FUNCTIONS marci@1081: marci@1031: /// \e marci@1031: virtual void solveSimplex() = 0; marci@1031: /// \e marci@1031: virtual void solvePrimalSimplex() = 0; marci@1031: /// \e marci@1031: virtual void solveDualSimplex() = 0; marci@1031: /// \e marci@1081: marci@1081: //HIGH LEVEL, SOLUTION RETRIEVING FUNCTIONS marci@1081: marci@1081: public: marci@1081: _Value getPrimal(const ColIt& col_it) { marci@1081: return _getPrimal(col_iter_map[col_it]); marci@1081: } marci@1031: /// \e marci@1048: virtual _Value getObjVal() = 0; marci@1081: marci@1081: //OTHER FUNCTIONS marci@1081: marci@1031: /// \e marci@1031: virtual int rowNum() const = 0; marci@1031: /// \e marci@1031: virtual int colNum() const = 0; marci@1031: /// \e marci@1031: virtual int warmUp() = 0; marci@1031: /// \e marci@1031: virtual void printWarmUpStatus(int i) = 0; marci@1031: /// \e marci@1031: virtual int getPrimalStatus() = 0; marci@1031: /// \e marci@1031: virtual void printPrimalStatus(int i) = 0; marci@1031: /// \e marci@1031: virtual int getDualStatus() = 0; marci@1031: /// \e marci@1031: virtual void printDualStatus(int i) = 0; marci@1031: /// Returns the status of the slack variable assigned to row \c row_it. marci@1031: virtual int getRowStat(const RowIt& row_it) = 0; marci@1031: /// \e marci@1031: virtual void printRowStatus(int i) = 0; marci@1031: /// Returns the status of the variable assigned to column \c col_it. marci@1031: virtual int getColStat(const ColIt& col_it) = 0; marci@1031: /// \e marci@1031: virtual void printColStatus(int i) = 0; marci@1031: }; marci@1031: marci@1048: marci@1031: /// \brief Wrappers for LP solvers marci@1031: /// marci@1031: /// This class implements a lemon wrapper for glpk. marci@1031: /// Later other LP-solvers will be wrapped into lemon. marci@1031: /// The aim of this class is to give a general surface to different marci@1031: /// solvers, i.e. it makes possible to write algorithms using LP's, marci@1031: /// in which the solver can be changed to an other one easily. marci@1081: class LPGLPK : public LPSolverBase { marci@1031: public: marci@1048: typedef LPSolverBase Parent; marci@1031: marci@1031: public: marci@1031: /// \e marci@1031: LPX* lp; marci@1031: marci@1031: public: marci@1031: /// \e marci@1081: LPGLPK() : Parent(), marci@1031: lp(lpx_create_prob()) { marci@1031: lpx_set_int_parm(lp, LPX_K_DUAL, 1); marci@1031: } marci@1031: /// \e marci@1081: ~LPGLPK() { marci@1031: lpx_delete_prob(lp); marci@1031: } marci@1081: marci@1081: //MATRIX INDEPEDENT MANIPULATING FUNCTIONS marci@1081: marci@1031: /// \e marci@1031: void setMinimize() { marci@1031: lpx_set_obj_dir(lp, LPX_MIN); marci@1031: } marci@1031: /// \e marci@1031: void setMaximize() { marci@1031: lpx_set_obj_dir(lp, LPX_MAX); marci@1031: } marci@1081: marci@1081: //LOW LEVEL INTERFACE, MATRIX MANIPULATING FUNCTIONS marci@1081: marci@1074: protected: marci@1031: /// \e marci@1074: int _addCol() { marci@1074: return lpx_add_cols(lp, 1); marci@1031: } marci@1031: /// \e marci@1074: int _addRow() { marci@1074: return lpx_add_rows(lp, 1); marci@1074: } marci@1074: /// \e marci@1081: virtual void _setRowCoeffs(int i, marci@1081: std::vector > coeffs) { marci@1074: int mem_length=1+colNum(); marci@1074: int* indices = new int[mem_length]; marci@1074: double* doubles = new double[mem_length]; marci@1074: int length=0; marci@1074: for (std::vector >:: marci@1074: const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) { marci@1074: ++length; marci@1074: indices[length]=it->first; marci@1074: doubles[length]=it->second; marci@1081: // std::cout << " " << indices[length] << " " marci@1081: // << doubles[length] << std::endl; marci@1031: } marci@1081: // std::cout << i << " " << length << std::endl; marci@1074: lpx_set_mat_row(lp, i, length, indices, doubles); marci@1074: delete [] indices; marci@1074: delete [] doubles; marci@1031: } marci@1074: /// \e marci@1081: virtual void _setColCoeffs(int i, marci@1081: std::vector > coeffs) { marci@1074: int mem_length=1+rowNum(); marci@1074: int* indices = new int[mem_length]; marci@1074: double* doubles = new double[mem_length]; marci@1074: int length=0; marci@1074: for (std::vector >:: marci@1074: const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) { marci@1074: ++length; marci@1074: indices[length]=it->first; marci@1074: doubles[length]=it->second; marci@1074: } marci@1074: lpx_set_mat_col(lp, i, length, indices, doubles); marci@1074: delete [] indices; marci@1074: delete [] doubles; marci@1031: } marci@1031: /// \e marci@1074: virtual void _eraseCol(int i) { marci@1031: int cols[2]; marci@1074: cols[1]=i; marci@1031: lpx_del_cols(lp, 1, cols); marci@1031: } marci@1074: virtual void _eraseRow(int i) { marci@1031: int rows[2]; marci@1074: rows[1]=i; marci@1031: lpx_del_rows(lp, 1, rows); marci@1031: } marci@1081: virtual void _setColBounds(int i, Bound bound, marci@1081: double lo, double up) { marci@1081: switch (bound) { marci@1081: case FREE: marci@1081: lpx_set_col_bnds(lp, i, LPX_FR, lo, up); marci@1081: break; marci@1081: case LOWER: marci@1081: lpx_set_col_bnds(lp, i, LPX_LO, lo, up); marci@1081: break; marci@1081: case UPPER: marci@1081: lpx_set_col_bnds(lp, i, LPX_UP, lo, up); marci@1081: break; marci@1081: case DOUBLE: marci@1081: lpx_set_col_bnds(lp, i, LPX_DB, lo, up); marci@1081: break; marci@1081: case FIXED: marci@1081: lpx_set_col_bnds(lp, i, LPX_FX, lo, up); marci@1081: break; marci@1081: } marci@1081: } marci@1081: virtual void _setRowBounds(int i, Bound bound, marci@1081: double lo, double up) { marci@1081: switch (bound) { marci@1081: case FREE: marci@1081: lpx_set_row_bnds(lp, i, LPX_FR, lo, up); marci@1081: break; marci@1081: case LOWER: marci@1081: lpx_set_row_bnds(lp, i, LPX_LO, lo, up); marci@1081: break; marci@1081: case UPPER: marci@1081: lpx_set_row_bnds(lp, i, LPX_UP, lo, up); marci@1081: break; marci@1081: case DOUBLE: marci@1081: lpx_set_row_bnds(lp, i, LPX_DB, lo, up); marci@1081: break; marci@1081: case FIXED: marci@1081: lpx_set_row_bnds(lp, i, LPX_FX, lo, up); marci@1081: break; marci@1081: } marci@1081: } marci@1081: protected: marci@1031: /// \e marci@1081: virtual double _getObjCoef(int i) { marci@1081: return lpx_get_obj_coef(lp, i); marci@1031: } marci@1031: /// \e marci@1081: virtual void _setObjCoef(int i, double obj_coef) { marci@1081: lpx_set_obj_coef(lp, i, obj_coef); marci@1031: } marci@1081: public: marci@1031: /// \e marci@1031: void solveSimplex() { lpx_simplex(lp); } marci@1031: /// \e marci@1031: void solvePrimalSimplex() { lpx_simplex(lp); } marci@1031: /// \e marci@1031: void solveDualSimplex() { lpx_simplex(lp); } marci@1031: /// \e marci@1081: protected: marci@1081: virtual double _getPrimal(int i) { marci@1081: return lpx_get_col_prim(lp, i); marci@1031: } marci@1081: public: marci@1031: /// \e marci@1031: double getObjVal() { return lpx_get_obj_val(lp); } marci@1031: /// \e marci@1031: int rowNum() const { return lpx_get_num_rows(lp); } marci@1031: /// \e marci@1031: int colNum() const { return lpx_get_num_cols(lp); } marci@1031: /// \e marci@1031: int warmUp() { return lpx_warm_up(lp); } marci@1031: /// \e marci@1031: void printWarmUpStatus(int i) { marci@1031: switch (i) { marci@1031: case LPX_E_OK: cout << "LPX_E_OK" << endl; break; marci@1031: case LPX_E_EMPTY: cout << "LPX_E_EMPTY" << endl; break; marci@1031: case LPX_E_BADB: cout << "LPX_E_BADB" << endl; break; marci@1031: case LPX_E_SING: cout << "LPX_E_SING" << endl; break; marci@1031: } marci@1031: } marci@1031: /// \e marci@1031: int getPrimalStatus() { return lpx_get_prim_stat(lp); } marci@1031: /// \e marci@1031: void printPrimalStatus(int i) { marci@1031: switch (i) { marci@1031: case LPX_P_UNDEF: cout << "LPX_P_UNDEF" << endl; break; marci@1031: case LPX_P_FEAS: cout << "LPX_P_FEAS" << endl; break; marci@1031: case LPX_P_INFEAS: cout << "LPX_P_INFEAS" << endl; break; marci@1031: case LPX_P_NOFEAS: cout << "LPX_P_NOFEAS" << endl; break; marci@1031: } marci@1031: } marci@1031: /// \e marci@1031: int getDualStatus() { return lpx_get_dual_stat(lp); } marci@1031: /// \e marci@1031: void printDualStatus(int i) { marci@1031: switch (i) { marci@1031: case LPX_D_UNDEF: cout << "LPX_D_UNDEF" << endl; break; marci@1031: case LPX_D_FEAS: cout << "LPX_D_FEAS" << endl; break; marci@1031: case LPX_D_INFEAS: cout << "LPX_D_INFEAS" << endl; break; marci@1031: case LPX_D_NOFEAS: cout << "LPX_D_NOFEAS" << endl; break; marci@1031: } marci@1031: } marci@1031: /// Returns the status of the slack variable assigned to row \c row_it. marci@1031: int getRowStat(const RowIt& row_it) { marci@1031: return lpx_get_row_stat(lp, row_iter_map[row_it]); marci@1031: } marci@1031: /// \e marci@1031: void printRowStatus(int i) { marci@1031: switch (i) { marci@1031: case LPX_BS: cout << "LPX_BS" << endl; break; marci@1031: case LPX_NL: cout << "LPX_NL" << endl; break; marci@1031: case LPX_NU: cout << "LPX_NU" << endl; break; marci@1031: case LPX_NF: cout << "LPX_NF" << endl; break; marci@1031: case LPX_NS: cout << "LPX_NS" << endl; break; marci@1031: } marci@1031: } marci@1031: /// Returns the status of the variable assigned to column \c col_it. marci@1031: int getColStat(const ColIt& col_it) { marci@1031: return lpx_get_col_stat(lp, col_iter_map[col_it]); marci@1031: } marci@1031: /// \e marci@1031: void printColStatus(int i) { marci@1031: switch (i) { marci@1031: case LPX_BS: cout << "LPX_BS" << endl; break; marci@1031: case LPX_NL: cout << "LPX_NL" << endl; break; marci@1031: case LPX_NU: cout << "LPX_NU" << endl; break; marci@1031: case LPX_NF: cout << "LPX_NF" << endl; break; marci@1031: case LPX_NS: cout << "LPX_NS" << endl; break; marci@1031: } marci@1031: } marci@1031: }; marci@1031: marci@1031: /// @} marci@1031: marci@1031: } //namespace lemon marci@1031: marci@1031: #endif //LEMON_LP_SOLVER_WRAPPER_H