# HG changeset patch # User marci # Date 1107262410 0 # Node ID 88ade201ffc6a8bbcaffc6241442b7df829fe99d # Parent ba28dfbea5f274c2f67c17ac3d499841d26f74dc lower and upper bound handling functions for rows diff -r ba28dfbea5f2 -r 88ade201ffc6 src/work/marci/lp/lp_solver_base.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/work/marci/lp/lp_solver_base.h Tue Feb 01 12:53:30 2005 +0000 @@ -0,0 +1,918 @@ +// -*- 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 + +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 _addCol() = 0; + /// \e + virtual int _addRow() = 0; + /// \e + virtual void _eraseCol(int i) = 0; + /// \e + virtual void _eraseRow(int i) = 0; + /// \e + virtual void _setRowCoeffs(int i, + const std::vector >& coeffs) = 0; + /// \e + virtual void _setColCoeffs(int i, + const std::vector >& coeffs) = 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 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) 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 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 + /// The lower bound of a linear expression (row) have to be given by an + /// extended number of type _Value, i.e. a finite number of type + /// _Value or -INF. + virtual void _setRowLowerBound(int i, _Value value) = 0; + /// \e + /// The lower bound of a linear expression (row) is an + /// extended number of type _Value, i.e. a finite number of type + /// _Value or -INF. + virtual _Value _getRowLowerBound(int i) = 0; + /// \e + /// The upper bound of a linear expression (row) have to be given by an + /// extended number of type _Value, i.e. a finite number of type + /// _Value or INF. + virtual void _setRowUpperBound(int i, _Value value) = 0; + /// \e + /// The upper bound of a linear expression (row) is an + /// extended number of type _Value, i.e. a finite number of type + /// _Value or INF. + virtual _Value _getRowUpperBound(int i) = 0; + /// \e + virtual void _setObjCoef(int i, _Value obj_coef) = 0; + /// \e + virtual _Value _getObjCoef(int i) = 0; + + //LOW LEVEL, SOLUTION RETRIEVING FUNCTIONS + + protected: + /// \e + virtual _Value _getPrimal(int i) = 0; + + //HIGH LEVEL INTERFACE, MATRIX MANIPULATING FUNTIONS + + public: + /// \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 + 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 + 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 + 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 setColLowerBound(ColIt col_it, _Value lo) { + _setColLowerBound(col_iter_map[col_it], lo); + } + /// \e + _Value getColLowerBound(ColIt col_it) { + return _getColLowerBound(col_iter_map[col_it]); + } + /// \e + void setColUpperBound(ColIt col_it, _Value up) { + _setColUpperBound(col_iter_map[col_it], up); + } + /// \e + _Value getColUpperBound(ColIt col_it) { + return _getColUpperBound(col_iter_map[col_it]); + } + /// \e + void setRowLowerBound(RowIt row_it, _Value lo) { + _setRowLowerBound(row_iter_map[row_it], lo); + } + /// \e + _Value getRowLowerBound(RowIt row_it) { + return _getRowLowerBound(row_iter_map[row_it]); + } + /// \e + void setRowUpperBound(RowIt row_it, _Value up) { + _setRowUpperBound(row_iter_map[row_it], up); + } + /// \e + _Value getRowUpperBound(RowIt row_it) { + return _getRowUpperBound(row_iter_map[row_it]); + } + /// \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: + + /// \e + _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 Wrapper for GLPK solver + /// + /// This class implements a lemon wrapper for GLPK. + 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 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 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 _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 _setRowLowerBound(int i, double lo) { + if (lo==INF) { + //FIXME error + } + int b=lpx_get_row_type(lp, i); + double up=lpx_get_row_ub(lp, i); + if (lo==-INF) { + switch (b) { + case LPX_FR: + case LPX_LO: + lpx_set_row_bnds(lp, i, LPX_FR, lo, up); + break; + case LPX_UP: + break; + case LPX_DB: + case LPX_FX: + lpx_set_row_bnds(lp, i, LPX_UP, lo, up); + break; + default: ; + //FIXME error + } + } else { + switch (b) { + case LPX_FR: + case LPX_LO: + lpx_set_row_bnds(lp, i, LPX_LO, lo, up); + break; + case LPX_UP: + case LPX_DB: + case LPX_FX: + if (lo==up) + lpx_set_row_bnds(lp, i, LPX_FX, lo, up); + else + lpx_set_row_bnds(lp, i, LPX_DB, lo, up); + break; + default: ; + //FIXME error + } + } + } + virtual double _getRowLowerBound(int i) { + int b=lpx_get_row_type(lp, i); + switch (b) { + case LPX_FR: + return -INF; + case LPX_LO: + return lpx_get_row_lb(lp, i); + case LPX_UP: + return -INF; + case LPX_DB: + case LPX_FX: + return lpx_get_row_lb(lp, i); + default: ; + //FIXME error + return 0.0; + } + } + virtual void _setRowUpperBound(int i, double up) { + if (up==-INF) { + //FIXME error + } + int b=lpx_get_row_type(lp, i); + double lo=lpx_get_row_lb(lp, i); + if (up==INF) { + switch (b) { + case LPX_FR: + case LPX_LO: + break; + case LPX_UP: + lpx_set_row_bnds(lp, i, LPX_FR, lo, up); + break; + case LPX_DB: + case LPX_FX: + lpx_set_row_bnds(lp, i, LPX_LO, lo, up); + break; + default: ; + //FIXME error + } + } else { + switch (b) { + case LPX_FR: + lpx_set_row_bnds(lp, i, LPX_UP, lo, up); + case LPX_LO: + if (lo==up) + lpx_set_row_bnds(lp, i, LPX_FX, lo, up); + else + lpx_set_row_bnds(lp, i, LPX_DB, lo, up); + break; + case LPX_UP: + lpx_set_row_bnds(lp, i, LPX_UP, lo, up); + break; + case LPX_DB: + case LPX_FX: + if (lo==up) + lpx_set_row_bnds(lp, i, LPX_FX, lo, up); + else + lpx_set_row_bnds(lp, i, LPX_DB, lo, up); + break; + default: ; + //FIXME error + } + } + } + virtual double _getRowUpperBound(int i) { + int b=lpx_get_row_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_row_ub(lp, i); + default: ; + //FIXME error + return 0.0; + } + } + /// \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 diff -r ba28dfbea5f2 -r 88ade201ffc6 src/work/marci/lp/lp_solver_wrapper_2.h --- a/src/work/marci/lp/lp_solver_wrapper_2.h Mon Jan 31 17:00:12 2005 +0000 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,551 +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 -extern "C" { -#include "glpk.h" -} - -#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; - protected: - /// \e - IterablePartition row_iter_map; - /// \e - IterablePartition col_iter_map; - /// \e - const int VALID_ID; - /// \e - const int INVALID_ID; - public: - /// \e - LPSolverBase() : row_iter_map(2), - col_iter_map(2), - VALID_ID(0), INVALID_ID(1) { } - /// \e - virtual ~LPSolverBase() { } - /// \e - virtual void setMinimize() = 0; - /// \e - virtual void setMaximize() = 0; - /// \e - virtual RowIt addRow() = 0; - /// \e - virtual ColIt addCol() = 0; - /// temporally, glpk style indexing - virtual void setRowCoeffs(RowIt row_it, int num, - int* indices, _Value* doubles) = 0; - //pair-bol kell megadni egy std range-et - /// \e - template - void setRowCoeffs(RowIt row_it, Begin begin, End end) { - int mem_length=1+colNum(); - int* indices = new int[mem_length]; - _Value* doubles = new _Value[mem_length]; - int length=0; - for ( ; begin!=end; ++begin) { - ++length; - indices[length]=col_iter_map[begin->first]; - doubles[length]=begin->second; - } - setRowCoeffs(row_it, length, indices, doubles); - delete [] indices; - delete [] doubles; - } - /// temporally, glpk style indexing - virtual void setColCoeffs(ColIt col_it, int num, - int* indices, _Value* doubles) = 0; - //pair-bol kell megadni egy std range-et - /// \e - template - void setColCoeffs(ColIt col_it, Begin begin, End end) { - int mem_length=1+rowNum(); - int* indices = new int[mem_length]; - _Value* doubles = new _Value[mem_length]; - int length=0; - for ( ; begin!=end; ++begin) { - ++length; - indices[length]=row_iter_map[begin->first]; - doubles[length]=begin->second; - } - setColCoeffs(col_it, length, indices, doubles); - delete [] indices; - delete [] doubles; - } - /// \e - virtual void eraseCol(const ColIt& col_it) = 0; - /// \e - virtual void eraseRow(const RowIt& row_it) = 0; - /// \e - virtual void setColBounds(const ColIt& col_it, int bound_type, - _Value lo, _Value up) =0; - /// \e - virtual _Value getObjCoef(const ColIt& col_it) = 0; - /// \e - virtual void setRowBounds(const RowIt& row_it, int bound_type, - _Value lo, _Value up) = 0; - /// \e - virtual void setObjCoef(const ColIt& col_it, _Value obj_coef) = 0; - /// \e - virtual void solveSimplex() = 0; - /// \e - virtual void solvePrimalSimplex() = 0; - /// \e - virtual void solveDualSimplex() = 0; - /// \e - virtual _Value getPrimal(const ColIt& col_it) = 0; - /// \e - virtual _Value getObjVal() = 0; - /// \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; - }; - - - /// \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 LPSolverWrapper : public LPSolverBase { - public: - typedef LPSolverBase Parent; - - // class Row { - // protected: - // int i; - // public: - // Row() { } - // Row(const Invalid&) : i(0) { } - // Row(const int& _i) : i(_i) { } - // operator int() const { return i; } - // }; - // class RowIt : public Row { - // public: - // RowIt(const Row& row) : Row(row) { } - // }; - - // class Col { - // protected: - // int i; - // public: - // Col() { } - // Col(const Invalid&) : i(0) { } - // Col(const int& _i) : i(_i) { } - // operator int() const { return i; } - // }; - // class ColIt : public Col { - // ColIt(const Col& col) : Col(col) { } - // }; - - public: - /// \e - LPX* lp; - - public: - /// \e - LPSolverWrapper() : Parent(), - lp(lpx_create_prob()) { - lpx_set_int_parm(lp, LPX_K_DUAL, 1); - } - /// \e - ~LPSolverWrapper() { - lpx_delete_prob(lp); - } - /// \e - void setMinimize() { - lpx_set_obj_dir(lp, LPX_MIN); - } - /// \e - void setMaximize() { - lpx_set_obj_dir(lp, LPX_MAX); - } - /// \e - ColIt addCol() { - int i=lpx_add_cols(lp, 1); - ColIt col_it; - col_iter_map.first(col_it, INVALID_ID); - if (col_iter_map.valid(col_it)) { //van hasznalhato hely - col_iter_map.set(col_it, INVALID_ID, VALID_ID); - col_iter_map[col_it]=i; - //col_id_to_lp_col_id[col_iter_map[col_it]]=i; - } else { //a cucc vegere kell inzertalni mert nincs szabad hely - //col_id_to_lp_col_id.push_back(i); - //int j=col_id_to_lp_col_id.size()-1; - col_it=col_iter_map.push_back(i, VALID_ID); - } - // edge_index_map.set(e, i); - // lpx_set_col_bnds(lp, i, LPX_DB, 0.0, 1.0); - // lpx_set_obj_coef(lp, i, cost[e]); - return col_it; - } - /// \e - RowIt addRow() { - int i=lpx_add_rows(lp, 1); - RowIt row_it; - row_iter_map.first(row_it, INVALID_ID); - if (row_iter_map.valid(row_it)) { //van hasznalhato hely - row_iter_map.set(row_it, INVALID_ID, VALID_ID); - 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_ID); - } - return row_it; - } - using Parent::setRowCoeffs; - void setRowCoeffs(RowIt row_it, int length, - int* indices, double* doubles) { - lpx_set_mat_row(lp, row_iter_map[row_it], length, indices, doubles); - } - using Parent::setColCoeffs; - void setColCoeffs(ColIt col_it, int length, - int* indices, double* doubles) { - lpx_set_mat_col(lp, col_iter_map[col_it], length, indices, doubles); - } - // //pair-bol kell megadni egy std range-et - // /// \e - // template - // void setColCoeffs(const ColIt& col_it, - // Begin begin, End end) { - // int mem_length=1+lpx_get_num_rows(lp); - // int* indices = new int[mem_length]; - // double* doubles = new double[mem_length]; - // int length=0; - // for ( ; begin!=end; ++begin) { - // ++length; - // indices[length]=row_iter_map[begin->first]; - // doubles[length]=begin->second; - // } - // lpx_set_mat_col(lp, col_iter_map[col_it], length, indices, doubles); - // delete [] indices; - // delete [] doubles; - // } - // //pair-bol kell megadni egy std range-et - // /// \e - // template - // void setRowCoeffs(const RowIt& row_it, - // Begin begin, End end) { - // int mem_length=1+lpx_get_num_cols(lp); - // int* indices = new int[mem_length]; - // double* doubles = new double[mem_length]; - // int length=0; - // for ( ; begin!=end; ++begin) { - // ++length; - // indices[length]=col_iter_map[begin->first]; - // doubles[length]=begin->second; - // } - // lpx_set_mat_row(lp, row_iter_map[row_it], length, indices, doubles); - // delete [] indices; - // delete [] doubles; - // } - /// \e - void eraseCol(const ColIt& col_it) { - col_iter_map.set(col_it, VALID_ID, INVALID_ID); - int cols[2]; - cols[1]=col_iter_map[col_it]; - lpx_del_cols(lp, 1, cols); - col_iter_map[col_it]=0; //glpk specifikus - ColIt it; - for (col_iter_map.first(it, VALID_ID); - 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_ID, INVALID_ID); - int rows[2]; - rows[1]=row_iter_map[row_it]; - lpx_del_rows(lp, 1, rows); - row_iter_map[row_it]=0; //glpk specifikus - RowIt it; - for (row_iter_map.first(it, VALID_ID); - row_iter_map.valid(it); row_iter_map.next(it)) { - if (row_iter_map[it]>rows[1]) --row_iter_map[it]; - } - } - /// \e - void setColBounds(const ColIt& col_it, int bound_type, - double lo, double up) { - lpx_set_col_bnds(lp, col_iter_map[col_it], bound_type, lo, up); - } - /// \e - double getObjCoef(const ColIt& col_it) { - return lpx_get_obj_coef(lp, col_iter_map[col_it]); - } - /// \e - void setRowBounds(const RowIt& row_it, int bound_type, - double lo, double up) { - lpx_set_row_bnds(lp, row_iter_map[row_it], bound_type, lo, up); - } - /// \e - void setObjCoef(const ColIt& col_it, double obj_coef) { - lpx_set_obj_coef(lp, col_iter_map[col_it], obj_coef); - } - /// \e - void solveSimplex() { lpx_simplex(lp); } - /// \e - void solvePrimalSimplex() { lpx_simplex(lp); } - /// \e - void solveDualSimplex() { lpx_simplex(lp); } - /// \e - double getPrimal(const ColIt& col_it) { - return lpx_get_col_prim(lp, col_iter_map[col_it]); - } - /// \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 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 diff -r ba28dfbea5f2 -r 88ade201ffc6 src/work/marci/lp/max_flow_expression.cc --- a/src/work/marci/lp/max_flow_expression.cc Mon Jan 31 17:00:12 2005 +0000 +++ b/src/work/marci/lp/max_flow_expression.cc Tue Feb 01 12:53:30 2005 +0000 @@ -6,7 +6,7 @@ #include #include #include -#include +#include using std::cout; using std::endl; @@ -51,15 +51,15 @@ EdgeIndexMap edge_index_map(g); PrimalMap flow(lp, edge_index_map); - // capacity function + // nonnegativity of flow and capacity function for (Graph::EdgeIt e(g); e!=INVALID; ++e) { ColIt col_it=lp.addCol(); edge_index_map.set(e, col_it); // interesting property in GLPK: // if you change the order of the following two lines, the // two runs of GLPK are extremely different + lp.setColLowerBound(col_it, 0); lp.setColUpperBound(col_it, cap[e]); - lp.setColLowerBound(col_it, 0); } for (Graph::NodeIt n(g); n!=INVALID; ++n) { @@ -72,11 +72,12 @@ if (n==s) { lp.setObjCoeffs(expr); } - // flow conservation + // flow conservation constraints if ((n!=s) && (n!=t)) { RowIt row_it=lp.addRow(); lp.setRowCoeffs(row_it, expr); - lp.setRowBounds(row_it, LPSolver::FIXED, 0.0, 0.0); + lp.setRowLowerBound(row_it, 0.0); + lp.setRowUpperBound(row_it, 0.0); } } lp.solveSimplex();