Do not append -Wall -W to CXXFLAGS when it is set on the commandline.
2 * lemon/lp_glpk.cc - Part of LEMON, a generic C++ optimization library
4 * Copyright (C) 2006 Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
5 * (Egervary Research Group on Combinatorial Optimization, EGRES).
7 * Permission to use, modify and distribute this software is granted
8 * provided that this copyright notice appears in all copies. For
9 * precise terms see the accompanying LICENSE file.
11 * This software is provided "AS IS" with no warranty of any kind,
12 * express or implied, and with no claim as to its suitability for any
17 #ifndef LEMON_LP_GLPK_CC
18 #define LEMON_LP_GLPK_CC
21 ///\brief Implementation of the LEMON-GLPK lp solver interface.
23 #include <lemon/lp_glpk.h>
28 LpGlpk::LpGlpk() : Parent(),
29 lp(lpx_create_prob()) {
30 ///\todo constrol function for this:
31 lpx_set_int_parm(lp, LPX_K_DUAL, 1);
39 int LpGlpk::_addCol() {
40 int i=lpx_add_cols(lp, 1);
41 _setColLowerBound(i, -INF);
42 _setColUpperBound(i, INF);
49 LpSolverBase &LpGlpk::_newLp()
51 LpGlpk* newlp=new LpGlpk();
57 LpSolverBase &LpGlpk::_copyLp()
59 LpGlpk* newlp=new LpGlpk();
61 //Coefficient matrix, row bounds
62 lpx_add_rows(newlp->lp, lpx_get_num_rows(lp));
63 lpx_add_cols(newlp->lp, lpx_get_num_cols(lp));
65 int ind[1+lpx_get_num_cols(lp)];
66 Value val[1+lpx_get_num_cols(lp)];
67 for (int i=1;i<=lpx_get_num_rows(lp);++i){
68 len=lpx_get_mat_row(lp,i,ind,val);
69 lpx_set_mat_row(newlp->lp, i,len,ind,val);
70 lpx_set_row_bnds(newlp->lp,i,lpx_get_row_type(lp,i),
71 lpx_get_row_lb(lp,i),lpx_get_row_ub(lp,i));
74 //Objective function, coloumn bounds
75 lpx_set_obj_dir(newlp->lp, lpx_get_obj_dir(lp));
76 //Objectif function's constant term treated separately
77 lpx_set_obj_coef(newlp->lp,0,lpx_get_obj_coef(lp,0));
78 for (int i=1;i<=lpx_get_num_cols(lp);++i){
79 lpx_set_obj_coef(newlp->lp,i,lpx_get_obj_coef(lp,i));
80 lpx_set_col_bnds(newlp->lp,i,lpx_get_col_type(lp,i),
81 lpx_get_col_lb(lp,i),lpx_get_col_ub(lp,i));
89 int LpGlpk::_addRow() {
90 int i=lpx_add_rows(lp, 1);
95 void LpGlpk::_eraseCol(int i) {
98 lpx_del_cols(lp, 1, cols);
101 void LpGlpk::_eraseRow(int i) {
104 lpx_del_rows(lp, 1, rows);
107 void LpGlpk::_getColName(int col, std::string & name)
110 char *n = lpx_get_col_name(lp,col);
115 void LpGlpk::_setColName(int col, const std::string & name)
117 lpx_set_col_name(lp,col,const_cast<char*>(name.c_str()));
120 void LpGlpk::_setRowCoeffs(int i,
123 const Value * values )
125 lpx_set_mat_row(lp, i, length,
126 const_cast<int * >(indices) ,
127 const_cast<Value * >(values));
130 void LpGlpk::_setColCoeffs(int i,
133 const Value * values)
135 lpx_set_mat_col(lp, i, length,
136 const_cast<int * >(indices),
137 const_cast<Value * >(values));
141 void LpGlpk::_setCoeff(int row, int col, Value value)
143 ///FIXME Of course this is not efficient at all, but GLPK knows not more.
144 // First approach: get one row, apply changes and set it again
145 //(one idea to improve this: maybe it is better to do this with 1 coloumn)
147 int mem_length=2+lpx_get_num_cols(lp);
148 int* indices = new int[mem_length];
149 Value* values = new Value[mem_length];
152 int length=lpx_get_mat_row(lp, row, indices, values);
154 //The following code does not suppose that the elements of the array indices are sorted
157 while (i <= length && !found){
158 if (indices[i]==col){
167 values[length]=value;
170 lpx_set_mat_row(lp, row, length, indices, values);
176 void LpGlpk::_setColLowerBound(int i, Value lo)
181 int b=lpx_get_col_type(lp, i);
182 double up=lpx_get_col_ub(lp, i);
187 lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
193 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
202 lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
208 lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
210 lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
219 void LpGlpk::_setColUpperBound(int i, Value up)
224 int b=lpx_get_col_type(lp, i);
225 double lo=lpx_get_col_lb(lp, i);
232 lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
236 lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
244 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
247 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
253 lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
255 lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
263 // void LpGlpk::_setRowLowerBound(int i, Value lo)
268 // int b=lpx_get_row_type(lp, i);
269 // double up=lpx_get_row_ub(lp, i);
274 // lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
280 // lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
289 // lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
295 // lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
297 // lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
305 // void LpGlpk::_setRowUpperBound(int i, Value up)
310 // int b=lpx_get_row_type(lp, i);
311 // double lo=lpx_get_row_lb(lp, i);
318 // lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
322 // lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
330 // lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
333 // lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
339 // lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
341 // lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
349 void LpGlpk::_setRowBounds(int i, Value lb, Value ub)
352 if (lb==INF || ub==-INF) {
358 lpx_set_row_bnds(lp, i, LPX_FR, lb, ub);
361 lpx_set_row_bnds(lp, i, LPX_UP, lb, ub);
366 lpx_set_row_bnds(lp, i, LPX_LO, lb, ub);
371 lpx_set_row_bnds(lp, i, LPX_FX, lb, ub);
374 lpx_set_row_bnds(lp, i, LPX_DB, lb, ub);
381 void LpGlpk::_setObjCoeff(int i, Value obj_coef)
383 //i=0 means the constant term (shift)
384 lpx_set_obj_coef(lp, i, obj_coef);
387 void LpGlpk::_clearObj()
389 for (int i=0;i<=lpx_get_num_cols(lp);++i){
390 lpx_set_obj_coef(lp, i, 0);
393 // void LpGlpk::_setObj(int length,
394 // int const * indices,
395 // Value const * values )
397 // Value new_values[1+lpx_num_cols()];
398 // for (i=0;i<=lpx_num_cols();++i){
401 // for (i=1;i<=length;++i){
402 // new_values[indices[i]]=values[i];
405 // for (i=0;i<=lpx_num_cols();++i){
406 // lpx_set_obj_coef(lp, i, new_values[i]);
410 LpGlpk::SolveExitStatus LpGlpk::_solve()
412 int i = lpx_simplex(lp);
421 LpGlpk::Value LpGlpk::_getPrimal(int i)
423 return lpx_get_col_prim(lp,i);
426 LpGlpk::Value LpGlpk::_getDual(int i)
428 return lpx_get_row_dual(lp,i);
431 LpGlpk::Value LpGlpk::_getPrimalValue()
433 return lpx_get_obj_val(lp);
435 bool LpGlpk::_isBasicCol(int i) {
436 return (lpx_get_col_stat(lp, i)==LPX_BS);
440 LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus()
442 int stat= lpx_get_status(lp);
444 case LPX_UNDEF://Undefined (no solve has been run yet)
446 case LPX_NOFEAS://There is no feasible solution (primal, I guess)
447 case LPX_INFEAS://Infeasible
449 case LPX_UNBND://Unbounded
451 case LPX_FEAS://Feasible
453 case LPX_OPT://Feasible
456 return UNDEFINED; //to avoid gcc warning
461 LpGlpk::SolutionStatus LpGlpk::_getDualStatus()
463 // std::cout<<"Itt megy: "<<lpx_get_dual_stat(lp)<<std::endl;
464 // std::cout<<"Itt a primal: "<<lpx_get_prim_stat(lp)<<std::endl;
466 switch (lpx_get_dual_stat(lp)) {
467 case LPX_D_UNDEF://Undefined (no solve has been run yet)
469 case LPX_D_NOFEAS://There is no dual feasible solution
470 // case LPX_D_INFEAS://Infeasible
472 case LPX_D_FEAS://Feasible
473 switch (lpx_get_status(lp)) {
482 return UNDEFINED; //to avoid gcc warning
487 LpGlpk::ProblemTypes LpGlpk::_getProblemType()
489 //int stat= lpx_get_status(lp);
490 int statp= lpx_get_prim_stat(lp);
491 int statd= lpx_get_dual_stat(lp);
492 if (statp==LPX_P_FEAS && statd==LPX_D_FEAS)
493 return PRIMAL_DUAL_FEASIBLE;
494 if (statp==LPX_P_FEAS && statd==LPX_D_NOFEAS)
495 return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
496 if (statp==LPX_P_NOFEAS && statd==LPX_D_FEAS)
497 return PRIMAL_INFEASIBLE_DUAL_FEASIBLE;
498 if (statp==LPX_P_NOFEAS && statd==LPX_D_NOFEAS)
499 return PRIMAL_DUAL_INFEASIBLE;
504 void LpGlpk::_setMax()
506 lpx_set_obj_dir(lp, LPX_MAX);
509 void LpGlpk::_setMin()
511 lpx_set_obj_dir(lp, LPX_MIN);
515 void LpGlpk::messageLevel(int m)
517 lpx_set_int_parm(lp, LPX_K_MSGLEV, m);
520 void LpGlpk::presolver(bool b)
522 lpx_set_int_parm(lp, LPX_K_PRESOL, b);
526 } //END OF NAMESPACE LEMON
528 #endif //LEMON_LP_GLPK_CC