Graph imlementations actually provide ReferenceMaps.
3 * This file is a part of LEMON, a generic C++ optimization library
5 * Copyright (C) 2003-2006
6 * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
7 * (Egervary Research Group on Combinatorial Optimization, EGRES).
9 * Permission to use, modify and distribute this software is granted
10 * provided that this copyright notice appears in all copies. For
11 * precise terms see the accompanying LICENSE file.
13 * This software is provided "AS IS" with no warranty of any kind,
14 * express or implied, and with no claim as to its suitability for any
20 ///\brief Implementation of the LEMON-GLPK lp solver interface.
22 #include <lemon/lp_glpk.h>
27 LpGlpk::LpGlpk() : Parent(),
28 lp(lpx_create_prob()) {
29 ///\todo constrol function for this:
30 lpx_set_int_parm(lp, LPX_K_DUAL, 1);
38 int LpGlpk::_addCol() {
39 int i=lpx_add_cols(lp, 1);
40 _setColLowerBound(i, -INF);
41 _setColUpperBound(i, INF);
48 LpSolverBase &LpGlpk::_newLp()
50 LpGlpk* newlp=new LpGlpk();
56 LpSolverBase &LpGlpk::_copyLp()
58 LpGlpk* newlp=new LpGlpk();
60 //Coefficient matrix, row bounds
61 lpx_add_rows(newlp->lp, lpx_get_num_rows(lp));
62 lpx_add_cols(newlp->lp, lpx_get_num_cols(lp));
64 int ind[1+lpx_get_num_cols(lp)];
65 Value val[1+lpx_get_num_cols(lp)];
66 for (int i=1;i<=lpx_get_num_rows(lp);++i){
67 len=lpx_get_mat_row(lp,i,ind,val);
68 lpx_set_mat_row(newlp->lp, i,len,ind,val);
69 lpx_set_row_bnds(newlp->lp,i,lpx_get_row_type(lp,i),
70 lpx_get_row_lb(lp,i),lpx_get_row_ub(lp,i));
73 //Objective function, coloumn bounds
74 lpx_set_obj_dir(newlp->lp, lpx_get_obj_dir(lp));
75 //Objectif function's constant term treated separately
76 lpx_set_obj_coef(newlp->lp,0,lpx_get_obj_coef(lp,0));
77 for (int i=1;i<=lpx_get_num_cols(lp);++i){
78 lpx_set_obj_coef(newlp->lp,i,lpx_get_obj_coef(lp,i));
79 lpx_set_col_bnds(newlp->lp,i,lpx_get_col_type(lp,i),
80 lpx_get_col_lb(lp,i),lpx_get_col_ub(lp,i));
88 int LpGlpk::_addRow() {
89 int i=lpx_add_rows(lp, 1);
94 void LpGlpk::_eraseCol(int i) {
97 lpx_del_cols(lp, 1, cols);
100 void LpGlpk::_eraseRow(int i) {
103 lpx_del_rows(lp, 1, rows);
106 void LpGlpk::_getColName(int col, std::string & name)
109 char *n = lpx_get_col_name(lp,col);
114 void LpGlpk::_setColName(int col, const std::string & name)
116 lpx_set_col_name(lp,col,const_cast<char*>(name.c_str()));
119 void LpGlpk::_setRowCoeffs(int i,
122 const Value * values )
124 lpx_set_mat_row(lp, i, length,
125 const_cast<int * >(indices) ,
126 const_cast<Value * >(values));
129 void LpGlpk::_setColCoeffs(int i,
132 const Value * values)
134 lpx_set_mat_col(lp, i, length,
135 const_cast<int * >(indices),
136 const_cast<Value * >(values));
140 void LpGlpk::_setCoeff(int row, int col, Value value)
142 ///FIXME Of course this is not efficient at all, but GLPK knows not more.
143 // First approach: get one row, apply changes and set it again
144 //(one idea to improve this: maybe it is better to do this with 1 coloumn)
146 int mem_length=2+lpx_get_num_cols(lp);
147 int* indices = new int[mem_length];
148 Value* values = new Value[mem_length];
151 int length=lpx_get_mat_row(lp, row, indices, values);
153 //The following code does not suppose that the elements of the array indices are sorted
156 while (i <= length && !found){
157 if (indices[i]==col){
166 values[length]=value;
169 lpx_set_mat_row(lp, row, length, indices, values);
175 void LpGlpk::_setColLowerBound(int i, Value lo)
180 int b=lpx_get_col_type(lp, i);
181 double up=lpx_get_col_ub(lp, i);
186 lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
192 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
201 lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
207 lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
209 lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
218 void LpGlpk::_setColUpperBound(int i, Value up)
223 int b=lpx_get_col_type(lp, i);
224 double lo=lpx_get_col_lb(lp, i);
231 lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
235 lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
243 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
246 lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
252 lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
254 lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
262 // void LpGlpk::_setRowLowerBound(int i, Value lo)
267 // int b=lpx_get_row_type(lp, i);
268 // double up=lpx_get_row_ub(lp, i);
273 // lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
279 // lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
288 // lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
294 // lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
296 // lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
304 // void LpGlpk::_setRowUpperBound(int i, Value up)
309 // int b=lpx_get_row_type(lp, i);
310 // double lo=lpx_get_row_lb(lp, i);
317 // lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
321 // lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
329 // lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
332 // lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
338 // lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
340 // lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
348 void LpGlpk::_setRowBounds(int i, Value lb, Value ub)
351 if (lb==INF || ub==-INF) {
357 lpx_set_row_bnds(lp, i, LPX_FR, lb, ub);
360 lpx_set_row_bnds(lp, i, LPX_UP, lb, ub);
365 lpx_set_row_bnds(lp, i, LPX_LO, lb, ub);
370 lpx_set_row_bnds(lp, i, LPX_FX, lb, ub);
373 lpx_set_row_bnds(lp, i, LPX_DB, lb, ub);
380 void LpGlpk::_setObjCoeff(int i, Value obj_coef)
382 //i=0 means the constant term (shift)
383 lpx_set_obj_coef(lp, i, obj_coef);
386 void LpGlpk::_clearObj()
388 for (int i=0;i<=lpx_get_num_cols(lp);++i){
389 lpx_set_obj_coef(lp, i, 0);
392 // void LpGlpk::_setObj(int length,
393 // int const * indices,
394 // Value const * values )
396 // Value new_values[1+lpx_num_cols()];
397 // for (i=0;i<=lpx_num_cols();++i){
400 // for (i=1;i<=length;++i){
401 // new_values[indices[i]]=values[i];
404 // for (i=0;i<=lpx_num_cols();++i){
405 // lpx_set_obj_coef(lp, i, new_values[i]);
409 LpGlpk::SolveExitStatus LpGlpk::_solve()
411 int i = lpx_simplex(lp);
420 LpGlpk::Value LpGlpk::_getPrimal(int i)
422 return lpx_get_col_prim(lp,i);
425 LpGlpk::Value LpGlpk::_getDual(int i)
427 return lpx_get_row_dual(lp,i);
430 LpGlpk::Value LpGlpk::_getPrimalValue()
432 return lpx_get_obj_val(lp);
434 bool LpGlpk::_isBasicCol(int i) {
435 return (lpx_get_col_stat(lp, i)==LPX_BS);
439 LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus()
441 int stat= lpx_get_status(lp);
443 case LPX_UNDEF://Undefined (no solve has been run yet)
445 case LPX_NOFEAS://There is no feasible solution (primal, I guess)
446 case LPX_INFEAS://Infeasible
448 case LPX_UNBND://Unbounded
450 case LPX_FEAS://Feasible
452 case LPX_OPT://Feasible
455 return UNDEFINED; //to avoid gcc warning
460 LpGlpk::SolutionStatus LpGlpk::_getDualStatus()
462 // std::cout<<"Itt megy: "<<lpx_get_dual_stat(lp)<<std::endl;
463 // std::cout<<"Itt a primal: "<<lpx_get_prim_stat(lp)<<std::endl;
465 switch (lpx_get_dual_stat(lp)) {
466 case LPX_D_UNDEF://Undefined (no solve has been run yet)
468 case LPX_D_NOFEAS://There is no dual feasible solution
469 // case LPX_D_INFEAS://Infeasible
471 case LPX_D_FEAS://Feasible
472 switch (lpx_get_status(lp)) {
481 return UNDEFINED; //to avoid gcc warning
486 LpGlpk::ProblemTypes LpGlpk::_getProblemType()
488 //int stat= lpx_get_status(lp);
489 int statp= lpx_get_prim_stat(lp);
490 int statd= lpx_get_dual_stat(lp);
491 if (statp==LPX_P_FEAS && statd==LPX_D_FEAS)
492 return PRIMAL_DUAL_FEASIBLE;
493 if (statp==LPX_P_FEAS && statd==LPX_D_NOFEAS)
494 return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
495 if (statp==LPX_P_NOFEAS && statd==LPX_D_FEAS)
496 return PRIMAL_INFEASIBLE_DUAL_FEASIBLE;
497 if (statp==LPX_P_NOFEAS && statd==LPX_D_NOFEAS)
498 return PRIMAL_DUAL_INFEASIBLE;
503 void LpGlpk::_setMax()
505 lpx_set_obj_dir(lp, LPX_MAX);
508 void LpGlpk::_setMin()
510 lpx_set_obj_dir(lp, LPX_MIN);
514 void LpGlpk::messageLevel(int m)
516 lpx_set_int_parm(lp, LPX_K_MSGLEV, m);
519 void LpGlpk::presolver(bool b)
521 lpx_set_int_parm(lp, LPX_K_PRESOL, b);
525 } //END OF NAMESPACE LEMON