COIN-OR::LEMON - Graph Library

Changeset 459:ed54c0d13df0 in lemon-1.2 for test/lp_test.cc


Ignore:
Timestamp:
12/02/08 22:48:28 (11 years ago)
Author:
Balazs Dezso <deba@…>
Branch:
default
Children:
460:76ec7bd57026, 502:17cabb114d52
Phase:
public
Message:

Thorough redesign of the LP/MIP interface (#44)

  • Redesigned class structure
  • Redesigned iterators
  • Some functions in the basic interface redesigned
  • More complete setting functions
  • Ray retrieving functions
  • Lot of improvements
  • Cplex common env
  • CLP macro definition to config.h.in
  • Update lp.h to also use soplex and clp
  • Remove default_solver_name
  • New solverName() function in solvers
  • Handle exceptions for MipCplex? test
  • Rename tolerance parameter to epsilon
  • Rename MapIt? to CoeffIt?
  • Lot of documentation improvements
  • Various bugfixes
File:
1 edited

Legend:

Unmodified
Added
Removed
  • test/lp_test.cc

    r458 r459  
    3838#endif
    3939
     40#ifdef HAVE_CLP
     41#include <lemon/lp_clp.h>
     42#endif
     43
    4044using namespace lemon;
    4145
    42 void lpTest(LpSolverBase & lp)
     46void lpTest(LpSolver& lp)
    4347{
    4448
    45 
    46 
    47   typedef LpSolverBase LP;
     49  typedef LpSolver LP;
    4850
    4951  std::vector<LP::Col> x(10);
     
    5355  lp.colUpperBound(x,1);
    5456  lp.colBounds(x,1,2);
    55 #ifndef GYORSITAS
    5657
    5758  std::vector<LP::Col> y(10);
     
    8788
    8889    e[p1]=2;
    89     e.constComp()=12;
     90    *e=12;
    9091    e[p1]+=2;
    91     e.constComp()+=12;
     92    *e+=12;
    9293    e[p1]-=2;
    93     e.constComp()-=12;
     94    *e-=12;
    9495
    9596    e=2;
     
    171172    e[x[3]]=4;
    172173    e[x[3]]=1;
    173     e.constComp()=12;
    174 
    175     lp.addRow(LP::INF,e,23);
    176     lp.addRow(LP::INF,3.0*(x[1]+x[2]/2)-x[3],23);
    177     lp.addRow(LP::INF,3.0*(x[1]+x[2]*2-5*x[3]+12-x[4]/3)+2*x[4]-4,23);
     174    *e=12;
     175
     176    lp.addRow(-LP::INF,e,23);
     177    lp.addRow(-LP::INF,3.0*(x[1]+x[2]/2)-x[3],23);
     178    lp.addRow(-LP::INF,3.0*(x[1]+x[2]*2-5*x[3]+12-x[4]/3)+2*x[4]-4,23);
    178179
    179180    lp.addRow(x[1]+x[3]<=x[5]-3);
     
    182183
    183184    std::ostringstream buf;
    184 
    185 
    186     //Checking the simplify function
    187 
    188 //     //How to check the simplify function? A map gives no information
    189 //     //on the question whether a given key is or is not stored in it, or
    190 //     //it does?
    191 //   Yes, it does, using the find() function.
    192     e=((p1+p2)+(p1-p2));
    193     e.simplify();
    194     buf << "Coeff. of p2 should be 0";
    195     //    std::cout<<e[p1]<<e[p2]<<e[p3]<<std::endl;
    196     check(e.find(p2)==e.end(), buf.str());
    197 
    198 
    199185
    200186
     
    210196    e.simplify(tolerance);
    211197    buf << "Coeff. of p2 should be 0";
    212     check(e.find(p2)==e.end(), buf.str());
     198    check(const_cast<const LpSolver::Expr&>(e)[p2]==0, buf.str());
    213199
    214200
     
    248234  }
    249235
    250 #endif
    251236}
    252237
    253 void solveAndCheck(LpSolverBase& lp, LpSolverBase::SolutionStatus stat,
     238void solveAndCheck(LpSolver& lp, LpSolver::ProblemType stat,
    254239                   double exp_opt) {
    255240  using std::string;
    256241  lp.solve();
    257   //int decimal,sign;
     242
    258243  std::ostringstream buf;
    259   buf << "Primalstatus should be: " << int(stat);
    260 
    261   //  itoa(stat,buf1, 10);
    262   check(lp.primalStatus()==stat, buf.str());
    263 
    264   if (stat ==  LpSolverBase::OPTIMAL) {
     244  buf << "PrimalType should be: " << int(stat) << int(lp.primalType());
     245
     246  check(lp.primalType()==stat, buf.str());
     247
     248  if (stat ==  LpSolver::OPTIMAL) {
    265249    std::ostringstream sbuf;
    266250    sbuf << "Wrong optimal value: the right optimum is " << exp_opt;
    267     check(std::abs(lp.primalValue()-exp_opt) < 1e-3, sbuf.str());
    268     //+ecvt(exp_opt,2)
     251    check(std::abs(lp.primal()-exp_opt) < 1e-3, sbuf.str());
    269252  }
    270253}
    271254
    272 void aTest(LpSolverBase & lp)
     255void aTest(LpSolver & lp)
    273256{
    274   typedef LpSolverBase LP;
     257  typedef LpSolver LP;
    275258
    276259 //The following example is very simple
    277260
    278   typedef LpSolverBase::Row Row;
    279   typedef LpSolverBase::Col Col;
     261  typedef LpSolver::Row Row;
     262  typedef LpSolver::Col Col;
    280263
    281264
     
    285268
    286269  //Constraints
    287   Row upright=lp.addRow(x1+x2 <=1);
     270  Row upright=lp.addRow(x1+2*x2 <=1);
    288271  lp.addRow(x1+x2 >=-1);
    289272  lp.addRow(x1-x2 <=1);
     
    295278  lp.obj(x1+x2);
    296279
    297   lp.max();
     280  lp.sense(lp.MAX);
    298281
    299282  //Testing the problem retrieving routines
    300283  check(lp.objCoeff(x1)==1,"First term should be 1 in the obj function!");
    301   check(lp.isMax(),"This is a maximization!");
     284  check(lp.sense() == lp.MAX,"This is a maximization!");
    302285  check(lp.coeff(upright,x1)==1,"The coefficient in question is 1!");
    303   //  std::cout<<lp.colLowerBound(x1)<<std::endl;
    304   check(  lp.colLowerBound(x1)==0,
    305           "The lower bound for variable x1 should be 0.");
    306   check(  lp.colUpperBound(x1)==LpSolverBase::INF,
    307           "The upper bound for variable x1 should be infty.");
    308   LpSolverBase::Value lb,ub;
    309   lp.getRowBounds(upright,lb,ub);
    310   check(  lb==-LpSolverBase::INF,
    311           "The lower bound for the first row should be -infty.");
    312   check(  ub==1,"The upper bound for the first row should be 1.");
    313   LpSolverBase::Expr e = lp.row(upright);
    314   check(  e.size() == 2, "The row retrieval gives back wrong expression.");
    315   check(  e[x1] == 1, "The first coefficient should 1.");
    316   check(  e[x2] == 1, "The second coefficient should 1.");
    317 
    318   LpSolverBase::DualExpr de = lp.col(x1);
    319   check(  de.size() == 4, "The col retrieval gives back wrong expression.");
     286  check(lp.colLowerBound(x1)==0,
     287        "The lower bound for variable x1 should be 0.");
     288  check(lp.colUpperBound(x1)==LpSolver::INF,
     289        "The upper bound for variable x1 should be infty.");
     290  check(lp.rowLowerBound(upright) == -LpSolver::INF,
     291        "The lower bound for the first row should be -infty.");
     292  check(lp.rowUpperBound(upright)==1,
     293        "The upper bound for the first row should be 1.");
     294  LpSolver::Expr e = lp.row(upright);
     295  check(e[x1] == 1, "The first coefficient should 1.");
     296  check(e[x2] == 2, "The second coefficient should 1.");
     297
     298  lp.row(upright, x1+x2 <=1);
     299  e = lp.row(upright);
     300  check(e[x1] == 1, "The first coefficient should 1.");
     301  check(e[x2] == 1, "The second coefficient should 1.");
     302
     303  LpSolver::DualExpr de = lp.col(x1);
    320304  check(  de[upright] == 1, "The first coefficient should 1.");
    321305
    322   LpSolverBase* clp = lp.copyLp();
     306  LpSolver* clp = lp.cloneSolver();
    323307
    324308  //Testing the problem retrieving routines
    325309  check(clp->objCoeff(x1)==1,"First term should be 1 in the obj function!");
    326   check(clp->isMax(),"This is a maximization!");
     310  check(clp->sense() == clp->MAX,"This is a maximization!");
    327311  check(clp->coeff(upright,x1)==1,"The coefficient in question is 1!");
    328312  //  std::cout<<lp.colLowerBound(x1)<<std::endl;
    329   check(  clp->colLowerBound(x1)==0,
    330           "The lower bound for variable x1 should be 0.");
    331   check(  clp->colUpperBound(x1)==LpSolverBase::INF,
    332           "The upper bound for variable x1 should be infty.");
    333 
    334   clp->getRowBounds(upright,lb,ub);
    335   check(  lb==-LpSolverBase::INF,
    336           "The lower bound for the first row should be -infty.");
    337   check(  ub==1,"The upper bound for the first row should be 1.");
     313  check(clp->colLowerBound(x1)==0,
     314        "The lower bound for variable x1 should be 0.");
     315  check(clp->colUpperBound(x1)==LpSolver::INF,
     316        "The upper bound for variable x1 should be infty.");
     317
     318  check(lp.rowLowerBound(upright)==-LpSolver::INF,
     319        "The lower bound for the first row should be -infty.");
     320  check(lp.rowUpperBound(upright)==1,
     321        "The upper bound for the first row should be 1.");
    338322  e = clp->row(upright);
    339   check(  e.size() == 2, "The row retrieval gives back wrong expression.");
    340   check(  e[x1] == 1, "The first coefficient should 1.");
    341   check(  e[x2] == 1, "The second coefficient should 1.");
     323  check(e[x1] == 1, "The first coefficient should 1.");
     324  check(e[x2] == 1, "The second coefficient should 1.");
    342325
    343326  de = clp->col(x1);
    344   check(  de.size() == 4, "The col retrieval gives back wrong expression.");
    345   check(  de[upright] == 1, "The first coefficient should 1.");
     327  check(de[upright] == 1, "The first coefficient should 1.");
    346328
    347329  delete clp;
     
    350332  //over the triangle with vertices (0,0) (0,1) (1,0)
    351333  double expected_opt=1;
    352   solveAndCheck(lp, LpSolverBase::OPTIMAL, expected_opt);
     334  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
    353335
    354336  //Minimization
    355   lp.min();
     337  lp.sense(lp.MIN);
    356338  expected_opt=0;
    357   solveAndCheck(lp, LpSolverBase::OPTIMAL, expected_opt);
     339  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
    358340
    359341  //Vertex (-1,0) instead of (0,0)
    360   lp.colLowerBound(x1, -LpSolverBase::INF);
     342  lp.colLowerBound(x1, -LpSolver::INF);
    361343  expected_opt=-1;
    362   solveAndCheck(lp, LpSolverBase::OPTIMAL, expected_opt);
     344  solveAndCheck(lp, LpSolver::OPTIMAL, expected_opt);
    363345
    364346  //Erase one constraint and return to maximization
    365   lp.eraseRow(upright);
    366   lp.max();
    367   expected_opt=LpSolverBase::INF;
    368   solveAndCheck(lp, LpSolverBase::INFINITE, expected_opt);
     347  lp.erase(upright);
     348  lp.sense(lp.MAX);
     349  expected_opt=LpSolver::INF;
     350  solveAndCheck(lp, LpSolver::UNBOUNDED, expected_opt);
    369351
    370352  //Infeasibilty
    371353  lp.addRow(x1+x2 <=-2);
    372   solveAndCheck(lp, LpSolverBase::INFEASIBLE, expected_opt);
    373 
    374   //Change problem and forget to solve
    375   lp.min();
    376   check(lp.primalStatus()==LpSolverBase::UNDEFINED,
    377         "Primalstatus should be UNDEFINED");
    378 
    379 
    380 //   lp.solve();
    381 //   if (lp.primalStatus()==LpSolverBase::OPTIMAL){
    382 //     std::cout<< "Z = "<<lp.primalValue()
    383 //              << " (error = " << lp.primalValue()-expected_opt
    384 //              << "); x1 = "<<lp.primal(x1)
    385 //              << "; x2 = "<<lp.primal(x2)
    386 //              <<std::endl;
    387 
    388 //   }
    389 //   else{
    390 //     std::cout<<lp.primalStatus()<<std::endl;
    391 //     std::cout<<"Optimal solution not found!"<<std::endl;
    392 //   }
    393 
    394 
     354  solveAndCheck(lp, LpSolver::INFEASIBLE, expected_opt);
    395355
    396356}
    397 
    398357
    399358int main()
     
    403362
    404363#ifdef HAVE_GLPK
    405   LpGlpk lp_glpk1,lp_glpk2;
    406   lpTest(lp_glpk1);
    407   aTest(lp_glpk2);
     364  {
     365    LpGlpk lp_glpk1,lp_glpk2;
     366    lpTest(lp_glpk1);
     367    aTest(lp_glpk2);
     368  }
    408369#endif
    409370
    410371#ifdef HAVE_CPLEX
    411   LpCplex lp_cplex1,lp_cplex2;
    412   lpTest(lp_cplex1);
    413   aTest(lp_cplex2);
     372  try {
     373    LpCplex lp_cplex1,lp_cplex2;
     374    lpTest(lp_cplex1);
     375    aTest(lp_cplex2);
     376  } catch (CplexEnv::LicenseError& error) {
     377#ifdef LEMON_FORCE_CPLEX_CHECK
     378    check(false, error.what());
     379#else
     380    std::cerr << error.what() << std::endl;
     381    std::cerr << "Cplex license check failed, lp check skipped" << std::endl;
     382#endif
     383  }
    414384#endif
    415385
    416386#ifdef HAVE_SOPLEX
    417   LpSoplex lp_soplex1,lp_soplex2;
    418   lpTest(lp_soplex1);
    419   aTest(lp_soplex2);
     387  {
     388    LpSoplex lp_soplex1,lp_soplex2;
     389    lpTest(lp_soplex1);
     390    aTest(lp_soplex2);
     391  }
     392#endif
     393
     394#ifdef HAVE_CLP
     395  {
     396    LpClp lp_clp1,lp_clp2;
     397    lpTest(lp_clp1);
     398    aTest(lp_clp2);
     399  }
    420400#endif
    421401
Note: See TracChangeset for help on using the changeset viewer.