athos@1241: // -*- c++ -*- athos@1241: #ifndef LEMON_LP_SOLVER_GLPK_H athos@1241: #define LEMON_LP_SOLVER_GLPK_H athos@1241: athos@1241: ///\ingroup misc athos@1241: ///\file athos@1241: athos@1241: // #include athos@1241: /* #include */ athos@1241: /* #include */ athos@1241: /* #include */ athos@1241: /* #include */ athos@1241: // #include athos@1241: //#include athos@1241: extern "C" { athos@1241: #include "glpk.h" athos@1241: } athos@1241: athos@1241: /* #include */ athos@1241: /* #include */ athos@1241: /* #include */ athos@1241: /* #include */ athos@1241: /* #include */ athos@1241: /* #include */ athos@1241: athos@1241: //#include athos@1241: //#include athos@1241: #include athos@1241: //#include athos@1241: //#include athos@1241: //#include athos@1241: //#include athos@1241: athos@1241: using std::cout; athos@1241: using std::cin; athos@1241: using std::endl; athos@1241: athos@1241: namespace lemon { athos@1241: athos@1241: athos@1241: template athos@1241: const Value LpSolverBase::INF=std::numeric_limits::infinity(); athos@1241: athos@1241: athos@1241: /// \brief Wrapper for GLPK solver athos@1241: /// athos@1241: /// This class implements a lemon wrapper for GLPK. athos@1241: class LpGlpk : public LpSolverBase { athos@1241: public: athos@1241: typedef LpSolverBase Parent; athos@1241: athos@1241: public: athos@1241: /// \e athos@1241: LPX* lp; athos@1241: athos@1241: public: athos@1241: /// \e athos@1241: LpGlpk() : Parent(), athos@1241: lp(lpx_create_prob()) { athos@1241: int_row_map.push_back(Row()); athos@1241: int_col_map.push_back(Col()); athos@1241: lpx_set_int_parm(lp, LPX_K_DUAL, 1); athos@1241: } athos@1241: /// \e athos@1241: ~LpGlpk() { athos@1241: lpx_delete_prob(lp); athos@1241: } athos@1241: athos@1241: //MATRIX INDEPEDENT MANIPULATING FUNCTIONS athos@1241: athos@1241: /// \e athos@1241: void setMinimize() { athos@1241: lpx_set_obj_dir(lp, LPX_MIN); athos@1241: } athos@1241: /// \e athos@1241: void setMaximize() { athos@1241: lpx_set_obj_dir(lp, LPX_MAX); athos@1241: } athos@1241: athos@1241: //LOW LEVEL INTERFACE, MATRIX MANIPULATING FUNCTIONS athos@1241: athos@1241: protected: athos@1241: /// \e athos@1241: int _addCol() { athos@1241: int i=lpx_add_cols(lp, 1); athos@1241: _setColLowerBound(i, -INF); athos@1241: _setColUpperBound(i, INF); athos@1241: return i; athos@1241: } athos@1241: /// \e athos@1241: int _addRow() { athos@1241: int i=lpx_add_rows(lp, 1); athos@1241: return i; athos@1241: } athos@1241: /// \e athos@1241: virtual void _setRowCoeffs(int i, athos@1241: const std::vector >& coeffs) { athos@1241: int mem_length=1+colNum(); athos@1241: int* indices = new int[mem_length]; athos@1241: double* doubles = new double[mem_length]; athos@1241: int length=0; athos@1241: for (std::vector >:: athos@1241: const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) { athos@1241: ++length; athos@1241: indices[length]=it->first; athos@1241: doubles[length]=it->second; athos@1241: } athos@1241: lpx_set_mat_row(lp, i, length, indices, doubles); athos@1241: delete [] indices; athos@1241: delete [] doubles; athos@1241: } athos@1241: /// \e athos@1241: virtual void _getRowCoeffs(int i, athos@1241: std::vector >& coeffs) { athos@1241: int mem_length=1+colNum(); athos@1241: int* indices = new int[mem_length]; athos@1241: double* doubles = new double[mem_length]; athos@1241: int length=lpx_get_mat_row(lp, i, indices, doubles); athos@1241: for (int i=1; i<=length; ++i) { athos@1241: coeffs.push_back(std::make_pair(indices[i], doubles[i])); athos@1241: } athos@1241: delete [] indices; athos@1241: delete [] doubles; athos@1241: } athos@1241: /// \e athos@1241: virtual void _setColCoeffs(int i, athos@1241: const std::vector >& coeffs) { athos@1241: int mem_length=1+rowNum(); athos@1241: int* indices = new int[mem_length]; athos@1241: double* doubles = new double[mem_length]; athos@1241: int length=0; athos@1241: for (std::vector >:: athos@1241: const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) { athos@1241: ++length; athos@1241: indices[length]=it->first; athos@1241: doubles[length]=it->second; athos@1241: } athos@1241: lpx_set_mat_col(lp, i, length, indices, doubles); athos@1241: delete [] indices; athos@1241: delete [] doubles; athos@1241: } athos@1241: /// \e athos@1241: virtual void _getColCoeffs(int i, athos@1241: std::vector >& coeffs) { athos@1241: int mem_length=1+rowNum(); athos@1241: int* indices = new int[mem_length]; athos@1241: double* doubles = new double[mem_length]; athos@1241: int length=lpx_get_mat_col(lp, i, indices, doubles); athos@1241: for (int i=1; i<=length; ++i) { athos@1241: coeffs.push_back(std::make_pair(indices[i], doubles[i])); athos@1241: } athos@1241: delete [] indices; athos@1241: delete [] doubles; athos@1241: } athos@1241: /// \e athos@1241: virtual void _eraseCol(int i) { athos@1241: int cols[2]; athos@1241: cols[1]=i; athos@1241: lpx_del_cols(lp, 1, cols); athos@1241: } athos@1241: virtual void _eraseRow(int i) { athos@1241: int rows[2]; athos@1241: rows[1]=i; athos@1241: lpx_del_rows(lp, 1, rows); athos@1241: } athos@1241: void _setCoeff(int col, int row, double value) { athos@1243: ///FIXME Of course this is not efficient at all, but GLPK knows not more. athos@1243: int change_this; athos@1243: bool get_set_row; athos@1243: //The only thing we can do is optimize on whether working with a row athos@1243: //or a coloumn athos@1243: int row_num = rowNum(); athos@1243: int col_num = colNum(); athos@1243: if (col_num