Changeset 1553


Ignore:
Timestamp:
Jul 31, 2010 3:30:09 PM (9 years ago)
Author:
lou
Message:

Clean up OsiSolverInterfaceMpsUnitTest?: change from asserts to error count,
remove invalid test of getFractionalIndices. Exclude vol prior to call, in
unitTest.

Location:
trunk/Osi
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/Osi/src/OsiCommonTest/OsiSolverInterfaceTest.cpp

    r1516 r1553  
    104104{
    105105  std::cout.flush() ;
    106   std::cerr <<msg;
    107   //cout <<endl <<"*****************************************"
    108   //     <<endl <<msg <<endl;
     106  std::cerr << msg;
    109107}
    110108
     
    125123  int i;
    126124  for ( i=0; i<size; i++ ) {
    127 
    128     // If both are equal to infinity then iterate
    129     if ( fabs(v1[i])==si1->getInfinity() && fabs(v2[i])==si2->getInfinity() )
    130        continue;
    131 
    132     // Test to see if equal
    133125    if ( !eq(v1[i],v2[i]) ) {
     126      std::cout.flush() ;
    134127      std::cerr <<"eq " <<i <<" " <<v1[i] <<" " <<v2[i] <<std::endl;
    135128      retVal = false;
    136129      break;
    137130    }
    138 
    139131  }
    140132  return retVal;
     
    15861578
    15871579    rowNames = si->getRowNames() ;
    1588     rowNameCnt = rowNames.size() ;
     1580    rowNameCnt = static_cast<int>(rowNames.size()) ;
    15891581    if (rowNameCnt != static_cast<int>(exmip1RowNames.size()))
    15901582    { std::cout
     
    16061598
    16071599    colNames = si->getColNames() ;
    1608     colNameCnt = colNames.size() ;
     1600    colNameCnt = static_cast<int>(colNames.size()) ;
    16091601    if (colNameCnt != static_cast<int>(exmip1ColNames.size()))
    16101602    { std::cout
     
    17051697    return (errCnt) ; }
    17061698  rowNames = si->getRowNames() ;
    1707   rowNameCnt = rowNames.size() ;
     1699  rowNameCnt = static_cast<int>(rowNames.size()) ;
    17081700  if (rowNameCnt != static_cast<int>(exmip1RowNames.size()))
    17091701  { std::cout
     
    17271719
    17281720  colNames = si->getColNames() ;
    1729   colNameCnt = colNames.size() ;
     1721  colNameCnt = static_cast<int>(colNames.size()) ;
    17301722  if (colNameCnt != static_cast<int>(exmip1ColNames.size()))
    17311723  { std::cout
     
    17621754    return (errCnt) ; }
    17631755  rowNames = si->getRowNames() ;
    1764   rowNameCnt = rowNames.size() ;
     1756  rowNameCnt = static_cast<int>(rowNames.size()) ;
    17651757  if (rowNameCnt != m)
    17661758  { failureMessage(solverName,"incorrect length row name vector") ;
     
    17951787  si->deleteRows(1,indices) ;
    17961788  rowNames = si->getRowNames() ;
    1797   rowNameCnt = rowNames.size() ;
     1789  rowNameCnt = static_cast<int>(rowNames.size()) ;
    17981790  if (rowNameCnt != m)
    17991791  { std::cout
     
    18371829    return (errCnt) ; }
    18381830  colNames = si->getColNames() ;
    1839   colNameCnt = colNames.size() ;
     1831  colNameCnt = static_cast<int>(colNames.size()) ;
    18401832  if (colNameCnt != n)
    18411833  { failureMessage(solverName,"incorrect length column name vector") ;
     
    18611853  si->deleteCols(1,indices) ;
    18621854  colNames = si->getColNames() ;
    1863   colNameCnt = colNames.size() ;
     1855  colNameCnt = static_cast<int>(colNames.size()) ;
    18641856  if (colNameCnt != n)
    18651857  { std::cout
     
    18911883  si->setRowNames(exmip1ColNames,0,3,2) ;
    18921884  rowNames = si->getRowNames() ;
    1893   rowNameCnt = rowNames.size() ;
     1885  rowNameCnt = static_cast<int>(rowNames.size()) ;
    18941886  if (rowNameCnt != m)
    18951887  { std::cout
     
    19201912  si->setColNames(exmip1RowNames,3,2,0) ;
    19211913  colNames = si->getColNames() ;
    1922   colNameCnt = colNames.size() ;
     1914  colNameCnt = static_cast<int>(colNames.size()) ;
    19231915  if (colNameCnt != n)
    19241916  { std::cout
     
    19531945  si->deleteRowNames(0,2) ;
    19541946  rowNames = si->getRowNames() ;
    1955   rowNameCnt = rowNames.size() ;
     1947  rowNameCnt = static_cast<int>(rowNames.size()) ;
    19561948  if (rowNameCnt != m-2)
    19571949  { std::cout
     
    19781970  si->deleteColNames(5,3) ;
    19791971  colNames = si->getColNames() ;
    1980   colNameCnt = colNames.size() ;
     1972  colNameCnt = static_cast<int>(colNames.size()) ;
    19811973  if (colNameCnt != n-3)
    19821974  { std::cout
     
    20162008  m = si->getNumRows() ;
    20172009  rowNames = si->getRowNames() ;
    2018   rowNameCnt = rowNames.size() ;
     2010  rowNameCnt = static_cast<int>(rowNames.size()) ;
    20192011  if (rowNameCnt != m+1)
    20202012  { std::cout
     
    20482040  n = si->getNumCols() ;
    20492041  colNames = si->getColNames() ;
    2050   colNameCnt = colNames.size() ;
     2042  colNameCnt = static_cast<int>(colNames.size()) ;
    20512043  if (colNameCnt != n)
    20522044  { std::cout
     
    26902682  bool solved = true;
    26912683  try {
    2692      si1->initialSolve();
     2684    si1->initialSolve();
    26932685  }
    26942686  catch (CoinError e) {
    2695      if (e.className() != "OsiVolSolverInterface" && e.className() != "OsiTestSolverInterface") {
    2696         failureMessage(*si1,"Couldn't load and solve LP in testWriteMps!\n");
    2697         abort();
    2698      }
    2699      solved = false;
     2687    if (e.className() != "OsiVolSolverInterface" &&
     2688        e.className() != "OsiTestSolverInterface") {
     2689      failureMessage(*si1,"Couldn't load and solve LP in testWriteMps!\n");
     2690      abort();
     2691    }
     2692    solved = false;
    27002693  }
    27012694  double soln = si1->getObjValue();
     
    27172710         "Couldn't load and solve mps file written by writeMpsNative!\n");
    27182711      abort();
    2719       }
     2712    }
    27202713    assert(eq(soln,si2->getObjValue()));
    27212714  }
     
    27332726         "Couldn't load and solve mps file written by writeMps!\n");
    27342727      abort();
    2735       }
     2728    }
    27362729    assert(eq(soln,si3->getObjValue()));
    27372730  }
     
    38283821  t14,t58 <= 30    tt24, t57 <= 20    t25, t35, t46 <= 10    t47 <= 2
    38293822 
    3830   It is dual unbounded and has two dual rays (transpose):
    3831 
    3832   r0 = [ 0 0 0 0 0 0 1 1 ]
    3833   r1 = [ 0 0 1 0 0 0 1 1 ]
    3834 
    3835   The routine doesn't actually test for these dual rays; rather, it tests for
    3836   rA >= 0, on the assumption that the dual constraint system is yA >= c.
     3823  The routine doesn't actually test for specific dual rays; rather, it tests for
     3824  rA >= 0 and rb < 0, on the assumption that the dual constraint system matches
     3825  the canonical form min yb  yA >= c. (More accurately, on the assumption that
     3826  the sign convention of the ray is correct for the canonical form.)
    38373827*/
    38383828
     
    38973887    errCnt++ ; }
    38983888/*
    3899   We have rays. Check to see if the solver found both. It's not really an
    3900   error to return only one --- the definition of getDualRays is ambiguous on
    3901   this point. It's definitely an error to claim none.
     3889  We have rays. Check to see how many. It's not really an error to return
     3890  only one --- there's no exhaustive inventory of rays at every vertex ---
     3891  but it's definitely an error to claim none, or to return more than the
     3892  maximum.
    39023893*/
    39033894  if (catchSomeRays == true)
    3904   { rayCnt = rays.size() ;
    3905     if (rayCnt < 2)
     3895  { rayCnt = static_cast<unsigned int>(rays.size()) ;
     3896    if (rayCnt < 1 || rayCnt > 5)
    39063897    { std::cout
    3907         << "  " << solverName << " returned only "
    3908         << rayCnt << " rays; two are available." << std::endl ;
    3909       if (rayCnt == 0) errCnt++ ; }
     3898        << "  " << solverName << " returned "
     3899        << rayCnt << " rays; expected between 1 and 5." << std::endl ;
     3900      errCnt++ ; }
    39103901
    39113902    unsigned int m,n,i,j ;
     
    39743965  return (errCnt) ; }
    39753966
     3967/*
     3968  Method to compare the problem representation held by a pair of solver
     3969  interfaces.
     3970*/
     3971bool compareProblems (OsiSolverInterface *osi1, OsiSolverInterface *osi2) {
     3972
     3973  bool areEquiv = true ;
     3974  std::string si1Name, si2Name ;
     3975  osi1->getStrParam(OsiSolverName,si1Name) ;
     3976  osi2->getStrParam(OsiSolverName,si2Name) ;
     3977
     3978  // Compare row and column counts
     3979  int colCnt = 0 ;
     3980  if (osi1->getNumCols() != osi2->getNumCols())
     3981  { std::cerr
     3982      << "  Unequal column count, "
     3983      << si1Name << " vs. " << si2Name << std::endl ;
     3984    return (false) ; }
     3985  else
     3986  { colCnt = osi1->getNumCols() ; }
     3987
     3988  int rowCnt = 0 ;
     3989  if (osi1->getNumRows() != osi2->getNumRows())
     3990  { std::cerr
     3991      << "  Unequal row count, "
     3992      << si1Name << " vs. " << si2Name << std::endl ;
     3993    return (false) ; }
     3994  else
     3995  { rowCnt = osi1->getNumRows() ; }
     3996
     3997  // Compare column bounds
     3998  areEquiv = equivalentVectors(osi1,osi2,1.e-10,
     3999                osi1->getColLower(),osi2->getColLower(),colCnt) ;
     4000  if (areEquiv == false)
     4001  { std::cerr
     4002      << "  Unequal column lower bounds, "
     4003      << si1Name << " vs. " << si2Name << std::endl ;
     4004    return (false) ; }
     4005  areEquiv = equivalentVectors(osi1,osi2,1.e-10,
     4006                osi1->getColUpper(),osi2->getColUpper(),colCnt) ;
     4007  if (areEquiv == false)
     4008  { std::cerr
     4009      << "  Unequal column upper bounds, "
     4010      << si1Name << " vs. " << si2Name << std::endl ;
     4011    return (false) ; }
     4012
     4013  // Compare row bounds
     4014  areEquiv = equivalentVectors(osi1,osi2,1.e-10,
     4015                osi1->getRowLower(),osi2->getRowLower(),rowCnt) ;
     4016  if (areEquiv == false)
     4017  { std::cerr
     4018      << "  Unequal row lower bounds, "
     4019      << si1Name << " vs. " << si2Name << std::endl ;
     4020    return (false) ; }
     4021  areEquiv = equivalentVectors(osi1,osi2,1.e-10,
     4022                osi1->getRowUpper(),osi2->getRowUpper(),rowCnt) ;
     4023  if (areEquiv == false)
     4024  { std::cerr
     4025      << "  Unequal row lower bounds, "
     4026      << si1Name << " vs. " << si2Name << std::endl ;
     4027    return (false) ; }
     4028
     4029  // Compare row sense
     4030  { const char *rowSense1 = osi1->getRowSense() ;
     4031    const char *rowSense2 = osi2->getRowSense() ;
     4032    areEquiv = true ;
     4033    for (int r = 0 ; r < rowCnt && areEquiv == true ; r++)
     4034    { if (rowSense1[r] != rowSense2[r])
     4035      { areEquiv = false ; } }
     4036    if (areEquiv == false)
     4037    { std::cerr
     4038        << "  Unequal row sense, "
     4039        << si1Name << " vs. " << si2Name << std::endl ;
     4040      return (false) ; } }
     4041
     4042  // Compare row rhs
     4043  areEquiv = equivalentVectors(osi1,osi2,1.e-10,
     4044                osi1->getRightHandSide(),osi2->getRightHandSide(),rowCnt) ;
     4045  if (areEquiv == false)
     4046  { std::cerr
     4047      << "  Unequal right-hand-side, "
     4048      << si1Name << " vs. " << si2Name << std::endl ;
     4049    return (false) ; }
     4050
     4051  // Compare range
     4052  areEquiv = equivalentVectors(osi1,osi2,1.e-10,
     4053                osi1->getRowRange(),osi2->getRowRange(),rowCnt) ;
     4054  if (areEquiv == false)
     4055  { std::cerr
     4056      << "  Unequal row range, "
     4057      << si1Name << " vs. " << si2Name << std::endl ;
     4058    return (false) ; }
     4059
     4060  // Compare objective sense
     4061  if (osi1->getObjSense() != osi2->getObjSense())
     4062  { std::cerr
     4063      << "  Unequal objective sense, "
     4064      << si1Name << " vs. " << si2Name << std::endl ;
     4065    return (false) ; }
     4066
     4067  // Compare objective coefficients
     4068  areEquiv = equivalentVectors(osi1,osi2,1.e-10,
     4069                osi1->getObjCoefficients(),osi2->getObjCoefficients(),colCnt) ;
     4070  if (areEquiv == false)
     4071  { std::cerr
     4072      << "  Unequal objective coefficients, "
     4073      << si1Name << " vs. " << si2Name << std::endl ;
     4074    return (false) ; }
     4075
     4076  // Compare number of elements
     4077  if (osi1->getNumElements() != osi2->getNumElements())
     4078  { std::cerr
     4079      << "  Unequal number of constraint matrix coefficients, "
     4080      << si1Name << " vs. " << si2Name << std::endl ;
     4081    return (false) ; }
     4082
     4083  // Compare constraint matrix, for both row-major and column-major orderings
     4084  { const CoinPackedMatrix *rmm1=osi1->getMatrixByRow() ;
     4085    const CoinPackedMatrix *rm  =osi2->getMatrixByRow() ;
     4086    if (!rmm1->isEquivalent(*rm))
     4087    { std::cerr
     4088        << "  Unequal constraint matrix, row-major ordering, "
     4089        << si1Name << " vs. " << si2Name << std::endl ;
     4090      return (false) ; }
     4091    const CoinPackedMatrix *cmm1=osi1->getMatrixByCol() ;
     4092    const CoinPackedMatrix *cm  =osi2->getMatrixByCol() ;
     4093    if (!cmm1->isEquivalent(*cm))
     4094    { std::cerr
     4095        << "  Unequal constraint matrix, column-major ordering, "
     4096        << si1Name << " vs. " << si2Name << std::endl ;
     4097      return (false) ; }
     4098  }
     4099  // Check column types
     4100  { areEquiv = true ;
     4101    for (int j = 0 ; j < colCnt && areEquiv == true ; j++)
     4102    { if (osi1->isContinuous(j) != osi2->isContinuous(j))
     4103        areEquiv = false ;
     4104      if (osi1->isBinary(j) != osi2->isBinary(j))
     4105        areEquiv = false ;
     4106      if (osi1->isIntegerNonBinary(j) != osi2->isIntegerNonBinary(j))
     4107        areEquiv = false ;
     4108      if (osi1->isFreeBinary(j) != osi2->isFreeBinary(j))
     4109        areEquiv = false ;
     4110      if (osi1->isInteger(j) != osi2->isInteger(j))
     4111        areEquiv = false ; }
     4112    if (areEquiv == false)
     4113    { std::cerr
     4114        << "  Unequal variable type, "
     4115        << si1Name << " vs. " << si2Name << std::endl ;
     4116      return (false) ; }
     4117  }
     4118  return (true) ;
     4119}
     4120
    39764121}       // end file-local namespace
    39774122
     
    40084153*/
    40094154  std::vector<std::string> mpsName ;
    4010   std::vector<bool> min ;
     4155  std::vector<bool> minObj ;
    40114156  std::vector<int> nRows ;
    40124157  std::vector<int> nCols ;
     
    40164161  And a macro to make the vector creation marginally readable.
    40174162*/
    4018 #define PUSH_MPS(zz_mpsName_zz,zz_min_zz,\
     4163#define PUSH_MPS(zz_mpsName_zz,zz_minObj_zz,\
    40194164                 zz_nRows_zz,zz_nCols_zz,zz_objValue_zz,zz_objValueTol_zz) \
    40204165  mpsName.push_back(zz_mpsName_zz) ; \
    4021   min.push_back(zz_min_zz) ; \
     4166  minObj.push_back(zz_minObj_zz) ; \
    40224167  nRows.push_back(zz_nRows_zz) ; \
    40234168  nCols.push_back(zz_nCols_zz) ; \
     
    41284273#undef PUSH_MPS
    41294274
    4130 /*
    4131   Create a vector of solver interfaces that we can use to run the test
    4132   problems. The strategy is to create a fresh clone of the `empty' solvers
    4133   from vecEmptySiP for each problem, then proceed in stages: read the MPS
    4134   file, solve the problem, check the solution. If there are multiple
    4135   solvers in vecSiP, the results of each solver are compared with its
    4136   neighbors in the vector.
    4137 */
    4138   std::vector<OsiSolverInterface*> vecSiP(vecEmptySiP.size()) ;
    4139 
    4140   // Create vector to store a name for each solver interface
    4141   // and a count on the number of problems the solver intface solved.
    4142   std::vector<std::string> siName;
    4143   std::vector<int> numProbSolved;
    4144   std::vector<double> timeTaken;
    4145   const int vecsize = vecSiP.size();
    4146   for ( i=0; i<vecsize; i++ ) {
    4147     siName.push_back("unknown");
    4148     numProbSolved.push_back(0);
    4149     timeTaken.push_back(0.0);
    4150   }
    4151 
    4152 
    4153   //Open the main loop to step through the MPS problems.
    4154   for (m = 0 ; m < mpsName.size() ; m++) {
    4155     std::cerr << "  processing mps file: " << mpsName[m]
    4156       << " (" << m+1 << " out of " << mpsName.size() << ")" << std::endl ;
    4157     bool allSolversReadMpsFile = true;
    4158 
    4159 
    4160     //Stage 1: Read the MPS file into each solver interface.
    4161     //Fill vecSiP with fresh clones of the solvers and read in the MPS file. As
    4162     //a basic check, make sure the size of the constraint matrix is correct.
    4163     for (i = vecSiP.size()-1 ; i >= 0 ; --i) {
     4275  const unsigned int numProblems = static_cast<unsigned int>(mpsName.size()) ;
     4276
     4277/*
     4278  Create vectors to hold solver interfaces, the name of each solver interface,
     4279  the current state of processing, and statistics about the number of problems
     4280  solved and the time taken.
     4281*/
     4282  const int numSolvers = static_cast<int>(vecEmptySiP.size()) ;
     4283  std::vector<OsiSolverInterface*> vecSiP(numSolvers) ;
     4284  std::vector<std::string> siName(numSolvers) ;
     4285  std::vector<int> siStage(numSolvers) ;
     4286  std::vector<int> numProbSolved(numSolvers) ;
     4287  std::vector<double> timeTaken(numSolvers) ;
     4288  for (i = 0 ; i < numSolvers ; i++)
     4289  { siName[i] = "unknown" ;
     4290    numProbSolved[i] = 0 ;
     4291    timeTaken[i] = 0.0 ; }
     4292/*
     4293  For each problem, create a fresh clone of the `empty' solvers
     4294  from vecEmptySiP, then proceed in stages: read the MPS file, solve the
     4295  problem, check the solution. If there are multiple solvers in vecSiP,
     4296  the results of each solver are compared with its neighbors in the vector.
     4297*/
     4298  for (m = 0 ; m < numProblems ; m++) {
     4299    std::cout << "  processing mps file: " << mpsName[m]
     4300      << " (" << m+1 << " out of " << numProblems << ")" << std::endl ;
     4301/*
     4302  Stage 0: Create fresh solver clones.
     4303*/
     4304    int solversReadMpsFile = 0 ;
     4305    for (i = numSolvers-1 ; i >= 0 ; --i) {
    41644306      vecSiP[i] = vecEmptySiP[i]->clone() ;
    4165 //#     if COIN_HAS_SYMPHONY
    4166 //      // bludgeon symphony about the head so it will not print the solution
    4167 //      { OsiSymSolverInterface *reallySymSi =
    4168 //          dynamic_cast<OsiSymSolverInterface *>(vecSiP[i]) ;
    4169 //      if (reallySymSi)
    4170 //      { reallySymSi->setSymParam(OsiSymVerbosity, -2) ; } }
    4171 //#     endif
    4172 
    4173       vecSiP[i]->getStrParam(OsiSolverName,siName[i]);
    4174 
     4307      vecSiP[i]->getStrParam(OsiSolverName,siName[i]) ;
     4308      siStage[i] = 0 ;
     4309    }
     4310/*
     4311  Stage 1: Read the MPS file into each solver interface.  As a basic check,
     4312  make sure the size of the constraint matrix is correct.
     4313*/
     4314    for (i = 0 ; i < numSolvers ; i++) {
    41754315      std::string fn = mpsDir+mpsName[m] ;
    41764316      vecSiP[i]->readMps(fn.c_str(),"mps") ;
    4177 
    4178       if (min[m])
     4317      if (minObj[m])
    41794318        vecSiP[i]->setObjSense(1.0) ;
    41804319      else
    41814320        vecSiP[i]->setObjSense(-1.0) ;
    4182 
    41834321      int nr = vecSiP[i]->getNumRows() ;
    41844322      int nc = vecSiP[i]->getNumCols() ;
    4185       assert(nr == nRows[m]-1) ;
    4186       assert(nc == nCols[m]) ;
     4323      if (nr == nRows[m]-1 && nc == nCols[m])
     4324      { siStage[i] = 1 ;
     4325        solversReadMpsFile++ ; }
    41874326    }
    4188 
    4189     //If we have multiple solvers, compare the representations.
    4190     if ( allSolversReadMpsFile )
    4191       for (i = vecSiP.size()-1 ; i > 0 ; --i) {
    4192         CoinPackedVector vim1,vi ;
    4193 
    4194         // Compare col lowerbounds
    4195         assert(
    4196           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
    4197           vecSiP[i-1]->getColLower(),vecSiP[i  ]->getColLower(),
    4198           vecSiP[i  ]->getNumCols() )
    4199           ) ;
    4200 
    4201         // Compare col upperbounds
    4202         assert(
    4203           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
    4204           vecSiP[i-1]->getColUpper(),vecSiP[i  ]->getColUpper(),
    4205           vecSiP[i  ]->getNumCols() )
    4206           ) ;
    4207 
    4208         // Compare row lowerbounds
    4209         assert(
    4210           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
    4211           vecSiP[i-1]->getRowLower(),vecSiP[i  ]->getRowLower(),
    4212           vecSiP[i  ]->getNumRows() )
    4213           ) ;
    4214 
    4215         // Compare row upperbounds
    4216         assert(
    4217           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
    4218           vecSiP[i-1]->getRowUpper(),vecSiP[i  ]->getRowUpper(),
    4219           vecSiP[i  ]->getNumRows() )
    4220           ) ;
    4221 
    4222         // Compare row sense
    4223         {
    4224           const char * rsm1 = vecSiP[i-1]->getRowSense() ;
    4225           const char * rs   = vecSiP[i  ]->getRowSense() ;
    4226           int nr = vecSiP[i]->getNumRows() ;
    4227           int r ;
    4228           for (r = 0 ; r < nr ; r++) assert (rsm1[r] == rs[r]) ;
    4229         }
    4230 
    4231         // Compare rhs
    4232         assert(
    4233           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
    4234           vecSiP[i-1]->getRightHandSide(),vecSiP[i  ]->getRightHandSide(),
    4235           vecSiP[i  ]->getNumRows() )
    4236           ) ;
    4237 
    4238         // Compare range
    4239         assert(
    4240           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
    4241           vecSiP[i-1]->getRowRange(),vecSiP[i  ]->getRowRange(),
    4242           vecSiP[i  ]->getNumRows() )
    4243           ) ;
    4244 
    4245         // Compare objective sense
    4246         assert( vecSiP[i-1]->getObjSense() == vecSiP[i  ]->getObjSense() ) ;
    4247 
    4248         // Compare objective coefficients
    4249         assert(
    4250           equivalentVectors(vecSiP[i-1],vecSiP[i], 1.e-10,
    4251           vecSiP[i-1]->getObjCoefficients(),vecSiP[i  ]->getObjCoefficients(),
    4252           vecSiP[i  ]->getNumCols() )
    4253           ) ;
    4254 
    4255         // Compare number of elements
    4256         assert( vecSiP[i-1]->getNumElements() == vecSiP[i]->getNumElements() ) ;
    4257 
    4258         // Compare constraint matrix
    4259         {
    4260           const CoinPackedMatrix * rmm1=vecSiP[i-1]->getMatrixByRow() ;
    4261           const CoinPackedMatrix * rm  =vecSiP[i  ]->getMatrixByRow() ;
    4262           assert( rmm1->isEquivalent(*rm) ) ;
    4263 
    4264           const CoinPackedMatrix * cmm1=vecSiP[i-1]->getMatrixByCol() ;
    4265           const CoinPackedMatrix * cm  =vecSiP[i  ]->getMatrixByCol() ;
    4266           assert( cmm1->isEquivalent(*cm) ) ;
    4267         }
     4327/*
     4328  If more than one solver succeeded, compare representations.
     4329*/
     4330    if (solversReadMpsFile > 0) {
     4331      // Find an initial pair to compare
     4332      int s1 ;
     4333      for (s1 = 0 ; s1 < numSolvers-1 && siStage[s1] < 1 ; s1++) ;
     4334      int s2 ;
     4335      for (s2 = s1+1 ; s2 < numSolvers && siStage[s2] < 1 ; s2++) ;
     4336      while (s2 < numSolvers) {
     4337        std::cout
     4338          << "  comparing problem representation for "
     4339          << siName[s1] << " and " << siName[s2] << " ..." ;
     4340        if (compareProblems(vecSiP[s1],vecSiP[s2]))
     4341          std::cout << " ok." << std::endl  ;
     4342        s1 = s2 ;
     4343        for (s2++ ; s2 < numSolvers && siStage[s2] < 1 ; s2++) ;
    42684344      }
    4269 
    4270       //If we have multiple solvers, compare the variable type information
    4271       if ( allSolversReadMpsFile )
    4272         for (i = vecSiP.size()-1 ; i > 0 ; --i){
    4273           CoinPackedVector vim1,vi ;
    4274           int c ;
    4275 
    4276           {
    4277             OsiVectorInt sm1 = vecSiP[i-1]->getFractionalIndices() ;
    4278             OsiVectorInt s   = vecSiP[i  ]->getFractionalIndices() ;
    4279             assert( sm1.size() == s.size() ) ;
    4280             for (c = s.size()-1 ; c >= 0 ; --c) assert( sm1[c] == s[c] ) ;
    4281           }
    4282 
    4283           {
    4284             int nc = vecSiP[i]->getNumCols() ;
    4285             for (c = 0 ; c < nc ; c++){
    4286               assert(
    4287                 vecSiP[i-1]->isContinuous(c) == vecSiP[i]->isContinuous(c)
    4288                 ) ;
    4289               assert(
    4290                 vecSiP[i-1]->isBinary(c) == vecSiP[i]->isBinary(c)
    4291                 ) ;
    4292               assert(
    4293                 vecSiP[i-1]->isIntegerNonBinary(c) ==
    4294                 vecSiP[i  ]->isIntegerNonBinary(c)
    4295                 ) ;
    4296               assert(
    4297                 vecSiP[i-1]->isFreeBinary(c) == vecSiP[i]->isFreeBinary(c)
    4298                 ) ;
    4299               assert(
    4300                 vecSiP[i-1]->isInteger(c) == vecSiP[i]->isInteger(c)
    4301                 ) ;
    4302             }
    4303           }
    4304         }
    4305 
    4306       //Stage 2: Call each solver to solve the problem.
    4307       //
    4308       // We call each solver, then check the return code and objective.
    4309       //
    4310       //    Note that the volume solver can't handle the Netlib cases. The strategy is
    4311       //    to require that it be the last solver in vecSiP and then break out of the
    4312       //    loop. This ensures that all previous solvers are run and compared to one
    4313       //    another.
    4314       for (i = 0 ; i < static_cast<int>(vecSiP.size()) ; ++i) {
    4315         double startTime = CoinCpuTime();
    4316        
    4317         // VOL does not solve netlib cases so don't bother trying to solve
    4318         std::string solverName;
    4319         if( vecSiP[i]->getStrParam(OsiSolverName, solverName) && solverName == "vol" )
    4320            break;
    4321 
    4322         try
    4323         { vecSiP[i]->initialSolve() ; }
    4324         catch (CoinError &thrownErr)
    4325         { std::cerr << thrownErr.className() << "::" << thrownErr.methodName()
    4326                     << ": " << thrownErr.message() << std::endl ; }
    4327         double timeOfSolution = CoinCpuTime()-startTime;
    4328         if (vecSiP[i]->isProvenOptimal()) {
    4329           double soln = vecSiP[i]->getObjValue();
    4330           CoinRelFltEq eq(objValueTol[m]) ;
    4331           if (eq(soln,objValue[m])) {
    4332             std::cerr
    4333               <<siName[i]<<"SolverInterface "
    4334               << soln << " = " << objValue[m] <<", "
    4335               << vecSiP[i]->getIterationCount() << " iters"
    4336               << "; okay";
    4337             numProbSolved[i]++;
    4338           } else  {
    4339             std::cerr <<siName[i] <<" " <<soln << " != " <<objValue[m] << "; error=" ;
    4340             std::cerr <<fabs(objValue[m] - soln);
    4341           }
    4342         } else {
    4343            if (vecSiP[i]->isProvenPrimalInfeasible())
    4344               std::cerr << "error; primal infeasible" ;
    4345 //#ifndef COIN_HAS_SYMPHONY
    4346            else if (vecSiP[i]->isProvenDualInfeasible())
    4347               std::cerr << "error; dual infeasible" ;
    4348 //#endif
    4349            else if (vecSiP[i]->isIterationLimitReached())
    4350               std::cerr << "error; iteration limit" ;
    4351            else if (vecSiP[i]->isAbandoned())
    4352               std::cerr << "error; abandoned" ;
    4353            else
    4354               std::cerr << "error; unknown" ;
    4355         }
    4356         std::cerr<<" - took " <<timeOfSolution<<" seconds."<<std::endl;
    4357         timeTaken[i] += timeOfSolution;
     4345    }
     4346/*
     4347  Stage 2: Ask each solver that successfully read the problem to solve it,
     4348  then check the return code and objective.
     4349*/
     4350    for (i = 0 ; i < numSolvers ; ++i)
     4351    { if (siStage[i] < 1) continue ;
     4352
     4353      double startTime = CoinCpuTime() ;
     4354      bool throwError = false ;
     4355      try
     4356      { vecSiP[i]->initialSolve() ; }
     4357      catch (CoinError &thrownErr)
     4358      { std::cout.flush() ;
     4359        std::cerr
     4360          << thrownErr.className() << "::" << thrownErr.methodName()
     4361          << ": " << thrownErr.message() << std::endl ;
     4362        throwError = true ; }
     4363      catch (...)
     4364      { std::cout.flush() ;
     4365        std::cerr << siName[i] << " threw unknown exception." << std::endl ;
     4366        throwError = true ; }
     4367      if (throwError) continue ;
     4368
     4369      double timeOfSolution = CoinCpuTime()-startTime;
     4370      if (vecSiP[i]->isProvenOptimal())
     4371      { double soln = vecSiP[i]->getObjValue();
     4372        CoinRelFltEq eq(objValueTol[m]) ;
     4373        if (eq(soln,objValue[m])) {
     4374          std::cout
     4375            << "  " << siName[i] << " "
     4376            << soln << " = " << objValue[m] << ", "
     4377            << vecSiP[i]->getIterationCount() << " iters"
     4378            << "; okay" ;
     4379          numProbSolved[i]++ ; }
     4380        else
     4381        { std::cout.flush() ;
     4382          std::cerr
     4383            << "  " << siName[i]
     4384            << soln << " != " << objValue[m] << "; error = "
     4385            << fabs(objValue[m]-soln) ;
     4386        }
     4387        std::cout
     4388          << " - took " << timeOfSolution << " seconds." << std::endl;
     4389        timeTaken[i] += timeOfSolution;
    43584390      }
    4359       /*
    4360       Delete the used solver interfaces so we can reload fresh clones for the
    4361       next problem.
    4362       */
    4363       for (i = vecSiP.size()-1 ; i >= 0 ; --i) delete vecSiP[i] ;
     4391      else
     4392      { std::cout.flush() ;
     4393        std::cerr << "  " << siName[i] << "; error " ;
     4394        if (vecSiP[i]->isProvenPrimalInfeasible())
     4395          std::cerr << "primal infeasible" ;
     4396        else if (vecSiP[i]->isIterationLimitReached())
     4397          std::cerr << "iteration limit" ;
     4398        else if (vecSiP[i]->isAbandoned())
     4399          std::cerr << "abandoned" ;
     4400        else
     4401          std::cerr << "unknown" ; } }
     4402/*
     4403  Delete the used solver interfaces so we can reload fresh clones for the
     4404  next problem.
     4405*/
     4406    for (i = 0 ; i < numSolvers ; i++) delete vecSiP[i] ; }
     4407/*
     4408  Print a summary for each solver.
     4409*/
     4410  for (i = 0 ; i < numSolvers ; i++) {
     4411    std::cout
     4412      << siName[i] << " solved "
     4413      << numProbSolved[i] << " out of "
     4414      << numProblems << " and took " << timeTaken[i] << " seconds."
     4415      << std::endl ;
    43644416  }
    4365 
    4366   const int siName_size = siName.size();
    4367   for ( i=0; i<siName_size; i++ ) {
    4368     std::cerr
    4369       <<siName[i]
    4370       <<" solved "
    4371       <<numProbSolved[i]
    4372       <<" out of "
    4373       <<objValue.size()
    4374       <<" and took "
    4375       <<timeTaken[i]
    4376       <<" seconds."
    4377       <<std::endl;
    4378   }
    4379 
    4380   return (0) ;
     4417/*
     4418  If we're testing just one solver, return the number of failed problems.
     4419  If we're doing multiple solvers, always claim success.
     4420*/
     4421  if (numSolvers == 1)
     4422    return (numProblems-numProbSolved[0]) ;
     4423  else
     4424    return (0) ;
    43814425}
    43824426
     
    51615205        assert(!exists ^ testHintParam(si,i,false,OsiForceDo,&throws)) ; }
    51625206
     5207      std::cout.flush() ;
    51635208      std::cerr << "Checked " << OsiLastHintParam <<
    51645209                   " hints x (true, false) at strength OsiForceDo; " <<
  • trunk/Osi/test/unitTest.cpp

    r1522 r1553  
    2727
    2828/*
     29  Currently the Osi unit test is configured to exercise only the external
     30  solvers. The Osi interfaces for Coin solvers have been moved out to the
     31  project's repository and each has its own private Osi unit test.
     32
     33  This unit test will include as many external solvers as are available. If
     34  none of them are available, the OsiTestSolver (currently a clone of Vol)
     35  will be used. If any other solver is available, its presence will disable
     36  use of the test solver. You can disable it manually by undefining
     37  USETESTSOLVER.
     38
     39  You may want to use the Osi unit test to compare two or more Coin solvers.
     40  In particular, OsiSolverInterfaceMpsUnitTest, which runs the Netlib problem
     41  set, is set up for exactly this sort of comparison.  To take advantage of
     42  it, you'll need to edit this file and Makefile in order to get it to work.
     43*/
     44#define USETESTSOLVER
     45
     46/*
    2947  Some convenient undef's, to make it easy to isolate a particular solver.
    3048  Uncomment to disable a solver that's included in the build. Leave them
    31   commented if you're happy with running the unitTest for all solvers in the
    32   build.
    33   Commenting USETESTSOLVER disables the use of the OsiTestSolver for testing
    34   in case none of the other solver interfaces is available.
    35 */
    36 
     49  commented if you're happy with running the unitTest for all solvers in
     50  the build.
     51*/
    3752// #undef COIN_HAS_XPR
    3853// #undef COIN_HAS_CPX
     
    4156// #undef COIN_HAS_GRB
    4257// #undef COIN_HAS_SPX
    43 #define USETESTSOLVER
    4458
    4559#ifdef COIN_HAS_XPR
     
    482496    OsiSolverInterface * xprSi = new OsiXprSolverInterface;
    483497    vecSi.push_back(xprSi);
    484 #endif
     498#   endif
    485499#   if COIN_HAS_CPX
    486500    OsiSolverInterface * cpxSi = new OsiCpxSolverInterface;
    487501    vecSi.push_back(cpxSi);
    488 #endif
     502#   endif
    489503#   if COIN_HAS_GLPK
    490504    OsiSolverInterface * glpkSi = new OsiGlpkSolverInterface;
     
    492506    glpkSi->setHintParam(OsiDoReducePrint,true,OsiHintDo) ;
    493507    vecSi.push_back(glpkSi);
    494 #endif
     508#   endif
    495509#   if COIN_HAS_MSK
    496510    OsiSolverInterface * MskSi = new OsiMskSolverInterface;
    497511    vecSi.push_back(MskSi);
    498 #endif
    499 #ifdef USETESTSOLVER
    500     OsiSolverInterface * testSi = new OsiTestSolverInterface;
    501     vecSi.push_back(testSi);
    502 #endif
     512#   endif
    503513#   if COIN_HAS_GRB
    504514    OsiSolverInterface * grbSi = new OsiGrbSolverInterface;
    505515    vecSi.push_back(grbSi);
    506 #endif
     516#   endif
    507517#   if COIN_HAS_SPX
    508518    OsiSolverInterface * spxSi = new OsiSpxSolverInterface;
    509519    vecSi.push_back(spxSi);
    510 #endif
    511 
    512     testingMessage( "Testing OsiSolverInterface on Netlib problems.\n" );
    513     OsiSolverInterfaceMpsUnitTest(vecSi,netlibDir);
     520#   endif
     521#   ifdef USETESTSOLVER
     522/*
     523  The test solver is normally Vol, which can't do any of the netlib problems.
     524  So let's not try.
     525*/
     526    {
     527      std::string solverName ;
     528      OsiSolverInterface * testSi = new OsiTestSolverInterface;
     529      testSi->getStrParam(OsiSolverName,solverName) ;
     530      if (solverName != "vol")
     531      { vecSi.push_back(testSi); }
     532      else
     533      { testingMessage("Test solver vol cannot do Netlib. Skipping.\n") ; }
     534    }
     535#   endif
     536
     537    if (vecSi.size() > 0)
     538    { testingMessage( "Testing OsiSolverInterface on Netlib problems.\n" );
     539      totalErrCnt += OsiSolverInterfaceMpsUnitTest(vecSi,netlibDir); }
    514540
    515541    unsigned int i;
     
    526552  error.print(true);
    527553  totalErrCnt += 1;
     554} catch (...) {
     555  std::cout.flush() ;
     556  std::cerr << "Caught unknown exception." ;
     557  totalErrCnt += 1 ;
    528558}
     559
    529560/*
    530561  We're done. Report on the results.
Note: See TracChangeset for help on using the changeset viewer.