source: stable/2.4/Cbc/src/unitTest.cpp @ 1271

Last change on this file since 1271 was 1271, checked in by forrest, 10 years ago

Creating new stable branch 2.4 from trunk (rev 1270)

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