// -*- 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 Of course this is not efficient at all, but GLPK knows not more. int change_this; bool get_set_row; //The only thing we can do is optimize on whether working with a row //or a coloumn int row_num = rowNum(); int col_num = colNum(); if (col_num