lemon/glpk.cc
changeset 783 ef88c0a30f85
parent 576 745e182d0139
child 877 141f9c0db4a3
     1.1 --- a/lemon/glpk.cc	Mon Jan 12 23:11:39 2009 +0100
     1.2 +++ b/lemon/glpk.cc	Thu Nov 05 15:48:01 2009 +0100
     1.3 @@ -2,7 +2,7 @@
     1.4   *
     1.5   * This file is a part of LEMON, a generic C++ optimization library.
     1.6   *
     1.7 - * Copyright (C) 2003-2008
     1.8 + * Copyright (C) 2003-2009
     1.9   * Egervary Jeno Kombinatorikus Optimalizalasi Kutatocsoport
    1.10   * (Egervary Research Group on Combinatorial Optimization, EGRES).
    1.11   *
    1.12 @@ -31,6 +31,7 @@
    1.13    GlpkBase::GlpkBase() : LpBase() {
    1.14      lp = glp_create_prob();
    1.15      glp_create_index(lp);
    1.16 +    messageLevel(MESSAGE_NOTHING);
    1.17    }
    1.18  
    1.19    GlpkBase::GlpkBase(const GlpkBase &other) : LpBase() {
    1.20 @@ -39,6 +40,7 @@
    1.21      glp_create_index(lp);
    1.22      rows = other.rows;
    1.23      cols = other.cols;
    1.24 +    messageLevel(MESSAGE_NOTHING);
    1.25    }
    1.26  
    1.27    GlpkBase::~GlpkBase() {
    1.28 @@ -57,6 +59,42 @@
    1.29      return i;
    1.30    }
    1.31  
    1.32 +  int GlpkBase::_addRow(Value lo, ExprIterator b, 
    1.33 +                        ExprIterator e, Value up) {
    1.34 +    int i = glp_add_rows(lp, 1);
    1.35 +
    1.36 +    if (lo == -INF) {
    1.37 +      if (up == INF) {
    1.38 +        glp_set_row_bnds(lp, i, GLP_FR, lo, up);
    1.39 +      } else {
    1.40 +        glp_set_row_bnds(lp, i, GLP_UP, lo, up);
    1.41 +      }    
    1.42 +    } else {
    1.43 +      if (up == INF) {
    1.44 +        glp_set_row_bnds(lp, i, GLP_LO, lo, up);
    1.45 +      } else if (lo != up) {        
    1.46 +        glp_set_row_bnds(lp, i, GLP_DB, lo, up);
    1.47 +      } else {
    1.48 +        glp_set_row_bnds(lp, i, GLP_FX, lo, up);
    1.49 +      }
    1.50 +    }
    1.51 +
    1.52 +    std::vector<int> indexes;
    1.53 +    std::vector<Value> values;
    1.54 +
    1.55 +    indexes.push_back(0);
    1.56 +    values.push_back(0);
    1.57 +
    1.58 +    for(ExprIterator it = b; it != e; ++it) {
    1.59 +      indexes.push_back(it->first);
    1.60 +      values.push_back(it->second);
    1.61 +    }
    1.62 +
    1.63 +    glp_set_mat_row(lp, i, values.size() - 1,
    1.64 +                    &indexes.front(), &values.front());
    1.65 +    return i;
    1.66 +  }
    1.67 +
    1.68    void GlpkBase::_eraseCol(int i) {
    1.69      int ca[2];
    1.70      ca[1] = i;
    1.71 @@ -522,20 +560,46 @@
    1.72      cols.clear();
    1.73    }
    1.74  
    1.75 +  void GlpkBase::freeEnv() {
    1.76 +    glp_free_env();
    1.77 +  }
    1.78 +
    1.79 +  void GlpkBase::_messageLevel(MessageLevel level) {
    1.80 +    switch (level) {
    1.81 +    case MESSAGE_NOTHING:
    1.82 +      _message_level = GLP_MSG_OFF;
    1.83 +      break;
    1.84 +    case MESSAGE_ERROR:
    1.85 +      _message_level = GLP_MSG_ERR;
    1.86 +      break;
    1.87 +    case MESSAGE_WARNING:
    1.88 +      _message_level = GLP_MSG_ERR;
    1.89 +      break;
    1.90 +    case MESSAGE_NORMAL:
    1.91 +      _message_level = GLP_MSG_ON;
    1.92 +      break;
    1.93 +    case MESSAGE_VERBOSE:
    1.94 +      _message_level = GLP_MSG_ALL;
    1.95 +      break;
    1.96 +    }
    1.97 +  }
    1.98 +
    1.99 +  GlpkBase::FreeEnvHelper GlpkBase::freeEnvHelper;
   1.100 +
   1.101    // GlpkLp members
   1.102  
   1.103    GlpkLp::GlpkLp()
   1.104 -    : LpBase(), GlpkBase(), LpSolver() {
   1.105 -    messageLevel(MESSAGE_NO_OUTPUT);
   1.106 +    : LpBase(), LpSolver(), GlpkBase() {
   1.107 +    presolver(false);
   1.108    }
   1.109  
   1.110    GlpkLp::GlpkLp(const GlpkLp& other)
   1.111 -    : LpBase(other), GlpkBase(other), LpSolver(other) {
   1.112 -    messageLevel(MESSAGE_NO_OUTPUT);
   1.113 +    : LpBase(other), LpSolver(other), GlpkBase(other) {
   1.114 +    presolver(false);
   1.115    }
   1.116  
   1.117 -  GlpkLp* GlpkLp::_newSolver() const { return new GlpkLp; }
   1.118 -  GlpkLp* GlpkLp::_cloneSolver() const { return new GlpkLp(*this); }
   1.119 +  GlpkLp* GlpkLp::newSolver() const { return new GlpkLp; }
   1.120 +  GlpkLp* GlpkLp::cloneSolver() const { return new GlpkLp(*this); }
   1.121  
   1.122    const char* GlpkLp::_solverName() const { return "GlpkLp"; }
   1.123  
   1.124 @@ -554,22 +618,26 @@
   1.125      glp_smcp smcp;
   1.126      glp_init_smcp(&smcp);
   1.127  
   1.128 -    switch (_message_level) {
   1.129 -    case MESSAGE_NO_OUTPUT:
   1.130 -      smcp.msg_lev = GLP_MSG_OFF;
   1.131 +    smcp.msg_lev = _message_level;
   1.132 +    smcp.presolve = _presolve;
   1.133 +
   1.134 +    // If the basis is not valid we get an error return value.
   1.135 +    // In this case we can try to create a new basis.
   1.136 +    switch (glp_simplex(lp, &smcp)) {
   1.137 +    case 0:
   1.138        break;
   1.139 -    case MESSAGE_ERROR_MESSAGE:
   1.140 -      smcp.msg_lev = GLP_MSG_ERR;
   1.141 +    case GLP_EBADB:
   1.142 +    case GLP_ESING:
   1.143 +    case GLP_ECOND:
   1.144 +      glp_term_out(false);
   1.145 +      glp_adv_basis(lp, 0);
   1.146 +      glp_term_out(true);
   1.147 +      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
   1.148        break;
   1.149 -    case MESSAGE_NORMAL_OUTPUT:
   1.150 -      smcp.msg_lev = GLP_MSG_ON;
   1.151 -      break;
   1.152 -    case MESSAGE_FULL_OUTPUT:
   1.153 -      smcp.msg_lev = GLP_MSG_ALL;
   1.154 -      break;
   1.155 +    default:
   1.156 +      return UNSOLVED;
   1.157      }
   1.158  
   1.159 -    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
   1.160      return SOLVED;
   1.161    }
   1.162  
   1.163 @@ -579,23 +647,26 @@
   1.164      glp_smcp smcp;
   1.165      glp_init_smcp(&smcp);
   1.166  
   1.167 -    switch (_message_level) {
   1.168 -    case MESSAGE_NO_OUTPUT:
   1.169 -      smcp.msg_lev = GLP_MSG_OFF;
   1.170 +    smcp.msg_lev = _message_level;
   1.171 +    smcp.meth = GLP_DUAL;
   1.172 +    smcp.presolve = _presolve;
   1.173 +
   1.174 +    // If the basis is not valid we get an error return value.
   1.175 +    // In this case we can try to create a new basis.
   1.176 +    switch (glp_simplex(lp, &smcp)) {
   1.177 +    case 0:
   1.178        break;
   1.179 -    case MESSAGE_ERROR_MESSAGE:
   1.180 -      smcp.msg_lev = GLP_MSG_ERR;
   1.181 +    case GLP_EBADB:
   1.182 +    case GLP_ESING:
   1.183 +    case GLP_ECOND:
   1.184 +      glp_term_out(false);
   1.185 +      glp_adv_basis(lp, 0);
   1.186 +      glp_term_out(true);
   1.187 +      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
   1.188        break;
   1.189 -    case MESSAGE_NORMAL_OUTPUT:
   1.190 -      smcp.msg_lev = GLP_MSG_ON;
   1.191 -      break;
   1.192 -    case MESSAGE_FULL_OUTPUT:
   1.193 -      smcp.msg_lev = GLP_MSG_ALL;
   1.194 -      break;
   1.195 +    default:
   1.196 +      return UNSOLVED;
   1.197      }
   1.198 -    smcp.meth = GLP_DUAL;
   1.199 -
   1.200 -    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
   1.201      return SOLVED;
   1.202    }
   1.203  
   1.204 @@ -813,24 +884,18 @@
   1.205      }
   1.206    }
   1.207  
   1.208 -  void GlpkLp::presolver(bool b) {
   1.209 -    lpx_set_int_parm(lp, LPX_K_PRESOL, b ? 1 : 0);
   1.210 -  }
   1.211 -
   1.212 -  void GlpkLp::messageLevel(MessageLevel m) {
   1.213 -    _message_level = m;
   1.214 +  void GlpkLp::presolver(bool presolve) {
   1.215 +    _presolve = presolve;
   1.216    }
   1.217  
   1.218    // GlpkMip members
   1.219  
   1.220    GlpkMip::GlpkMip()
   1.221 -    : LpBase(), GlpkBase(), MipSolver() {
   1.222 -    messageLevel(MESSAGE_NO_OUTPUT);
   1.223 +    : LpBase(), MipSolver(), GlpkBase() {
   1.224    }
   1.225  
   1.226    GlpkMip::GlpkMip(const GlpkMip& other)
   1.227 -    : LpBase(), GlpkBase(other), MipSolver() {
   1.228 -    messageLevel(MESSAGE_NO_OUTPUT);
   1.229 +    : LpBase(), MipSolver(), GlpkBase(other) {
   1.230    }
   1.231  
   1.232    void GlpkMip::_setColType(int i, GlpkMip::ColTypes col_type) {
   1.233 @@ -859,42 +924,32 @@
   1.234      glp_smcp smcp;
   1.235      glp_init_smcp(&smcp);
   1.236  
   1.237 -    switch (_message_level) {
   1.238 -    case MESSAGE_NO_OUTPUT:
   1.239 -      smcp.msg_lev = GLP_MSG_OFF;
   1.240 -      break;
   1.241 -    case MESSAGE_ERROR_MESSAGE:
   1.242 -      smcp.msg_lev = GLP_MSG_ERR;
   1.243 -      break;
   1.244 -    case MESSAGE_NORMAL_OUTPUT:
   1.245 -      smcp.msg_lev = GLP_MSG_ON;
   1.246 -      break;
   1.247 -    case MESSAGE_FULL_OUTPUT:
   1.248 -      smcp.msg_lev = GLP_MSG_ALL;
   1.249 -      break;
   1.250 -    }
   1.251 +    smcp.msg_lev = _message_level;
   1.252      smcp.meth = GLP_DUAL;
   1.253  
   1.254 -    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
   1.255 +    // If the basis is not valid we get an error return value.
   1.256 +    // In this case we can try to create a new basis.
   1.257 +    switch (glp_simplex(lp, &smcp)) {
   1.258 +    case 0:
   1.259 +      break;
   1.260 +    case GLP_EBADB:
   1.261 +    case GLP_ESING:
   1.262 +    case GLP_ECOND:
   1.263 +      glp_term_out(false);
   1.264 +      glp_adv_basis(lp, 0);
   1.265 +      glp_term_out(true);
   1.266 +      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
   1.267 +      break;
   1.268 +    default:
   1.269 +      return UNSOLVED;
   1.270 +    }
   1.271 +
   1.272      if (glp_get_status(lp) != GLP_OPT) return SOLVED;
   1.273  
   1.274      glp_iocp iocp;
   1.275      glp_init_iocp(&iocp);
   1.276  
   1.277 -    switch (_message_level) {
   1.278 -    case MESSAGE_NO_OUTPUT:
   1.279 -      iocp.msg_lev = GLP_MSG_OFF;
   1.280 -      break;
   1.281 -    case MESSAGE_ERROR_MESSAGE:
   1.282 -      iocp.msg_lev = GLP_MSG_ERR;
   1.283 -      break;
   1.284 -    case MESSAGE_NORMAL_OUTPUT:
   1.285 -      iocp.msg_lev = GLP_MSG_ON;
   1.286 -      break;
   1.287 -    case MESSAGE_FULL_OUTPUT:
   1.288 -      iocp.msg_lev = GLP_MSG_ALL;
   1.289 -      break;
   1.290 -    }
   1.291 +    iocp.msg_lev = _message_level;
   1.292  
   1.293      if (glp_intopt(lp, &iocp) != 0) return UNSOLVED;
   1.294      return SOLVED;
   1.295 @@ -940,13 +995,9 @@
   1.296      return glp_mip_obj_val(lp);
   1.297    }
   1.298  
   1.299 -  GlpkMip* GlpkMip::_newSolver() const { return new GlpkMip; }
   1.300 -  GlpkMip* GlpkMip::_cloneSolver() const {return new GlpkMip(*this); }
   1.301 +  GlpkMip* GlpkMip::newSolver() const { return new GlpkMip; }
   1.302 +  GlpkMip* GlpkMip::cloneSolver() const {return new GlpkMip(*this); }
   1.303  
   1.304    const char* GlpkMip::_solverName() const { return "GlpkMip"; }
   1.305  
   1.306 -  void GlpkMip::messageLevel(MessageLevel m) {
   1.307 -    _message_level = m;
   1.308 -  }
   1.309 -
   1.310  } //END OF NAMESPACE LEMON