COIN-OR::LEMON - Graph Library

Changeset 459:ed54c0d13df0 in lemon-1.2 for lemon/lp_glpk.cc


Ignore:
Timestamp:
12/02/08 22:48:28 (15 years ago)
Author:
Balazs Dezso <deba@…>
Branch:
default
Children:
460:76ec7bd57026, 502:17cabb114d52
Phase:
public
Message:

Thorough redesign of the LP/MIP interface (#44)

  • Redesigned class structure
  • Redesigned iterators
  • Some functions in the basic interface redesigned
  • More complete setting functions
  • Ray retrieving functions
  • Lot of improvements
  • Cplex common env
  • CLP macro definition to config.h.in
  • Update lp.h to also use soplex and clp
  • Remove default_solver_name
  • New solverName() function in solvers
  • Handle exceptions for MipCplex? test
  • Rename tolerance parameter to epsilon
  • Rename MapIt? to CoeffIt?
  • Lot of documentation improvements
  • Various bugfixes
File:
1 edited

Legend:

Unmodified
Added
Removed
  • lemon/lp_glpk.cc

    r458 r459  
    1818
    1919///\file
    20 ///\brief Implementation of the LEMON-GLPK lp solver interface.
     20///\brief Implementation of the LEMON GLPK LP and MIP solver interface.
    2121
    2222#include <lemon/lp_glpk.h>
    23 //#include <iostream>
    24 
    25 extern "C" {
    2623#include <glpk.h>
    27 }
    28 
    29 #if GLP_MAJOR_VERSION > 4 || (GLP_MAJOR_VERSION == 4 && GLP_MINOR_VERSION > 15)
    30 #define LEMON_glp(func) (glp_##func)
    31 #define LEMON_lpx(func) (lpx_##func)
    32 
    33 #define LEMON_GLP(def) (GLP_##def)
    34 #define LEMON_LPX(def) (LPX_##def)
    35 
    36 #else
    37 
    38 #define LEMON_glp(func) (lpx_##func)
    39 #define LEMON_lpx(func) (lpx_##func)
    40 
    41 #define LEMON_GLP(def) (LPX_##def)
    42 #define LEMON_LPX(def) (LPX_##def)
    43 
    44 #endif
     24
     25#include <lemon/assert.h>
    4526
    4627namespace lemon {
    4728
    48   LpGlpk::LpGlpk() : Parent() {
    49     solved = false;
    50     rows = _lp_bits::LpId(1);
    51     cols = _lp_bits::LpId(1);
    52     lp = LEMON_glp(create_prob)();
    53     LEMON_glp(create_index)(lp);
    54     messageLevel(0);
    55   }
    56 
    57   LpGlpk::LpGlpk(const LpGlpk &glp) : Parent() {
    58     solved = false;
    59     rows = _lp_bits::LpId(1);
    60     cols = _lp_bits::LpId(1);
    61     lp = LEMON_glp(create_prob)();
    62     LEMON_glp(create_index)(lp);
    63     messageLevel(0);
    64     //Coefficient matrix, row bounds
    65     LEMON_glp(add_rows)(lp, LEMON_glp(get_num_rows)(glp.lp));
    66     LEMON_glp(add_cols)(lp, LEMON_glp(get_num_cols)(glp.lp));
    67     int len;
    68     std::vector<int> ind(1+LEMON_glp(get_num_cols)(glp.lp));
    69     std::vector<Value> val(1+LEMON_glp(get_num_cols)(glp.lp));
    70     for (int i=1;i<=LEMON_glp(get_num_rows)(glp.lp);++i)
    71       {
    72         len=LEMON_glp(get_mat_row)(glp.lp,i,&*ind.begin(),&*val.begin());
    73         LEMON_glp(set_mat_row)(lp, i,len,&*ind.begin(),&*val.begin());
    74         LEMON_glp(set_row_bnds)(lp,i,
    75                                 LEMON_glp(get_row_type)(glp.lp,i),
    76                                 LEMON_glp(get_row_lb)(glp.lp,i),
    77                                 LEMON_glp(get_row_ub)(glp.lp,i));
    78       }
    79 
    80     //Objective function, coloumn bounds
    81     LEMON_glp(set_obj_dir)(lp, LEMON_glp(get_obj_dir)(glp.lp));
    82     //Objectif function's constant term treated separately
    83     LEMON_glp(set_obj_coef)(lp,0,LEMON_glp(get_obj_coef)(glp.lp,0));
    84     for (int i=1;i<=LEMON_glp(get_num_cols)(glp.lp);++i)
    85       {
    86         LEMON_glp(set_obj_coef)(lp,i,
    87                                 LEMON_glp(get_obj_coef)(glp.lp,i));
    88         LEMON_glp(set_col_bnds)(lp,i,
    89                                 LEMON_glp(get_col_type)(glp.lp,i),
    90                                 LEMON_glp(get_col_lb)(glp.lp,i),
    91                                 LEMON_glp(get_col_ub)(glp.lp,i));
    92       }
    93     rows = glp.rows;
    94     cols = glp.cols;
    95   }
    96 
    97   LpGlpk::~LpGlpk() {
    98     LEMON_glp(delete_prob)(lp);
    99   }
    100 
    101   int LpGlpk::_addCol() {
    102     int i=LEMON_glp(add_cols)(lp, 1);
    103     LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FR), 0.0, 0.0);
    104     solved = false;
     29  // GlpkBase members
     30
     31  GlpkBase::GlpkBase() : LpBase() {
     32    lp = glp_create_prob();
     33    glp_create_index(lp);
     34  }
     35
     36  GlpkBase::GlpkBase(const GlpkBase &other) : LpBase() {
     37    lp = glp_create_prob();
     38    glp_copy_prob(lp, other.lp, GLP_ON);
     39    glp_create_index(lp);
     40    rows = other.rows;
     41    cols = other.cols;
     42  }
     43
     44  GlpkBase::~GlpkBase() {
     45    glp_delete_prob(lp);
     46  }
     47
     48  int GlpkBase::_addCol() {
     49    int i = glp_add_cols(lp, 1);
     50    glp_set_col_bnds(lp, i, GLP_FR, 0.0, 0.0);
    10551    return i;
    10652  }
    10753
    108   ///\e
    109 
    110 
    111   LpSolverBase* LpGlpk::_newLp()
    112   {
    113     LpGlpk* newlp = new LpGlpk;
    114     return newlp;
    115   }
    116 
    117   ///\e
    118 
    119   LpSolverBase* LpGlpk::_copyLp()
    120   {
    121     LpGlpk *newlp = new LpGlpk(*this);
    122     return newlp;
    123   }
    124 
    125   int LpGlpk::_addRow() {
    126     int i=LEMON_glp(add_rows)(lp, 1);
    127     solved = false;
     54  int GlpkBase::_addRow() {
     55    int i = glp_add_rows(lp, 1);
     56    glp_set_row_bnds(lp, i, GLP_FR, 0.0, 0.0);
    12857    return i;
    12958  }
    13059
    131 
    132   void LpGlpk::_eraseCol(int i) {
     60  void GlpkBase::_eraseCol(int i) {
    13361    int ca[2];
    134     ca[1]=i;
    135     LEMON_glp(del_cols)(lp, 1, ca);
    136     solved = false;
    137   }
    138 
    139   void LpGlpk::_eraseRow(int i) {
     62    ca[1] = i;
     63    glp_del_cols(lp, 1, ca);
     64  }
     65
     66  void GlpkBase::_eraseRow(int i) {
    14067    int ra[2];
    141     ra[1]=i;
    142     LEMON_glp(del_rows)(lp, 1, ra);
    143     solved = false;
    144   }
    145 
    146   void LpGlpk::_getColName(int c, std::string & name) const
    147   {
    148 
    149     const char *n = LEMON_glp(get_col_name)(lp,c);
    150     name = n?n:"";
    151   }
    152 
    153 
    154   void LpGlpk::_setColName(int c, const std::string & name)
    155   {
    156     LEMON_glp(set_col_name)(lp,c,const_cast<char*>(name.c_str()));
    157 
    158   }
    159 
    160   int LpGlpk::_colByName(const std::string& name) const
    161   {
    162     int k = LEMON_glp(find_col)(lp, const_cast<char*>(name.c_str()));
     68    ra[1] = i;
     69    glp_del_rows(lp, 1, ra);
     70  }
     71
     72  void GlpkBase::_eraseColId(int i) {
     73    cols.eraseIndex(i);
     74    cols.shiftIndices(i);
     75  }
     76
     77  void GlpkBase::_eraseRowId(int i) {
     78    rows.eraseIndex(i);
     79    rows.shiftIndices(i);
     80  }
     81
     82  void GlpkBase::_getColName(int c, std::string& name) const {
     83    const char *str = glp_get_col_name(lp, c);
     84    if (str) name = str;
     85    else name.clear();
     86  }
     87
     88  void GlpkBase::_setColName(int c, const std::string & name) {
     89    glp_set_col_name(lp, c, const_cast<char*>(name.c_str()));
     90
     91  }
     92
     93  int GlpkBase::_colByName(const std::string& name) const {
     94    int k = glp_find_col(lp, const_cast<char*>(name.c_str()));
    16395    return k > 0 ? k : -1;
    16496  }
    16597
    166 
    167   void LpGlpk::_setRowCoeffs(int i, ConstRowIterator b, ConstRowIterator e)
    168   {
    169     std::vector<int> indices;
     98  void GlpkBase::_getRowName(int r, std::string& name) const {
     99    const char *str = glp_get_row_name(lp, r);
     100    if (str) name = str;
     101    else name.clear();
     102  }
     103
     104  void GlpkBase::_setRowName(int r, const std::string & name) {
     105    glp_set_row_name(lp, r, const_cast<char*>(name.c_str()));
     106
     107  }
     108
     109  int GlpkBase::_rowByName(const std::string& name) const {
     110    int k = glp_find_row(lp, const_cast<char*>(name.c_str()));
     111    return k > 0 ? k : -1;
     112  }
     113
     114  void GlpkBase::_setRowCoeffs(int i, ExprIterator b, ExprIterator e) {
     115    std::vector<int> indexes;
    170116    std::vector<Value> values;
    171117
    172     indices.push_back(0);
     118    indexes.push_back(0);
    173119    values.push_back(0);
    174120
    175     for(ConstRowIterator it=b; it!=e; ++it) {
    176       indices.push_back(it->first);
     121    for(ExprIterator it = b; it != e; ++it) {
     122      indexes.push_back(it->first);
    177123      values.push_back(it->second);
    178124    }
    179125
    180     LEMON_glp(set_mat_row)(lp, i, values.size() - 1,
    181                                 &indices[0], &values[0]);
    182 
    183     solved = false;
    184   }
    185 
    186   void LpGlpk::_getRowCoeffs(int ix, RowIterator b) const
    187   {
    188     int length = LEMON_glp(get_mat_row)(lp, ix, 0, 0);
    189 
    190     std::vector<int> indices(length + 1);
     126    glp_set_mat_row(lp, i, values.size() - 1,
     127                    &indexes.front(), &values.front());
     128  }
     129
     130  void GlpkBase::_getRowCoeffs(int ix, InsertIterator b) const {
     131    int length = glp_get_mat_row(lp, ix, 0, 0);
     132
     133    std::vector<int> indexes(length + 1);
    191134    std::vector<Value> values(length + 1);
    192135
    193     LEMON_glp(get_mat_row)(lp, ix, &indices[0], &values[0]);
     136    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
    194137
    195138    for (int i = 1; i <= length; ++i) {
    196       *b = std::make_pair(indices[i], values[i]);
     139      *b = std::make_pair(indexes[i], values[i]);
    197140      ++b;
    198141    }
    199142  }
    200143
    201   void LpGlpk::_setColCoeffs(int ix, ConstColIterator b, ConstColIterator e) {
    202 
    203     std::vector<int> indices;
     144  void GlpkBase::_setColCoeffs(int ix, ExprIterator b,
     145                                     ExprIterator e) {
     146
     147    std::vector<int> indexes;
    204148    std::vector<Value> values;
    205149
    206     indices.push_back(0);
     150    indexes.push_back(0);
    207151    values.push_back(0);
    208152
    209     for(ConstColIterator it=b; it!=e; ++it) {
    210       indices.push_back(it->first);
     153    for(ExprIterator it = b; it != e; ++it) {
     154      indexes.push_back(it->first);
    211155      values.push_back(it->second);
    212156    }
    213157
    214     LEMON_glp(set_mat_col)(lp, ix, values.size() - 1,
    215                                 &indices[0], &values[0]);
    216 
    217     solved = false;
    218   }
    219 
    220   void LpGlpk::_getColCoeffs(int ix, ColIterator b) const
    221   {
    222     int length = LEMON_glp(get_mat_col)(lp, ix, 0, 0);
    223 
    224     std::vector<int> indices(length + 1);
     158    glp_set_mat_col(lp, ix, values.size() - 1,
     159                    &indexes.front(), &values.front());
     160  }
     161
     162  void GlpkBase::_getColCoeffs(int ix, InsertIterator b) const {
     163    int length = glp_get_mat_col(lp, ix, 0, 0);
     164
     165    std::vector<int> indexes(length + 1);
    225166    std::vector<Value> values(length + 1);
    226167
    227     LEMON_glp(get_mat_col)(lp, ix, &indices[0], &values[0]);
    228 
    229     for (int i = 1; i <= length; ++i) {
    230       *b = std::make_pair(indices[i], values[i]);
     168    glp_get_mat_col(lp, ix, &indexes.front(), &values.front());
     169
     170    for (int i = 1; i  <= length; ++i) {
     171      *b = std::make_pair(indexes[i], values[i]);
    231172      ++b;
    232173    }
    233174  }
    234175
    235   void LpGlpk::_setCoeff(int ix, int jx, Value value)
    236   {
    237 
    238     if (LEMON_glp(get_num_cols)(lp) < LEMON_glp(get_num_rows)(lp)) {
    239 
    240       int length=LEMON_glp(get_mat_row)(lp, ix, 0, 0);
    241 
    242       std::vector<int> indices(length + 2);
     176  void GlpkBase::_setCoeff(int ix, int jx, Value value) {
     177
     178    if (glp_get_num_cols(lp) < glp_get_num_rows(lp)) {
     179
     180      int length = glp_get_mat_row(lp, ix, 0, 0);
     181
     182      std::vector<int> indexes(length + 2);
    243183      std::vector<Value> values(length + 2);
    244184
    245       LEMON_glp(get_mat_row)(lp, ix, &indices[0], &values[0]);
     185      glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
    246186
    247187      //The following code does not suppose that the elements of the
    248       //array indices are sorted
    249       bool found=false;
    250       for (int i = 1; i <= length; ++i) {
    251         if (indices[i]==jx){
    252           found=true;
    253           values[i]=value;
     188      //array indexes are sorted
     189      bool found = false;
     190      for (int i = 1; i  <= length; ++i) {
     191        if (indexes[i] == jx) {
     192          found = true;
     193          values[i] = value;
    254194          break;
    255195        }
    256196      }
    257       if (!found){
     197      if (!found) {
    258198        ++length;
    259         indices[length]=jx;
    260         values[length]=value;
    261       }
    262 
    263       LEMON_glp(set_mat_row)(lp, ix, length, &indices[0], &values[0]);
     199        indexes[length] = jx;
     200        values[length] = value;
     201      }
     202
     203      glp_set_mat_row(lp, ix, length, &indexes.front(), &values.front());
    264204
    265205    } else {
    266206
    267       int length=LEMON_glp(get_mat_col)(lp, jx, 0, 0);
    268 
    269       std::vector<int> indices(length + 2);
     207      int length = glp_get_mat_col(lp, jx, 0, 0);
     208
     209      std::vector<int> indexes(length + 2);
    270210      std::vector<Value> values(length + 2);
    271211
    272       LEMON_glp(get_mat_col)(lp, jx, &indices[0], &values[0]);
     212      glp_get_mat_col(lp, jx, &indexes.front(), &values.front());
    273213
    274214      //The following code does not suppose that the elements of the
    275       //array indices are sorted
    276       bool found=false;
     215      //array indexes are sorted
     216      bool found = false;
    277217      for (int i = 1; i <= length; ++i) {
    278         if (indices[i]==ix){
    279           found=true;
    280           values[i]=value;
     218        if (indexes[i] == ix) {
     219          found = true;
     220          values[i] = value;
    281221          break;
    282222        }
    283223      }
    284       if (!found){
     224      if (!found) {
    285225        ++length;
    286         indices[length]=ix;
    287         values[length]=value;
    288       }
    289 
    290       LEMON_glp(set_mat_col)(lp, jx, length, &indices[0], &values[0]);
    291     }
    292 
    293     solved = false;
    294   }
    295 
    296   LpGlpk::Value LpGlpk::_getCoeff(int ix, int jx) const
    297   {
    298 
    299     int length=LEMON_glp(get_mat_row)(lp, ix, 0, 0);
    300 
    301     std::vector<int> indices(length + 1);
     226        indexes[length] = ix;
     227        values[length] = value;
     228      }
     229
     230      glp_set_mat_col(lp, jx, length, &indexes.front(), &values.front());
     231    }
     232
     233  }
     234
     235  GlpkBase::Value GlpkBase::_getCoeff(int ix, int jx) const {
     236
     237    int length = glp_get_mat_row(lp, ix, 0, 0);
     238
     239    std::vector<int> indexes(length + 1);
    302240    std::vector<Value> values(length + 1);
    303241
    304     LEMON_glp(get_mat_row)(lp, ix, &indices[0], &values[0]);
    305 
    306     //The following code does not suppose that the elements of the
    307     //array indices are sorted
    308     for (int i = 1; i <= length; ++i) {
    309       if (indices[i]==jx){
     242    glp_get_mat_row(lp, ix, &indexes.front(), &values.front());
     243
     244    for (int i = 1; i  <= length; ++i) {
     245      if (indexes[i] == jx) {
    310246        return values[i];
    311247      }
    312248    }
     249
    313250    return 0;
    314 
    315   }
    316 
    317 
    318   void LpGlpk::_setColLowerBound(int i, Value lo)
    319   {
    320     if (lo==INF) {
    321       //FIXME error
    322     }
    323     int b=LEMON_glp(get_col_type)(lp, i);
    324     double up=LEMON_glp(get_col_ub)(lp, i);
    325     if (lo==-INF) {
     251  }
     252
     253  void GlpkBase::_setColLowerBound(int i, Value lo) {
     254    LEMON_ASSERT(lo != INF, "Invalid bound");
     255
     256    int b = glp_get_col_type(lp, i);
     257    double up = glp_get_col_ub(lp, i);
     258    if (lo == -INF) {
    326259      switch (b) {
    327       case LEMON_GLP(FR):
    328       case LEMON_GLP(LO):
    329         LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FR), lo, up);
    330         break;
    331       case LEMON_GLP(UP):
    332         break;
    333       case LEMON_GLP(DB):
    334       case LEMON_GLP(FX):
    335         LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(UP), lo, up);
    336         break;
    337       default: ;
    338         //FIXME error
     260      case GLP_FR:
     261      case GLP_LO:
     262        glp_set_col_bnds(lp, i, GLP_FR, lo, up);
     263        break;
     264      case GLP_UP:
     265        break;
     266      case GLP_DB:
     267      case GLP_FX:
     268        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
     269        break;
     270      default:
     271        break;
    339272      }
    340273    } else {
    341274      switch (b) {
    342       case LEMON_GLP(FR):
    343       case LEMON_GLP(LO):
    344         LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(LO), lo, up);
    345         break;
    346       case LEMON_GLP(UP):
    347       case LEMON_GLP(DB):
    348       case LEMON_GLP(FX):
    349         if (lo==up)
    350           LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FX), lo, up);
     275      case GLP_FR:
     276      case GLP_LO:
     277        glp_set_col_bnds(lp, i, GLP_LO, lo, up);
     278        break;
     279      case GLP_UP:
     280      case GLP_DB:
     281      case GLP_FX:
     282        if (lo == up)
     283          glp_set_col_bnds(lp, i, GLP_FX, lo, up);
    351284        else
    352           LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(DB), lo, up);
    353         break;
    354       default: ;
    355         //FIXME error
    356       }
    357     }
    358 
    359     solved = false;
    360   }
    361 
    362   LpGlpk::Value LpGlpk::_getColLowerBound(int i) const
    363   {
    364     int b=LEMON_glp(get_col_type)(lp, i);
     285          glp_set_col_bnds(lp, i, GLP_DB, lo, up);
     286        break;
     287      default:
     288        break;
     289      }
     290    }
     291  }
     292
     293  GlpkBase::Value GlpkBase::_getColLowerBound(int i) const {
     294    int b = glp_get_col_type(lp, i);
     295    switch (b) {
     296    case GLP_LO:
     297    case GLP_DB:
     298    case GLP_FX:
     299      return glp_get_col_lb(lp, i);
     300    default:
     301      return -INF;
     302    }
     303  }
     304
     305  void GlpkBase::_setColUpperBound(int i, Value up) {
     306    LEMON_ASSERT(up != -INF, "Invalid bound");
     307
     308    int b = glp_get_col_type(lp, i);
     309    double lo = glp_get_col_lb(lp, i);
     310    if (up == INF) {
    365311      switch (b) {
    366       case LEMON_GLP(LO):
    367       case LEMON_GLP(DB):
    368       case LEMON_GLP(FX):
    369         return LEMON_glp(get_col_lb)(lp, i);
    370       default: ;
    371         return -INF;
    372       }
    373   }
    374 
    375   void LpGlpk::_setColUpperBound(int i, Value up)
    376   {
    377     if (up==-INF) {
    378       //FIXME error
    379     }
    380     int b=LEMON_glp(get_col_type)(lp, i);
    381     double lo=LEMON_glp(get_col_lb)(lp, i);
    382     if (up==INF) {
    383       switch (b) {
    384       case LEMON_GLP(FR):
    385       case LEMON_GLP(LO):
    386         break;
    387       case LEMON_GLP(UP):
    388         LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FR), lo, up);
    389         break;
    390       case LEMON_GLP(DB):
    391       case LEMON_GLP(FX):
    392         LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(LO), lo, up);
    393         break;
    394       default: ;
    395         //FIXME error
     312      case GLP_FR:
     313      case GLP_LO:
     314        break;
     315      case GLP_UP:
     316        glp_set_col_bnds(lp, i, GLP_FR, lo, up);
     317        break;
     318      case GLP_DB:
     319      case GLP_FX:
     320        glp_set_col_bnds(lp, i, GLP_LO, lo, up);
     321        break;
     322      default:
     323        break;
    396324      }
    397325    } else {
    398326      switch (b) {
    399       case LEMON_GLP(FR):
    400         LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(UP), lo, up);
    401         break;
    402       case LEMON_GLP(UP):
    403         LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(UP), lo, up);
    404         break;
    405       case LEMON_GLP(LO):
    406       case LEMON_GLP(DB):
    407       case LEMON_GLP(FX):
    408         if (lo==up)
    409           LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(FX), lo, up);
     327      case GLP_FR:
     328        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
     329        break;
     330      case GLP_UP:
     331        glp_set_col_bnds(lp, i, GLP_UP, lo, up);
     332        break;
     333      case GLP_LO:
     334      case GLP_DB:
     335      case GLP_FX:
     336        if (lo == up)
     337          glp_set_col_bnds(lp, i, GLP_FX, lo, up);
    410338        else
    411           LEMON_glp(set_col_bnds)(lp, i, LEMON_GLP(DB), lo, up);
    412         break;
    413       default: ;
    414         //FIXME error
    415       }
    416     }
    417 
    418     solved = false;
    419   }
    420 
    421   LpGlpk::Value LpGlpk::_getColUpperBound(int i) const
    422   {
    423     int b=LEMON_glp(get_col_type)(lp, i);
     339          glp_set_col_bnds(lp, i, GLP_DB, lo, up);
     340        break;
     341      default:
     342        break;
     343      }
     344    }
     345
     346  }
     347
     348  GlpkBase::Value GlpkBase::_getColUpperBound(int i) const {
     349    int b = glp_get_col_type(lp, i);
    424350      switch (b) {
    425       case LEMON_GLP(UP):
    426       case LEMON_GLP(DB):
    427       case LEMON_GLP(FX):
    428         return LEMON_glp(get_col_ub)(lp, i);
    429       default: ;
     351      case GLP_UP:
     352      case GLP_DB:
     353      case GLP_FX:
     354        return glp_get_col_ub(lp, i);
     355      default:
    430356        return INF;
    431357      }
    432358  }
    433359
    434   void LpGlpk::_setRowBounds(int i, Value lb, Value ub)
    435   {
    436     //Bad parameter
    437     if (lb==INF || ub==-INF) {
    438       //FIXME error
    439     }
    440 
    441     if (lb == -INF){
    442       if (ub == INF){
    443         LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(FR), lb, ub);
    444       }
    445       else{
    446         LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(UP), lb, ub);
    447       }
    448     }
    449     else{
    450       if (ub==INF){
    451         LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(LO), lb, ub);
    452 
    453       }
    454       else{
    455         if (lb == ub){
    456           LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(FX), lb, ub);
     360  void GlpkBase::_setRowLowerBound(int i, Value lo) {
     361    LEMON_ASSERT(lo != INF, "Invalid bound");
     362
     363    int b = glp_get_row_type(lp, i);
     364    double up = glp_get_row_ub(lp, i);
     365    if (lo == -INF) {
     366      switch (b) {
     367      case GLP_FR:
     368      case GLP_LO:
     369        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
     370        break;
     371      case GLP_UP:
     372        break;
     373      case GLP_DB:
     374      case GLP_FX:
     375        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
     376        break;
     377      default:
     378        break;
     379      }
     380    } else {
     381      switch (b) {
     382      case GLP_FR:
     383      case GLP_LO:
     384        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
     385        break;
     386      case GLP_UP:
     387      case GLP_DB:
     388      case GLP_FX:
     389        if (lo == up)
     390          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
     391        else
     392          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
     393        break;
     394      default:
     395        break;
     396      }
     397    }
     398
     399  }
     400
     401  GlpkBase::Value GlpkBase::_getRowLowerBound(int i) const {
     402    int b = glp_get_row_type(lp, i);
     403    switch (b) {
     404    case GLP_LO:
     405    case GLP_DB:
     406    case GLP_FX:
     407      return glp_get_row_lb(lp, i);
     408    default:
     409      return -INF;
     410    }
     411  }
     412
     413  void GlpkBase::_setRowUpperBound(int i, Value up) {
     414    LEMON_ASSERT(up != -INF, "Invalid bound");
     415
     416    int b = glp_get_row_type(lp, i);
     417    double lo = glp_get_row_lb(lp, i);
     418    if (up == INF) {
     419      switch (b) {
     420      case GLP_FR:
     421      case GLP_LO:
     422        break;
     423      case GLP_UP:
     424        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
     425        break;
     426      case GLP_DB:
     427      case GLP_FX:
     428        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
     429        break;
     430      default:
     431        break;
     432      }
     433    } else {
     434      switch (b) {
     435      case GLP_FR:
     436        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
     437        break;
     438      case GLP_UP:
     439        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
     440        break;
     441      case GLP_LO:
     442      case GLP_DB:
     443      case GLP_FX:
     444        if (lo == up)
     445          glp_set_row_bnds(lp, i, GLP_FX, lo, up);
     446        else
     447          glp_set_row_bnds(lp, i, GLP_DB, lo, up);
     448        break;
     449      default:
     450        break;
     451      }
     452    }
     453  }
     454
     455  GlpkBase::Value GlpkBase::_getRowUpperBound(int i) const {
     456    int b = glp_get_row_type(lp, i);
     457    switch (b) {
     458    case GLP_UP:
     459    case GLP_DB:
     460    case GLP_FX:
     461      return glp_get_row_ub(lp, i);
     462    default:
     463      return INF;
     464    }
     465  }
     466
     467  void GlpkBase::_setObjCoeffs(ExprIterator b, ExprIterator e) {
     468    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
     469      glp_set_obj_coef(lp, i, 0.0);
     470    }
     471    for (ExprIterator it = b; it != e; ++it) {
     472      glp_set_obj_coef(lp, it->first, it->second);
     473    }
     474  }
     475
     476  void GlpkBase::_getObjCoeffs(InsertIterator b) const {
     477    for (int i = 1; i <= glp_get_num_cols(lp); ++i) {
     478      Value val = glp_get_obj_coef(lp, i);
     479      if (val != 0.0) {
     480        *b = std::make_pair(i, val);
     481        ++b;
     482      }
     483    }
     484  }
     485
     486  void GlpkBase::_setObjCoeff(int i, Value obj_coef) {
     487    //i = 0 means the constant term (shift)
     488    glp_set_obj_coef(lp, i, obj_coef);
     489  }
     490
     491  GlpkBase::Value GlpkBase::_getObjCoeff(int i) const {
     492    //i = 0 means the constant term (shift)
     493    return glp_get_obj_coef(lp, i);
     494  }
     495
     496  void GlpkBase::_setSense(GlpkBase::Sense sense) {
     497    switch (sense) {
     498    case MIN:
     499      glp_set_obj_dir(lp, GLP_MIN);
     500      break;
     501    case MAX:
     502      glp_set_obj_dir(lp, GLP_MAX);
     503      break;
     504    }
     505  }
     506
     507  GlpkBase::Sense GlpkBase::_getSense() const {
     508    switch(glp_get_obj_dir(lp)) {
     509    case GLP_MIN:
     510      return MIN;
     511    case GLP_MAX:
     512      return MAX;
     513    default:
     514      LEMON_ASSERT(false, "Wrong sense");
     515      return GlpkBase::Sense();
     516    }
     517  }
     518
     519  void GlpkBase::_clear() {
     520    glp_erase_prob(lp);
     521    rows.clear();
     522    cols.clear();
     523  }
     524
     525  // LpGlpk members
     526
     527  LpGlpk::LpGlpk()
     528    : LpBase(), GlpkBase(), LpSolver() {
     529    messageLevel(MESSAGE_NO_OUTPUT);
     530  }
     531
     532  LpGlpk::LpGlpk(const LpGlpk& other)
     533    : LpBase(other), GlpkBase(other), LpSolver(other) {
     534    messageLevel(MESSAGE_NO_OUTPUT);
     535  }
     536
     537  LpGlpk* LpGlpk::_newSolver() const { return new LpGlpk; }
     538  LpGlpk* LpGlpk::_cloneSolver() const { return new LpGlpk(*this); }
     539
     540  const char* LpGlpk::_solverName() const { return "LpGlpk"; }
     541
     542  void LpGlpk::_clear_temporals() {
     543    _primal_ray.clear();
     544    _dual_ray.clear();
     545  }
     546
     547  LpGlpk::SolveExitStatus LpGlpk::_solve() {
     548    return solvePrimal();
     549  }
     550
     551  LpGlpk::SolveExitStatus LpGlpk::solvePrimal() {
     552    _clear_temporals();
     553
     554    glp_smcp smcp;
     555    glp_init_smcp(&smcp);
     556
     557    switch (_message_level) {
     558    case MESSAGE_NO_OUTPUT:
     559      smcp.msg_lev = GLP_MSG_OFF;
     560      break;
     561    case MESSAGE_ERROR_MESSAGE:
     562      smcp.msg_lev = GLP_MSG_ERR;
     563      break;
     564    case MESSAGE_NORMAL_OUTPUT:
     565      smcp.msg_lev = GLP_MSG_ON;
     566      break;
     567    case MESSAGE_FULL_OUTPUT:
     568      smcp.msg_lev = GLP_MSG_ALL;
     569      break;
     570    }
     571
     572    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
     573    return SOLVED;
     574  }
     575
     576  LpGlpk::SolveExitStatus LpGlpk::solveDual() {
     577    _clear_temporals();
     578
     579    glp_smcp smcp;
     580    glp_init_smcp(&smcp);
     581
     582    switch (_message_level) {
     583    case MESSAGE_NO_OUTPUT:
     584      smcp.msg_lev = GLP_MSG_OFF;
     585      break;
     586    case MESSAGE_ERROR_MESSAGE:
     587      smcp.msg_lev = GLP_MSG_ERR;
     588      break;
     589    case MESSAGE_NORMAL_OUTPUT:
     590      smcp.msg_lev = GLP_MSG_ON;
     591      break;
     592    case MESSAGE_FULL_OUTPUT:
     593      smcp.msg_lev = GLP_MSG_ALL;
     594      break;
     595    }
     596    smcp.meth = GLP_DUAL;
     597
     598    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
     599    return SOLVED;
     600  }
     601
     602  LpGlpk::Value LpGlpk::_getPrimal(int i) const {
     603    return glp_get_col_prim(lp, i);
     604  }
     605
     606  LpGlpk::Value LpGlpk::_getDual(int i) const {
     607    return glp_get_row_dual(lp, i);
     608  }
     609
     610  LpGlpk::Value LpGlpk::_getPrimalValue() const {
     611    return glp_get_obj_val(lp);
     612  }
     613
     614  LpGlpk::VarStatus LpGlpk::_getColStatus(int i) const {
     615    switch (glp_get_col_stat(lp, i)) {
     616    case GLP_BS:
     617      return BASIC;
     618    case GLP_UP:
     619      return UPPER;
     620    case GLP_LO:
     621      return LOWER;
     622    case GLP_NF:
     623      return FREE;
     624    case GLP_NS:
     625      return FIXED;
     626    default:
     627      LEMON_ASSERT(false, "Wrong column status");
     628      return LpGlpk::VarStatus();
     629    }
     630  }
     631
     632  LpGlpk::VarStatus LpGlpk::_getRowStatus(int i) const {
     633    switch (glp_get_row_stat(lp, i)) {
     634    case GLP_BS:
     635      return BASIC;
     636    case GLP_UP:
     637      return UPPER;
     638    case GLP_LO:
     639      return LOWER;
     640    case GLP_NF:
     641      return FREE;
     642    case GLP_NS:
     643      return FIXED;
     644    default:
     645      LEMON_ASSERT(false, "Wrong row status");
     646      return LpGlpk::VarStatus();
     647    }
     648  }
     649
     650  LpGlpk::Value LpGlpk::_getPrimalRay(int i) const {
     651    if (_primal_ray.empty()) {
     652      int row_num = glp_get_num_rows(lp);
     653      int col_num = glp_get_num_cols(lp);
     654
     655      _primal_ray.resize(col_num + 1, 0.0);
     656
     657      int index = glp_get_unbnd_ray(lp);
     658      if (index != 0) {
     659        // The primal ray is found in primal simplex second phase
     660        LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) :
     661                      glp_get_col_stat(lp, index - row_num)) != GLP_BS,
     662                     "Wrong primal ray");
     663
     664        bool negate = glp_get_obj_dir(lp) == GLP_MAX;
     665
     666        if (index > row_num) {
     667          _primal_ray[index - row_num] = 1.0;
     668          if (glp_get_col_dual(lp, index - row_num) > 0) {
     669            negate = !negate;
     670          }
     671        } else {
     672          if (glp_get_row_dual(lp, index) > 0) {
     673            negate = !negate;
     674          }
    457675        }
    458         else{
    459           LEMON_glp(set_row_bnds)(lp, i, LEMON_GLP(DB), lb, ub);
     676
     677        std::vector<int> ray_indexes(row_num + 1);
     678        std::vector<Value> ray_values(row_num + 1);
     679        int ray_length = glp_eval_tab_col(lp, index, &ray_indexes.front(),
     680                                          &ray_values.front());
     681
     682        for (int i = 1; i <= ray_length; ++i) {
     683          if (ray_indexes[i] > row_num) {
     684            _primal_ray[ray_indexes[i] - row_num] = ray_values[i];
     685          }
    460686        }
    461       }
    462     }
    463 
    464     solved = false;
    465   }
    466 
    467   void LpGlpk::_getRowBounds(int i, Value &lb, Value &ub) const
    468   {
    469 
    470     int b=LEMON_glp(get_row_type)(lp, i);
    471     switch (b) {
    472     case LEMON_GLP(FR):
    473     case LEMON_GLP(UP):
    474       lb = -INF;
    475         break;
     687
     688        if (negate) {
     689          for (int i = 1; i <= col_num; ++i) {
     690            _primal_ray[i] = - _primal_ray[i];
     691          }
     692        }
     693      } else {
     694        for (int i = 1; i <= col_num; ++i) {
     695          _primal_ray[i] = glp_get_col_prim(lp, i);
     696        }
     697      }
     698    }
     699    return _primal_ray[i];
     700  }
     701
     702  LpGlpk::Value LpGlpk::_getDualRay(int i) const {
     703    if (_dual_ray.empty()) {
     704      int row_num = glp_get_num_rows(lp);
     705
     706      _dual_ray.resize(row_num + 1, 0.0);
     707
     708      int index = glp_get_unbnd_ray(lp);
     709      if (index != 0) {
     710        // The dual ray is found in dual simplex second phase
     711        LEMON_ASSERT((index <= row_num ? glp_get_row_stat(lp, index) :
     712                      glp_get_col_stat(lp, index - row_num)) == GLP_BS,
     713
     714                     "Wrong dual ray");
     715
     716        int idx;
     717        bool negate = false;
     718
     719        if (index > row_num) {
     720          idx = glp_get_col_bind(lp, index - row_num);
     721          if (glp_get_col_prim(lp, index - row_num) >
     722              glp_get_col_ub(lp, index - row_num)) {
     723            negate = true;
     724          }
     725        } else {
     726          idx = glp_get_row_bind(lp, index);
     727          if (glp_get_row_prim(lp, index) > glp_get_row_ub(lp, index)) {
     728            negate = true;
     729          }
     730        }
     731
     732        _dual_ray[idx] = negate ?  - 1.0 : 1.0;
     733
     734        glp_btran(lp, &_dual_ray.front());
     735      } else {
     736        double eps = 1e-7;
     737        // The dual ray is found in primal simplex first phase
     738        // We assume that the glpk minimizes the slack to get feasible solution
     739        for (int i = 1; i <= row_num; ++i) {
     740          int index = glp_get_bhead(lp, i);
     741          if (index <= row_num) {
     742            double res = glp_get_row_prim(lp, index);
     743            if (res > glp_get_row_ub(lp, index) + eps) {
     744              _dual_ray[i] = -1;
     745            } else if (res < glp_get_row_lb(lp, index) - eps) {
     746              _dual_ray[i] = 1;
     747            } else {
     748              _dual_ray[i] = 0;
     749            }
     750            _dual_ray[i] *= glp_get_rii(lp, index);
     751          } else {
     752            double res = glp_get_col_prim(lp, index - row_num);
     753            if (res > glp_get_col_ub(lp, index - row_num) + eps) {
     754              _dual_ray[i] = -1;
     755            } else if (res < glp_get_col_lb(lp, index - row_num) - eps) {
     756              _dual_ray[i] = 1;
     757            } else {
     758              _dual_ray[i] = 0;
     759            }
     760            _dual_ray[i] /= glp_get_sjj(lp, index - row_num);
     761          }
     762        }
     763
     764        glp_btran(lp, &_dual_ray.front());
     765
     766        for (int i = 1; i <= row_num; ++i) {
     767          _dual_ray[i] /= glp_get_rii(lp, i);
     768        }
     769      }
     770    }
     771    return _dual_ray[i];
     772  }
     773
     774  LpGlpk::ProblemType LpGlpk::_getPrimalType() const {
     775    if (glp_get_status(lp) == GLP_OPT)
     776      return OPTIMAL;
     777    switch (glp_get_prim_stat(lp)) {
     778    case GLP_UNDEF:
     779      return UNDEFINED;
     780    case GLP_FEAS:
     781    case GLP_INFEAS:
     782      if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
     783        return UNBOUNDED;
     784      } else {
     785        return UNDEFINED;
     786      }
     787    case GLP_NOFEAS:
     788      return INFEASIBLE;
    476789    default:
    477       lb=LEMON_glp(get_row_lb)(lp, i);
    478     }
    479 
    480     switch (b) {
    481     case LEMON_GLP(FR):
    482     case LEMON_GLP(LO):
    483       ub = INF;
    484         break;
     790      LEMON_ASSERT(false, "Wrong primal type");
     791      return  LpGlpk::ProblemType();
     792    }
     793  }
     794
     795  LpGlpk::ProblemType LpGlpk::_getDualType() const {
     796    if (glp_get_status(lp) == GLP_OPT)
     797      return OPTIMAL;
     798    switch (glp_get_dual_stat(lp)) {
     799    case GLP_UNDEF:
     800      return UNDEFINED;
     801    case GLP_FEAS:
     802    case GLP_INFEAS:
     803      if (glp_get_prim_stat(lp) == GLP_NOFEAS) {
     804        return UNBOUNDED;
     805      } else {
     806        return UNDEFINED;
     807      }
     808    case GLP_NOFEAS:
     809      return INFEASIBLE;
    485810    default:
    486       ub=LEMON_glp(get_row_ub)(lp, i);
    487     }
    488 
    489   }
    490 
    491   void LpGlpk::_setObjCoeff(int i, Value obj_coef)
    492   {
    493     //i=0 means the constant term (shift)
    494     LEMON_glp(set_obj_coef)(lp, i, obj_coef);
    495 
    496     solved = false;
    497   }
    498 
    499   LpGlpk::Value LpGlpk::_getObjCoeff(int i) const {
    500     //i=0 means the constant term (shift)
    501     return LEMON_glp(get_obj_coef)(lp, i);
    502   }
    503 
    504   void LpGlpk::_clearObj()
    505   {
    506     for (int i=0;i<=LEMON_glp(get_num_cols)(lp);++i){
    507       LEMON_glp(set_obj_coef)(lp, i, 0);
    508     }
    509 
    510     solved = false;
    511   }
    512 
    513   LpGlpk::SolveExitStatus LpGlpk::_solve()
    514   {
    515     // A way to check the problem to be solved
    516     //LEMON_glp(write_cpxlp(lp,"naittvan.cpx");
    517 
    518     LEMON_lpx(std_basis)(lp);
    519     int i =  LEMON_lpx(simplex)(lp);
    520 
    521     switch (i) {
    522     case LEMON_LPX(E_OK):
    523       solved = true;
    524       return SOLVED;
     811      LEMON_ASSERT(false, "Wrong primal type");
     812      return  LpGlpk::ProblemType();
     813    }
     814  }
     815
     816  void LpGlpk::presolver(bool b) {
     817    lpx_set_int_parm(lp, LPX_K_PRESOL, b ? 1 : 0);
     818  }
     819
     820  void LpGlpk::messageLevel(MessageLevel m) {
     821    _message_level = m;
     822  }
     823
     824  // MipGlpk members
     825
     826  MipGlpk::MipGlpk()
     827    : LpBase(), GlpkBase(), MipSolver() {
     828    messageLevel(MESSAGE_NO_OUTPUT);
     829  }
     830
     831  MipGlpk::MipGlpk(const MipGlpk& other)
     832    : LpBase(), GlpkBase(other), MipSolver() {
     833    messageLevel(MESSAGE_NO_OUTPUT);
     834  }
     835
     836  void MipGlpk::_setColType(int i, MipGlpk::ColTypes col_type) {
     837    switch (col_type) {
     838    case INTEGER:
     839      glp_set_col_kind(lp, i, GLP_IV);
     840      break;
     841    case REAL:
     842      glp_set_col_kind(lp, i, GLP_CV);
     843      break;
     844    }
     845  }
     846
     847  MipGlpk::ColTypes MipGlpk::_getColType(int i) const {
     848    switch (glp_get_col_kind(lp, i)) {
     849    case GLP_IV:
     850    case GLP_BV:
     851      return INTEGER;
    525852    default:
    526       return UNSOLVED;
    527     }
    528   }
    529 
    530   LpGlpk::Value LpGlpk::_getPrimal(int i) const
    531   {
    532     return LEMON_glp(get_col_prim)(lp,i);
    533   }
    534 
    535   LpGlpk::Value LpGlpk::_getDual(int i) const
    536   {
    537     return LEMON_glp(get_row_dual)(lp,i);
    538   }
    539 
    540   LpGlpk::Value LpGlpk::_getPrimalValue() const
    541   {
    542     return LEMON_glp(get_obj_val)(lp);
    543   }
    544   bool LpGlpk::_isBasicCol(int i) const
    545   {
    546     return (LEMON_glp(get_col_stat)(lp, i)==LEMON_GLP(BS));
    547   }
    548 
    549 
    550   LpGlpk::SolutionStatus LpGlpk::_getPrimalStatus() const
    551   {
    552     if (!solved) return UNDEFINED;
    553     int stat=  LEMON_lpx(get_status)(lp);
    554     switch (stat) {
    555     case LEMON_LPX(UNDEF)://Undefined (no solve has been run yet)
    556       return UNDEFINED;
    557     case LEMON_LPX(NOFEAS)://There is no feasible solution (primal, I guess)
    558     case LEMON_LPX(INFEAS)://Infeasible
    559       return INFEASIBLE;
    560     case LEMON_LPX(UNBND)://Unbounded
    561       return INFINITE;
    562     case LEMON_LPX(FEAS)://Feasible
    563       return FEASIBLE;
    564     case LEMON_LPX(OPT)://Feasible
    565       return OPTIMAL;
    566     default:
    567       return UNDEFINED; //to avoid gcc warning
    568       //FIXME error
    569     }
    570   }
    571 
    572   LpGlpk::SolutionStatus LpGlpk::_getDualStatus() const
    573   {
    574     if (!solved) return UNDEFINED;
    575     switch (LEMON_lpx(get_dual_stat)(lp)) {
    576     case LEMON_LPX(D_UNDEF)://Undefined (no solve has been run yet)
    577       return UNDEFINED;
    578     case LEMON_LPX(D_NOFEAS)://There is no dual feasible solution
    579 //    case LEMON_LPX(D_INFEAS://Infeasible
    580       return INFEASIBLE;
    581     case LEMON_LPX(D_FEAS)://Feasible
    582       switch (LEMON_lpx(get_status)(lp)) {
    583       case LEMON_LPX(NOFEAS):
    584         return INFINITE;
    585       case LEMON_LPX(OPT):
     853      return REAL;
     854    }
     855
     856  }
     857
     858  MipGlpk::SolveExitStatus MipGlpk::_solve() {
     859    glp_smcp smcp;
     860    glp_init_smcp(&smcp);
     861
     862    switch (_message_level) {
     863    case MESSAGE_NO_OUTPUT:
     864      smcp.msg_lev = GLP_MSG_OFF;
     865      break;
     866    case MESSAGE_ERROR_MESSAGE:
     867      smcp.msg_lev = GLP_MSG_ERR;
     868      break;
     869    case MESSAGE_NORMAL_OUTPUT:
     870      smcp.msg_lev = GLP_MSG_ON;
     871      break;
     872    case MESSAGE_FULL_OUTPUT:
     873      smcp.msg_lev = GLP_MSG_ALL;
     874      break;
     875    }
     876    smcp.meth = GLP_DUAL;
     877
     878    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
     879    if (glp_get_status(lp) != GLP_OPT) return SOLVED;
     880
     881    glp_iocp iocp;
     882    glp_init_iocp(&iocp);
     883
     884    switch (_message_level) {
     885    case MESSAGE_NO_OUTPUT:
     886      iocp.msg_lev = GLP_MSG_OFF;
     887      break;
     888    case MESSAGE_ERROR_MESSAGE:
     889      iocp.msg_lev = GLP_MSG_ERR;
     890      break;
     891    case MESSAGE_NORMAL_OUTPUT:
     892      iocp.msg_lev = GLP_MSG_ON;
     893      break;
     894    case MESSAGE_FULL_OUTPUT:
     895      iocp.msg_lev = GLP_MSG_ALL;
     896      break;
     897    }
     898
     899    if (glp_intopt(lp, &iocp) != 0) return UNSOLVED;
     900    return SOLVED;
     901  }
     902
     903
     904  MipGlpk::ProblemType MipGlpk::_getType() const {
     905    switch (glp_get_status(lp)) {
     906    case GLP_OPT:
     907      switch (glp_mip_status(lp)) {
     908      case GLP_UNDEF:
     909        return UNDEFINED;
     910      case GLP_NOFEAS:
     911        return INFEASIBLE;
     912      case GLP_FEAS:
     913        return FEASIBLE;
     914      case GLP_OPT:
    586915        return OPTIMAL;
    587916      default:
    588         return FEASIBLE;
     917        LEMON_ASSERT(false, "Wrong problem type.");
     918        return MipGlpk::ProblemType();
     919      }
     920    case GLP_NOFEAS:
     921      return INFEASIBLE;
     922    case GLP_INFEAS:
     923    case GLP_FEAS:
     924      if (glp_get_dual_stat(lp) == GLP_NOFEAS) {
     925        return UNBOUNDED;
     926      } else {
     927        return UNDEFINED;
    589928      }
    590929    default:
    591       return UNDEFINED; //to avoid gcc warning
    592       //FIXME error
    593     }
    594   }
    595 
    596   LpGlpk::ProblemTypes LpGlpk::_getProblemType() const
    597   {
    598     if (!solved) return UNKNOWN;
    599       //int stat=  LEMON_glp(get_status(lp);
    600     int statp=  LEMON_lpx(get_prim_stat)(lp);
    601     int statd=  LEMON_lpx(get_dual_stat)(lp);
    602     if (statp==LEMON_LPX(P_FEAS) && statd==LEMON_LPX(D_FEAS))
    603         return PRIMAL_DUAL_FEASIBLE;
    604     if (statp==LEMON_LPX(P_FEAS) && statd==LEMON_LPX(D_NOFEAS))
    605         return PRIMAL_FEASIBLE_DUAL_INFEASIBLE;
    606     if (statp==LEMON_LPX(P_NOFEAS) && statd==LEMON_LPX(D_FEAS))
    607         return PRIMAL_INFEASIBLE_DUAL_FEASIBLE;
    608     if (statp==LEMON_LPX(P_NOFEAS) && statd==LEMON_LPX(D_NOFEAS))
    609         return PRIMAL_DUAL_INFEASIBLE;
    610     //In all other cases
    611     return UNKNOWN;
    612   }
    613 
    614   void LpGlpk::_setMax()
    615   {
    616     solved = false;
    617     LEMON_glp(set_obj_dir)(lp, LEMON_GLP(MAX));
    618   }
    619 
    620   void LpGlpk::_setMin()
    621   {
    622     solved = false;
    623     LEMON_glp(set_obj_dir)(lp, LEMON_GLP(MIN));
    624   }
    625 
    626   bool LpGlpk::_isMax() const
    627   {
    628     return (LEMON_glp(get_obj_dir)(lp)==LEMON_GLP(MAX));
    629   }
    630 
    631 
    632 
    633   void LpGlpk::messageLevel(int m)
    634   {
    635     LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_MSGLEV), m);
    636   }
    637 
    638   void LpGlpk::presolver(bool b)
    639   {
    640     LEMON_lpx(set_int_parm)(lp, LEMON_LPX(K_PRESOL), b);
    641   }
    642 
     930      LEMON_ASSERT(false, "Wrong problem type.");
     931      return MipGlpk::ProblemType();
     932    }
     933  }
     934
     935  MipGlpk::Value MipGlpk::_getSol(int i) const {
     936    return glp_mip_col_val(lp, i);
     937  }
     938
     939  MipGlpk::Value MipGlpk::_getSolValue() const {
     940    return glp_mip_obj_val(lp);
     941  }
     942
     943  MipGlpk* MipGlpk::_newSolver() const { return new MipGlpk; }
     944  MipGlpk* MipGlpk::_cloneSolver() const {return new MipGlpk(*this); }
     945
     946  const char* MipGlpk::_solverName() const { return "MipGlpk"; }
     947
     948  void MipGlpk::messageLevel(MessageLevel m) {
     949    _message_level = m;
     950  }
    643951
    644952} //END OF NAMESPACE LEMON
Note: See TracChangeset for help on using the changeset viewer.