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