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