COIN-OR::LEMON - Graph Library

Changeset 2605:852361980706 in lemon-0.x


Ignore:
Timestamp:
04/08/08 18:01:28 (16 years ago)
Author:
Balazs Dezso
Branch:
default
Phase:
public
Convert:
svn:c9d7d8f5-90d6-0310-b91f-818b3a526b0e/lemon/trunk@3488
Message:

Bug fixes in LP solvers

  • the copyLp is clarified
  • newLp and copyLp gives back pointers
  • cplex gives back empty string for variables without name
  • cplex row and column retrieval
  • added macro for soplex
Files:
11 edited

Legend:

Unmodified
Added
Removed
  • lemon/config.h.in

    r1435 r2605  
    44/* Define to 1 if you have GLPK. */
    55#undef HAVE_GLPK
     6
     7/* Define to 1 if you have SOPLEX. */
     8#undef HAVE_SOPLEX
  • lemon/lp_base.h

    r2569 r2605  
    372372      }
    373373
    374       //std::ostream &
    375       void prettyPrint(std::ostream &os) {
    376         //std::fmtflags os.flags();
    377         //os.setf(std::ios::showpos);
    378         Base::iterator j=Base::begin();
    379         if (j!=Base::end())
    380           os<<j->second<<"*x["<<id(j->first)<<"]";
    381         ++j;
    382         for (; j!=Base::end(); ++j){
    383           if (j->second>=0)
    384             os<<"+";
    385           os<<j->second<<"*x["<<id(j->first)<<"]";
    386         }
    387         //Nem valami korrekt, de nem talaltam meg, hogy kell
    388         //os.unsetf(std::ios::showpos);
    389 
    390         //return os;
    391       }
    392 
    393374    };
    394375   
     
    482463      }
    483464
    484       void prettyPrint(std::ostream &os) {
    485         if (_lb==-LpSolverBase::INF||isNaN(_lb))
    486           os<<"-infty<=";
    487         else
    488           os<<_lb<<"<=";
    489         _expr.prettyPrint(os);
    490         if (_ub==LpSolverBase::INF)
    491           os<<"<=infty";
    492         else
    493           os<<"<="<<_ub;
    494         //return os;
    495       }
    496 
    497465    };
    498466   
     
    736704
    737705    //Abstract virtual functions
    738     virtual LpSolverBase &_newLp() = 0;
    739     virtual LpSolverBase &_copyLp(){
    740       ///\todo This should be implemented here, too, when we have
    741       ///problem retrieving routines. It can be overriden.
    742 
    743       //Starting:
    744       LpSolverBase & newlp(_newLp());
     706    virtual LpSolverBase* _newLp() = 0;
     707    virtual LpSolverBase* _copyLp(){
     708      LpSolverBase* newlp = _newLp();
     709
     710      std::map<Col, Col> ref;
     711      for (LpSolverBase::ColIt it(*this); it != INVALID; ++it) {
     712        Col ccol = newlp->addCol();
     713        ref[it] = ccol;
     714        newlp->colName(ccol, colName(it));
     715        newlp->colLowerBound(ccol, colLowerBound(it));
     716        newlp->colUpperBound(ccol, colUpperBound(it));
     717      }
     718
     719      for (LpSolverBase::RowIt it(*this); it != INVALID; ++it) {
     720        Expr e = row(it), ce;
     721        for (Expr::iterator jt = e.begin(); jt != e.end(); ++jt) {
     722          ce[ref[jt->first]] = jt->second;
     723        }
     724        ce += e.constComp();
     725        Row r = newlp->addRow(ce);
     726
     727        double lower, upper;
     728        getRowBounds(it, lower, upper);
     729        newlp->rowBounds(r, lower, upper);
     730      }
     731
    745732      return newlp;
    746       //return *(LpSolverBase*)0;
    747733    };
    748734
     
    805791
    806792    ///Creates a new LP problem
    807     LpSolverBase &newLp() {return _newLp();}
     793    LpSolverBase* newLp() {return _newLp();}
    808794    ///Makes a copy of the LP problem
    809     LpSolverBase &copyLp() {return _copyLp();}
     795    LpSolverBase* copyLp() {return _copyLp();}
    810796   
    811797    ///\name Build up and modify the LP
  • lemon/lp_cplex.cc

    r2591 r2605  
    1818
    1919#include <iostream>
     20#include <vector>
    2021#include<lemon/lp_cplex.h>
    2122
     
    2425namespace lemon {
    2526 
    26   LpCplex::LpCplex() : LpSolverBase() {
     27  LpCplex::LpCplex() {
    2728    //    env = CPXopenCPLEXdevelop(&status);     
    2829    env = CPXopenCPLEX(&status);     
    2930    lp = CPXcreateprob(env, &status, "LP problem");
    3031  }
     32
     33  LpCplex::LpCplex(const LpCplex& cplex) : LpSolverBase() {
     34    env = CPXopenCPLEX(&status);     
     35    lp = CPXcloneprob(env, cplex.lp, &status);
     36    rows = cplex.rows;
     37    cols = cplex.cols;
     38  }
    3139 
    3240  LpCplex::~LpCplex() {
    33     CPXfreeprob(env,&lp); 
    34     CPXcloseCPLEX(&env); 
    35   }
    36  
    37   LpSolverBase &LpCplex::_newLp()
     41    CPXfreeprob(env,&lp);
     42    CPXcloseCPLEX(&env);
     43  }
     44 
     45  LpSolverBase* LpCplex::_newLp()
    3846  {
    3947    //The first approach opens a new environment
    40     LpCplex* newlp=new LpCplex();
    41     return *newlp;
    42   }
    43 
    44   LpSolverBase &LpCplex::_copyLp() {
    45     ///\bug FixID data is not copied!
    46     //The first approach opens a new environment
    47     LpCplex* newlp=new LpCplex();
    48     //The routine CPXcloneprob can be used to create a new CPLEX problem
    49     //object and copy all the problem data from an existing problem
    50     //object to it. Solution and starting information is not copied.
    51     newlp->lp = CPXcloneprob(env, lp, &status);
    52     return *newlp;
     48    return new LpCplex();
     49  }
     50
     51  LpSolverBase* LpCplex::_copyLp() {
     52    return new LpCplex(*this);
    5353  }
    5454
     
    5757    int i = CPXgetnumcols(env, lp);
    5858    Value lb[1],ub[1];
    59     lb[0]=-INF;//-CPX_INFBOUND;
    60     ub[0]=INF;//CPX_INFBOUND;
     59    lb[0]=-INF;
     60    ub[0]=INF;
    6161    status = CPXnewcols(env, lp, 1, NULL, lb, ub, NULL, NULL);
    6262    return i;
     
    9090    int storespace;
    9191    CPXgetcolname(env, lp, 0, 0, 0, &storespace, col, col);
    92 
     92    if (storespace == 0) {
     93      name.clear();
     94      return;
     95    }
     96   
    9397    storespace *= -1;
    9498    std::vector<char> buf(storespace);
     
    137141
    138142  void LpCplex::_getRowCoeffs(int i, RowIterator b) const {
     143    int tmp1, tmp2, tmp3, length;
     144    CPXgetrows(env, lp, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
     145   
     146    length = -length;
     147    std::vector<int> indices(length);
     148    std::vector<double> values(length);
     149
     150    CPXgetrows(env, lp, &tmp1, &tmp2, &indices[0], &values[0],
     151               length, &tmp3, i, i);
     152   
     153    for (int i = 0; i < length; ++i) {
     154      *b = std::make_pair(indices[i], values[i]);
     155      ++b;
     156    }
     157   
    139158    /// \todo implement
    140159  }
     
    157176
    158177  void LpCplex::_getColCoeffs(int i, ColIterator b) const {
    159     /// \todo implement
     178
     179    int tmp1, tmp2, tmp3, length;
     180    CPXgetcols(env, lp, &tmp1, &tmp2, 0, 0, 0, &length, i, i);
     181   
     182    length = -length;
     183    std::vector<int> indices(length);
     184    std::vector<double> values(length);
     185
     186    CPXgetcols(env, lp, &tmp1, &tmp2, &indices[0], &values[0],
     187               length, &tmp3, i, i);
     188   
     189    for (int i = 0; i < length; ++i) {
     190      *b = std::make_pair(indices[i], values[i]);
     191      ++b;
     192    }
     193   
    160194  }
    161195 
     
    188222    LpCplex::Value x;
    189223    CPXgetlb (env, lp, &x, i, i);
     224    if (x <= -CPX_INFBOUND) x = -INF;
    190225    return x;
    191226  }
     
    206241    LpCplex::Value x;
    207242    CPXgetub (env, lp, &x, i, i);
     243    if (x >= CPX_INFBOUND) x = INF;
    208244    return x;
    209245  }
     
    470506// Description: Method for linear optimization.
    471507// Determines which algorithm is used when CPXlpopt() (or "optimize" in the Interactive Optimizer) is called. Currently the behavior of the "Automatic" setting is that CPLEX simply invokes the dual simplex method, but this capability may be expanded in the future so that CPLEX chooses the method based on problem characteristics
     508#if CPX_VERSION < 900
    472509  void statusSwitch(CPXENVptr env,int& stat){
    473 #if CPX_VERSION < 900
    474510    int lpmethod;
    475511    CPXgetintparam (env,CPX_PARAM_LPMETHOD,&lpmethod);
     
    483519      }
    484520    }
     521  }
     522#else
     523  void statusSwitch(CPXENVptr,int&){}
    485524#endif
    486   }
    487525
    488526  LpCplex::SolutionStatus LpCplex::_getPrimalStatus() const
  • lemon/lp_cplex.h

    r2553 r2605  
    5050    LpCplex();
    5151    /// \e
     52    LpCplex(const LpCplex&);
     53    /// \e
    5254    ~LpCplex();
    5355
    5456  protected:
    55     virtual LpSolverBase &_newLp();
    56     virtual LpSolverBase &_copyLp();
     57    virtual LpSolverBase* _newLp();
     58    virtual LpSolverBase* _copyLp();
    5759
    5860
     
    101103    virtual bool _isMax() const;
    102104
     105  public:
     106
     107    CPXENVptr cplexEnv() { return env; }
     108    CPXLPptr cplexLp() { return lp; }
     109
    103110  };
    104111} //END OF NAMESPACE LEMON
  • lemon/lp_glpk.cc

    r2591 r2605  
    9090                                LEMON_glp(get_col_ub)(glp.lp,i));
    9191      }
     92    rows = glp.rows;
     93    cols = glp.cols;
    9294  }
    9395 
     
    106108
    107109
    108   LpSolverBase &LpGlpk::_newLp()
    109   {
    110     LpGlpk* newlp=new LpGlpk;
    111     return *newlp;
     110  LpSolverBase* LpGlpk::_newLp()
     111  {
     112    LpGlpk* newlp = new LpGlpk;
     113    return newlp;
    112114  }
    113115 
    114116  ///\e
    115117
    116   LpSolverBase &LpGlpk::_copyLp()
    117   {
    118     LpGlpk* newlp=new LpGlpk(*this);
    119     return *newlp;
     118  LpSolverBase* LpGlpk::_copyLp()
     119  {
     120    LpGlpk *newlp = new LpGlpk(*this);
     121    return newlp;
    120122  }
    121123
  • lemon/lp_glpk.h

    r2557 r2605  
    5050   
    5151  protected:
    52     virtual LpSolverBase &_newLp();
    53     virtual LpSolverBase &_copyLp();
     52    virtual LpSolverBase* _newLp();
     53    virtual LpSolverBase* _copyLp();
    5454
    5555    virtual int _addCol();
     
    121121    ///Pointer to the underlying GLPK data structure.
    122122    LPX *lpx() {return lp;}
     123
     124    ///Returns the constraint identifier understood by GLPK.
     125    int lpxRow(Row r) { return _lpId(r); }
     126
     127    ///Returns the variable identifier understood by GLPK.
     128    int lpxCol(Col c) { return _lpId(c); }
    123129  };
    124130} //END OF NAMESPACE LEMON
  • lemon/lp_skeleton.cc

    r2553 r2605  
    2323namespace lemon {
    2424 
    25   LpSolverBase &LpSkeleton::_newLp()
     25  LpSolverBase* LpSkeleton::_newLp()
    2626  {
    2727    LpSolverBase *tmp=0;
    28     return *tmp;
     28    return tmp;
    2929  }
    3030 
    31   LpSolverBase &LpSkeleton::_copyLp()
     31  LpSolverBase* LpSkeleton::_copyLp()
    3232  {
    3333    LpSolverBase *tmp=0;
    34     return *tmp;
     34    return tmp;
    3535  }
    3636
  • lemon/lp_skeleton.h

    r2553 r2605  
    3333
    3434    ///\e
    35     virtual LpSolverBase &_newLp();
     35    virtual LpSolverBase* _newLp();
    3636    ///\e
    37     virtual LpSolverBase &_copyLp();
     37    virtual LpSolverBase* _copyLp();
    3838    /// \e
    3939    virtual int _addCol();
  • lemon/lp_soplex.cc

    r2553 r2605  
    3737    delete soplex;
    3838  }
    39  
    40   LpSolverBase &LpSoplex::_newLp() {
     39
     40  LpSoplex::LpSoplex(const LpSoplex& lp) : LpSolverBase() {
     41    rows = lp.rows;
     42    rows.setIdHandler(relocateIdHandler);
     43
     44    cols = lp.cols;
     45    cols.setIdHandler(relocateIdHandler);
     46
     47    soplex = new soplex::SoPlex;
     48    (*static_cast<soplex::SPxLP*>(soplex)) = *(lp.soplex);
     49
     50    colNames = lp.colNames;
     51    invColNames = lp.invColNames;
     52
     53    primal_value = lp.primal_value;
     54    dual_value = lp.dual_value;
     55
     56  }
     57 
     58  LpSolverBase* LpSoplex::_newLp() {
    4159    LpSoplex* newlp = new LpSoplex();
    42     return *newlp;
    43   }
    44 
    45   LpSolverBase &LpSoplex::_copyLp() {
    46     LpSoplex* newlp = new LpSoplex();
    47     (*static_cast<soplex::SPxLP*>(newlp->soplex)) = *soplex;
    48     return *newlp;
     60    return newlp;
     61  }
     62
     63  LpSolverBase* LpSoplex::_copyLp() {
     64    LpSoplex* newlp = new LpSoplex(*this);
     65    return newlp;
    4966  }
    5067
  • lemon/lp_soplex.h

    r2553 r2605  
    6767    LpSoplex();
    6868    /// \e
     69    LpSoplex(const LpSoplex&);
     70    /// \e
    6971    ~LpSoplex();
    7072
    7173  protected:
    7274
    73     virtual LpSolverBase &_newLp();
    74     virtual LpSolverBase &_copyLp();
     75    virtual LpSolverBase* _newLp();
     76    virtual LpSolverBase* _copyLp();
    7577
    7678    virtual int _addCol();
  • test/lp_test.cc

    r2571 r2605  
    2121#include "test_tools.h"
    2222#include <lemon/tolerance.h>
     23#include <lemon/lp_utils.h>
    2324
    2425#ifdef HAVE_CONFIG_H
     
    217218  {
    218219    LP::DualExpr e,f,g;
    219     LP::Row p1,p2,p3,p4,p5;
     220    LP::Row p1 = INVALID, p2 = INVALID, p3 = INVALID,
     221      p4 = INVALID, p5 = INVALID;
    220222   
    221223    e[p1]=2;
     
    296298  lp.max();
    297299
    298 
    299300  //Testing the problem retrieving routines
    300301  check(lp.objCoeff(x1)==1,"First term should be 1 in the obj function!");
     
    308309  check(  lb==-LpSolverBase::INF,"The lower bound for the first row should be -infty.");
    309310  check(  ub==1,"The upper bound for the first row should be 1.");
    310 
     311  LpSolverBase::Expr e = lp.row(upright);
     312  check(  e.size() == 2, "The row retrieval gives back wrong expression.");
     313  check(  e[x1] == 1, "The first coefficient should 1.");
     314  check(  e[x2] == 1, "The second coefficient should 1.");
     315
     316  LpSolverBase::DualExpr de = lp.col(x1);
     317  check(  de.size() == 4, "The col retrieval gives back wrong expression.");
     318  check(  de[upright] == 1, "The first coefficient should 1.");
     319
     320  LpSolverBase* clp = lp.copyLp();
     321
     322  //Testing the problem retrieving routines
     323  check(clp->objCoeff(x1)==1,"First term should be 1 in the obj function!");
     324  check(clp->isMax(),"This is a maximization!");
     325  check(clp->coeff(upright,x1)==1,"The coefficient in question is 1!");
     326  //  std::cout<<lp.colLowerBound(x1)<<std::endl;
     327  check(  clp->colLowerBound(x1)==0,"The lower bound for variable x1 should be 0.");
     328  std::cerr << clp->colUpperBound(x1) << std::endl;
     329  check(  clp->colUpperBound(x1)==LpSolverBase::INF,"The upper bound for variable x1 should be infty.");
     330
     331  clp->getRowBounds(upright,lb,ub);
     332  check(  lb==-LpSolverBase::INF,"The lower bound for the first row should be -infty.");
     333  check(  ub==1,"The upper bound for the first row should be 1.");
     334  e = clp->row(upright);
     335  check(  e.size() == 2, "The row retrieval gives back wrong expression.");
     336  check(  e[x1] == 1, "The first coefficient should 1.");
     337  check(  e[x2] == 1, "The second coefficient should 1.");
     338
     339  de = clp->col(x1);
     340  check(  de.size() == 4, "The col retrieval gives back wrong expression.");
     341  check(  de[upright] == 1, "The first coefficient should 1.");
     342 
     343  delete clp;
    311344
    312345  //Maximization of x1+x2
     
    338371  lp.min();
    339372  check(lp.primalStatus()==LpSolverBase::UNDEFINED,"Primalstatus should be UNDEFINED");
     373
    340374
    341375//   lp.solve();
Note: See TracChangeset for help on using the changeset viewer.