source: trunk/Cbc/src/unitTestClp.cpp @ 2105

Last change on this file since 2105 was 2105, checked in by forrest, 3 years ago

mostly reporting options plus a few tweaks

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