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