2 #ifndef LEMON_LP_SOLVER_GLPK_H
3 #define LEMON_LP_SOLVER_GLPK_H
11 #include <lp_solver_base.h>
16 template <typename Value>
17 const Value LpSolverBase<Value>::INF=std::numeric_limits<Value>::infinity();
20 /// \brief Wrapper for GLPK solver
22 /// This class implements a lemon wrapper for GLPK.
23 class LpGlpk : public LpSolverBase<double> {
27 typedef LpSolverBase<double> Parent;
34 lp(lpx_create_prob()) {
35 //int_row_map.push_back(Row());
36 //int_col_map.push_back(Col());
37 lpx_set_int_parm(lp, LPX_K_DUAL, 1);
44 //MATRIX INDEPEDENT MANIPULATING FUNCTIONS
48 lpx_set_obj_dir(lp, LPX_MIN);
52 lpx_set_obj_dir(lp, LPX_MAX);
56 /// Retrieve number of rows
57 int rowNum() const { return lpx_get_num_rows(lp); }
59 /// Retrieve number of coloumns
60 int colNum() const { return lpx_get_num_cols(lp); }
64 int LpGlpk::_addCol() {
65 int i=lpx_add_cols(lp, 1);
66 _setColLowerBound(i, -INF);
67 _setColUpperBound(i, INF);
71 int LpGlpk::_addRow() {
72 int i=lpx_add_rows(lp, 1);
76 virtual void _setRowCoeffs(int i,
77 const std::vector<std::pair<int, double> >& coeffs) {
78 int mem_length=1+colNum();
79 int* indices = new int[mem_length];
80 double* doubles = new double[mem_length];
82 for (std::vector<std::pair<int, double> >::
83 const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) {
85 indices[length]=it->first;
86 doubles[length]=it->second;
88 lpx_set_mat_row(lp, i, length, indices, doubles);
93 virtual void _getRowCoeffs(int i,
94 std::vector<std::pair<int, double> >& coeffs) {
95 int mem_length=1+colNum();
96 int* indices = new int[mem_length];
97 double* doubles = new double[mem_length];
98 int length=lpx_get_mat_row(lp, i, indices, doubles);
99 for (int i=1; i<=length; ++i) {
100 coeffs.push_back(std::make_pair(indices[i], doubles[i]));
106 virtual void _setColCoeffs(int i,
107 const std::vector<std::pair<int, double> >& coeffs) {
108 int mem_length=1+rowNum();
109 int* indices = new int[mem_length];
110 double* doubles = new double[mem_length];
112 for (std::vector<std::pair<int, double> >::
113 const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) {
115 indices[length]=it->first;
116 doubles[length]=it->second;
118 lpx_set_mat_col(lp, i, length, indices, doubles);
123 virtual void _getColCoeffs(int i,
124 std::vector<std::pair<int, double> >& coeffs) {
125 int mem_length=1+rowNum();
126 int* indices = new int[mem_length];
127 double* doubles = new double[mem_length];
128 int length=lpx_get_mat_col(lp, i, indices, doubles);
129 for (int i=1; i<=length; ++i) {
130 coeffs.push_back(std::make_pair(indices[i], doubles[i]));
136 virtual void _eraseCol(int i) {
139 lpx_del_cols(lp, 1, cols);
141 virtual void _eraseRow(int i) {
144 lpx_del_rows(lp, 1, rows);
147 void _setCoeff(int row, int col, double value) {
148 ///FIXME Of course this is not efficient at all, but GLPK knows not more.
149 /// First approach: get one row, apply changes and set it again
151 int mem_length=1+colNum();
152 int* indices = new int[mem_length];
153 double* doubles = new double[mem_length];
156 int length=lpx_get_mat_row(lp, i, indices, doubles);
158 //The following code does not suppose that the elements of the array indices are sorted
161 while (i <= length && !found){
171 doubles[length]=value;
174 // This is a piece of code that assumes that the array 'indices' is sorted.
175 // Not ready, I suppose.
176 // //We need another arrays to put the data back, anyway
177 // int* new_indices = new int[length+1];
178 // double* new_doubles = new double[length+1];
182 // while (i <= length && indices[i]<col){
183 // new_indiced[i]=indices[i];
184 // new_doubles[i]=doubles[i];
187 // if (i>length || indices[i]>col){
188 // //Ha atugrottuk, vagy a vegen van
189 // new_indices[i]=col;
190 // new_doubles[i]=value;
194 // //I.e.: indices[i]=col
195 // new_doubles[i]=value;
199 // while (i <= length){
200 // new_indices[i+offset]=indices[i];
201 // new_values[i+offset]=values[i];
204 lpx_set_mat_row(lp, row, length, indices, doubles);
208 // lpx_set_mat_row(lp, row, length+offset, new_indices, new_doubles);
209 // delete [] new_indices;
210 // delete [] new_doubles;
214 double _getCoeff(int col, int row) {
215 /// FIXME not yet implemented
218 virtual void _setColLowerBound(int i, double lo) {
222 int b=lpx_get_col_type(lp, i);
223 double up=lpx_get_col_ub(lp, i);
228 lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
234 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
243 lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
249 lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
251 lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
258 virtual double _getColLowerBound(int i) {
259 int b=lpx_get_col_type(lp, i);
264 return lpx_get_col_lb(lp, i);
269 return lpx_get_col_lb(lp, i);
275 virtual void _setColUpperBound(int i, double up) {
279 int b=lpx_get_col_type(lp, i);
280 double lo=lpx_get_col_lb(lp, i);
287 lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
291 lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
299 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
302 lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
304 lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
307 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
312 lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
314 lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
321 virtual double _getColUpperBound(int i) {
322 int b=lpx_get_col_type(lp, i);
330 return lpx_get_col_ub(lp, i);
336 virtual void _setRowLowerBound(int i, double lo) {
340 int b=lpx_get_row_type(lp, i);
341 double up=lpx_get_row_ub(lp, i);
346 lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
352 lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
361 lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
367 lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
369 lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
376 virtual double _getRowLowerBound(int i) {
377 int b=lpx_get_row_type(lp, i);
382 return lpx_get_row_lb(lp, i);
387 return lpx_get_row_lb(lp, i);
393 virtual void _setRowUpperBound(int i, double up) {
397 int b=lpx_get_row_type(lp, i);
398 double lo=lpx_get_row_lb(lp, i);
405 lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
409 lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
417 lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
420 lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
422 lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
425 lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
430 lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
432 lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
439 virtual double _getRowUpperBound(int i) {
440 int b=lpx_get_row_type(lp, i);
448 return lpx_get_row_ub(lp, i);
455 virtual double _getObjCoeff(int i) {
456 return lpx_get_obj_coef(lp, i);
459 virtual void _setObjCoeff(int i, double obj_coef) {
460 lpx_set_obj_coef(lp, i, obj_coef);
464 virtual double _getPrimal(int i) {
465 return lpx_get_col_prim(lp, i);
471 void _setColCont(int i) { lpx_set_col_kind(lp, i, LPX_CV); }
473 void _setColInt(int i) { lpx_set_col_kind(lp, i, LPX_IV); }
475 double _getMIPPrimal(int i) { return lpx_mip_col_val(lp, i); }
480 // void solveSimplex() { lpx_simplex(lp); }
482 // void solvePrimalSimplex() { lpx_simplex(lp); }
484 // void solveDualSimplex() { lpx_simplex(lp); }
486 // double getObjVal() { return lpx_get_obj_val(lp); }
488 // int warmUp() { return lpx_warm_up(lp); }
490 // void printWarmUpStatus(int i) {
492 // case LPX_E_OK: cout << "LPX_E_OK" << endl; break;
493 // case LPX_E_EMPTY: cout << "LPX_E_EMPTY" << endl; break;
494 // case LPX_E_BADB: cout << "LPX_E_BADB" << endl; break;
495 // case LPX_E_SING: cout << "LPX_E_SING" << endl; break;
499 // int getPrimalStatus() { return lpx_get_prim_stat(lp); }
501 // void printPrimalStatus(int i) {
503 // case LPX_P_UNDEF: cout << "LPX_P_UNDEF" << endl; break;
504 // case LPX_P_FEAS: cout << "LPX_P_FEAS" << endl; break;
505 // case LPX_P_INFEAS: cout << "LPX_P_INFEAS" << endl; break;
506 // case LPX_P_NOFEAS: cout << "LPX_P_NOFEAS" << endl; break;
510 // int getDualStatus() { return lpx_get_dual_stat(lp); }
512 // void printDualStatus(int i) {
514 // case LPX_D_UNDEF: cout << "LPX_D_UNDEF" << endl; break;
515 // case LPX_D_FEAS: cout << "LPX_D_FEAS" << endl; break;
516 // case LPX_D_INFEAS: cout << "LPX_D_INFEAS" << endl; break;
517 // case LPX_D_NOFEAS: cout << "LPX_D_NOFEAS" << endl; break;
520 // /// Returns the status of the slack variable assigned to row \c row.
521 // int getRowStat(const Row& row) {
522 // return lpx_get_row_stat(lp, row_iter_map[row]);
525 // void printRowStatus(int i) {
527 // case LPX_BS: cout << "LPX_BS" << endl; break;
528 // case LPX_NL: cout << "LPX_NL" << endl; break;
529 // case LPX_NU: cout << "LPX_NU" << endl; break;
530 // case LPX_NF: cout << "LPX_NF" << endl; break;
531 // case LPX_NS: cout << "LPX_NS" << endl; break;
534 // /// Returns the status of the variable assigned to column \c col.
535 // int getColStat(const Col& col) {
536 // return lpx_get_col_stat(lp, col_iter_map[col]);
539 // void printColStatus(int i) {
541 // case LPX_BS: cout << "LPX_BS" << endl; break;
542 // case LPX_NL: cout << "LPX_NL" << endl; break;
543 // case LPX_NU: cout << "LPX_NU" << endl; break;
544 // case LPX_NF: cout << "LPX_NF" << endl; break;
545 // case LPX_NS: cout << "LPX_NS" << endl; break;
551 // void solveBandB() { lpx_integer(lp); }
553 // void setLP() { lpx_set_class(lp, LPX_LP); }
555 // void setMIP() { lpx_set_class(lp, LPX_MIP); }
565 #endif //LEMON_LP_SOLVER_GLPK_H