Fixing presolver and basis handling (#255)
authorBalazs Dezso <deba@inf.elte.hu>
Wed, 01 Apr 2009 22:54:00 +0200
changeset 5577ab97e2a0c33
parent 556 eda12d8ac953
child 558 e7017ec2d5cd
Fixing presolver and basis handling (#255)
lemon/glpk.cc
lemon/glpk.h
     1.1 --- a/lemon/glpk.cc	Wed Apr 01 14:18:35 2009 +0100
     1.2 +++ b/lemon/glpk.cc	Wed Apr 01 22:54:00 2009 +0200
     1.3 @@ -533,11 +533,13 @@
     1.4    GlpkLp::GlpkLp()
     1.5      : LpBase(), LpSolver(), GlpkBase() {
     1.6      messageLevel(MESSAGE_NO_OUTPUT);
     1.7 +    presolver(false);
     1.8    }
     1.9  
    1.10    GlpkLp::GlpkLp(const GlpkLp& other)
    1.11      : LpBase(other), LpSolver(other), GlpkBase(other) {
    1.12      messageLevel(MESSAGE_NO_OUTPUT);
    1.13 +    presolver(false);
    1.14    }
    1.15  
    1.16    GlpkLp* GlpkLp::newSolver() const { return new GlpkLp; }
    1.17 @@ -574,8 +576,24 @@
    1.18        smcp.msg_lev = GLP_MSG_ALL;
    1.19        break;
    1.20      }
    1.21 +    smcp.presolve = _presolve;
    1.22  
    1.23 -    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
    1.24 +    // If the basis is not valid we get an error return value.
    1.25 +    // In this case we can try to create a new basis.
    1.26 +    switch (glp_simplex(lp, &smcp)) {
    1.27 +    case 0:
    1.28 +      break;
    1.29 +    case GLP_EBADB:
    1.30 +    case GLP_ESING:
    1.31 +    case GLP_ECOND:
    1.32 +      lpx_set_int_parm(lp, LPX_K_MSGLEV, smcp.msg_lev);
    1.33 +      glp_adv_basis(lp, 0);
    1.34 +      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
    1.35 +      break;
    1.36 +    default:
    1.37 +      return UNSOLVED;
    1.38 +    }
    1.39 +
    1.40      return SOLVED;
    1.41    }
    1.42  
    1.43 @@ -600,8 +618,23 @@
    1.44        break;
    1.45      }
    1.46      smcp.meth = GLP_DUAL;
    1.47 +    smcp.presolve = _presolve;
    1.48  
    1.49 -    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
    1.50 +    // If the basis is not valid we get an error return value.
    1.51 +    // In this case we can try to create a new basis.
    1.52 +    switch (glp_simplex(lp, &smcp)) {
    1.53 +    case 0:
    1.54 +      break;
    1.55 +    case GLP_EBADB:
    1.56 +    case GLP_ESING:
    1.57 +    case GLP_ECOND:
    1.58 +      lpx_set_int_parm(lp, LPX_K_MSGLEV, smcp.msg_lev);
    1.59 +      glp_adv_basis(lp, 0);
    1.60 +      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
    1.61 +      break;
    1.62 +    default:
    1.63 +      return UNSOLVED;
    1.64 +    }
    1.65      return SOLVED;
    1.66    }
    1.67  
    1.68 @@ -819,8 +852,8 @@
    1.69      }
    1.70    }
    1.71  
    1.72 -  void GlpkLp::presolver(bool b) {
    1.73 -    lpx_set_int_parm(lp, LPX_K_PRESOL, b ? 1 : 0);
    1.74 +  void GlpkLp::presolver(bool presolve) {
    1.75 +    _presolve = presolve;
    1.76    }
    1.77  
    1.78    void GlpkLp::messageLevel(MessageLevel m) {
    1.79 @@ -881,7 +914,22 @@
    1.80      }
    1.81      smcp.meth = GLP_DUAL;
    1.82  
    1.83 -    if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
    1.84 +    // If the basis is not valid we get an error return value.
    1.85 +    // In this case we can try to create a new basis.
    1.86 +    switch (glp_simplex(lp, &smcp)) {
    1.87 +    case 0:
    1.88 +      break;
    1.89 +    case GLP_EBADB:
    1.90 +    case GLP_ESING:
    1.91 +    case GLP_ECOND:
    1.92 +      lpx_set_int_parm(lp, LPX_K_MSGLEV, smcp.msg_lev);
    1.93 +      glp_adv_basis(lp, 0);
    1.94 +      if (glp_simplex(lp, &smcp) != 0) return UNSOLVED;
    1.95 +      break;
    1.96 +    default:
    1.97 +      return UNSOLVED;
    1.98 +    }
    1.99 +
   1.100      if (glp_get_status(lp) != GLP_OPT) return SOLVED;
   1.101  
   1.102      glp_iocp iocp;
     2.1 --- a/lemon/glpk.h	Wed Apr 01 14:18:35 2009 +0100
     2.2 +++ b/lemon/glpk.h	Wed Apr 01 22:54:00 2009 +0200
     2.3 @@ -178,12 +178,18 @@
     2.4      ///Solve with dual simplex
     2.5      SolveExitStatus solveDual();
     2.6  
     2.7 +  private:
     2.8 +
     2.9 +    bool _presolve;
    2.10 +
    2.11 +  public:
    2.12 +
    2.13      ///Turns on or off the presolver
    2.14  
    2.15      ///Turns on (\c b is \c true) or off (\c b is \c false) the presolver
    2.16      ///
    2.17      ///The presolver is off by default.
    2.18 -    void presolver(bool b);
    2.19 +    void presolver(bool presolve);
    2.20  
    2.21      ///Enum for \c messageLevel() parameter
    2.22      enum MessageLevel {