1.1 --- a/src/work/athos/lp/lp_solver_glpk.h Sun Apr 17 18:57:22 2005 +0000
1.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
1.3 @@ -1,565 +0,0 @@
1.4 -// -*- c++ -*-
1.5 -#ifndef LEMON_LP_SOLVER_GLPK_H
1.6 -#define LEMON_LP_SOLVER_GLPK_H
1.7 -
1.8 -///\ingroup misc
1.9 -///\file
1.10 -
1.11 -extern "C" {
1.12 -#include "glpk.h"
1.13 -}
1.14 -#include <lp_solver_base.h>
1.15 -
1.16 -namespace lemon {
1.17 -
1.18 -
1.19 - template <typename Value>
1.20 - const Value LpSolverBase<Value>::INF=std::numeric_limits<Value>::infinity();
1.21 -
1.22 -
1.23 - /// \brief Wrapper for GLPK solver
1.24 - ///
1.25 - /// This class implements a lemon wrapper for GLPK.
1.26 - class LpGlpk : public LpSolverBase<double> {
1.27 -
1.28 - public:
1.29 -
1.30 - typedef LpSolverBase<double> Parent;
1.31 -
1.32 - /// \e
1.33 - LPX* lp;
1.34 -
1.35 - /// \e
1.36 - LpGlpk() : Parent(),
1.37 - lp(lpx_create_prob()) {
1.38 - //int_row_map.push_back(Row());
1.39 - //int_col_map.push_back(Col());
1.40 - lpx_set_int_parm(lp, LPX_K_DUAL, 1);
1.41 - }
1.42 - /// \e
1.43 - ~LpGlpk() {
1.44 - lpx_delete_prob(lp);
1.45 - }
1.46 -
1.47 - //MATRIX INDEPEDENT MANIPULATING FUNCTIONS
1.48 -
1.49 - /// \e
1.50 - void setMinimize() {
1.51 - lpx_set_obj_dir(lp, LPX_MIN);
1.52 - }
1.53 - /// \e
1.54 - void setMaximize() {
1.55 - lpx_set_obj_dir(lp, LPX_MAX);
1.56 - }
1.57 -
1.58 - /// \e
1.59 - /// Retrieve number of rows
1.60 - int rowNum() const { return lpx_get_num_rows(lp); }
1.61 - /// \e
1.62 - /// Retrieve number of coloumns
1.63 - int colNum() const { return lpx_get_num_cols(lp); }
1.64 -
1.65 - protected:
1.66 - /// \e
1.67 - int LpGlpk::_addCol() {
1.68 - int i=lpx_add_cols(lp, 1);
1.69 - _setColLowerBound(i, -INF);
1.70 - _setColUpperBound(i, INF);
1.71 - return i;
1.72 - }
1.73 - /// \e
1.74 - int LpGlpk::_addRow() {
1.75 - int i=lpx_add_rows(lp, 1);
1.76 - return i;
1.77 - }
1.78 - /// \e
1.79 - virtual void _setRowCoeffs(int i,
1.80 - const std::vector<std::pair<int, double> >& coeffs) {
1.81 - int mem_length=1+colNum();
1.82 - int* indices = new int[mem_length];
1.83 - double* doubles = new double[mem_length];
1.84 - int length=0;
1.85 - for (std::vector<std::pair<int, double> >::
1.86 - const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) {
1.87 - ++length;
1.88 - indices[length]=it->first;
1.89 - doubles[length]=it->second;
1.90 - }
1.91 - lpx_set_mat_row(lp, i, length, indices, doubles);
1.92 - delete [] indices;
1.93 - delete [] doubles;
1.94 - }
1.95 - /// \e
1.96 - virtual void _getRowCoeffs(int i,
1.97 - std::vector<std::pair<int, double> >& coeffs) {
1.98 - int mem_length=1+colNum();
1.99 - int* indices = new int[mem_length];
1.100 - double* doubles = new double[mem_length];
1.101 - int length=lpx_get_mat_row(lp, i, indices, doubles);
1.102 - for (int i=1; i<=length; ++i) {
1.103 - coeffs.push_back(std::make_pair(indices[i], doubles[i]));
1.104 - }
1.105 - delete [] indices;
1.106 - delete [] doubles;
1.107 - }
1.108 - /// \e
1.109 - virtual void _setColCoeffs(int i,
1.110 - const std::vector<std::pair<int, double> >& coeffs) {
1.111 - int mem_length=1+rowNum();
1.112 - int* indices = new int[mem_length];
1.113 - double* doubles = new double[mem_length];
1.114 - int length=0;
1.115 - for (std::vector<std::pair<int, double> >::
1.116 - const_iterator it=coeffs.begin(); it!=coeffs.end(); ++it) {
1.117 - ++length;
1.118 - indices[length]=it->first;
1.119 - doubles[length]=it->second;
1.120 - }
1.121 - lpx_set_mat_col(lp, i, length, indices, doubles);
1.122 - delete [] indices;
1.123 - delete [] doubles;
1.124 - }
1.125 - /// \e
1.126 - virtual void _getColCoeffs(int i,
1.127 - std::vector<std::pair<int, double> >& coeffs) {
1.128 - int mem_length=1+rowNum();
1.129 - int* indices = new int[mem_length];
1.130 - double* doubles = new double[mem_length];
1.131 - int length=lpx_get_mat_col(lp, i, indices, doubles);
1.132 - for (int i=1; i<=length; ++i) {
1.133 - coeffs.push_back(std::make_pair(indices[i], doubles[i]));
1.134 - }
1.135 - delete [] indices;
1.136 - delete [] doubles;
1.137 - }
1.138 - /// \e
1.139 - virtual void _eraseCol(int i) {
1.140 - int cols[2];
1.141 - cols[1]=i;
1.142 - lpx_del_cols(lp, 1, cols);
1.143 - }
1.144 - virtual void _eraseRow(int i) {
1.145 - int rows[2];
1.146 - rows[1]=i;
1.147 - lpx_del_rows(lp, 1, rows);
1.148 - }
1.149 -
1.150 - void _setCoeff(int row, int col, double value) {
1.151 - ///FIXME Of course this is not efficient at all, but GLPK knows not more.
1.152 - /// First approach: get one row, apply changes and set it again
1.153 -
1.154 - int mem_length=1+colNum();
1.155 - int* indices = new int[mem_length];
1.156 - double* doubles = new double[mem_length];
1.157 -
1.158 -
1.159 - int length=lpx_get_mat_row(lp, i, indices, doubles);
1.160 -
1.161 - //The following code does not suppose that the elements of the array indices are sorted
1.162 - int i=1;
1.163 - bool found=false;
1.164 - while (i <= length && !found){
1.165 - if (indices[i]=col){
1.166 - found = true;
1.167 - doubles[i]=value;
1.168 - }
1.169 - ++i;
1.170 - }
1.171 - if (!found){
1.172 - ++length;
1.173 - indices[length]=col;
1.174 - doubles[length]=value;
1.175 - }
1.176 -
1.177 -// This is a piece of code that assumes that the array 'indices' is sorted.
1.178 -// Not ready, I suppose.
1.179 -// //We need another arrays to put the data back, anyway
1.180 -// int* new_indices = new int[length+1];
1.181 -// double* new_doubles = new double[length+1];
1.182 -// int offset;
1.183 -
1.184 -// int i=1;
1.185 -// while (i <= length && indices[i]<col){
1.186 -// new_indiced[i]=indices[i];
1.187 -// new_doubles[i]=doubles[i];
1.188 -// ++i;
1.189 -// }
1.190 -// if (i>length || indices[i]>col){
1.191 -// //Ha atugrottuk, vagy a vegen van
1.192 -// new_indices[i]=col;
1.193 -// new_doubles[i]=value;
1.194 -// offset = 1;
1.195 -// }
1.196 -// else{
1.197 -// //I.e.: indices[i]=col
1.198 -// new_doubles[i]=value;
1.199 -// offset = 0;
1.200 -// ++i;
1.201 -// }
1.202 -// while (i <= length){
1.203 -// new_indices[i+offset]=indices[i];
1.204 -// new_values[i+offset]=values[i];
1.205 -// }
1.206 -
1.207 - lpx_set_mat_row(lp, row, length, indices, doubles);
1.208 - delete [] indices;
1.209 - delete [] doubles;
1.210 -
1.211 -// lpx_set_mat_row(lp, row, length+offset, new_indices, new_doubles);
1.212 -// delete [] new_indices;
1.213 -// delete [] new_doubles;
1.214 -
1.215 -
1.216 - }
1.217 - double _getCoeff(int col, int row) {
1.218 - /// FIXME not yet implemented
1.219 - return 0.0;
1.220 - }
1.221 - virtual void _setColLowerBound(int i, double lo) {
1.222 - if (lo==INF) {
1.223 - //FIXME error
1.224 - }
1.225 - int b=lpx_get_col_type(lp, i);
1.226 - double up=lpx_get_col_ub(lp, i);
1.227 - if (lo==-INF) {
1.228 - switch (b) {
1.229 - case LPX_FR:
1.230 - case LPX_LO:
1.231 - lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
1.232 - break;
1.233 - case LPX_UP:
1.234 - break;
1.235 - case LPX_DB:
1.236 - case LPX_FX:
1.237 - lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
1.238 - break;
1.239 - default: ;
1.240 - //FIXME error
1.241 - }
1.242 - } else {
1.243 - switch (b) {
1.244 - case LPX_FR:
1.245 - case LPX_LO:
1.246 - lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
1.247 - break;
1.248 - case LPX_UP:
1.249 - case LPX_DB:
1.250 - case LPX_FX:
1.251 - if (lo==up)
1.252 - lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
1.253 - else
1.254 - lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
1.255 - break;
1.256 - default: ;
1.257 - //FIXME error
1.258 - }
1.259 - }
1.260 - }
1.261 - virtual double _getColLowerBound(int i) {
1.262 - int b=lpx_get_col_type(lp, i);
1.263 - switch (b) {
1.264 - case LPX_FR:
1.265 - return -INF;
1.266 - case LPX_LO:
1.267 - return lpx_get_col_lb(lp, i);
1.268 - case LPX_UP:
1.269 - return -INF;
1.270 - case LPX_DB:
1.271 - case LPX_FX:
1.272 - return lpx_get_col_lb(lp, i);
1.273 - default: ;
1.274 - //FIXME error
1.275 - return 0.0;
1.276 - }
1.277 - }
1.278 - virtual void _setColUpperBound(int i, double up) {
1.279 - if (up==-INF) {
1.280 - //FIXME error
1.281 - }
1.282 - int b=lpx_get_col_type(lp, i);
1.283 - double lo=lpx_get_col_lb(lp, i);
1.284 - if (up==INF) {
1.285 - switch (b) {
1.286 - case LPX_FR:
1.287 - case LPX_LO:
1.288 - break;
1.289 - case LPX_UP:
1.290 - lpx_set_col_bnds(lp, i, LPX_FR, lo, up);
1.291 - break;
1.292 - case LPX_DB:
1.293 - case LPX_FX:
1.294 - lpx_set_col_bnds(lp, i, LPX_LO, lo, up);
1.295 - break;
1.296 - default: ;
1.297 - //FIXME error
1.298 - }
1.299 - } else {
1.300 - switch (b) {
1.301 - case LPX_FR:
1.302 - lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
1.303 - case LPX_LO:
1.304 - if (lo==up)
1.305 - lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
1.306 - else
1.307 - lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
1.308 - break;
1.309 - case LPX_UP:
1.310 - lpx_set_col_bnds(lp, i, LPX_UP, lo, up);
1.311 - break;
1.312 - case LPX_DB:
1.313 - case LPX_FX:
1.314 - if (lo==up)
1.315 - lpx_set_col_bnds(lp, i, LPX_FX, lo, up);
1.316 - else
1.317 - lpx_set_col_bnds(lp, i, LPX_DB, lo, up);
1.318 - break;
1.319 - default: ;
1.320 - //FIXME error
1.321 - }
1.322 - }
1.323 - }
1.324 - virtual double _getColUpperBound(int i) {
1.325 - int b=lpx_get_col_type(lp, i);
1.326 - switch (b) {
1.327 - case LPX_FR:
1.328 - case LPX_LO:
1.329 - return INF;
1.330 - case LPX_UP:
1.331 - case LPX_DB:
1.332 - case LPX_FX:
1.333 - return lpx_get_col_ub(lp, i);
1.334 - default: ;
1.335 - //FIXME error
1.336 - return 0.0;
1.337 - }
1.338 - }
1.339 - virtual void _setRowLowerBound(int i, double lo) {
1.340 - if (lo==INF) {
1.341 - //FIXME error
1.342 - }
1.343 - int b=lpx_get_row_type(lp, i);
1.344 - double up=lpx_get_row_ub(lp, i);
1.345 - if (lo==-INF) {
1.346 - switch (b) {
1.347 - case LPX_FR:
1.348 - case LPX_LO:
1.349 - lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
1.350 - break;
1.351 - case LPX_UP:
1.352 - break;
1.353 - case LPX_DB:
1.354 - case LPX_FX:
1.355 - lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
1.356 - break;
1.357 - default: ;
1.358 - //FIXME error
1.359 - }
1.360 - } else {
1.361 - switch (b) {
1.362 - case LPX_FR:
1.363 - case LPX_LO:
1.364 - lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
1.365 - break;
1.366 - case LPX_UP:
1.367 - case LPX_DB:
1.368 - case LPX_FX:
1.369 - if (lo==up)
1.370 - lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
1.371 - else
1.372 - lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
1.373 - break;
1.374 - default: ;
1.375 - //FIXME error
1.376 - }
1.377 - }
1.378 - }
1.379 - virtual double _getRowLowerBound(int i) {
1.380 - int b=lpx_get_row_type(lp, i);
1.381 - switch (b) {
1.382 - case LPX_FR:
1.383 - return -INF;
1.384 - case LPX_LO:
1.385 - return lpx_get_row_lb(lp, i);
1.386 - case LPX_UP:
1.387 - return -INF;
1.388 - case LPX_DB:
1.389 - case LPX_FX:
1.390 - return lpx_get_row_lb(lp, i);
1.391 - default: ;
1.392 - //FIXME error
1.393 - return 0.0;
1.394 - }
1.395 - }
1.396 - virtual void _setRowUpperBound(int i, double up) {
1.397 - if (up==-INF) {
1.398 - //FIXME error
1.399 - }
1.400 - int b=lpx_get_row_type(lp, i);
1.401 - double lo=lpx_get_row_lb(lp, i);
1.402 - if (up==INF) {
1.403 - switch (b) {
1.404 - case LPX_FR:
1.405 - case LPX_LO:
1.406 - break;
1.407 - case LPX_UP:
1.408 - lpx_set_row_bnds(lp, i, LPX_FR, lo, up);
1.409 - break;
1.410 - case LPX_DB:
1.411 - case LPX_FX:
1.412 - lpx_set_row_bnds(lp, i, LPX_LO, lo, up);
1.413 - break;
1.414 - default: ;
1.415 - //FIXME error
1.416 - }
1.417 - } else {
1.418 - switch (b) {
1.419 - case LPX_FR:
1.420 - lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
1.421 - case LPX_LO:
1.422 - if (lo==up)
1.423 - lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
1.424 - else
1.425 - lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
1.426 - break;
1.427 - case LPX_UP:
1.428 - lpx_set_row_bnds(lp, i, LPX_UP, lo, up);
1.429 - break;
1.430 - case LPX_DB:
1.431 - case LPX_FX:
1.432 - if (lo==up)
1.433 - lpx_set_row_bnds(lp, i, LPX_FX, lo, up);
1.434 - else
1.435 - lpx_set_row_bnds(lp, i, LPX_DB, lo, up);
1.436 - break;
1.437 - default: ;
1.438 - //FIXME error
1.439 - }
1.440 - }
1.441 - }
1.442 - virtual double _getRowUpperBound(int i) {
1.443 - int b=lpx_get_row_type(lp, i);
1.444 - switch (b) {
1.445 - case LPX_FR:
1.446 - case LPX_LO:
1.447 - return INF;
1.448 - case LPX_UP:
1.449 - case LPX_DB:
1.450 - case LPX_FX:
1.451 - return lpx_get_row_ub(lp, i);
1.452 - default: ;
1.453 - //FIXME error
1.454 - return 0.0;
1.455 - }
1.456 - }
1.457 - /// \e
1.458 - virtual double _getObjCoeff(int i) {
1.459 - return lpx_get_obj_coef(lp, i);
1.460 - }
1.461 - /// \e
1.462 - virtual void _setObjCoeff(int i, double obj_coef) {
1.463 - lpx_set_obj_coef(lp, i, obj_coef);
1.464 - }
1.465 -
1.466 - protected:
1.467 - virtual double _getPrimal(int i) {
1.468 - return lpx_get_col_prim(lp, i);
1.469 - }
1.470 -
1.471 - //MIP
1.472 - protected:
1.473 - /// \e
1.474 - void _setColCont(int i) { lpx_set_col_kind(lp, i, LPX_CV); }
1.475 - /// \e
1.476 - void _setColInt(int i) { lpx_set_col_kind(lp, i, LPX_IV); }
1.477 - /// \e
1.478 - double _getMIPPrimal(int i) { return lpx_mip_col_val(lp, i); }
1.479 -
1.480 -
1.481 -// public:
1.482 -// /// \e
1.483 -// void solveSimplex() { lpx_simplex(lp); }
1.484 -// /// \e
1.485 -// void solvePrimalSimplex() { lpx_simplex(lp); }
1.486 -// /// \e
1.487 -// void solveDualSimplex() { lpx_simplex(lp); }
1.488 -// /// \e
1.489 -// double getObjVal() { return lpx_get_obj_val(lp); }
1.490 -// /// \e
1.491 -// int warmUp() { return lpx_warm_up(lp); }
1.492 -// /// \e
1.493 -// void printWarmUpStatus(int i) {
1.494 -// switch (i) {
1.495 -// case LPX_E_OK: cout << "LPX_E_OK" << endl; break;
1.496 -// case LPX_E_EMPTY: cout << "LPX_E_EMPTY" << endl; break;
1.497 -// case LPX_E_BADB: cout << "LPX_E_BADB" << endl; break;
1.498 -// case LPX_E_SING: cout << "LPX_E_SING" << endl; break;
1.499 -// }
1.500 -// }
1.501 -// /// \e
1.502 -// int getPrimalStatus() { return lpx_get_prim_stat(lp); }
1.503 -// /// \e
1.504 -// void printPrimalStatus(int i) {
1.505 -// switch (i) {
1.506 -// case LPX_P_UNDEF: cout << "LPX_P_UNDEF" << endl; break;
1.507 -// case LPX_P_FEAS: cout << "LPX_P_FEAS" << endl; break;
1.508 -// case LPX_P_INFEAS: cout << "LPX_P_INFEAS" << endl; break;
1.509 -// case LPX_P_NOFEAS: cout << "LPX_P_NOFEAS" << endl; break;
1.510 -// }
1.511 -// }
1.512 -// /// \e
1.513 -// int getDualStatus() { return lpx_get_dual_stat(lp); }
1.514 -// /// \e
1.515 -// void printDualStatus(int i) {
1.516 -// switch (i) {
1.517 -// case LPX_D_UNDEF: cout << "LPX_D_UNDEF" << endl; break;
1.518 -// case LPX_D_FEAS: cout << "LPX_D_FEAS" << endl; break;
1.519 -// case LPX_D_INFEAS: cout << "LPX_D_INFEAS" << endl; break;
1.520 -// case LPX_D_NOFEAS: cout << "LPX_D_NOFEAS" << endl; break;
1.521 -// }
1.522 -// }
1.523 -// /// Returns the status of the slack variable assigned to row \c row.
1.524 -// int getRowStat(const Row& row) {
1.525 -// return lpx_get_row_stat(lp, row_iter_map[row]);
1.526 -// }
1.527 -// /// \e
1.528 -// void printRowStatus(int i) {
1.529 -// switch (i) {
1.530 -// case LPX_BS: cout << "LPX_BS" << endl; break;
1.531 -// case LPX_NL: cout << "LPX_NL" << endl; break;
1.532 -// case LPX_NU: cout << "LPX_NU" << endl; break;
1.533 -// case LPX_NF: cout << "LPX_NF" << endl; break;
1.534 -// case LPX_NS: cout << "LPX_NS" << endl; break;
1.535 -// }
1.536 -// }
1.537 -// /// Returns the status of the variable assigned to column \c col.
1.538 -// int getColStat(const Col& col) {
1.539 -// return lpx_get_col_stat(lp, col_iter_map[col]);
1.540 -// }
1.541 -// /// \e
1.542 -// void printColStatus(int i) {
1.543 -// switch (i) {
1.544 -// case LPX_BS: cout << "LPX_BS" << endl; break;
1.545 -// case LPX_NL: cout << "LPX_NL" << endl; break;
1.546 -// case LPX_NU: cout << "LPX_NU" << endl; break;
1.547 -// case LPX_NF: cout << "LPX_NF" << endl; break;
1.548 -// case LPX_NS: cout << "LPX_NS" << endl; break;
1.549 -// }
1.550 -// }
1.551 -
1.552 -// // MIP
1.553 -// /// \e
1.554 -// void solveBandB() { lpx_integer(lp); }
1.555 -// /// \e
1.556 -// void setLP() { lpx_set_class(lp, LPX_LP); }
1.557 -// /// \e
1.558 -// void setMIP() { lpx_set_class(lp, LPX_MIP); }
1.559 -
1.560 -
1.561 -
1.562 - };
1.563 -
1.564 - /// @}
1.565 -
1.566 -} //namespace lemon
1.567 -
1.568 -#endif //LEMON_LP_SOLVER_GLPK_H