diff -r 88a2ab6bfc4a -r dadc9987c537 src/work/athos/lp/lp_solver_glpk.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/work/athos/lp/lp_solver_glpk.h Tue Mar 22 12:02:29 2005 +0000 @@ -0,0 +1,517 @@ +// -*- c++ -*- +#ifndef LEMON_LP_SOLVER_GLPK_H +#define LEMON_LP_SOLVER_GLPK_H + +///\ingroup misc +///\file + +// #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 + +using std::cout; +using std::cin; +using std::endl; + +namespace lemon { + + + template + const Value LpSolverBase::INF=std::numeric_limits::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()) { + int_row_map.push_back(Row()); + int_col_map.push_back(Col()); + 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; + } + lpx_set_mat_row(lp, i, length, indices, doubles); + delete [] indices; + delete [] doubles; + } + /// \e + virtual void _getRowCoeffs(int i, + std::vector >& coeffs) { + int mem_length=1+colNum(); + int* indices = new int[mem_length]; + double* doubles = new double[mem_length]; + int length=lpx_get_mat_row(lp, i, indices, doubles); + for (int i=1; i<=length; ++i) { + coeffs.push_back(std::make_pair(indices[i], doubles[i])); + } + 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 _getColCoeffs(int i, + std::vector >& coeffs) { + int mem_length=1+rowNum(); + int* indices = new int[mem_length]; + double* doubles = new double[mem_length]; + int length=lpx_get_mat_col(lp, i, indices, doubles); + for (int i=1; i<=length; ++i) { + coeffs.push_back(std::make_pair(indices[i], doubles[i])); + } + 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); + } + void _setCoeff(int col, int row, double value) { + /// FIXME not yet implemented + } + double _getCoeff(int col, int row) { + /// FIXME not yet implemented + return 0.0; + } + 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 _getObjCoeff(int i) { + return lpx_get_obj_coef(lp, i); + } + /// \e + virtual void _setObjCoeff(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); } + 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. + int getRowStat(const Row& row) { + return lpx_get_row_stat(lp, row_iter_map[row]); + } + /// \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. + int getColStat(const Col& col) { + return lpx_get_col_stat(lp, col_iter_map[col]); + } + /// \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; + } + } + + // MIP + /// \e + void solveBandB() { lpx_integer(lp); } + /// \e + void setLP() { lpx_set_class(lp, LPX_LP); } + /// \e + void setMIP() { lpx_set_class(lp, LPX_MIP); } + protected: + /// \e + void _setColCont(int i) { lpx_set_col_kind(lp, i, LPX_CV); } + /// \e + void _setColInt(int i) { lpx_set_col_kind(lp, i, LPX_IV); } + /// \e + double _getMIPPrimal(int i) { return lpx_mip_col_val(lp, i); } + }; + + /// @} + +} //namespace lemon + +#endif //LEMON_LP_SOLVER_GLPK_H