source: trunk/Cbc/src/unitTestClp.cpp

Last change on this file was 2467, checked in by unxusr, 5 months ago

spaces after angles

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 25.5 KB
Line 
1/* $Id: unitTestClp.cpp 2467 2019-01-03 21:26:29Z forrest $ */
2// Copyright (C) 2002, International Business Machines
3// Corporation and others.  All Rights Reserved.
4// This code is licensed under the terms of the Eclipse Public License (EPL).
5
6#include <cstdio>
7#include <string>
8#include <iostream>
9#include <iomanip>
10
11#include "CoinTime.hpp"
12#include "CoinFileIO.hpp"
13#include "CbcModel.hpp"
14#include "CbcHeuristic.hpp"
15#include "CbcCutGenerator.hpp"
16#include "CbcBranchCut.hpp"
17#include "CglProbing.hpp"
18#include "OsiClpSolverInterface.hpp"
19#include "ClpFactorization.hpp"
20#include "OsiRowCutDebugger.hpp"
21//#############################################################################
22
23#ifdef NDEBUG
24#undef NDEBUG
25#endif
26
27//#############################################################################
28
29// Display message on stdout and stderr
30void testingMessage(const char *const msg)
31{
32  std::cout << msg;
33  //cout <<endl <<"*****************************************"
34  //     <<endl <<msg <<endl;
35}
36
37//#############################################################################
38
39static inline bool CbcTestFile(const std::string name)
40{
41  FILE *fp = fopen(name.c_str(), "r");
42  if (fp) {
43    fclose(fp);
44    return true;
45  }
46  return false;
47}
48
49//#############################################################################
50
51bool CbcTestMpsFile(std::string &fname)
52{
53  if (CbcTestFile(fname)) {
54    return true;
55  }
56  if (CbcTestFile(fname + ".mps")) {
57    fname += ".mps";
58    return true;
59  }
60  if (CbcTestFile(fname + ".MPS")) {
61    fname += ".MPS";
62    return true;
63  }
64  if (CoinFileInput::haveGzipSupport()) {
65    if (CbcTestFile(fname + ".gz")) {
66      return true;
67    }
68    if (CbcTestFile(fname + ".mps.gz")) {
69      fname += ".mps";
70      return true;
71    }
72    if (CbcTestFile(fname + ".MPS.gz")) {
73      fname += ".MPS";
74      return true;
75    }
76    if (CbcTestFile(fname + ".MPS.GZ")) {
77      fname += ".MPS";
78      return true;
79    }
80  }
81  if (CoinFileInput::haveBzip2Support()) {
82    if (CbcTestFile(fname + ".bz2")) {
83      return true;
84    }
85    if (CbcTestFile(fname + ".mps.bz2")) {
86      fname += ".mps";
87      return true;
88    }
89    if (CbcTestFile(fname + ".MPS.bz2")) {
90      fname += ".MPS";
91      return true;
92    }
93    if (CbcTestFile(fname + ".MPS.BZ2")) {
94      fname += ".MPS";
95      return true;
96    }
97  }
98  return false;
99}
100//#############################################################################
101/*
102  jjf: testSwitch -2 unitTest, -1 normal (==2)
103
104  MiplibTest might be more appropriate.
105
106  TestSwitch and stuff[6] together control how much of miplib is executed:
107    For testSwitch set to:
108      -2: solve p0033 and p0201 only (the unit test)
109      -1: solve miplib sets #0 and #1
110       0: solve nothing
111       k: execute sets j:k, where j is determined by the value of stuff[6]
112  The last parameter of PUSH_MPS specifies the test set membership.
113
114  For -miplib, -extra2 sets testSwitch, -extra3 sets stuff[6]. The command
115    cbc -extra2 -2 -miplib
116  will execute the unit test on the miplib directory.
117
118  dirMiplib should end in the directory separator character for the platform.
119
120  If you want to activate the row cut debugger for a given problem, change the
121  last parameter of the PUSH_MPS macro for the problem to true.
122
123  Returns 0 if all goes well, -1 if the Miplib directory is missing, otherwise
124     100*(number with bad objective)+(number that exceeded node limit)
125*/
126int CbcClpUnitTest(const CbcModel &saveModel, const std::string &dirMiplib,
127  int testSwitch, const double *stuff)
128{
129  // Stop Windows popup
130  WindowsErrorPopupBlocker();
131  unsigned int m;
132
133  // Do an existence check.
134  std::string test1 = dirMiplib + "p0033";
135  bool doTest = CbcTestMpsFile(test1);
136  if (!doTest) {
137    std::cout
138      << "Not doing miplib run as can't find mps files." << std::endl
139      << "Perhaps you're trying to read gzipped (.gz) files without libz?"
140      << std::endl;
141    return (0);
142  }
143  int dfltPrecision = static_cast< int >(std::cout.precision());
144  /*
145  Set the range of problems to be tested. testSwitch = -2 is special and is
146  picked up below.
147*/
148  int loSet = 0;
149  int hiSet = 0;
150  if (testSwitch == -1) {
151    loSet = 0;
152    hiSet = 1;
153  } else if (testSwitch >= 0) {
154    loSet = static_cast< int >(stuff[6]);
155    hiSet = testSwitch;
156    std::cout
157      << "Solving miplib problems in sets " << loSet
158      << ":" << hiSet << "." << std::endl;
159  }
160  /*
161  Vectors to hold test problem names and characteristics.
162*/
163  std::vector< std::string > mpsName;
164  std::vector< int > nRows;
165  std::vector< int > nCols;
166  std::vector< double > objValueC;
167  std::vector< double > objValue;
168  std::vector< int > testSet;
169  std::vector< int > rowCutDebugger;
170/*
171  A macro to make the vector creation marginally readable. Parameters are
172  name, rows, columns, integer objective, continuous objective, set ID,
173  row cut debugger
174
175  To enable the row cut debugger for a given problem, change the last
176  parameter to true. Don't forget to turn it off before committing changes!
177*/
178#define PUSH_MPS(zz_mpsName_zz,                              \
179  zz_nRows_zz, zz_nCols_zz, zz_objValue_zz, zz_objValueC_zz, \
180  zz_testSet_zz, zz_rcDbg_zz)                                \
181  mpsName.push_back(zz_mpsName_zz);                          \
182  nRows.push_back(zz_nRows_zz);                              \
183  nCols.push_back(zz_nCols_zz);                              \
184  objValueC.push_back(zz_objValueC_zz);                      \
185  testSet.push_back(zz_testSet_zz);                          \
186  objValue.push_back(zz_objValue_zz);                        \
187  rowCutDebugger.push_back(zz_rcDbg_zz);
188  /*
189  Push the miplib problems. Except for -2 (unitTest), push all, even if we're
190  not going to do all of them.
191*/
192  if (testSwitch == -2) {
193    PUSH_MPS("p0033", 16, 33, 3089, 2520.57, 0, false);
194    PUSH_MPS("p0201", 133, 201, 7615, 6875.0, 0, false);
195    // PUSH_MPS("flugpl", 18, 18, 1201500, 1167185.7, 0, false);
196  } else {
197/*
198  Load up the problem vector. Note that the row counts here include the
199  objective function.
200*/
201#if 1
202    PUSH_MPS("10teams", 230, 2025, 924, 917, 1, false);
203    PUSH_MPS("air03", 124, 10757, 340160, 338864.25, 0, false);
204    PUSH_MPS("air04", 823, 8904, 56137, 55535.436, 2, false);
205    PUSH_MPS("air05", 426, 7195, 26374, 25877.609, 2, false);
206    PUSH_MPS("arki001", 1048, 1388, 7580813.0459, 7579599.80787, 7, false);
207    PUSH_MPS("bell3a", 123, 133, 878430.32, 862578.64, 0, false);
208    PUSH_MPS("bell5", 91, 104, 8966406.49, 8608417.95, 1, false);
209    PUSH_MPS("blend2", 274, 353, 7.598985, 6.9156751140, 0, false);
210    PUSH_MPS("cap6000", 2176, 6000, -2451377, -2451537.325, 1, false);
211    PUSH_MPS("dano3mip", 3202, 13873, 728.1111, 576.23162474, 7, false);
212    PUSH_MPS("danoint", 664, 521, 65.67, 62.637280418, 6, false);
213    PUSH_MPS("dcmulti", 290, 548, 188182, 183975.5397, 0, false);
214    PUSH_MPS("dsbmip", 1182, 1886, -305.19817501, -305.19817501, 0, false);
215    PUSH_MPS("egout", 98, 141, 568.101, 149.589, 0, false);
216    PUSH_MPS("enigma", 21, 100, 0.0, 0.0, 0, false);
217    PUSH_MPS("fast0507", 507, 63009, 174, 172.14556668, 5, false);
218    PUSH_MPS("fiber", 363, 1298, 405935.18000, 156082.51759, 0, false);
219    PUSH_MPS("fixnet6", 478, 878, 3983, 1200.88, 1, false);
220    PUSH_MPS("flugpl", 18, 18, 1201500, 1167185.7, 0, false);
221    PUSH_MPS("gen", 780, 870, 112313, 112130.0, 0, false);
222    PUSH_MPS("gesa2", 1392, 1224, 25779856.372, 25476489.678, 1, false);
223    PUSH_MPS("gesa2_o", 1248, 1224, 25779856.372, 25476489.678, 1, false);
224    PUSH_MPS("gesa3", 1368, 1152, 27991042.648, 27833632.451, 0, false);
225    PUSH_MPS("gesa3_o", 1224, 1152, 27991042.648, 27833632.451, 0, false);
226    PUSH_MPS("gt2", 29, 188, 21166.000, 13460.233074, 0, false);
227    PUSH_MPS("harp2", 112, 2993, -73899798.00, -74353341.502, 6, false);
228    PUSH_MPS("khb05250", 101, 1350, 106940226, 95919464.0, 0, false);
229    PUSH_MPS("l152lav", 97, 1989, 4722, 4656.36, 1, false);
230    PUSH_MPS("lseu", 28, 89, 1120, 834.68, 0, false);
231    PUSH_MPS("mas74", 13, 151, 11801.18573, 10482.79528, 3, false);
232    PUSH_MPS("mas76", 12, 151, 40005.05414, 38893.9036, 2, false);
233    PUSH_MPS("misc03", 96, 160, 3360, 1910., 0, false);
234    PUSH_MPS("misc06", 820, 1808, 12850.8607, 12841.6, 0, false);
235    PUSH_MPS("misc07", 212, 260, 2810, 1415.0, 1, false);
236    PUSH_MPS("mitre", 2054, 10724, 115155, 114740.5184, 1, false);
237    PUSH_MPS("mkc", 3411, 5325, -553.75, -611.85, 7, false); // suboptimal
238    PUSH_MPS("mod008", 6, 319, 307, 290.9, 0, false);
239    PUSH_MPS("mod010", 146, 2655, 6548, 6532.08, 0, false);
240    PUSH_MPS("mod011", 4480, 10958, -54558535, -62121982.55, 2, false);
241    PUSH_MPS("modglob", 291, 422, 20740508, 20430947., 2, false);
242    PUSH_MPS("noswot", 182, 128, -43, -43.0, 6, false);
243    PUSH_MPS("nw04", 36, 87482, 16862, 16310.66667, 1, false);
244    PUSH_MPS("p0033", 16, 33, 3089, 2520.57, 0, false);
245    PUSH_MPS("p0201", 133, 201, 7615, 6875.0, 0, false);
246    PUSH_MPS("p0282", 241, 282, 258411, 176867.50, 0, false);
247    PUSH_MPS("p0548", 176, 548, 8691, 315.29, 0, false);
248    PUSH_MPS("p2756", 755, 2756, 3124, 2688.75, 0, false);
249    PUSH_MPS("pk1", 45, 86, 11.0, 0.0, 2, false);
250    PUSH_MPS("pp08a", 136, 240, 7350.0, 2748.3452381, 1, false);
251    PUSH_MPS("pp08aCUTS", 246, 240, 7350.0, 5480.6061563, 1, false);
252    PUSH_MPS("qiu", 1192, 840, -132.873137, -931.638857, 3, false);
253    PUSH_MPS("qnet1", 503, 1541, 16029.692681, 14274.102667, 0, false);
254    PUSH_MPS("qnet1_o", 456, 1541, 16029.692681, 12095.571667, 0, false);
255    PUSH_MPS("rentacar", 6803, 9557, 30356761, 28806137.644, 0, false);
256    PUSH_MPS("rgn", 24, 180, 82.1999, 48.7999, 0, false);
257    PUSH_MPS("rout", 291, 556, 1077.56, 981.86428571, 3, false);
258    PUSH_MPS("set1ch", 492, 712, 54537.75, 32007.73, 5, false);
259    PUSH_MPS("seymour", 4944, 1372, 423, 403.84647413, 7, false);
260    PUSH_MPS("seymour_1", 4944, 1372, 410.76370, 403.84647413, 5, false);
261    PUSH_MPS("stein27", 118, 27, 18, 13.0, 0, false);
262    PUSH_MPS("stein45", 331, 45, 30, 22.0, 1, false);
263    PUSH_MPS("swath", 884, 6805, 497.603, 334.4968581, 7, false);
264    PUSH_MPS("vpm1", 234, 378, 20, 15.4167, 0, false);
265    PUSH_MPS("vpm2", 234, 378, 13.75, 9.8892645972, 0, false);
266#endif
267  }
268#undef PUSH_MPS
269
270  /*
271  Normally the problems are executed in order. Define RANDOM_ORDER below to
272  randomize.
273
274  #define RANDOM_ORDER
275*/
276  int which[100];
277  int nLoop = static_cast< int >(mpsName.size());
278  assert(nLoop <= 100);
279  for (int i = 0; i < nLoop; i++)
280    which[i] = i;
281
282#ifdef RANDOM_ORDER
283  unsigned int iTime = static_cast< unsigned int >(CoinGetTimeOfDay() - 1.256e9);
284  std::cout << "Time (seed) " << iTime << "." << std::endl;
285  double sort[100];
286  CoinDrand48(true, iTime);
287  for (int i = 0; i < nLoop; i++)
288    sort[i] = CoinDrand48();
289  CoinSort_2(sort, sort + nLoop, which);
290#endif
291
292  int problemCnt = 0;
293  for (m = 0; m < mpsName.size(); m++) {
294    int setID = testSet[m];
295    if (loSet <= setID && setID <= hiSet)
296      problemCnt++;
297  }
298
299  int numberFailures = 0;
300  int numberAttempts = 0;
301  int numProbSolved = 0;
302  double timeTaken = 0.0;
303
304//#define CLP_FACTORIZATION_INSTRUMENT
305#ifdef CLP_FACTORIZATION_INSTRUMENT
306  double timeTakenFac = 0.0;
307#endif
308
309  /*
310  Open the main loop to step through the MPS problems.
311*/
312  for (unsigned int mw = 0; mw < mpsName.size(); mw++) {
313    m = which[mw];
314    int setID = testSet[m];
315    // Skip if problem is not in specified problem set(s)
316    if (!(loSet <= setID && setID <= hiSet))
317      continue;
318
319    numberAttempts++;
320    std::cout << "  processing mps file: " << mpsName[m]
321              << " (" << numberAttempts << " out of "
322              << problemCnt << ")" << std::endl;
323    /*
324  Stage 1: Read the MPS and make sure the size of the constraint matrix
325           is correct.
326*/
327    CbcModel *model = new CbcModel(saveModel);
328
329    std::string fn = dirMiplib + mpsName[m];
330    if (!CbcTestMpsFile(fn)) {
331      std::cout << "ERROR: Cannot find MPS file " << fn << "." << std::endl;
332      continue;
333    }
334    model->solver()->readMps(fn.c_str(), "");
335    assert(model->getNumRows() == nRows[m]);
336    assert(model->getNumCols() == nCols[m]);
337
338    // Careful! We're initialising for the benefit of other code.
339    CoinDrand48(true, 1234567);
340    //printf("RAND1 %g %g\n",CoinDrand48(true,1234567),model->randomNumberGenerator()->randomDouble());
341    //printf("RAND1 %g\n",CoinDrand48(true,1234567));
342
343    // Higher limits for the serious problems.
344    int testMaximumNodes = 200000;
345    if (hiSet > 1)
346      testMaximumNodes = 20000000;
347    if (model->getMaximumNodes() > testMaximumNodes) {
348      model->setMaximumNodes(testMaximumNodes);
349    }
350    /*
351  Stage 2: Call solver to solve the problem.
352*/
353
354#ifdef CLP_FACTORIZATION_INSTRUMENT
355    extern double factorization_instrument(int type);
356    double facTime1 = factorization_instrument(0);
357    std::cout
358      << "Factorization - initial solve " << facTime1 << " seconds."
359      << std::endl;
360    timeTakenFac += facTime1;
361#endif
362
363    double startTime = CoinCpuTime() + CoinCpuTimeJustChildren();
364
365    // Setup specific to clp
366    OsiClpSolverInterface *siClp = dynamic_cast< OsiClpSolverInterface * >(model->solver());
367    ClpSimplex *modelC = NULL;
368    if (siClp) {
369      modelC = siClp->getModelPtr();
370      ClpMatrixBase *matrix = modelC->clpMatrix();
371      ClpPackedMatrix *clpMatrix = dynamic_cast< ClpPackedMatrix * >(matrix);
372      if (stuff && stuff[9] && clpMatrix) {
373        // vector matrix!
374        clpMatrix->makeSpecialColumnCopy();
375      }
376
377#ifdef JJF_ZERO
378      if (clpMatrix) {
379        int numberRows = clpMatrix->getNumRows();
380        int numberColumns = clpMatrix->getNumCols();
381        double *elements = clpMatrix->getMutableElements();
382        const int *row = clpMatrix->getIndices();
383        const CoinBigIndex *columnStart = clpMatrix->getVectorStarts();
384        const int *columnLength = clpMatrix->getVectorLengths();
385        double *smallest = new double[numberRows];
386        double *largest = new double[numberRows];
387        char *flag = new char[numberRows];
388        CoinZeroN(flag, numberRows);
389        for (int i = 0; i < numberRows; i++) {
390          smallest[i] = COIN_DBL_MAX;
391          largest[i] = 0.0;
392        }
393        for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
394          bool isInteger = modelC->isInteger(iColumn);
395          CoinBigIndex j;
396          for (j = columnStart[iColumn];
397               j < columnStart[iColumn] + columnLength[iColumn]; j++) {
398            int iRow = row[j];
399            double value = fabs(elements[j]);
400            if (!isInteger)
401              flag[iRow] = 1;
402            smallest[iRow] = CoinMin(smallest[iRow], value);
403            largest[iRow] = CoinMax(largest[iRow], value);
404          }
405        }
406        double *rowLower = modelC->rowLower();
407        double *rowUpper = modelC->rowUpper();
408        bool changed = false;
409        for (int i = 0; i < numberRows; i++) {
410          if (flag[i] && smallest[i] > 10.0 && false) {
411            smallest[i] = 1.0 / smallest[i];
412            if (rowLower[i] > -1.0e20)
413              rowLower[i] *= smallest[i];
414            if (rowUpper[i] < 1.0e20)
415              rowUpper[i] *= smallest[i];
416            changed = true;
417          } else {
418            smallest[i] = 0.0;
419          }
420        }
421        if (changed) {
422          printf("SCALED\n");
423          for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
424            CoinBigIndex j;
425            for (j = columnStart[iColumn];
426                 j < columnStart[iColumn] + columnLength[iColumn]; j++) {
427              int iRow = row[j];
428              if (smallest[iRow])
429                elements[j] *= smallest[iRow];
430            }
431          }
432        }
433        delete[] smallest;
434        delete[] largest;
435        delete[] flag;
436      }
437#endif // JJF_ZERO
438
439      model->checkModel();
440      modelC->tightenPrimalBounds(0.0, 0, true);
441      model->initialSolve();
442      if (modelC->dualBound() == 1.0e10) {
443        // user did not set - so modify
444        // get largest scaled away from bound
445        ClpSimplex temp = *modelC;
446        temp.dual(0, 7);
447        double largestScaled = 1.0e-12;
448        double largest = 1.0e-12;
449        int numberRows = temp.numberRows();
450        const double *rowPrimal = temp.primalRowSolution();
451        const double *rowLower = temp.rowLower();
452        const double *rowUpper = temp.rowUpper();
453        const double *rowScale = temp.rowScale();
454        int iRow;
455        for (iRow = 0; iRow < numberRows; iRow++) {
456          double value = rowPrimal[iRow];
457          double above = value - rowLower[iRow];
458          double below = rowUpper[iRow] - value;
459          if (above < 1.0e12) {
460            largest = CoinMax(largest, above);
461          }
462          if (below < 1.0e12) {
463            largest = CoinMax(largest, below);
464          }
465          if (rowScale) {
466            double multiplier = rowScale[iRow];
467            above *= multiplier;
468            below *= multiplier;
469          }
470          if (above < 1.0e12) {
471            largestScaled = CoinMax(largestScaled, above);
472          }
473          if (below < 1.0e12) {
474            largestScaled = CoinMax(largestScaled, below);
475          }
476        }
477
478        int numberColumns = temp.numberColumns();
479        const double *columnPrimal = temp.primalColumnSolution();
480        const double *columnLower = temp.columnLower();
481        const double *columnUpper = temp.columnUpper();
482        const double *columnScale = temp.columnScale();
483        int iColumn;
484        for (iColumn = 0; iColumn < numberColumns; iColumn++) {
485          double value = columnPrimal[iColumn];
486          double above = value - columnLower[iColumn];
487          double below = columnUpper[iColumn] - value;
488          if (above < 1.0e12) {
489            largest = CoinMax(largest, above);
490          }
491          if (below < 1.0e12) {
492            largest = CoinMax(largest, below);
493          }
494          if (columnScale) {
495            double multiplier = 1.0 / columnScale[iColumn];
496            above *= multiplier;
497            below *= multiplier;
498          }
499          if (above < 1.0e12) {
500            largestScaled = CoinMax(largestScaled, above);
501          }
502          if (below < 1.0e12) {
503            largestScaled = CoinMax(largestScaled, below);
504          }
505        }
506        std::cout << "Largest (scaled) away from bound " << largestScaled
507                  << " unscaled " << largest << std::endl;
508#ifdef JJF_ZERO
509        modelC->setDualBound(CoinMax(1.0001e8,
510          CoinMin(1000.0 * largestScaled, 1.00001e10)));
511#else
512        modelC->setDualBound(CoinMax(1.0001e9,
513          CoinMin(1000.0 * largestScaled, 1.0001e10)));
514#endif
515      }
516    } // end clp-specific setup
517    /*
518  Cut passes: For small models (n < 500) always do 100 passes, if possible
519  (-100). For larger models, use minimum drop to stop (100, 20).
520*/
521    model->setMinimumDrop(CoinMin(5.0e-2,
522      fabs(model->getMinimizationObjValue()) * 1.0e-3 + 1.0e-4));
523    if (CoinAbs(model->getMaximumCutPassesAtRoot()) <= 100) {
524      if (model->getNumCols() < 500) {
525        model->setMaximumCutPassesAtRoot(-100);
526      } else if (model->getNumCols() < 5000) {
527        model->setMaximumCutPassesAtRoot(100);
528      } else {
529        model->setMaximumCutPassesAtRoot(20);
530      }
531    }
532    // If defaults then increase trust for small models
533    if (model->numberStrong() == 5 && model->numberBeforeTrust() == 10) {
534      int numberColumns = model->getNumCols();
535      if (numberColumns <= 50) {
536        model->setNumberBeforeTrust(1000);
537      } else if (numberColumns <= 100) {
538        model->setNumberBeforeTrust(100);
539      } else if (numberColumns <= 300) {
540        model->setNumberBeforeTrust(50);
541      }
542    }
543    //if (model->getNumCols()>=500) {
544    // switch off Clp stuff
545    //model->setFastNodeDepth(-1);
546    //}
547    /*
548  Activate the row cut debugger, if requested.
549*/
550    if (rowCutDebugger[m] == true) {
551      std::string probName;
552      model->solver()->getStrParam(OsiProbName, probName);
553      model->solver()->activateRowCutDebugger(probName.c_str());
554      if (model->solver()->getRowCutDebugger())
555        std::cout << "Row cut debugger activated for ";
556      else
557        std::cout << "Failed to activate row cut debugger for ";
558      std::cout << mpsName[m] << "." << std::endl;
559    }
560    setCutAndHeuristicOptions(*model);
561    /*
562  More clp-specific setup.
563*/
564    if (siClp) {
565#ifdef CLP_MULTIPLE_FACTORIZATIONS
566      if (!modelC->factorization()->isDenseOrSmall()) {
567        int denseCode = stuff ? static_cast< int >(stuff[4]) : -1;
568        int smallCode = stuff ? static_cast< int >(stuff[10]) : -1;
569        if (stuff && stuff[8] >= 1) {
570          if (denseCode < 0)
571            denseCode = 40;
572          if (smallCode < 0)
573            smallCode = 40;
574        }
575        if (denseCode > 0)
576          modelC->factorization()->setGoDenseThreshold(denseCode);
577        if (smallCode > 0)
578          modelC->factorization()->setGoSmallThreshold(smallCode);
579        if (denseCode >= modelC->numberRows()) {
580          //printf("problem going dense\n");
581          //modelC->factorization()->goDenseOrSmall(modelC->numberRows());
582        }
583      }
584#endif
585      if (stuff && stuff[8] >= 1) {
586        printf("Fast node size Columns %d rows %d - depth %d\n",
587          modelC->numberColumns(), modelC->numberRows(),
588          model->fastNodeDepth());
589        if (modelC->numberColumns() + modelC->numberRows() <= 10000 && model->fastNodeDepth() == -1)
590          model->setFastNodeDepth(-10 /*-9*/);
591      }
592    }
593#ifdef CONFLICT_CUTS
594    {
595      model->setCutoffAsConstraint(true); // very slow on bell5 ??
596      int moreOptions = model->moreSpecialOptions();
597      model->setMoreSpecialOptions(moreOptions | 4194304);
598    }
599#endif
600    /*
601  Finally, the actual call to solve the MIP with branch-and-cut.
602*/
603    model->branchAndBound();
604
605#ifdef CLP_FACTORIZATION_INSTRUMENT
606    double facTime = factorization_instrument(0);
607    std::cout << "Factorization " << facTime << " seconds." << std::endl,
608      timeTakenFac += facTime;
609#endif
610
611    /*
612  Stage 3: Do the statistics and check the answer.
613*/
614    double timeOfSolution = CoinCpuTime() + CoinCpuTimeJustChildren() - startTime;
615    std::cout
616      << "Cuts at root node changed objective from "
617      << model->getContinuousObjective() << " to "
618      << model->rootObjectiveAfterCuts() << std::endl;
619    int numberGenerators = model->numberCutGenerators();
620    for (int iGenerator = 0; iGenerator < numberGenerators; iGenerator++) {
621      CbcCutGenerator *generator = model->cutGenerator(iGenerator);
622#ifdef CLIQUE_ANALYSIS
623#ifndef CLP_INVESTIGATE
624      CglImplication *implication = dynamic_cast< CglImplication * >(generator->generator());
625      if (implication)
626        continue;
627#endif
628#endif
629      std::cout
630        << generator->cutGeneratorName() << " was tried "
631        << generator->numberTimesEntered() << " times and created "
632        << generator->numberCutsInTotal() << " cuts of which "
633        << generator->numberCutsActive()
634        << " were active after adding rounds of cuts";
635      if (generator->timing())
636        std::cout << " (" << generator->timeInCutGenerator() << " seconds)";
637      std::cout << "." << std::endl;
638    }
639    std::cout
640      << model->getNumberHeuristicSolutions()
641      << " solutions found by heuristics." << std::endl;
642    int numberHeuristics = model->numberHeuristics();
643    for (int iHeuristic = 0; iHeuristic < numberHeuristics; iHeuristic++) {
644      CbcHeuristic *heuristic = model->heuristic(iHeuristic);
645      if (heuristic->numRuns()) {
646        std::cout
647          << heuristic->heuristicName() << " was tried "
648          << heuristic->numRuns() << " times out of "
649          << heuristic->numCouldRun() << " and created "
650          << heuristic->numberSolutionsFound() << " solutions." << std::endl;
651      }
652    }
653    /*
654  Check for the correct answer.
655*/
656    if (!model->status()) {
657
658      double objActual = model->getObjValue();
659      double objExpect = objValue[m];
660      double tolerance = CoinMin(fabs(objActual), fabs(objExpect));
661      tolerance = CoinMax(1.0e-5, 1.0e-5 * tolerance);
662      //CoinRelFltEq eq(1.0e-3) ;
663
664      std::cout
665        << "cbc_clp (" << mpsName[m] << ") "
666        << std::setprecision(10) << objActual;
667      if (fabs(objActual - objExpect) < tolerance) {
668        std::cout << std::setprecision(dfltPrecision) << "; okay";
669        numProbSolved++;
670      } else {
671        std::cout
672          << " != " << objExpect << std::setprecision(dfltPrecision)
673          << "; error = " << fabs(objExpect - objActual);
674        numberFailures++;
675        //#ifdef COIN_DEVELOP
676        //abort();
677        //#endif
678      }
679    } else {
680      std::cout
681        << "cbc_clp (" << mpsName[m] << ") status not optimal; "
682        << "assuming too many nodes";
683    }
684    timeTaken += timeOfSolution;
685    std::cout
686      << " -- (" << model->getNodeCount() << " n / "
687      << model->getIterationCount() << " i / "
688      << timeOfSolution << " s) (subtotal " << timeTaken << " seconds)"
689      << std::endl;
690    delete model;
691  }
692  /*
693  End main loop on MPS problems. Print a summary and calculate the return
694  value.
695*/
696  int returnCode = 0;
697  std::cout
698    << "cbc_clp solved " << numProbSolved << " out of " << numberAttempts;
699  int numberOnNodes = numberAttempts - numProbSolved - numberFailures;
700  if (numberFailures || numberOnNodes) {
701    if (numberOnNodes) {
702      std::cout << " (" << numberOnNodes << " stopped on nodes)";
703      returnCode = numberOnNodes;
704    }
705    if (numberFailures) {
706      std::cout << " (" << numberFailures << " gave bad answer!)";
707      returnCode += 100 * numberFailures;
708    }
709  }
710  std::cout
711    << " and took " << timeTaken << " seconds." << std::endl;
712
713  if (testSwitch == -2) {
714    if (numberFailures || numberOnNodes) {
715      std::cout << "****** Unit Test failed." << std::endl;
716      std::cerr << "****** Unit Test failed." << std::endl;
717    } else {
718      std::cerr << "****** Unit Test succeeded." << std::endl;
719    }
720  }
721#ifdef CLP_FACTORIZATION_INSTRUMENT
722  std::cout
723    << "Total factorization time " << timeTakenFac << "seconds." << std::endl;
724#endif
725  return (returnCode);
726}
727
728/* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
729*/
Note: See TracBrowser for help on using the repository browser.