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 not yet implemented
169 double _getCoeff(int col, int row) {
170 /// FIXME not yet implemented
173 virtual void _setColLowerBound(int i, double lo) {
177 int b=lpx_get_col_type(lp, i);
178 double up=lpx_get_col_ub(lp, i);
183 lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
189 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
198 lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
204 lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
206 lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
213 virtual double _getColLowerBound(int i) {
214 int b=lpx_get_col_type(lp, i);
219 return lpx_get_col_lb(lp, i);
224 return lpx_get_col_lb(lp, i);
230 virtual void _setColUpperBound(int i, double up) {
234 int b=lpx_get_col_type(lp, i);
235 double lo=lpx_get_col_lb(lp, i);
242 lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
246 lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
254 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
257 lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
259 lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
262 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
267 lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
269 lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
276 virtual double _getColUpperBound(int i) {
277 int b=lpx_get_col_type(lp, i);
285 return lpx_get_col_ub(lp, i);
291 virtual void _setRowLowerBound(int i, double lo) {
295 int b=lpx_get_row_type(lp, i);
296 double up=lpx_get_row_ub(lp, i);
301 lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
307 lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
316 lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
322 lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
324 lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
331 virtual double _getRowLowerBound(int i) {
332 int b=lpx_get_row_type(lp, i);
337 return lpx_get_row_lb(lp, i);
342 return lpx_get_row_lb(lp, i);
348 virtual void _setRowUpperBound(int i, double up) {
352 int b=lpx_get_row_type(lp, i);
353 double lo=lpx_get_row_lb(lp, i);
360 lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
364 lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
372 lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
375 lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
377 lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
380 lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
385 lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
387 lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
394 virtual double _getRowUpperBound(int i) {
395 int b=lpx_get_row_type(lp, i);
403 return lpx_get_row_ub(lp, i);
410 virtual double _getObjCoeff(int i) {
411 return lpx_get_obj_coef(lp, i);
414 virtual void _setObjCoeff(int i, double obj_coef) {
415 lpx_set_obj_coef(lp, i, obj_coef);
419 void solveSimplex() { lpx_simplex(lp); }
421 void solvePrimalSimplex() { lpx_simplex(lp); }
423 void solveDualSimplex() { lpx_simplex(lp); }
425 virtual double _getPrimal(int i) {
426 return lpx_get_col_prim(lp, i);
430 double getObjVal() { return lpx_get_obj_val(lp); }
432 int rowNum() const { return lpx_get_num_rows(lp); }
434 int colNum() const { return lpx_get_num_cols(lp); }
436 int warmUp() { return lpx_warm_up(lp); }
438 void printWarmUpStatus(int i) {
440 case LPX_E_OK: cout << "LPX_E_OK" << endl; break;
441 case LPX_E_EMPTY: cout << "LPX_E_EMPTY" << endl; break;
442 case LPX_E_BADB: cout << "LPX_E_BADB" << endl; break;
443 case LPX_E_SING: cout << "LPX_E_SING" << endl; break;
447 int getPrimalStatus() { return lpx_get_prim_stat(lp); }
449 void printPrimalStatus(int i) {
451 case LPX_P_UNDEF: cout << "LPX_P_UNDEF" << endl; break;
452 case LPX_P_FEAS: cout << "LPX_P_FEAS" << endl; break;
453 case LPX_P_INFEAS: cout << "LPX_P_INFEAS" << endl; break;
454 case LPX_P_NOFEAS: cout << "LPX_P_NOFEAS" << endl; break;
458 int getDualStatus() { return lpx_get_dual_stat(lp); }
460 void printDualStatus(int i) {
462 case LPX_D_UNDEF: cout << "LPX_D_UNDEF" << endl; break;
463 case LPX_D_FEAS: cout << "LPX_D_FEAS" << endl; break;
464 case LPX_D_INFEAS: cout << "LPX_D_INFEAS" << endl; break;
465 case LPX_D_NOFEAS: cout << "LPX_D_NOFEAS" << endl; break;
468 /// Returns the status of the slack variable assigned to row \c row.
469 int getRowStat(const Row& row) {
470 return lpx_get_row_stat(lp, row_iter_map[row]);
473 void printRowStatus(int i) {
475 case LPX_BS: cout << "LPX_BS" << endl; break;
476 case LPX_NL: cout << "LPX_NL" << endl; break;
477 case LPX_NU: cout << "LPX_NU" << endl; break;
478 case LPX_NF: cout << "LPX_NF" << endl; break;
479 case LPX_NS: cout << "LPX_NS" << endl; break;
482 /// Returns the status of the variable assigned to column \c col.
483 int getColStat(const Col& col) {
484 return lpx_get_col_stat(lp, col_iter_map[col]);
487 void printColStatus(int i) {
489 case LPX_BS: cout << "LPX_BS" << endl; break;
490 case LPX_NL: cout << "LPX_NL" << endl; break;
491 case LPX_NU: cout << "LPX_NU" << endl; break;
492 case LPX_NF: cout << "LPX_NF" << endl; break;
493 case LPX_NS: cout << "LPX_NS" << endl; break;
499 void solveBandB() { lpx_integer(lp); }
501 void setLP() { lpx_set_class(lp, LPX_LP); }
503 void setMIP() { lpx_set_class(lp, LPX_MIP); }
506 void _setColCont(int i) { lpx_set_col_kind(lp, i, LPX_CV); }
508 void _setColInt(int i) { lpx_set_col_kind(lp, i, LPX_IV); }
510 double _getMIPPrimal(int i) { return lpx_mip_col_val(lp, i); }
517 #endif //LEMON_LP_SOLVER_GLPK_H