source: trunk/Cbc/src/unitTest.cpp @ 862

Last change on this file since 862 was 641, checked in by forrest, 12 years ago

moving devel unit test

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 12.6 KB
Line 
1// Copyright (C) 2002, International Business Machines
2// Corporation and others.  All Rights Reserved.
3// Test individual classes or groups of classes
4
5#include "CbcConfig.h"
6
7#if defined(_MSC_VER)
8// Turn off compiler warning about long names
9#  pragma warning(disable:4786)
10#endif
11
12#include <cstdlib>
13#include <cassert>
14#include <vector>
15#include <iostream>
16#include <cstdio>
17
18#include "CoinHelperFunctions.hpp"
19
20#ifdef COIN_HAS_CBC
21#include "OsiCbcSolverInterface.hpp"
22#endif
23#ifdef COIN_HAS_OSL
24#include "OsiOslSolverInterface.hpp"
25#endif
26#ifdef COIN_HAS_SPX
27#include "OsiSpxSolverInterface.hpp"
28#endif
29#ifdef COIN_HAS_DYLP
30#include "OsiDylpSolverInterface.hpp"
31#endif
32#ifdef COIN_HAS_GLPK
33#include "OsiGlpkSolverInterface.hpp"
34#endif
35#ifdef COIN_HAS_CLP
36#include "OsiClpSolverInterface.hpp"
37#endif
38#ifdef NDEBUG
39#undef NDEBUG
40#endif
41
42#include "CoinTime.hpp"
43// Function Prototypes. Function definitions is in this file.
44void testingMessage( const char * const msg );
45
46#ifdef COIN_HAS_CBC
47void CbcMiplibTest (const std::vector<OsiCbcSolverInterface*> & vecEmptySiP,
48                    const std::string & mpsDir)
49{
50  int i ;
51  unsigned int m ;
52  // See if files exist
53  FILE * fp;
54  bool doTest=false;
55  std::string test1 = mpsDir +"p0033";
56  fp=fopen(test1.c_str(),"r");
57  if (fp) {
58    doTest=true;
59    fclose(fp);
60  }
61#ifdef COIN_USE_ZLIB
62  test1 += ".gz";
63  fp=fopen(test1.c_str(),"r");
64  if (fp) {
65    doTest=true;
66    fclose(fp);
67  }
68#endif
69  if (!doTest)
70    return;
71  /*
72    Vectors to hold test problem names and characteristics. The objective value
73    after optimization (objValue) must agree to the specified tolerance
74    (objValueTol).
75  */
76  std::vector<std::string> mpsName ;
77  std::vector<int> nRows ;
78  std::vector<int> nCols ;
79  std::vector<double> objValueC ;
80  std::vector<double> objValue ;
81  std::vector<int> strategy ;
82  /*
83    And a macro to make the vector creation marginally readable.
84  */
85#define PUSH_MPS(zz_mpsName_zz,\
86                 zz_nRows_zz,zz_nCols_zz,zz_objValue_zz,zz_objValueC_zz, \
87                 zz_strategy_zz) \
88  mpsName.push_back(zz_mpsName_zz) ; \
89  nRows.push_back(zz_nRows_zz) ; \
90  nCols.push_back(zz_nCols_zz) ; \
91  objValueC.push_back(zz_objValueC_zz) ; \
92  strategy.push_back(zz_strategy_zz) ; \
93  objValue.push_back(zz_objValue_zz) ;
94 
95  /*
96    Load up the problem vector. Note that the row counts here include the
97    objective function.
98 
99    Set HOWMANY to 0 for no test, 1 for some, 2 for many, 3 for all.
100  */
101#define HOWMANY 1
102#if HOWMANY
103#if HOWMANY>1
104    PUSH_MPS("10teams",230,2025,924,917,7)
105#endif
106    PUSH_MPS("air03",124,10757,340160,338864.25,7)
107#if HOWMANY==3
108    PUSH_MPS("air04",823,8904,56137,55535.436,8)
109    PUSH_MPS("air05",426,7195,26374,25877.609,8)
110#endif
111    //    PUSH_MPS("arki001",1048,1388,7580813.0459,7579599.80787,7)
112    PUSH_MPS("bell3a",123,133,878430.32,862578.64,7)
113#if HOWMANY>1
114    PUSH_MPS("bell5",91,104,8966406.49,8608417.95,7)
115#endif
116    PUSH_MPS("blend2",274,353,7.598985,6.9156751140,7)
117#if HOWMANY>1
118    PUSH_MPS("cap6000",2176,6000,-2451377,-2451537.325,7)
119#endif
120    //    PUSH_MPS("dano3mip",3202,13873,728.1111,576.23162474,7)
121    //    PUSH_MPS("danoint",664,521,65.67,62.637280418,7)
122    PUSH_MPS("dcmulti",290,548,188182,183975.5397,7)
123    PUSH_MPS("dsbmip",1182,1886,-305.19817501,-305.19817501,7)
124    PUSH_MPS("egout",98,141,568.101,149.589,7)
125    PUSH_MPS("enigma",21,100,0.0,0.0,7)
126#if HOWMANY==3
127    PUSH_MPS("fast0507",507,63009,174,172.14556668,7)
128#endif
129    PUSH_MPS("fiber",363,1298,405935.18000,156082.51759,7)
130#if HOWMANY>1
131    PUSH_MPS("fixnet6",478,878,3983,1200.88,7)
132#endif
133    PUSH_MPS("flugpl",18,18,1201500,1167185.7,7)
134    PUSH_MPS("gen",780,870,112313,112130.0,7)
135#if HOWMANY>1
136    PUSH_MPS("gesa2",1392,1224,25779856.372,25476489.678,7)
137    PUSH_MPS("gesa2_o",1248,1224,25779856.372,25476489.678,7)
138#endif
139    PUSH_MPS("gesa3",1368,1152,27991042.648,27833632.451,7)
140    PUSH_MPS("gesa3_o",1224,1152,27991042.648,27833632.451,7)
141    PUSH_MPS("gt2",29,188,21166.000,13460.233074,7)
142#if HOWMANY==3
143    PUSH_MPS("harp2",112,2993,-73899798.00,-74353341.502,7)
144#endif
145    PUSH_MPS("khb05250",101,1350,106940226,95919464.0,7)
146#if HOWMANY>1
147    PUSH_MPS("l152lav",97,1989,4722,4656.36,7)
148#endif
149    PUSH_MPS("lseu",28,89,1120,834.68,7)
150    PUSH_MPS("misc03",96,160,3360,1910.,7)
151    PUSH_MPS("misc06",820,1808,12850.8607,12841.6,7)
152#if HOWMANY>1
153    PUSH_MPS("misc07",212,260,2810,1415.0,7)
154    PUSH_MPS("mitre",2054,10724,115155,114740.5184,7)
155#endif
156    PUSH_MPS("mod008",6,319,307,290.9,7)
157    PUSH_MPS("mod010",146,2655,6548,6532.08,7)
158#if HOWMANY==3
159    PUSH_MPS("mod011",4480,10958,-54558535,-62121982.55,7)
160    PUSH_MPS("modglob",291,422,20740508,20430947.,7)
161    PUSH_MPS("noswot",182,128,-43,-43.0,7)
162#endif
163#if HOWMANY>1
164    PUSH_MPS("nw04",36,87482,16862,16310.66667,7)
165#endif
166    PUSH_MPS("p0033",16,33,3089,2520.57,7)
167    PUSH_MPS("p0201",133,201,7615,6875.0,7)
168    PUSH_MPS("p0282",241,282,258411,176867.50,7)
169    PUSH_MPS("p0548",176,548,8691,315.29,7)
170    PUSH_MPS("p2756",755,2756,3124,2688.75,7)
171#if HOWMANY==3
172    PUSH_MPS("pk1",45,86,11.0,0.0,7)
173#endif
174#if HOWMANY>1
175    PUSH_MPS("pp08a",136,240,7350.0,2748.3452381,7)
176    PUSH_MPS("pp08aCUTS",246,240,7350.0,5480.6061563,7)
177#endif
178#if HOWMANY==3
179    PUSH_MPS("qiu",1192,840,-132.873137,-931.638857,7)
180#endif
181    PUSH_MPS("qnet1",503,1541,16029.692681,14274.102667,7)
182    PUSH_MPS("qnet1_o",456,1541,16029.692681,12095.571667,7)
183    PUSH_MPS("rentacar",6803,9557,30356761,28806137.644,7)
184    PUSH_MPS("rgn",24,180,82.1999,48.7999,7)
185#if HOWMANY==3
186    PUSH_MPS("rout",291,556,1077.56,981.86428571,7)
187    PUSH_MPS("set1ch",492,712,54537.75,32007.73,7)
188#endif
189    //    PUSH_MPS("seymour",4944,1372,423,403.84647413,7)
190    PUSH_MPS("stein27",118,27,18,13.0,7)
191#if HOWMANY>1
192    PUSH_MPS("stein45",331,45,30,22.0,7)
193#endif
194    PUSH_MPS("vpm1",234,378,20,15.4167,7)
195    PUSH_MPS("vpm2",234,378,13.75,9.8892645972,7)
196#endif
197#undef PUSH_MPS
198   
199  /*
200    Create a vector of solver interfaces that we can use to run the test
201    problems. The strategy is to create a fresh clone of the `empty' solvers
202    from vecEmptySiP for each problem, then proceed in stages: read the MPS
203    file, solve the problem, check the solution. If there are multiple
204    solvers in vecSiP, the results of each solver are compared with its
205    neighbors in the vector.
206  */
207  int numberSolvers=vecEmptySiP.size();
208  std::vector<OsiSolverInterface*> vecSiP(numberSolvers) ;
209
210  // Create vector to store a name for each solver interface
211  // and a count on the number of problems the solver interface solved.
212  std::vector<std::string> siName;
213  std::vector<int> numProbSolved;
214  std::vector<double> timeTaken;
215  for ( i=0; i<numberSolvers; i++ ) {
216    std::string name;
217    vecEmptySiP[i]->getStrParam(OsiSolverName,name);
218    siName.push_back(name);
219    numProbSolved.push_back(0);
220    timeTaken.push_back(0.0);
221  }
222 
223  /*
224    Open the main loops. Outer loop steps through MPS problems, inner loop
225    steps through solvers.
226  */
227  for (m = 0 ; m < mpsName.size() ; m++)
228  { std::cerr << "  processing mps file: " << mpsName[m] 
229              << " (" << m+1 << " out of " << mpsName.size() << ")"
230              << std::endl ;
231    for (i = vecSiP.size()-1 ; i >= 0 ; --i) {
232      vecSiP[i] = vecEmptySiP[i]->clone() ;
233    /*
234      Stage 1: Read the MPS file into the solver interface.
235
236      As a basic check, make sure the size of the constraint matrix is correct.
237    */
238     
239      std::string fn = mpsDir+mpsName[m] ;
240      vecSiP[i]->readMps(fn.c_str(),"") ;
241     
242      vecSiP[i]->setObjSense(1.0) ;
243     
244      int nr = vecSiP[i]->getNumRows() ;
245      int nc = vecSiP[i]->getNumCols() ;
246      assert(nr == nRows[m]) ;
247      assert(nc == nCols[m]) ;
248    /*
249      Stage 2: Call the solver to get a solution for the LP relaxation.
250    */
251      double startTime = CoinCpuTime();
252      OsiCbcSolverInterface * integerSolver =
253        dynamic_cast<OsiCbcSolverInterface *>(vecSiP[i]) ;
254      assert(integerSolver);
255      integerSolver->initialSolve();
256    /*
257      Stage 3: Call the solver to perform branch and cut.
258     
259      We call each solver, then check the return code and objective.
260      Limits are 50000 nodes and one hour of time.
261    */
262
263      integerSolver->setMaximumNodes(50000);
264      integerSolver->setMaximumSeconds(60*60);
265      integerSolver->getModelPtr()->messageHandler()->setLogLevel(1) ;
266      integerSolver->branchAndBound();
267     
268      double timeOfSolution = CoinCpuTime()-startTime;
269      if (!integerSolver->status()) { 
270        double soln = integerSolver->getObjValue();       
271        CoinRelFltEq eq(1.0e-3) ;
272        if (eq(soln,objValue[m])) { 
273          std::cerr
274            <<siName[i]<<" "
275            << soln << " = " << objValue[m] << " ; okay";
276          numProbSolved[i]++;
277        } else  { 
278          std::cerr <<siName[i] <<" " <<soln << " != " <<objValue[m] << "; error=" ;
279          std::cerr <<fabs(objValue[m] - soln); 
280        }
281      } else {
282        std::cerr << "error; too many nodes" ;
283      }
284      std::cerr<<" - took " <<timeOfSolution<<" seconds."<<std::endl; 
285      timeTaken[i] += timeOfSolution;
286      delete integerSolver;
287    }
288  }
289
290  const int siName_size = siName.size();
291  for ( i=0; i<siName_size; i++ ) {
292    std::cerr
293      <<siName[i] 
294      <<" solved " 
295      <<numProbSolved[i]
296      <<" out of "
297      <<objValue.size()
298      <<" and took "
299      <<timeTaken[i]
300      <<" seconds."
301      <<std::endl;
302  } 
303}
304#endif  // COIN_HAS_CBC
305
306//----------------------------------------------------------------
307// unitTest  [-miplibDir=V2]
308//
309// where:
310//   -miplibDir: directory containing miplib files
311//       Default value V2="./examples/miplib3"
312//
313// All parameters are optional.
314//----------------------------------------------------------------
315
316int mainTest (int argc, const char *argv[])
317{
318  int i;
319
320
321  // define valid parameter keywords
322  std::set<std::string> definedKeyWords;
323  definedKeyWords.insert("-miplibDir");
324
325  // Create a map of parameter keys and associated data
326  std::map<std::string,std::string> parms;
327  for ( i=1; i<argc; i++ ) {
328    std::string parm(argv[i]);
329    std::string key,value;
330    unsigned int  eqPos = parm.find('=');
331
332    // Does parm contain and '='
333    if ( eqPos==std::string::npos ) {
334      //Parm does not contain '='
335      key = parm;
336    }
337    else {
338      key=parm.substr(0,eqPos);
339      value=parm.substr(eqPos+1);
340    }
341
342    // Is specifed key valid?
343    if ( definedKeyWords.find(key) == definedKeyWords.end() ) {
344      // invalid key word.
345      // Write help text
346      std::cerr <<"Undefined parameter \"" <<key <<"\".\n";
347      std::cerr <<"Correct usage: \n";
348      std::cerr <<"  unitTest [-miplibDir=V2] \n";
349      std::cerr <<"  where:\n";
350      std::cerr <<"    -miplibDir: directory containing miplib files\n";
351      std::cerr <<"        Default value V2=\"./Data/miplib3\"\n";
352      return 1;
353    }
354    parms[key]=value;
355  }
356 
357  const char dirsep =  CoinFindDirSeparator();
358 
359  // Set directory containing miplib data files.
360  std::string miplibDir;
361  if (parms.find("-miplibDir") != parms.end())
362    miplibDir=parms["-miplibDir"] + dirsep;
363  else 
364    miplibDir = dirsep == '/' ? "./Data/miplib3/" : ".\\Data\\miplib3\\";
365#ifdef COIN_HAS_CBC
366
367  {
368    // Create vector of solver interfaces
369    std::vector<OsiCbcSolverInterface*> vecSi;
370    CbcStrategyDefault strategy(false);
371#   if COIN_HAS_OSL
372    OsiSolverInterface * oslSi = new OsiOslSolverInterface;
373    vecSi.push_back(new OsiCbcSolverInterface(oslSi,&strategy));
374#endif
375#   if COIN_HAS_SPX
376    OsiSolverInterface * spxSi = new OsiSpxSolverInterface;
377    vecSi.push_back(new OsiCbcSolverInterface(spxSi,&strategy));
378#endif
379#   if COIN_HAS_CLP
380    OsiSolverInterface *clpSi = new OsiClpSolverInterface ;
381    /* Quiet, already! */
382    clpSi->setHintParam(OsiDoReducePrint,true,OsiHintDo) ;
383    vecSi.push_back(new OsiCbcSolverInterface(clpSi,&strategy));
384#endif
385#   if COIN_HAS_DYLP
386    OsiSolverInterface * dylpSi = new OsiDylpSolverInterface;
387    vecSi.push_back(new OsiCbcSolverInterface(dylpSi,&strategy));
388#endif
389#   if COIN_HAS_GLPK
390    OsiSolverInterface * glpkSi = new OsiGlpkSolverInterface;
391    vecSi.push_back(new OsiCbcSolverInterface(glpkSi,&strategy));
392#endif
393
394    testingMessage( "Testing some miplib stuff\n" );
395    CbcMiplibTest(vecSi,miplibDir);
396
397    unsigned int i;
398    for (i=0; i<vecSi.size(); i++)
399      delete vecSi[i];
400  }
401#else   // COIN_HAS_CBC
402  std::cerr
403    << "cbc has been built without OsiCbc support. To enable the -miplib\n"
404    << "option, you must enable libOsiCbc in Makefile.location, then\n"
405    << "execute the command `make clean cbc' to rebuild the cbc program."
406    << std::endl ;
407#endif  // COIN_HAS_CBC
408  testingMessage( "All tests completed successfully\n" );
409  return 0;
410}
411
412 
413// Display message on stdout and stderr
414void testingMessage( const char * const msg )
415{
416  std::cerr << msg << std::endl ;
417  // std::cout << msg << std::endl ;
418}
419
Note: See TracBrowser for help on using the repository browser.