diff -r c9218405595b -r d8d6ab871608 lemon/lp_glpk.cc --- a/lemon/lp_glpk.cc Mon May 07 11:42:18 2007 +0000 +++ b/lemon/lp_glpk.cc Mon May 07 18:19:55 2007 +0000 @@ -21,61 +21,84 @@ #include //#include + +#if GLP_MAJOR_VERSION > 4 || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION > 15) +#define LEMON_glp(func) (glp_##func) +#define LEMON_lpx(func) (lpx_##func) + +#define LEMON_GLP(def) (GLP_##def) +#define LEMON_LPX(def) (LPX_##def) + +#else + +#define LEMON_glp(func) (lpx_##func) +#define LEMON_lpx(func) (lpx_##func) + +#define LEMON_GLP(def) (LPX_##def) +#define LEMON_LPX(def) (LPX_##def) + +#endif + namespace lemon { - LpGlpk::LpGlpk() : Parent() { + solved = false; rows = _lp_bits::LpId(1); cols = _lp_bits::LpId(1); - lp = lpx_create_prob(); - lpx_create_index(lp); - ///\todo control function for this: - lpx_set_int_parm(lp, LPX_K_DUAL, 1); + lp = LEMON_glp(create_prob)(); + LEMON_glp(create_index)(lp); + LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_DUAL), 1); messageLevel(0); } LpGlpk::LpGlpk(const LpGlpk &glp) : Parent() { + solved = false; rows = _lp_bits::LpId(1); cols = _lp_bits::LpId(1); - lp = lpx_create_prob(); - lpx_create_index(lp); + lp = LEMON_glp(create_prob)(); + LEMON_glp(create_index)(lp); ///\todo control function for this: - lpx_set_int_parm(lp, LPX_K_DUAL, 1); + LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_DUAL), 1); messageLevel(0); //Coefficient matrix, row bounds - lpx_add_rows(lp, lpx_get_num_rows(glp.lp)); - lpx_add_cols(lp, lpx_get_num_cols(glp.lp)); + LEMON_glp(add_rows)(lp, LEMON_glp(get_num_rows)(glp.lp)); + LEMON_glp(add_cols)(lp, LEMON_glp(get_num_cols)(glp.lp)); int len; - int ind[1+lpx_get_num_cols(glp.lp)]; - Value val[1+lpx_get_num_cols(glp.lp)]; - for (int i=1;i<=lpx_get_num_rows(glp.lp);++i) + int ind[1+LEMON_glp(get_num_cols)(glp.lp)]; + Value val[1+LEMON_glp(get_num_cols)(glp.lp)]; + for (int i=1;i<=LEMON_glp(get_num_rows)(glp.lp);++i) { - len=lpx_get_mat_row(glp.lp,i,ind,val); - lpx_set_mat_row(lp, i,len,ind,val); - lpx_set_row_bnds(lp,i,lpx_get_row_type(glp.lp,i), - lpx_get_row_lb(glp.lp,i),lpx_get_row_ub(glp.lp,i)); + len=LEMON_glp(get_mat_row)(glp.lp,i,ind,val); + LEMON_glp(set_mat_row)(lp, i,len,ind,val); + LEMON_glp(set_row_bnds)(lp,i, + LEMON_glp(get_row_type)(glp.lp,i), + LEMON_glp(get_row_lb)(glp.lp,i), + LEMON_glp(get_row_ub)(glp.lp,i)); } //Objective function, coloumn bounds - lpx_set_obj_dir(lp, lpx_get_obj_dir(glp.lp)); + LEMON_glp(set_obj_dir)(lp, LEMON_glp(get_obj_dir)(glp.lp)); //Objectif function's constant term treated separately - lpx_set_obj_coef(lp,0,lpx_get_obj_coef(glp.lp,0)); - for (int i=1;i<=lpx_get_num_cols(glp.lp);++i) + LEMON_glp(set_obj_coef)(lp,0,LEMON_glp(get_obj_coef)(glp.lp,0)); + for (int i=1;i<=LEMON_glp(get_num_cols)(glp.lp);++i) { - lpx_set_obj_coef(lp,i,lpx_get_obj_coef(glp.lp,i)); - lpx_set_col_bnds(lp,i,lpx_get_col_type(glp.lp,i), - lpx_get_col_lb(glp.lp,i),lpx_get_col_ub(glp.lp,i)); + LEMON_glp(set_obj_coef)(lp,i, + LEMON_glp(get_obj_coef)(glp.lp,i)); + LEMON_glp(set_col_bnds)(lp,i, + LEMON_glp(get_col_type)(glp.lp,i), + LEMON_glp(get_col_lb)(glp.lp,i), + LEMON_glp(get_col_ub)(glp.lp,i)); } } LpGlpk::~LpGlpk() { - lpx_delete_prob(lp); + LEMON_glp(delete_prob)(lp); } int LpGlpk::_addCol() { - int i=lpx_add_cols(lp, 1); - _setColLowerBound(i, -INF); - _setColUpperBound(i, INF); + int i=LEMON_glp(add_cols)(lp, 1); + LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FR), 0.0, 0.0); + solved = false; return i; } @@ -97,7 +120,8 @@ } int LpGlpk::_addRow() { - int i=lpx_add_rows(lp, 1); + int i=LEMON_glp(add_rows)(lp, 1); + solved = false; return i; } @@ -105,32 +129,34 @@ void LpGlpk::_eraseCol(int i) { int ca[2]; ca[1]=i; - lpx_del_cols(lp, 1, ca); + LEMON_glp(del_cols)(lp, 1, ca); + solved = false; } void LpGlpk::_eraseRow(int i) { int ra[2]; ra[1]=i; - lpx_del_rows(lp, 1, ra); + LEMON_glp(del_rows)(lp, 1, ra); + solved = false; } void LpGlpk::_getColName(int c, std::string & name) const { - char *n = lpx_get_col_name(lp,c); + const char *n = LEMON_glp(get_col_name)(lp,c); name = n?n:""; } void LpGlpk::_setColName(int c, const std::string & name) { - lpx_set_col_name(lp,c,const_cast(name.c_str())); + LEMON_glp(set_col_name)(lp,c,const_cast(name.c_str())); } int LpGlpk::_colByName(const std::string& name) const { - int k = lpx_find_col(lp, const_cast(name.c_str())); + int k = LEMON_glp(find_col)(lp, const_cast(name.c_str())); return k > 0 ? k : -1; } @@ -148,17 +174,20 @@ values.push_back(it->second); } - lpx_set_mat_row(lp, i, values.size() - 1, &indices[0], &values[0]); + LEMON_glp(set_mat_row)(lp, i, values.size() - 1, + &indices[0], &values[0]); + + solved = false; } void LpGlpk::_getRowCoeffs(int ix, RowIterator b) const { - int length = lpx_get_mat_row(lp, ix, 0, 0); + int length = LEMON_glp(get_mat_row)(lp, ix, 0, 0); std::vector indices(length + 1); std::vector values(length + 1); - lpx_get_mat_row(lp, ix, &indices[0], &values[0]); + LEMON_glp(get_mat_row)(lp, ix, &indices[0], &values[0]); for (int i = 1; i <= length; ++i) { *b = std::make_pair(indices[i], values[i]); @@ -179,17 +208,20 @@ values.push_back(it->second); } - lpx_set_mat_col(lp, ix, values.size() - 1, &indices[0], &values[0]); + LEMON_glp(set_mat_col)(lp, ix, values.size() - 1, + &indices[0], &values[0]); + + solved = false; } void LpGlpk::_getColCoeffs(int ix, ColIterator b) const { - int length = lpx_get_mat_col(lp, ix, 0, 0); + int length = LEMON_glp(get_mat_col)(lp, ix, 0, 0); std::vector indices(length + 1); std::vector values(length + 1); - lpx_get_mat_col(lp, ix, &indices[0], &values[0]); + LEMON_glp(get_mat_col)(lp, ix, &indices[0], &values[0]); for (int i = 1; i <= length; ++i) { *b = std::make_pair(indices[i], values[i]); @@ -200,14 +232,14 @@ void LpGlpk::_setCoeff(int ix, int jx, Value value) { - if (lpx_get_num_cols(lp) < lpx_get_num_rows(lp)) { + if (LEMON_glp(get_num_cols)(lp) < LEMON_glp(get_num_rows)(lp)) { - int length=lpx_get_mat_row(lp, ix, 0, 0); + int length=LEMON_glp(get_mat_row)(lp, ix, 0, 0); std::vector indices(length + 2); std::vector values(length + 2); - lpx_get_mat_row(lp, ix, &indices[0], &values[0]); + LEMON_glp(get_mat_row)(lp, ix, &indices[0], &values[0]); //The following code does not suppose that the elements of the //array indices are sorted @@ -225,16 +257,16 @@ values[length]=value; } - lpx_set_mat_row(lp, ix, length, &indices[0], &values[0]); + LEMON_glp(set_mat_row)(lp, ix, length, &indices[0], &values[0]); } else { - int length=lpx_get_mat_col(lp, jx, 0, 0); + int length=LEMON_glp(get_mat_col)(lp, jx, 0, 0); std::vector indices(length + 2); std::vector values(length + 2); - lpx_get_mat_col(lp, jx, &indices[0], &values[0]); + LEMON_glp(get_mat_col)(lp, jx, &indices[0], &values[0]); //The following code does not suppose that the elements of the //array indices are sorted @@ -252,19 +284,21 @@ values[length]=value; } - lpx_set_mat_col(lp, jx, length, &indices[0], &values[0]); + LEMON_glp(set_mat_col)(lp, jx, length, &indices[0], &values[0]); } + + solved = false; } LpGlpk::Value LpGlpk::_getCoeff(int ix, int jx) const { - int length=lpx_get_mat_row(lp, ix, 0, 0); + int length=LEMON_glp(get_mat_row)(lp, ix, 0, 0); std::vector indices(length + 1); std::vector values(length + 1); - lpx_get_mat_row(lp, ix, &indices[0], &values[0]); + LEMON_glp(get_mat_row)(lp, ix, &indices[0], &values[0]); //The following code does not suppose that the elements of the //array indices are sorted @@ -283,52 +317,53 @@ if (lo==INF) { //FIXME error } - int b=lpx_get_col_type(lp, i); - double up=lpx_get_col_ub(lp, i); + int b=LEMON_glp(get_col_type)(lp, i); + double up=LEMON_glp(get_col_ub)(lp, i); if (lo==-INF) { switch (b) { - case LPX_FR: - case LPX_LO: - lpx_set_col_bnds(lp, i, LPX_FR, lo, up); + case LEMON_GLP(FR): + case LEMON_GLP(LO): + LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FR), lo, up); break; - case LPX_UP: + case LEMON_GLP(UP): break; - case LPX_DB: - case LPX_FX: - lpx_set_col_bnds(lp, i, LPX_UP, lo, up); + case LEMON_GLP(DB): + case LEMON_GLP(FX): + LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(UP), lo, up); break; default: ; //FIXME error } } else { switch (b) { - case LPX_FR: - case LPX_LO: - lpx_set_col_bnds(lp, i, LPX_LO, lo, up); + case LEMON_GLP(FR): + case LEMON_GLP(LO): + LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(LO), lo, up); break; - case LPX_UP: - case LPX_DB: - case LPX_FX: + case LEMON_GLP(UP): + case LEMON_GLP(DB): + case LEMON_GLP(FX): if (lo==up) - lpx_set_col_bnds(lp, i, LPX_FX, lo, up); + LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FX), lo, up); else - lpx_set_col_bnds(lp, i, LPX_DB, lo, up); + LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(DB), lo, up); break; default: ; //FIXME error } } + solved = false; } LpGlpk::Value LpGlpk::_getColLowerBound(int i) const { - int b=lpx_get_col_type(lp, i); + int b=LEMON_glp(get_col_type)(lp, i); switch (b) { - case LPX_LO: - case LPX_DB: - case LPX_FX: - return lpx_get_col_lb(lp, i); + case LEMON_GLP(LO): + case LEMON_GLP(DB): + case LEMON_GLP(FX): + return LEMON_glp(get_col_lb)(lp, i); default: ; return -INF; } @@ -339,53 +374,55 @@ if (up==-INF) { //FIXME error } - int b=lpx_get_col_type(lp, i); - double lo=lpx_get_col_lb(lp, i); + int b=LEMON_glp(get_col_type)(lp, i); + double lo=LEMON_glp(get_col_lb)(lp, i); if (up==INF) { switch (b) { - case LPX_FR: - case LPX_LO: + case LEMON_GLP(FR): + case LEMON_GLP(LO): break; - case LPX_UP: - lpx_set_col_bnds(lp, i, LPX_FR, lo, up); + case LEMON_GLP(UP): + LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FR), lo, up); break; - case LPX_DB: - case LPX_FX: - lpx_set_col_bnds(lp, i, LPX_LO, lo, up); + case LEMON_GLP(DB): + case LEMON_GLP(FX): + LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(LO), lo, up); break; default: ; //FIXME error } } else { switch (b) { - case LPX_FR: - lpx_set_col_bnds(lp, i, LPX_UP, lo, up); + case LEMON_GLP(FR): + LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(UP), lo, up); break; - case LPX_UP: - lpx_set_col_bnds(lp, i, LPX_UP, lo, up); + case LEMON_GLP(UP): + LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(UP), lo, up); break; - case LPX_LO: - case LPX_DB: - case LPX_FX: + case LEMON_GLP(LO): + case LEMON_GLP(DB): + case LEMON_GLP(FX): if (lo==up) - lpx_set_col_bnds(lp, i, LPX_FX, lo, up); + LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FX), lo, up); else - lpx_set_col_bnds(lp, i, LPX_DB, lo, up); + LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(DB), lo, up); break; default: ; //FIXME error } } + + solved = false; } LpGlpk::Value LpGlpk::_getColUpperBound(int i) const { - int b=lpx_get_col_type(lp, i); + int b=LEMON_glp(get_col_type)(lp, i); switch (b) { - case LPX_UP: - case LPX_DB: - case LPX_FX: - return lpx_get_col_ub(lp, i); + case LEMON_GLP(UP): + case LEMON_GLP(DB): + case LEMON_GLP(FX): + return LEMON_glp(get_col_ub)(lp, i); default: ; return INF; } @@ -400,49 +437,50 @@ if (lb == -INF){ if (ub == INF){ - lpx_set_row_bnds(lp, i, LPX_FR, lb, ub); + LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(FR), lb, ub); } else{ - lpx_set_row_bnds(lp, i, LPX_UP, lb, ub); + LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(UP), lb, ub); } } else{ if (ub==INF){ - lpx_set_row_bnds(lp, i, LPX_LO, lb, ub); + LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(LO), lb, ub); } else{ if (lb == ub){ - lpx_set_row_bnds(lp, i, LPX_FX, lb, ub); + LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(FX), lb, ub); } else{ - lpx_set_row_bnds(lp, i, LPX_DB, lb, ub); + LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(DB), lb, ub); } } } + solved = false; } void LpGlpk::_getRowBounds(int i, Value &lb, Value &ub) const { - int b=lpx_get_row_type(lp, i); + int b=LEMON_glp(get_row_type)(lp, i); switch (b) { - case LPX_FR: - case LPX_UP: + case LEMON_GLP(FR): + case LEMON_GLP(UP): lb = -INF; break; default: - lb=lpx_get_row_lb(lp, i); + lb=LEMON_glp(get_row_lb)(lp, i); } switch (b) { - case LPX_FR: - case LPX_LO: + case LEMON_GLP(FR): + case LEMON_GLP(LO): ub = INF; break; default: - ub=lpx_get_row_ub(lp, i); + ub=LEMON_glp(get_row_ub)(lp, i); } } @@ -450,31 +488,36 @@ void LpGlpk::_setObjCoeff(int i, Value obj_coef) { //i=0 means the constant term (shift) - lpx_set_obj_coef(lp, i, obj_coef); + LEMON_glp(set_obj_coef)(lp, i, obj_coef); + + solved = false; } LpGlpk::Value LpGlpk::_getObjCoeff(int i) const { //i=0 means the constant term (shift) - return lpx_get_obj_coef(lp, i); + return LEMON_glp(get_obj_coef)(lp, i); } void LpGlpk::_clearObj() { - for (int i=0;i<=lpx_get_num_cols(lp);++i){ - lpx_set_obj_coef(lp, i, 0); + for (int i=0;i<=LEMON_glp(get_num_cols)(lp);++i){ + LEMON_glp(set_obj_coef)(lp, i, 0); } + + solved = false; } LpGlpk::SolveExitStatus LpGlpk::_solve() { // A way to check the problem to be solved - //lpx_write_cpxlp(lp,"naittvan.cpx"); + //LEMON_glp(write_cpxlp(lp,"naittvan.cpx"); - lpx_std_basis(lp); - int i = lpx_simplex(lp); + LEMON_lpx(std_basis)(lp); + int i = LEMON_lpx(simplex)(lp); switch (i) { - case LPX_E_OK: + case LEMON_LPX(E_OK): + solved = true; return SOLVED; default: return UNSOLVED; @@ -483,38 +526,39 @@ LpGlpk::Value LpGlpk::_getPrimal(int i) const { - return lpx_get_col_prim(lp,i); + return LEMON_glp(get_col_prim)(lp,i); } LpGlpk::Value LpGlpk::_getDual(int i) const { - return lpx_get_row_dual(lp,i); + return LEMON_glp(get_row_dual)(lp,i); } LpGlpk::Value LpGlpk::_getPrimalValue() const { - return lpx_get_obj_val(lp); + return LEMON_glp(get_obj_val)(lp); } bool LpGlpk::_isBasicCol(int i) const { - return (lpx_get_col_stat(lp, i)==LPX_BS); + return (LEMON_glp(get_col_stat)(lp, i)==LEMON_GLP(BS)); } LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus() const { - int stat= lpx_get_status(lp); + if (!solved) return UNDEFINED; + int stat= LEMON_lpx(get_status)(lp); switch (stat) { - case LPX_UNDEF://Undefined (no solve has been run yet) + case LEMON_LPX(UNDEF)://Undefined (no solve has been run yet) return UNDEFINED; - case LPX_NOFEAS://There is no feasible solution (primal, I guess) - case LPX_INFEAS://Infeasible + case LEMON_LPX(NOFEAS)://There is no feasible solution (primal, I guess) + case LEMON_LPX(INFEAS)://Infeasible return INFEASIBLE; - case LPX_UNBND://Unbounded + case LEMON_LPX(UNBND)://Unbounded return INFINITE; - case LPX_FEAS://Feasible + case LEMON_LPX(FEAS)://Feasible return FEASIBLE; - case LPX_OPT://Feasible + case LEMON_LPX(OPT)://Feasible return OPTIMAL; default: return UNDEFINED; //to avoid gcc warning @@ -524,17 +568,18 @@ LpGlpk::SolutionStatus LpGlpk::_getDualStatus() const { - switch (lpx_get_dual_stat(lp)) { - case LPX_D_UNDEF://Undefined (no solve has been run yet) + if (!solved) return UNDEFINED; + switch (LEMON_lpx(get_dual_stat)(lp)) { + case LEMON_LPX(D_UNDEF)://Undefined (no solve has been run yet) return UNDEFINED; - case LPX_D_NOFEAS://There is no dual feasible solution -// case LPX_D_INFEAS://Infeasible + case LEMON_LPX(D_NOFEAS)://There is no dual feasible solution +// case LEMON_LPX(D_INFEAS://Infeasible return INFEASIBLE; - case LPX_D_FEAS://Feasible - switch (lpx_get_status(lp)) { - case LPX_NOFEAS: + case LEMON_LPX(D_FEAS)://Feasible + switch (LEMON_lpx(get_status)(lp)) { + case LEMON_LPX(NOFEAS): return INFINITE; - case LPX_OPT: + case LEMON_LPX(OPT): return OPTIMAL; default: return FEASIBLE; @@ -547,16 +592,17 @@ LpGlpk::ProblemTypes LpGlpk::_getProblemType() const { - //int stat= lpx_get_status(lp); - int statp= lpx_get_prim_stat(lp); - int statd= lpx_get_dual_stat(lp); - if (statp==LPX_P_FEAS && statd==LPX_D_FEAS) + if (!solved) return UNKNOWN; + //int stat= LEMON_glp(get_status(lp); + int statp= LEMON_lpx(get_prim_stat)(lp); + int statd= LEMON_lpx(get_dual_stat)(lp); + if (statp==LEMON_LPX(P_FEAS) && statd==LEMON_LPX(D_FEAS)) return PRIMAL_DUAL_FEASIBLE; - if (statp==LPX_P_FEAS && statd==LPX_D_NOFEAS) + if (statp==LEMON_LPX(P_FEAS) && statd==LEMON_LPX(D_NOFEAS)) return PRIMAL_FEASIBLE_DUAL_INFEASIBLE; - if (statp==LPX_P_NOFEAS && statd==LPX_D_FEAS) + if (statp==LEMON_LPX(P_NOFEAS) && statd==LEMON_LPX(D_FEAS)) return PRIMAL_INFEASIBLE_DUAL_FEASIBLE; - if (statp==LPX_P_NOFEAS && statd==LPX_D_NOFEAS) + if (statp==LEMON_LPX(P_NOFEAS) && statd==LEMON_LPX(D_NOFEAS)) return PRIMAL_DUAL_INFEASIBLE; //In all other cases return UNKNOWN; @@ -564,29 +610,31 @@ void LpGlpk::_setMax() { - lpx_set_obj_dir(lp, LPX_MAX); + solved = false; + LEMON_glp(set_obj_dir)(lp, LEMON_GLP(MAX)); } void LpGlpk::_setMin() { - lpx_set_obj_dir(lp, LPX_MIN); + solved = false; + LEMON_glp(set_obj_dir)(lp, LEMON_GLP(MIN)); } bool LpGlpk::_isMax() const { - return (lpx_get_obj_dir(lp)==LPX_MAX); + return (LEMON_glp(get_obj_dir)(lp)==LEMON_GLP(MAX)); } void LpGlpk::messageLevel(int m) { - lpx_set_int_parm(lp, LPX_K_MSGLEV, m); + LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_MSGLEV), m); } void LpGlpk::presolver(bool b) { - lpx_set_int_parm(lp, LPX_K_PRESOL, b); + LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_PRESOL), b); }