2 #ifndef LEMON_LP_SOLVER_GLPK_H
3 #define LEMON_LP_SOLVER_GLPK_H
9 /* #include <stdlib.h> */
10 /* #include <iostream> */
12 /* #include <limits> */
19 /* #include <iostream> */
20 /* #include <vector> */
21 /* #include <string> */
23 /* #include <memory> */
24 /* #include <utility> */
26 //#include <lemon/invalid.h>
27 //#include <expression.h>
28 #include <lp_solver_base.h>
30 //#include <lemon/max_flow.h>
31 //#include <augmenting_flow.h>
32 //#include <iter_map.h>
41 template <typename Value>
42 const Value LpSolverBase<Value>::INF=std::numeric_limits<Value>::infinity();
45 /// \brief Wrapper for GLPK solver
47 /// This class implements a lemon wrapper for GLPK.
48 class LpGlpk : public LpSolverBase<double> {
50 typedef LpSolverBase<double> Parent;
59 lp(lpx_create_prob()) {
60 int_row_map.push_back(Row());
61 int_col_map.push_back(Col());
62 lpx_set_int_parm(lp, LPX_K_DUAL, 1);
69 //MATRIX INDEPEDENT MANIPULATING FUNCTIONS
73 lpx_set_obj_dir(lp, LPX_MIN);
77 lpx_set_obj_dir(lp, LPX_MAX);
80 //LOW LEVEL INTERFACE, MATRIX MANIPULATING FUNCTIONS
85 int i=lpx_add_cols(lp, 1);
86 _setColLowerBound(i, -INF);
87 _setColUpperBound(i, INF);
92 int i=lpx_add_rows(lp, 1);
96 virtual void _setRowCoeffs(int i,
97 const std::vector<std::pair<int, double> >& coeffs) {
98 int mem_length=1+colNum();
99 int* indices = new int[mem_length];
100 double* doubles = new double[mem_length];
102 for (std::vector<std::pair<int, double> >::
103 const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) {
105 indices[length]=it->first;
106 doubles[length]=it->second;
108 lpx_set_mat_row(lp, i, length, indices, doubles);
113 virtual void _getRowCoeffs(int i,
114 std::vector<std::pair<int, double> >& coeffs) {
115 int mem_length=1+colNum();
116 int* indices = new int[mem_length];
117 double* doubles = new double[mem_length];
118 int length=lpx_get_mat_row(lp, i, indices, doubles);
119 for (int i=1; i<=length; ++i) {
120 coeffs.push_back(std::make_pair(indices[i], doubles[i]));
126 virtual void _setColCoeffs(int i,
127 const std::vector<std::pair<int, double> >& coeffs) {
128 int mem_length=1+rowNum();
129 int* indices = new int[mem_length];
130 double* doubles = new double[mem_length];
132 for (std::vector<std::pair<int, double> >::
133 const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) {
135 indices[length]=it->first;
136 doubles[length]=it->second;
138 lpx_set_mat_col(lp, i, length, indices, doubles);
143 virtual void _getColCoeffs(int i,
144 std::vector<std::pair<int, double> >& coeffs) {
145 int mem_length=1+rowNum();
146 int* indices = new int[mem_length];
147 double* doubles = new double[mem_length];
148 int length=lpx_get_mat_col(lp, i, indices, doubles);
149 for (int i=1; i<=length; ++i) {
150 coeffs.push_back(std::make_pair(indices[i], doubles[i]));
156 virtual void _eraseCol(int i) {
159 lpx_del_cols(lp, 1, cols);
161 virtual void _eraseRow(int i) {
164 lpx_del_rows(lp, 1, rows);
166 void _setCoeff(int col, int row, double value) {
167 ///FIXME Of course this is not efficient at all, but GLPK knows not more.
170 //The only thing we can do is optimize on whether working with a row
172 int row_num = rowNum();
173 int col_num = colNum();
174 if (col_num<row_num){
175 //There are more rows than coloumns
177 int mem_length=1+row_num;
178 int* indices = new int[mem_length];
179 double* doubles = new double[mem_length];
180 int length=lpx_get_mat_col(lp, i, indices, doubles);
183 int mem_length=1+col_num;
184 int* indices = new int[mem_length];
185 double* doubles = new double[mem_length];
186 int length=lpx_get_mat_row(lp, i, indices, doubles);
189 int* indices = new int[mem_length];
190 double* doubles = new double[mem_length];
191 int length=lpx_get_mat_col(lp, i, indices, doubles);
197 double _getCoeff(int col, int row) {
198 /// FIXME not yet implemented
201 virtual void _setColLowerBound(int i, double lo) {
205 int b=lpx_get_col_type(lp, i);
206 double up=lpx_get_col_ub(lp, i);
211 lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
217 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
226 lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
232 lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
234 lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
241 virtual double _getColLowerBound(int i) {
242 int b=lpx_get_col_type(lp, i);
247 return lpx_get_col_lb(lp, i);
252 return lpx_get_col_lb(lp, i);
258 virtual void _setColUpperBound(int i, double up) {
262 int b=lpx_get_col_type(lp, i);
263 double lo=lpx_get_col_lb(lp, i);
270 lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
274 lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
282 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
285 lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
287 lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
290 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
295 lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
297 lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
304 virtual double _getColUpperBound(int i) {
305 int b=lpx_get_col_type(lp, i);
313 return lpx_get_col_ub(lp, i);
319 virtual void _setRowLowerBound(int i, double lo) {
323 int b=lpx_get_row_type(lp, i);
324 double up=lpx_get_row_ub(lp, i);
329 lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
335 lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
344 lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
350 lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
352 lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
359 virtual double _getRowLowerBound(int i) {
360 int b=lpx_get_row_type(lp, i);
365 return lpx_get_row_lb(lp, i);
370 return lpx_get_row_lb(lp, i);
376 virtual void _setRowUpperBound(int i, double up) {
380 int b=lpx_get_row_type(lp, i);
381 double lo=lpx_get_row_lb(lp, i);
388 lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
392 lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
400 lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
403 lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
405 lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
408 lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
413 lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
415 lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
422 virtual double _getRowUpperBound(int i) {
423 int b=lpx_get_row_type(lp, i);
431 return lpx_get_row_ub(lp, i);
438 virtual double _getObjCoeff(int i) {
439 return lpx_get_obj_coef(lp, i);
442 virtual void _setObjCoeff(int i, double obj_coef) {
443 lpx_set_obj_coef(lp, i, obj_coef);
447 void solveSimplex() { lpx_simplex(lp); }
449 void solvePrimalSimplex() { lpx_simplex(lp); }
451 void solveDualSimplex() { lpx_simplex(lp); }
453 virtual double _getPrimal(int i) {
454 return lpx_get_col_prim(lp, i);
458 double getObjVal() { return lpx_get_obj_val(lp); }
460 int rowNum() const { return lpx_get_num_rows(lp); }
462 int colNum() const { return lpx_get_num_cols(lp); }
464 int warmUp() { return lpx_warm_up(lp); }
466 void printWarmUpStatus(int i) {
468 case LPX_E_OK: cout << "LPX_E_OK" << endl; break;
469 case LPX_E_EMPTY: cout << "LPX_E_EMPTY" << endl; break;
470 case LPX_E_BADB: cout << "LPX_E_BADB" << endl; break;
471 case LPX_E_SING: cout << "LPX_E_SING" << endl; break;
475 int getPrimalStatus() { return lpx_get_prim_stat(lp); }
477 void printPrimalStatus(int i) {
479 case LPX_P_UNDEF: cout << "LPX_P_UNDEF" << endl; break;
480 case LPX_P_FEAS: cout << "LPX_P_FEAS" << endl; break;
481 case LPX_P_INFEAS: cout << "LPX_P_INFEAS" << endl; break;
482 case LPX_P_NOFEAS: cout << "LPX_P_NOFEAS" << endl; break;
486 int getDualStatus() { return lpx_get_dual_stat(lp); }
488 void printDualStatus(int i) {
490 case LPX_D_UNDEF: cout << "LPX_D_UNDEF" << endl; break;
491 case LPX_D_FEAS: cout << "LPX_D_FEAS" << endl; break;
492 case LPX_D_INFEAS: cout << "LPX_D_INFEAS" << endl; break;
493 case LPX_D_NOFEAS: cout << "LPX_D_NOFEAS" << endl; break;
496 /// Returns the status of the slack variable assigned to row \c row.
497 int getRowStat(const Row& row) {
498 return lpx_get_row_stat(lp, row_iter_map[row]);
501 void printRowStatus(int i) {
503 case LPX_BS: cout << "LPX_BS" << endl; break;
504 case LPX_NL: cout << "LPX_NL" << endl; break;
505 case LPX_NU: cout << "LPX_NU" << endl; break;
506 case LPX_NF: cout << "LPX_NF" << endl; break;
507 case LPX_NS: cout << "LPX_NS" << endl; break;
510 /// Returns the status of the variable assigned to column \c col.
511 int getColStat(const Col& col) {
512 return lpx_get_col_stat(lp, col_iter_map[col]);
515 void printColStatus(int i) {
517 case LPX_BS: cout << "LPX_BS" << endl; break;
518 case LPX_NL: cout << "LPX_NL" << endl; break;
519 case LPX_NU: cout << "LPX_NU" << endl; break;
520 case LPX_NF: cout << "LPX_NF" << endl; break;
521 case LPX_NS: cout << "LPX_NS" << endl; break;
527 void solveBandB() { lpx_integer(lp); }
529 void setLP() { lpx_set_class(lp, LPX_LP); }
531 void setMIP() { lpx_set_class(lp, LPX_MIP); }
534 void _setColCont(int i) { lpx_set_col_kind(lp, i, LPX_CV); }
536 void _setColInt(int i) { lpx_set_col_kind(lp, i, LPX_IV); }
538 double _getMIPPrimal(int i) { return lpx_mip_col_val(lp, i); }
545 #endif //LEMON_LP_SOLVER_GLPK_H