source: trunk/Cbc/src/CbcSolverHeuristics.cpp

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

simplify handling of parameters and remove staticParameterData which made CbcMain0 and CbcMain1 not thread safe

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 65.2 KB
Line 
1/* $Id: CbcSolverHeuristics.cpp 2479 2019-02-07 19:50:37Z unxusr $ */
2// Copyright (C) 2007, 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/*! \file CbcSolverHeuristics.cpp
7    \brief Second level routines for the cbc stand-alone solver.
8*/
9
10#include "CbcConfig.h"
11#include "CoinPragma.hpp"
12
13#include "CoinTime.hpp"
14
15#include "OsiClpSolverInterface.hpp"
16
17#include "ClpPresolve.hpp"
18
19#include "CbcOrClpParam.hpp"
20
21#include "CbcModel.hpp"
22
23#include "CbcHeuristicLocal.hpp"
24#include "CbcHeuristicPivotAndFix.hpp"
25//#include "CbcHeuristicPivotAndComplement.hpp"
26#include "CbcHeuristicRandRound.hpp"
27#include "CbcHeuristicGreedy.hpp"
28#include "CbcHeuristicFPump.hpp"
29#include "CbcHeuristicRINS.hpp"
30#include "CbcHeuristicDW.hpp"
31#include "CbcHeuristicVND.hpp"
32
33#include "CbcHeuristicDiveCoefficient.hpp"
34#include "CbcHeuristicDiveFractional.hpp"
35#include "CbcHeuristicDiveGuided.hpp"
36#include "CbcHeuristicDiveVectorLength.hpp"
37#include "CbcHeuristicDivePseudoCost.hpp"
38#include "CbcHeuristicDiveLineSearch.hpp"
39
40#include "CbcStrategy.hpp"
41#include "OsiAuxInfo.hpp"
42
43#include "ClpSimplexOther.hpp"
44
45// Crunch down model
46void crunchIt(ClpSimplex *model)
47{
48#ifdef JJF_ZERO
49  model->dual();
50#else
51  int numberColumns = model->numberColumns();
52  int numberRows = model->numberRows();
53  // Use dual region
54  double *rhs = model->dualRowSolution();
55  int *whichRow = new int[3 * numberRows];
56  int *whichColumn = new int[2 * numberColumns];
57  int nBound;
58  ClpSimplex *small = static_cast< ClpSimplexOther * >(model)->crunch(rhs, whichRow, whichColumn,
59    nBound, false, false);
60  if (small) {
61    small->dual();
62    if (small->problemStatus() == 0) {
63      model->setProblemStatus(0);
64      static_cast< ClpSimplexOther * >(model)->afterCrunch(*small, whichRow, whichColumn, nBound);
65    } else if (small->problemStatus() != 3) {
66      model->setProblemStatus(1);
67    } else {
68      if (small->problemStatus() == 3) {
69        // may be problems
70        small->computeObjectiveValue();
71        model->setObjectiveValue(small->objectiveValue());
72        model->setProblemStatus(3);
73      } else {
74        model->setProblemStatus(3);
75      }
76    }
77    delete small;
78  } else {
79    model->setProblemStatus(1);
80  }
81  delete[] whichRow;
82  delete[] whichColumn;
83#endif
84}
85/*
86  On input
87  doAction - 0 just fix in original and return NULL
88             1 return fixed non-presolved solver
89             2 as one but use presolve Inside this
90             3 use presolve and fix ones with large cost
91             ? do heuristics and set best solution
92             ? do BAB and just set best solution
93             10+ then use lastSolution and relax a few
94             -2 cleanup afterwards if using 2
95  On output - number fixed
96*/
97OsiClpSolverInterface *
98fixVubs(CbcModel &model, int skipZero2,
99  int &doAction,
100  CoinMessageHandler * /*generalMessageHandler*/,
101  const double *lastSolution, double dextra[6],
102  int extra[5])
103{
104  if (doAction == 11 && !lastSolution)
105    lastSolution = model.bestSolution();
106  assert(((doAction >= 0 && doAction <= 3) && !lastSolution) || (doAction == 11 && lastSolution));
107  double fractionIntFixed = dextra[3];
108  double fractionFixed = dextra[4];
109  double fixAbove = dextra[2];
110  double fixAboveValue = (dextra[5] > 0.0) ? dextra[5] : 1.0;
111#ifdef COIN_DETAIL
112  double time1 = CoinCpuTime();
113#endif
114  int leaveIntFree = extra[1];
115  OsiSolverInterface *originalSolver = model.solver();
116  OsiClpSolverInterface *originalClpSolver = dynamic_cast< OsiClpSolverInterface * >(originalSolver);
117  ClpSimplex *originalLpSolver = originalClpSolver->getModelPtr();
118  int *originalColumns = NULL;
119  OsiClpSolverInterface *clpSolver;
120  ClpSimplex *lpSolver;
121  ClpPresolve pinfo;
122  assert(originalSolver->getObjSense() > 0);
123  if (doAction == 2 || doAction == 3) {
124    double *saveLB = NULL;
125    double *saveUB = NULL;
126    int numberColumns = originalLpSolver->numberColumns();
127    if (fixAbove > 0.0) {
128#ifdef COIN_DETAIL
129      double time1 = CoinCpuTime();
130#endif
131      originalClpSolver->initialSolve();
132      COIN_DETAIL_PRINT(printf("first solve took %g seconds\n", CoinCpuTime() - time1));
133      double *columnLower = originalLpSolver->columnLower();
134      double *columnUpper = originalLpSolver->columnUpper();
135      const double *solution = originalLpSolver->primalColumnSolution();
136      saveLB = CoinCopyOfArray(columnLower, numberColumns);
137      saveUB = CoinCopyOfArray(columnUpper, numberColumns);
138      const double *objective = originalLpSolver->getObjCoefficients();
139      int iColumn;
140      int nFix = 0;
141      int nArt = 0;
142      for (iColumn = 0; iColumn < numberColumns; iColumn++) {
143        if (objective[iColumn] > fixAbove) {
144          if (solution[iColumn] < columnLower[iColumn] + 1.0e-8) {
145            columnUpper[iColumn] = columnLower[iColumn];
146            nFix++;
147          } else {
148            nArt++;
149          }
150        } else if (objective[iColumn] < -fixAbove) {
151          if (solution[iColumn] > columnUpper[iColumn] - 1.0e-8) {
152            columnLower[iColumn] = columnUpper[iColumn];
153            nFix++;
154          } else {
155            nArt++;
156          }
157        }
158      }
159      COIN_DETAIL_PRINT(printf("%d artificials fixed, %d left as in solution\n", nFix, nArt));
160      lpSolver = pinfo.presolvedModel(*originalLpSolver, 1.0e-8, true, 10);
161      if (!lpSolver || doAction == 2) {
162        // take off fixing in original
163        memcpy(columnLower, saveLB, numberColumns * sizeof(double));
164        memcpy(columnUpper, saveUB, numberColumns * sizeof(double));
165      }
166      delete[] saveLB;
167      delete[] saveUB;
168      if (!lpSolver) {
169        // try again
170        pinfo.destroyPresolve();
171        lpSolver = pinfo.presolvedModel(*originalLpSolver, 1.0e-8, true, 10);
172        assert(lpSolver);
173      }
174    } else {
175      lpSolver = pinfo.presolvedModel(*originalLpSolver, 1.0e-8, true, 10);
176      assert(lpSolver);
177    }
178    clpSolver = new OsiClpSolverInterface(lpSolver, true);
179    assert(lpSolver == clpSolver->getModelPtr());
180    numberColumns = lpSolver->numberColumns();
181    originalColumns = CoinCopyOfArray(pinfo.originalColumns(), numberColumns);
182    doAction = 1;
183  } else {
184    OsiSolverInterface *solver = originalSolver->clone();
185    clpSolver = dynamic_cast< OsiClpSolverInterface * >(solver);
186    lpSolver = clpSolver->getModelPtr();
187  }
188  // Tighten bounds
189  lpSolver->tightenPrimalBounds(0.0, 11, true);
190  int numberColumns = clpSolver->getNumCols();
191  double *saveColumnLower = CoinCopyOfArray(lpSolver->columnLower(), numberColumns);
192  double *saveColumnUpper = CoinCopyOfArray(lpSolver->columnUpper(), numberColumns);
193  //char generalPrint[200];
194  const double *objective = lpSolver->getObjCoefficients();
195  double *columnLower = lpSolver->columnLower();
196  double *columnUpper = lpSolver->columnUpper();
197  int numberRows = clpSolver->getNumRows();
198  int iRow, iColumn;
199
200  // Row copy
201  CoinPackedMatrix matrixByRow(*clpSolver->getMatrixByRow());
202  const double *elementByRow = matrixByRow.getElements();
203  const int *column = matrixByRow.getIndices();
204  const CoinBigIndex *rowStart = matrixByRow.getVectorStarts();
205  const int *rowLength = matrixByRow.getVectorLengths();
206
207  // Column copy
208  CoinPackedMatrix matrixByCol(*clpSolver->getMatrixByCol());
209  //const double * element = matrixByCol.getElements();
210  const int *row = matrixByCol.getIndices();
211  const CoinBigIndex *columnStart = matrixByCol.getVectorStarts();
212  const int *columnLength = matrixByCol.getVectorLengths();
213
214  const double *rowLower = clpSolver->getRowLower();
215  const double *rowUpper = clpSolver->getRowUpper();
216
217  // Get maximum size of VUB tree
218  // otherColumn is one fixed to 0 if this one zero
219  CoinBigIndex nEl = matrixByCol.getNumElements();
220  CoinBigIndex *fixColumn = new CoinBigIndex[numberColumns + 1];
221  int *otherColumn = new int[nEl];
222  int *fix = new int[numberColumns];
223  char *mark = new char[numberColumns];
224  memset(mark, 0, numberColumns);
225  int numberInteger = 0;
226  int numberOther = 0;
227  fixColumn[0] = 0;
228  double large = lpSolver->largeValue(); // treat bounds > this as infinite
229#ifndef NDEBUG
230  double large2 = 1.0e10 * large;
231#endif
232  double tolerance = lpSolver->primalTolerance();
233  int *check = new int[numberRows];
234  for (iRow = 0; iRow < numberRows; iRow++) {
235    check[iRow] = -2; // don't check
236    if (rowLower[iRow] < -1.0e6 && rowUpper[iRow] > 1.0e6)
237      continue; // unlikely
238    // possible row
239    int numberPositive = 0;
240    int iPositive = -1;
241    int numberNegative = 0;
242    int iNegative = -1;
243    CoinBigIndex rStart = rowStart[iRow];
244    CoinBigIndex rEnd = rowStart[iRow] + rowLength[iRow];
245    CoinBigIndex j;
246    int kColumn;
247    for (j = rStart; j < rEnd; ++j) {
248      double value = elementByRow[j];
249      kColumn = column[j];
250      if (columnUpper[kColumn] > columnLower[kColumn]) {
251        if (value > 0.0) {
252          numberPositive++;
253          iPositive = kColumn;
254        } else {
255          numberNegative++;
256          iNegative = kColumn;
257        }
258      }
259    }
260    if (numberPositive == 1 && numberNegative == 1)
261      check[iRow] = -1; // try both
262    if (numberPositive == 1 && rowLower[iRow] > -1.0e20)
263      check[iRow] = iPositive;
264    else if (numberNegative == 1 && rowUpper[iRow] < 1.0e20)
265      check[iRow] = iNegative;
266  }
267  for (iColumn = 0; iColumn < numberColumns; iColumn++) {
268    fix[iColumn] = -1;
269    if (columnUpper[iColumn] > columnLower[iColumn] + 1.0e-8) {
270      if (clpSolver->isInteger(iColumn))
271        numberInteger++;
272      if (columnLower[iColumn] == 0.0) {
273        bool infeasible = false;
274        fix[iColumn] = 0;
275        // fake upper bound
276        double saveUpper = columnUpper[iColumn];
277        columnUpper[iColumn] = 0.0;
278        for (CoinBigIndex i = columnStart[iColumn];
279             i < columnStart[iColumn] + columnLength[iColumn]; i++) {
280          iRow = row[i];
281          if (check[iRow] != -1 && check[iRow] != iColumn)
282            continue; // unlikely
283          // possible row
284          int infiniteUpper = 0;
285          int infiniteLower = 0;
286          double maximumUp = 0.0;
287          double maximumDown = 0.0;
288          double newBound;
289          CoinBigIndex rStart = rowStart[iRow];
290          CoinBigIndex rEnd = rowStart[iRow] + rowLength[iRow];
291          CoinBigIndex j;
292          int kColumn;
293          // Compute possible lower and upper ranges
294          for (j = rStart; j < rEnd; ++j) {
295            double value = elementByRow[j];
296            kColumn = column[j];
297            if (value > 0.0) {
298              if (columnUpper[kColumn] >= large) {
299                ++infiniteUpper;
300              } else {
301                maximumUp += columnUpper[kColumn] * value;
302              }
303              if (columnLower[kColumn] <= -large) {
304                ++infiniteLower;
305              } else {
306                maximumDown += columnLower[kColumn] * value;
307              }
308            } else if (value < 0.0) {
309              if (columnUpper[kColumn] >= large) {
310                ++infiniteLower;
311              } else {
312                maximumDown += columnUpper[kColumn] * value;
313              }
314              if (columnLower[kColumn] <= -large) {
315                ++infiniteUpper;
316              } else {
317                maximumUp += columnLower[kColumn] * value;
318              }
319            }
320          }
321          // Build in a margin of error
322          maximumUp += 1.0e-8 * fabs(maximumUp);
323          maximumDown -= 1.0e-8 * fabs(maximumDown);
324          double maxUp = maximumUp + infiniteUpper * 1.0e31;
325          double maxDown = maximumDown - infiniteLower * 1.0e31;
326          if (maxUp <= rowUpper[iRow] + tolerance && maxDown >= rowLower[iRow] - tolerance) {
327            //printf("Redundant row in vubs %d\n",iRow);
328          } else {
329            if (maxUp < rowLower[iRow] - 100.0 * tolerance || maxDown > rowUpper[iRow] + 100.0 * tolerance) {
330              infeasible = true;
331              break;
332            }
333            double lower = rowLower[iRow];
334            double upper = rowUpper[iRow];
335            for (j = rStart; j < rEnd; ++j) {
336              double value = elementByRow[j];
337              kColumn = column[j];
338              double nowLower = columnLower[kColumn];
339              double nowUpper = columnUpper[kColumn];
340              if (value > 0.0) {
341                // positive value
342                if (lower > -large) {
343                  if (!infiniteUpper) {
344                    assert(nowUpper < large2);
345                    newBound = nowUpper + (lower - maximumUp) / value;
346                    // relax if original was large
347                    if (fabs(maximumUp) > 1.0e8)
348                      newBound -= 1.0e-12 * fabs(maximumUp);
349                  } else if (infiniteUpper == 1 && nowUpper > large) {
350                    newBound = (lower - maximumUp) / value;
351                    // relax if original was large
352                    if (fabs(maximumUp) > 1.0e8)
353                      newBound -= 1.0e-12 * fabs(maximumUp);
354                  } else {
355                    newBound = -COIN_DBL_MAX;
356                  }
357                  if (newBound > nowLower + 1.0e-12 && newBound > -large) {
358                    // Tighten the lower bound
359                    // check infeasible (relaxed)
360                    if (nowUpper < newBound) {
361                      if (nowUpper - newBound < -100.0 * tolerance) {
362                        infeasible = true;
363                        break;
364                      }
365                    }
366                  }
367                }
368                if (upper < large) {
369                  if (!infiniteLower) {
370                    assert(nowLower > -large2);
371                    newBound = nowLower + (upper - maximumDown) / value;
372                    // relax if original was large
373                    if (fabs(maximumDown) > 1.0e8)
374                      newBound += 1.0e-12 * fabs(maximumDown);
375                  } else if (infiniteLower == 1 && nowLower < -large) {
376                    newBound = (upper - maximumDown) / value;
377                    // relax if original was large
378                    if (fabs(maximumDown) > 1.0e8)
379                      newBound += 1.0e-12 * fabs(maximumDown);
380                  } else {
381                    newBound = COIN_DBL_MAX;
382                  }
383                  if (newBound < nowUpper - 1.0e-12 && newBound < large) {
384                    // Tighten the upper bound
385                    // check infeasible (relaxed)
386                    if (nowLower > newBound) {
387                      if (newBound - nowLower < -100.0 * tolerance) {
388                        infeasible = true;
389                        break;
390                      } else {
391                        newBound = nowLower;
392                      }
393                    }
394                    if (!newBound || (clpSolver->isInteger(kColumn) && newBound < 0.999)) {
395                      // fix to zero
396                      if (!mark[kColumn]) {
397                        otherColumn[numberOther++] = kColumn;
398                        mark[kColumn] = 1;
399                        if (check[iRow] == -1)
400                          check[iRow] = iColumn;
401                        else
402                          assert(check[iRow] == iColumn);
403                      }
404                    }
405                  }
406                }
407              } else {
408                // negative value
409                if (lower > -large) {
410                  if (!infiniteUpper) {
411                    assert(nowLower < large2);
412                    newBound = nowLower + (lower - maximumUp) / value;
413                    // relax if original was large
414                    if (fabs(maximumUp) > 1.0e8)
415                      newBound += 1.0e-12 * fabs(maximumUp);
416                  } else if (infiniteUpper == 1 && nowLower < -large) {
417                    newBound = (lower - maximumUp) / value;
418                    // relax if original was large
419                    if (fabs(maximumUp) > 1.0e8)
420                      newBound += 1.0e-12 * fabs(maximumUp);
421                  } else {
422                    newBound = COIN_DBL_MAX;
423                  }
424                  if (newBound < nowUpper - 1.0e-12 && newBound < large) {
425                    // Tighten the upper bound
426                    // check infeasible (relaxed)
427                    if (nowLower > newBound) {
428                      if (newBound - nowLower < -100.0 * tolerance) {
429                        infeasible = true;
430                        break;
431                      } else {
432                        newBound = nowLower;
433                      }
434                    }
435                    if (!newBound || (clpSolver->isInteger(kColumn) && newBound < 0.999)) {
436                      // fix to zero
437                      if (!mark[kColumn]) {
438                        otherColumn[numberOther++] = kColumn;
439                        mark[kColumn] = 1;
440                        if (check[iRow] == -1)
441                          check[iRow] = iColumn;
442                        else
443                          assert(check[iRow] == iColumn);
444                      }
445                    }
446                  }
447                }
448                if (upper < large) {
449                  if (!infiniteLower) {
450                    assert(nowUpper < large2);
451                    newBound = nowUpper + (upper - maximumDown) / value;
452                    // relax if original was large
453                    if (fabs(maximumDown) > 1.0e8)
454                      newBound -= 1.0e-12 * fabs(maximumDown);
455                  } else if (infiniteLower == 1 && nowUpper > large) {
456                    newBound = (upper - maximumDown) / value;
457                    // relax if original was large
458                    if (fabs(maximumDown) > 1.0e8)
459                      newBound -= 1.0e-12 * fabs(maximumDown);
460                  } else {
461                    newBound = -COIN_DBL_MAX;
462                  }
463                  if (newBound > nowLower + 1.0e-12 && newBound > -large) {
464                    // Tighten the lower bound
465                    // check infeasible (relaxed)
466                    if (nowUpper < newBound) {
467                      if (nowUpper - newBound < -100.0 * tolerance) {
468                        infeasible = true;
469                        break;
470                      }
471                    }
472                  }
473                }
474              }
475            }
476          }
477        }
478        for (CoinBigIndex i = fixColumn[iColumn]; i < numberOther; i++)
479          mark[otherColumn[i]] = 0;
480        // reset bound unless infeasible
481        if (!infeasible || !clpSolver->isInteger(iColumn))
482          columnUpper[iColumn] = saveUpper;
483        else if (clpSolver->isInteger(iColumn))
484          columnLower[iColumn] = 1.0;
485      }
486    }
487    fixColumn[iColumn + 1] = numberOther;
488  }
489  delete[] check;
490  delete[] mark;
491  // Now do reverse way
492  int *counts = new int[numberColumns];
493  CoinZeroN(counts, numberColumns);
494  for (iColumn = 0; iColumn < numberColumns; iColumn++) {
495    for (CoinBigIndex i = fixColumn[iColumn]; i < fixColumn[iColumn + 1]; i++)
496      counts[otherColumn[i]]++;
497  }
498  numberOther = 0;
499  CoinBigIndex *fixColumn2 = new CoinBigIndex[numberColumns + 1];
500  int *otherColumn2 = new int[fixColumn[numberColumns]];
501  fixColumn2[0] = 0;
502  for (iColumn = 0; iColumn < numberColumns; iColumn++) {
503    numberOther += counts[iColumn];
504    counts[iColumn] = 0;
505    fixColumn2[iColumn + 1] = numberOther;
506  }
507  // Create other way
508  for (iColumn = 0; iColumn < numberColumns; iColumn++) {
509    for (CoinBigIndex i = fixColumn[iColumn]; i < fixColumn[iColumn + 1]; i++) {
510      int jColumn = otherColumn[i];
511      CoinBigIndex put = fixColumn2[jColumn] + counts[jColumn];
512      counts[jColumn]++;
513      otherColumn2[put] = iColumn;
514    }
515  }
516  // get top layer i.e. those which are not fixed by any other
517  int kLayer = 0;
518  while (true) {
519    int numberLayered = 0;
520    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
521      if (fix[iColumn] == kLayer) {
522        for (CoinBigIndex i = fixColumn2[iColumn]; i < fixColumn2[iColumn + 1]; i++) {
523          int jColumn = otherColumn2[i];
524          if (fix[jColumn] == kLayer) {
525            fix[iColumn] = kLayer + 100;
526          }
527        }
528      }
529      if (fix[iColumn] == kLayer) {
530        numberLayered++;
531      }
532    }
533    if (numberLayered) {
534      kLayer += 100;
535    } else {
536      break;
537    }
538  }
539  for (int iPass = 0; iPass < 2; iPass++) {
540    for (int jLayer = 0; jLayer < kLayer; jLayer++) {
541      int check[] = { -1, 0, 1, 2, 3, 4, 5, 10, 50, 100, 500, 1000, 5000, 10000, COIN_INT_MAX };
542      int nCheck = static_cast< int >(sizeof(check) / sizeof(int));
543      int countsI[20];
544      int countsC[20];
545      assert(nCheck <= 20);
546      memset(countsI, 0, nCheck * sizeof(int));
547      memset(countsC, 0, nCheck * sizeof(int));
548      check[nCheck - 1] = numberColumns;
549      int numberLayered = 0;
550      int numberInteger = 0;
551      for (iColumn = 0; iColumn < numberColumns; iColumn++) {
552        if (fix[iColumn] == jLayer) {
553          numberLayered++;
554          int nFix = static_cast< int >(fixColumn[iColumn + 1] - fixColumn[iColumn]);
555          if (iPass) {
556            // just integers
557            nFix = 0;
558            for (CoinBigIndex i = fixColumn[iColumn]; i < fixColumn[iColumn + 1]; i++) {
559              int jColumn = otherColumn[i];
560              if (clpSolver->isInteger(jColumn))
561                nFix++;
562            }
563          }
564          int iFix;
565          for (iFix = 0; iFix < nCheck; iFix++) {
566            if (nFix <= check[iFix])
567              break;
568          }
569          assert(iFix < nCheck);
570          if (clpSolver->isInteger(iColumn)) {
571            numberInteger++;
572            countsI[iFix]++;
573          } else {
574            countsC[iFix]++;
575          }
576        }
577      }
578#ifdef COIN_DETAIL
579      if (numberLayered) {
580        printf("%d (%d integer) at priority %d\n", numberLayered, numberInteger, 1 + (jLayer / 100));
581        char buffer[50];
582        for (int i = 1; i < nCheck; i++) {
583          if (countsI[i] || countsC[i]) {
584            if (i == 1)
585              sprintf(buffer, " ==    zero            ");
586            else if (i < nCheck - 1)
587              sprintf(buffer, "> %6d and <= %6d ", check[i - 1], check[i]);
588            else
589              sprintf(buffer, "> %6d                ", check[i - 1]);
590            printf("%s %8d integers and %8d continuous\n", buffer, countsI[i], countsC[i]);
591          }
592        }
593      }
594#endif
595    }
596  }
597  delete[] counts;
598  // Now do fixing
599  {
600    // switch off presolve and up weight
601    ClpSolve solveOptions;
602    //solveOptions.setPresolveType(ClpSolve::presolveOff,0);
603    solveOptions.setSolveType(ClpSolve::usePrimalorSprint);
604    //solveOptions.setSpecialOption(1,3,30); // sprint
605    int numberColumns = lpSolver->numberColumns();
606    int iColumn;
607    bool allSlack = true;
608    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
609      if (lpSolver->getColumnStatus(iColumn) == ClpSimplex::basic) {
610        allSlack = false;
611        break;
612      }
613    }
614    if (allSlack)
615      solveOptions.setSpecialOption(1, 2, 50); // idiot
616    lpSolver->setInfeasibilityCost(1.0e11);
617    lpSolver->defaultFactorizationFrequency();
618    if (doAction != 11)
619      lpSolver->initialSolve(solveOptions);
620    double *columnLower = lpSolver->columnLower();
621    double *columnUpper = lpSolver->columnUpper();
622    double *fullSolution = lpSolver->primalColumnSolution();
623    const double *dj = lpSolver->dualColumnSolution();
624    int iPass = 0;
625#define MAXPROB 2
626    ClpSimplex models[MAXPROB];
627    int kPass = -1;
628    int kLayer = 0;
629    int skipZero = 0;
630    if (skipZero2 == -1)
631      skipZero2 = 40; //-1;
632    /* 0 fixed to 0 by choice
633           1 lb of 1 by choice
634           2 fixed to 0 by another
635           3 as 2 but this go
636           -1 free
637        */
638    char *state = new char[numberColumns];
639    for (iColumn = 0; iColumn < numberColumns; iColumn++)
640      state[iColumn] = -1;
641    while (true) {
642      double largest = -0.1;
643      double smallest = 1.1;
644      int iLargest = -1;
645      int iSmallest = -1;
646      int atZero = 0;
647      int atOne = 0;
648      int toZero = 0;
649      int toOne = 0;
650      int numberFree = 0;
651      int numberGreater = 0;
652      columnLower = lpSolver->columnLower();
653      columnUpper = lpSolver->columnUpper();
654      fullSolution = lpSolver->primalColumnSolution();
655      if (doAction == 11) {
656        {
657          double *columnLower = lpSolver->columnLower();
658          double *columnUpper = lpSolver->columnUpper();
659          //      lpSolver->dual();
660          memcpy(columnLower, saveColumnLower, numberColumns * sizeof(double));
661          memcpy(columnUpper, saveColumnUpper, numberColumns * sizeof(double));
662          //      lpSolver->dual();
663          int iColumn;
664          for (iColumn = 0; iColumn < numberColumns; iColumn++) {
665            if (columnUpper[iColumn] > columnLower[iColumn] + 1.0e-8) {
666              if (clpSolver->isInteger(iColumn)) {
667                double value = lastSolution[iColumn];
668                int iValue = static_cast< int >(value + 0.5);
669                assert(fabs(value - static_cast< double >(iValue)) < 1.0e-3);
670                assert(iValue >= columnLower[iColumn] && iValue <= columnUpper[iColumn]);
671                columnLower[iColumn] = iValue;
672                columnUpper[iColumn] = iValue;
673              }
674            }
675          }
676          lpSolver->initialSolve(solveOptions);
677          memcpy(columnLower, saveColumnLower, numberColumns * sizeof(double));
678          memcpy(columnUpper, saveColumnUpper, numberColumns * sizeof(double));
679        }
680        for (iColumn = 0; iColumn < numberColumns; iColumn++) {
681          if (columnUpper[iColumn] > columnLower[iColumn] + 1.0e-8) {
682            if (clpSolver->isInteger(iColumn)) {
683              double value = lastSolution[iColumn];
684              int iValue = static_cast< int >(value + 0.5);
685              assert(fabs(value - static_cast< double >(iValue)) < 1.0e-3);
686              assert(iValue >= columnLower[iColumn] && iValue <= columnUpper[iColumn]);
687              if (!fix[iColumn]) {
688                if (iValue == 0) {
689                  state[iColumn] = 0;
690                  assert(!columnLower[iColumn]);
691                  columnUpper[iColumn] = 0.0;
692                } else if (iValue == 1) {
693                  state[iColumn] = 1;
694                  columnLower[iColumn] = 1.0;
695                } else {
696                  // leave fixed
697                  columnLower[iColumn] = iValue;
698                  columnUpper[iColumn] = iValue;
699                }
700              } else if (iValue == 0) {
701                state[iColumn] = 10;
702                columnUpper[iColumn] = 0.0;
703              } else {
704                // leave fixed
705                columnLower[iColumn] = iValue;
706                columnUpper[iColumn] = iValue;
707              }
708            }
709          }
710        }
711        int jLayer = 0;
712        int nFixed = -1;
713        int nTotalFixed = 0;
714        while (nFixed) {
715          nFixed = 0;
716          for (iColumn = 0; iColumn < numberColumns; iColumn++) {
717            if (columnUpper[iColumn] == 0.0 && fix[iColumn] == jLayer) {
718              for (CoinBigIndex i = fixColumn[iColumn]; i < fixColumn[iColumn + 1]; i++) {
719                int jColumn = otherColumn[i];
720                if (columnUpper[jColumn]) {
721                  bool canFix = true;
722                  for (CoinBigIndex k = fixColumn2[jColumn]; k < fixColumn2[jColumn + 1]; k++) {
723                    int kColumn = otherColumn2[k];
724                    if (state[kColumn] == 1) {
725                      canFix = false;
726                      break;
727                    }
728                  }
729                  if (canFix) {
730                    columnUpper[jColumn] = 0.0;
731                    nFixed++;
732                  }
733                }
734              }
735            }
736          }
737          nTotalFixed += nFixed;
738          jLayer += 100;
739        }
740        COIN_DETAIL_PRINT(printf("This fixes %d variables in lower priorities\n", nTotalFixed));
741        break;
742      }
743      for (iColumn = 0; iColumn < numberColumns; iColumn++) {
744        if (!clpSolver->isInteger(iColumn) || fix[iColumn] > kLayer)
745          continue;
746        // skip if fixes nothing
747        if (fixColumn[iColumn + 1] - fixColumn[iColumn] <= skipZero2)
748          continue;
749        double value = fullSolution[iColumn];
750        if (value > 1.00001) {
751          numberGreater++;
752          continue;
753        }
754        double lower = columnLower[iColumn];
755        double upper = columnUpper[iColumn];
756        if (lower == upper) {
757          if (lower)
758            atOne++;
759          else
760            atZero++;
761          continue;
762        }
763        if (value < 1.0e-7) {
764          toZero++;
765          columnUpper[iColumn] = 0.0;
766          state[iColumn] = 10;
767          continue;
768        }
769        if (value > 1.0 - 1.0e-7) {
770          toOne++;
771          columnLower[iColumn] = 1.0;
772          state[iColumn] = 1;
773          continue;
774        }
775        numberFree++;
776        // skip if fixes nothing
777        if (fixColumn[iColumn + 1] - fixColumn[iColumn] <= skipZero)
778          continue;
779        if (value < smallest) {
780          smallest = value;
781          iSmallest = iColumn;
782        }
783        if (value > largest) {
784          largest = value;
785          iLargest = iColumn;
786        }
787      }
788      if (toZero || toOne)
789        COIN_DETAIL_PRINT(printf("%d at 0 fixed and %d at one fixed\n", toZero, toOne));
790      COIN_DETAIL_PRINT(printf("%d variables free, %d fixed to 0, %d to 1 - smallest %g, largest %g\n",
791        numberFree, atZero, atOne, smallest, largest));
792      if (numberGreater && !iPass)
793        COIN_DETAIL_PRINT(printf("%d variables have value > 1.0\n", numberGreater));
794      //skipZero2=0; // leave 0 fixing
795      int jLayer = 0;
796      int nFixed = -1;
797      int nTotalFixed = 0;
798      while (nFixed) {
799        nFixed = 0;
800        for (iColumn = 0; iColumn < numberColumns; iColumn++) {
801          if (columnUpper[iColumn] == 0.0 && fix[iColumn] == jLayer) {
802            for (CoinBigIndex i = fixColumn[iColumn]; i < fixColumn[iColumn + 1]; i++) {
803              int jColumn = otherColumn[i];
804              if (columnUpper[jColumn]) {
805                bool canFix = true;
806                for (CoinBigIndex k = fixColumn2[jColumn]; k < fixColumn2[jColumn + 1]; k++) {
807                  int kColumn = otherColumn2[k];
808                  if (state[kColumn] == 1) {
809                    canFix = false;
810                    break;
811                  }
812                }
813                if (canFix) {
814                  columnUpper[jColumn] = 0.0;
815                  nFixed++;
816                }
817              }
818            }
819          }
820        }
821        nTotalFixed += nFixed;
822        jLayer += 100;
823      }
824      COIN_DETAIL_PRINT(printf("This fixes %d variables in lower priorities\n", nTotalFixed));
825      if (iLargest < 0 || numberFree <= leaveIntFree)
826        break;
827      double movement;
828      int way;
829      if (smallest <= 1.0 - largest && smallest < 0.2 && largest < fixAboveValue) {
830        columnUpper[iSmallest] = 0.0;
831        state[iSmallest] = 0;
832        movement = smallest;
833        way = -1;
834      } else {
835        columnLower[iLargest] = 1.0;
836        state[iLargest] = 1;
837        movement = 1.0 - largest;
838        way = 1;
839      }
840      double saveObj = lpSolver->objectiveValue();
841      iPass++;
842      kPass = iPass % MAXPROB;
843      models[kPass] = *lpSolver;
844      if (way == -1) {
845        // fix others
846        for (CoinBigIndex i = fixColumn[iSmallest]; i < fixColumn[iSmallest + 1]; i++) {
847          int jColumn = otherColumn[i];
848          if (state[jColumn] == -1) {
849            columnUpper[jColumn] = 0.0;
850            state[jColumn] = 3;
851          }
852        }
853      }
854      double maxCostUp = COIN_DBL_MAX;
855      objective = lpSolver->getObjCoefficients();
856      if (way == -1)
857        maxCostUp = (1.0 - movement) * objective[iSmallest];
858      lpSolver->setDualObjectiveLimit(saveObj + maxCostUp);
859      crunchIt(lpSolver);
860      double moveObj = lpSolver->objectiveValue() - saveObj;
861      COIN_DETAIL_PRINT(printf("movement %s was %g costing %g\n",
862        (way == -1) ? "down" : "up", movement, moveObj));
863      if (way == -1 && (moveObj >= maxCostUp || lpSolver->status())) {
864        // go up
865        columnLower = models[kPass].columnLower();
866        columnUpper = models[kPass].columnUpper();
867        columnLower[iSmallest] = 1.0;
868        columnUpper[iSmallest] = saveColumnUpper[iSmallest];
869        *lpSolver = models[kPass];
870        columnLower = lpSolver->columnLower();
871        columnUpper = lpSolver->columnUpper();
872        fullSolution = lpSolver->primalColumnSolution();
873        dj = lpSolver->dualColumnSolution();
874        columnLower[iSmallest] = 1.0;
875        columnUpper[iSmallest] = saveColumnUpper[iSmallest];
876        state[iSmallest] = 1;
877        // unfix others
878        for (CoinBigIndex i = fixColumn[iSmallest]; i < fixColumn[iSmallest + 1]; i++) {
879          int jColumn = otherColumn[i];
880          if (state[jColumn] == 3) {
881            columnUpper[jColumn] = saveColumnUpper[jColumn];
882            state[jColumn] = -1;
883          }
884        }
885        crunchIt(lpSolver);
886      }
887      models[kPass] = *lpSolver;
888    }
889    lpSolver->dual();
890    COIN_DETAIL_PRINT(printf("Fixing took %g seconds\n", CoinCpuTime() - time1));
891    columnLower = lpSolver->columnLower();
892    columnUpper = lpSolver->columnUpper();
893    fullSolution = lpSolver->primalColumnSolution();
894    dj = lpSolver->dualColumnSolution();
895    int *sort = new int[numberColumns];
896    double *dsort = new double[numberColumns];
897    int chunk = 20;
898    int iRelax = 0;
899    //double fractionFixed=6.0/8.0;
900    // relax while lots fixed
901    while (true) {
902      if (skipZero2 > 10 && doAction < 10)
903        break;
904      iRelax++;
905      int n = 0;
906      double sum0 = 0.0;
907      double sum00 = 0.0;
908      double sum1 = 0.0;
909      for (iColumn = 0; iColumn < numberColumns; iColumn++) {
910        if (!clpSolver->isInteger(iColumn) || fix[iColumn] > kLayer)
911          continue;
912        // skip if fixes nothing
913        if (fixColumn[iColumn + 1] - fixColumn[iColumn] == 0 && doAction < 10)
914          continue;
915        double djValue = dj[iColumn];
916        if (state[iColumn] == 1) {
917          assert(columnLower[iColumn]);
918          assert(fullSolution[iColumn] > 0.1);
919          if (djValue > 0.0) {
920            //printf("YY dj of %d at %g is %g\n",iColumn,value,djValue);
921            sum1 += djValue;
922            sort[n] = iColumn;
923            dsort[n++] = -djValue;
924          } else {
925            //printf("dj of %d at %g is %g\n",iColumn,value,djValue);
926          }
927        } else if (state[iColumn] == 0 || state[iColumn] == 10) {
928          assert(fullSolution[iColumn] < 0.1);
929          assert(!columnUpper[iColumn]);
930          double otherValue = 0.0;
931          int nn = 0;
932          for (CoinBigIndex i = fixColumn[iColumn]; i < fixColumn[iColumn + 1]; i++) {
933            int jColumn = otherColumn[i];
934            if (columnUpper[jColumn] == 0.0) {
935              if (dj[jColumn] < -1.0e-5) {
936                nn++;
937                otherValue += dj[jColumn]; // really need to look at rest
938              }
939            }
940          }
941          if (djValue < -1.0e-2 || otherValue < -1.0e-2) {
942            //printf("XX dj of %d at %g is %g - %d out of %d contribute %g\n",iColumn,value,djValue,
943            // nn,fixColumn[iColumn+1]-fixColumn[iColumn],otherValue);
944            if (djValue < 1.0e-8) {
945              sum0 -= djValue;
946              sum00 -= otherValue;
947              sort[n] = iColumn;
948              if (djValue < -1.0e-2)
949                dsort[n++] = djValue + otherValue;
950              else
951                dsort[n++] = djValue + 0.001 * otherValue;
952            }
953          } else {
954            //printf("dj of %d at %g is %g - no contribution from %d\n",iColumn,value,djValue,
955            //   fixColumn[iColumn+1]-fixColumn[iColumn]);
956          }
957        }
958      }
959      CoinSort_2(dsort, dsort + n, sort);
960      double *originalColumnLower = saveColumnLower;
961      double *originalColumnUpper = saveColumnUpper;
962      double *lo = CoinCopyOfArray(columnLower, numberColumns);
963      double *up = CoinCopyOfArray(columnUpper, numberColumns);
964      for (int k = 0; k < CoinMin(chunk, n); k++) {
965        iColumn = sort[k];
966        state[iColumn] = -2;
967      }
968      memcpy(columnLower, originalColumnLower, numberColumns * sizeof(double));
969      memcpy(columnUpper, originalColumnUpper, numberColumns * sizeof(double));
970      int nFixed = 0;
971      int nFixed0 = 0;
972      int nFixed1 = 0;
973      for (iColumn = 0; iColumn < numberColumns; iColumn++) {
974        if (state[iColumn] == 0 || state[iColumn] == 10) {
975          columnUpper[iColumn] = 0.0;
976          assert(lo[iColumn] == 0.0);
977          nFixed++;
978          nFixed0++;
979          for (CoinBigIndex i = fixColumn[iColumn]; i < fixColumn[iColumn + 1]; i++) {
980            int jColumn = otherColumn[i];
981            if (columnUpper[jColumn]) {
982              bool canFix = true;
983              for (CoinBigIndex k = fixColumn2[jColumn]; k < fixColumn2[jColumn + 1]; k++) {
984                int kColumn = otherColumn2[k];
985                if (state[kColumn] == 1 || state[kColumn] == -2) {
986                  canFix = false;
987                  break;
988                }
989              }
990              if (canFix) {
991                columnUpper[jColumn] = 0.0;
992                assert(lo[jColumn] == 0.0);
993                nFixed++;
994              }
995            }
996          }
997        } else if (state[iColumn] == 1) {
998          columnLower[iColumn] = 1.0;
999          nFixed1++;
1000        }
1001      }
1002      COIN_DETAIL_PRINT(printf("%d fixed %d orig 0 %d 1\n", nFixed, nFixed0, nFixed1));
1003      int jLayer = 0;
1004      nFixed = -1;
1005      int nTotalFixed = 0;
1006      while (nFixed) {
1007        nFixed = 0;
1008        for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1009          if (columnUpper[iColumn] == 0.0 && fix[iColumn] == jLayer) {
1010            for (CoinBigIndex i = fixColumn[iColumn]; i < fixColumn[iColumn + 1]; i++) {
1011              int jColumn = otherColumn[i];
1012              if (columnUpper[jColumn]) {
1013                bool canFix = true;
1014                for (CoinBigIndex k = fixColumn2[jColumn]; k < fixColumn2[jColumn + 1]; k++) {
1015                  int kColumn = otherColumn2[k];
1016                  if (state[kColumn] == 1 || state[kColumn] == -2) {
1017                    canFix = false;
1018                    break;
1019                  }
1020                }
1021                if (canFix) {
1022                  columnUpper[jColumn] = 0.0;
1023                  assert(lo[jColumn] == 0.0);
1024                  nFixed++;
1025                }
1026              }
1027            }
1028          }
1029        }
1030        nTotalFixed += nFixed;
1031        jLayer += 100;
1032      }
1033      nFixed = 0;
1034      int nFixedI = 0;
1035      for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1036        if (columnLower[iColumn] == columnUpper[iColumn]) {
1037          if (clpSolver->isInteger(iColumn))
1038            nFixedI++;
1039          nFixed++;
1040        }
1041      }
1042      COIN_DETAIL_PRINT(printf("This fixes %d variables in lower priorities - total %d (%d integer) - all target %d, int target %d\n",
1043        nTotalFixed, nFixed, nFixedI, static_cast< int >(fractionFixed * numberColumns), static_cast< int >(fractionIntFixed * numberInteger)));
1044      int nBad = 0;
1045      int nRelax = 0;
1046      for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1047        if (lo[iColumn] < columnLower[iColumn] || up[iColumn] > columnUpper[iColumn]) {
1048          COIN_DETAIL_PRINT(printf("bad %d old %g %g, new %g %g\n", iColumn, lo[iColumn], up[iColumn],
1049            columnLower[iColumn], columnUpper[iColumn]));
1050          nBad++;
1051        }
1052        if (lo[iColumn] > columnLower[iColumn] || up[iColumn] < columnUpper[iColumn]) {
1053          nRelax++;
1054        }
1055      }
1056      COIN_DETAIL_PRINT(printf("%d relaxed\n", nRelax));
1057      if (iRelax > 20 && nRelax == chunk)
1058        nRelax = 0;
1059      if (iRelax > 50)
1060        nRelax = 0;
1061      assert(!nBad);
1062      delete[] lo;
1063      delete[] up;
1064      lpSolver->primal(1);
1065      if (nFixed < fractionFixed * numberColumns || nFixedI < fractionIntFixed * numberInteger || !nRelax)
1066        break;
1067    }
1068    delete[] state;
1069    delete[] sort;
1070    delete[] dsort;
1071  }
1072  delete[] fix;
1073  delete[] fixColumn;
1074  delete[] otherColumn;
1075  delete[] otherColumn2;
1076  delete[] fixColumn2;
1077  // See if was presolved
1078  if (originalColumns) {
1079    columnLower = lpSolver->columnLower();
1080    columnUpper = lpSolver->columnUpper();
1081    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1082      saveColumnLower[iColumn] = columnLower[iColumn];
1083      saveColumnUpper[iColumn] = columnUpper[iColumn];
1084    }
1085    pinfo.postsolve(true);
1086    columnLower = originalLpSolver->columnLower();
1087    columnUpper = originalLpSolver->columnUpper();
1088    double *newColumnLower = lpSolver->columnLower();
1089    double *newColumnUpper = lpSolver->columnUpper();
1090    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1091      int jColumn = originalColumns[iColumn];
1092      columnLower[jColumn] = CoinMax(columnLower[jColumn], newColumnLower[iColumn]);
1093      columnUpper[jColumn] = CoinMin(columnUpper[jColumn], newColumnUpper[iColumn]);
1094    }
1095    numberColumns = originalLpSolver->numberColumns();
1096    delete[] originalColumns;
1097  }
1098  delete[] saveColumnLower;
1099  delete[] saveColumnUpper;
1100  if (!originalColumns) {
1101    // Basis
1102    memcpy(originalLpSolver->statusArray(), lpSolver->statusArray(), numberRows + numberColumns);
1103    memcpy(originalLpSolver->primalColumnSolution(), lpSolver->primalColumnSolution(), numberColumns * sizeof(double));
1104    memcpy(originalLpSolver->primalRowSolution(), lpSolver->primalRowSolution(), numberRows * sizeof(double));
1105    // Fix in solver
1106    columnLower = lpSolver->columnLower();
1107    columnUpper = lpSolver->columnUpper();
1108  }
1109  double *originalColumnLower = originalLpSolver->columnLower();
1110  double *originalColumnUpper = originalLpSolver->columnUpper();
1111  // number fixed
1112  doAction = 0;
1113  for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1114    originalColumnLower[iColumn] = columnLower[iColumn];
1115    originalColumnUpper[iColumn] = columnUpper[iColumn];
1116    if (columnLower[iColumn] == columnUpper[iColumn])
1117      doAction++;
1118  }
1119  COIN_DETAIL_PRINT(printf("%d fixed by vub preprocessing\n", doAction));
1120  if (originalColumns) {
1121    originalLpSolver->initialSolve();
1122  }
1123  delete clpSolver;
1124  return NULL;
1125}
1126
1127int doHeuristics(CbcModel *model, int type, std::vector< CbcOrClpParam > parameters_,
1128  int noPrinting_, int initialPumpTune)
1129{
1130#ifdef JJF_ZERO //NEW_STYLE_SOLVER==0
1131  CbcOrClpParam *parameters_ = parameters;
1132  int numberParameters_ = numberParameters;
1133  bool noPrinting_ = noPrinting_;
1134#endif
1135  char generalPrint[10000];
1136  CoinMessages generalMessages = model->messages();
1137  CoinMessageHandler *generalMessageHandler = model->messageHandler();
1138  //generalMessageHandler->setPrefix(false);
1139  bool anyToDo = false;
1140  int logLevel = parameters_[whichParam(CLP_PARAM_INT_LOGLEVEL, parameters_)].intValue();
1141  int useFpump = parameters_[whichParam(CBC_PARAM_STR_FPUMP, parameters_)].currentOptionAsInteger();
1142  int useRounding = parameters_[whichParam(CBC_PARAM_STR_ROUNDING, parameters_)].currentOptionAsInteger();
1143  int useGreedy = parameters_[whichParam(CBC_PARAM_STR_GREEDY, parameters_)].currentOptionAsInteger();
1144  int useCombine = parameters_[whichParam(CBC_PARAM_STR_COMBINE, parameters_)].currentOptionAsInteger();
1145  int useProximity = parameters_[whichParam(CBC_PARAM_STR_PROXIMITY, parameters_)].currentOptionAsInteger();
1146  int useCrossover = parameters_[whichParam(CBC_PARAM_STR_CROSSOVER2, parameters_)].currentOptionAsInteger();
1147  //int usePivotC = parameters_[whichParam(CBC_PARAM_STR_PIVOTANDCOMPLEMENT, parameters_)].currentOptionAsInteger();
1148  int usePivotF = parameters_[whichParam(CBC_PARAM_STR_PIVOTANDFIX, parameters_)].currentOptionAsInteger();
1149  int useRand = parameters_[whichParam(CBC_PARAM_STR_RANDROUND, parameters_)].currentOptionAsInteger();
1150  int useRINS = parameters_[whichParam(CBC_PARAM_STR_RINS, parameters_)].currentOptionAsInteger();
1151  int useRENS = parameters_[whichParam(CBC_PARAM_STR_RENS, parameters_)].currentOptionAsInteger();
1152  int useVND = parameters_[whichParam(CBC_PARAM_STR_VND, parameters_)].currentOptionAsInteger();
1153  int useDINS = parameters_[whichParam(CBC_PARAM_STR_DINS, parameters_)].currentOptionAsInteger();
1154  int useDIVING2 = parameters_[whichParam(CBC_PARAM_STR_DIVINGS, parameters_)].currentOptionAsInteger();
1155  int useNaive = parameters_[whichParam(CBC_PARAM_STR_NAIVE, parameters_)].currentOptionAsInteger();
1156  int useDW = parameters_[whichParam(CBC_PARAM_STR_DW, parameters_)].currentOptionAsInteger();
1157  int kType = (type < 10) ? type : 1;
1158  assert(kType == 1 || kType == 2);
1159  // FPump done first as it only works if no solution
1160  if (useFpump >= kType && useFpump <= kType + 1) {
1161    anyToDo = true;
1162    CbcHeuristicFPump heuristic4(*model);
1163    double dextra3 = parameters_[whichParam(CBC_PARAM_DBL_SMALLBAB, parameters_)].doubleValue();
1164    heuristic4.setFractionSmall(dextra3);
1165    double dextra1 = parameters_[whichParam(CBC_PARAM_DBL_ARTIFICIALCOST, parameters_)].doubleValue();
1166    if (dextra1)
1167      heuristic4.setArtificialCost(dextra1);
1168    heuristic4.setMaximumPasses(parameters_[whichParam(CBC_PARAM_INT_FPUMPITS, parameters_)].intValue());
1169    if (parameters_[whichParam(CBC_PARAM_INT_FPUMPITS, parameters_)].intValue() == 21)
1170      heuristic4.setIterationRatio(1.0);
1171    int pumpTune = parameters_[whichParam(CBC_PARAM_INT_FPUMPTUNE, parameters_)].intValue();
1172    int pumpTune2 = parameters_[whichParam(CBC_PARAM_INT_FPUMPTUNE2, parameters_)].intValue();
1173    if (pumpTune > 0) {
1174      bool printStuff = (pumpTune != initialPumpTune || logLevel > 1 || pumpTune2 > 0)
1175        && !noPrinting_;
1176      if (printStuff) {
1177        generalMessageHandler->message(CBC_GENERAL, generalMessages)
1178          << "Options for feasibility pump - "
1179          << CoinMessageEol;
1180      }
1181      /*
1182            >=10000000 for using obj
1183            >=1000000 use as accumulate switch
1184            >=1000 use index+1 as number of large loops
1185            >=100 use dextra1 as cutoff
1186            %100 == 10,20 etc for experimentation
1187            1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds
1188            4 and static continuous, 5 as 3 but no internal integers
1189            6 as 3 but all slack basis!
1190            */
1191      double value = model->solver()->getObjSense() * model->solver()->getObjValue();
1192      int w = pumpTune / 10;
1193      int i = w % 10;
1194      w /= 10;
1195      int c = w % 10;
1196      w /= 10;
1197      int r = w;
1198      int accumulate = r / 1000;
1199      r -= 1000 * accumulate;
1200      if (accumulate >= 100) {
1201        int which = accumulate / 100;
1202        accumulate -= 100 * which;
1203        which--;
1204        // weights and factors
1205        double weight[] = { 0.01, 0.01, 0.1, 0.1, 0.5, 0.5, 1.0, 1.0, 5.0, 5.0 };
1206        double factor[] = { 0.1, 0.5, 0.1, 0.5, 0.1, 0.5, 0.1, 0.5, 0.1, 0.5 };
1207        heuristic4.setInitialWeight(weight[which]);
1208        heuristic4.setWeightFactor(factor[which]);
1209        if (printStuff) {
1210          sprintf(generalPrint, "Initial weight for objective %g, decay factor %g",
1211            weight[which], factor[which]);
1212          generalMessageHandler->message(CBC_GENERAL, generalMessages)
1213            << generalPrint
1214            << CoinMessageEol;
1215        }
1216      }
1217      // fake cutoff
1218      if (c) {
1219        double cutoff;
1220        model->solver()->getDblParam(OsiDualObjectiveLimit, cutoff);
1221        cutoff = CoinMin(cutoff, value + 0.05 * fabs(value) * c);
1222        double fakeCutoff = parameters_[whichParam(CBC_PARAM_DBL_FAKECUTOFF, parameters_)].doubleValue();
1223        if (fakeCutoff)
1224          cutoff = fakeCutoff;
1225        heuristic4.setFakeCutoff(cutoff);
1226        if (printStuff) {
1227          sprintf(generalPrint, "Fake cutoff of %g", cutoff);
1228          generalMessageHandler->message(CBC_GENERAL, generalMessages)
1229            << generalPrint
1230            << CoinMessageEol;
1231        }
1232      }
1233      int offRandomEtc = 0;
1234      if (pumpTune2) {
1235        if ((pumpTune2 / 1000) != 0) {
1236          offRandomEtc = 1000000 * (pumpTune2 / 1000);
1237          if (printStuff) {
1238            generalMessageHandler->message(CBC_GENERAL, generalMessages)
1239              << "Feasibility pump may run twice"
1240              << CoinMessageEol;
1241          }
1242          pumpTune2 = pumpTune2 % 1000;
1243        }
1244        if ((pumpTune2 / 100) != 0) {
1245          offRandomEtc += 100 * (pumpTune2 / 100);
1246          if (printStuff) {
1247            generalMessageHandler->message(CBC_GENERAL, generalMessages)
1248              << "Not using randomized objective"
1249              << CoinMessageEol;
1250          }
1251        }
1252        int maxAllowed = pumpTune2 % 100;
1253        if (maxAllowed) {
1254          offRandomEtc += 1000 * maxAllowed;
1255          if (printStuff) {
1256            sprintf(generalPrint, "Fixing if same for %d passes",
1257              maxAllowed);
1258            generalMessageHandler->message(CBC_GENERAL, generalMessages)
1259              << generalPrint
1260              << CoinMessageEol;
1261          }
1262        }
1263      }
1264      if (accumulate) {
1265        heuristic4.setAccumulate(accumulate);
1266        if (printStuff) {
1267          if (accumulate) {
1268            sprintf(generalPrint, "Accumulate of %d", accumulate);
1269            generalMessageHandler->message(CBC_GENERAL, generalMessages)
1270              << generalPrint
1271              << CoinMessageEol;
1272          }
1273        }
1274      }
1275      if (r) {
1276        // also set increment
1277        //double increment = (0.01*i+0.005)*(fabs(value)+1.0e-12);
1278        double increment = 0.0;
1279        double fakeIncrement = parameters_[whichParam(CBC_PARAM_DBL_FAKEINCREMENT, parameters_)].doubleValue();
1280        if (fakeIncrement)
1281          increment = fakeIncrement;
1282        if (increment >= 0.0)
1283          heuristic4.setAbsoluteIncrement(increment);
1284        else
1285          heuristic4.setRelativeIncrement(-increment);
1286        heuristic4.setMaximumRetries(r + 1);
1287        if (printStuff) {
1288          if (increment) {
1289            if (increment > 0.0)
1290              sprintf(generalPrint, "Absolute increment of %g", increment);
1291            else
1292              sprintf(generalPrint, "Relative increment of %g", -increment);
1293            generalMessageHandler->message(CBC_GENERAL, generalMessages)
1294              << generalPrint
1295              << CoinMessageEol;
1296          }
1297          sprintf(generalPrint, "%d retries", r + 1);
1298          generalMessageHandler->message(CBC_GENERAL, generalMessages)
1299            << generalPrint
1300            << CoinMessageEol;
1301        }
1302      }
1303      if (i + offRandomEtc) {
1304        heuristic4.setFeasibilityPumpOptions(i * 10 + offRandomEtc);
1305        if (printStuff) {
1306          sprintf(generalPrint, "Feasibility pump options of %d",
1307            i * 10 + offRandomEtc);
1308          generalMessageHandler->message(CBC_GENERAL, generalMessages)
1309            << generalPrint
1310            << CoinMessageEol;
1311        }
1312      }
1313      pumpTune = pumpTune % 100;
1314      if (pumpTune == 6)
1315        pumpTune = 13;
1316      heuristic4.setWhen((pumpTune % 10) + 10);
1317      if (printStuff) {
1318        sprintf(generalPrint, "Tuning (fixing) %d", pumpTune % 10);
1319        generalMessageHandler->message(CBC_GENERAL, generalMessages)
1320          << generalPrint
1321          << CoinMessageEol;
1322      }
1323    }
1324    heuristic4.setHeuristicName("feasibility pump");
1325    //#define ROLF
1326#ifdef ROLF
1327    CbcHeuristicFPump pump(*model);
1328    pump.setMaximumTime(60);
1329    pump.setMaximumPasses(100);
1330    pump.setMaximumRetries(1);
1331    pump.setFixOnReducedCosts(0);
1332    pump.setHeuristicName("Feasibility pump");
1333    pump.setFractionSmall(1.0);
1334    pump.setWhen(13);
1335    model->addHeuristic(&pump);
1336#else
1337    model->addHeuristic(&heuristic4);
1338#endif
1339  }
1340  if (useRounding >= type && useRounding >= kType && useRounding <= kType + 1) {
1341    CbcRounding heuristic1(*model);
1342    heuristic1.setHeuristicName("rounding");
1343    model->addHeuristic(&heuristic1);
1344    anyToDo = true;
1345  }
1346  if (useGreedy >= type && useGreedy >= kType && useGreedy <= kType + 1) {
1347    CbcHeuristicGreedyCover heuristic3(*model);
1348    heuristic3.setHeuristicName("greedy cover");
1349    CbcHeuristicGreedyEquality heuristic3a(*model);
1350    heuristic3a.setHeuristicName("greedy equality");
1351    model->addHeuristic(&heuristic3);
1352    model->addHeuristic(&heuristic3a);
1353    anyToDo = true;
1354  }
1355  if ((useRENS == 7 && kType == 1) || (useRENS == 8 && kType == 2)) {
1356    useRENS = 1 + 2 * (useRENS - 7);
1357    CbcHeuristicRENS heuristic6a(*model);
1358    heuristic6a.setHeuristicName("RENSdj");
1359    heuristic6a.setFractionSmall(0.6 /*3.4*/);
1360    heuristic6a.setFeasibilityPumpOptions(3);
1361    heuristic6a.setNumberNodes(10);
1362    heuristic6a.setWhereFrom(4 * 256 + 4 * 1);
1363    heuristic6a.setWhen(2);
1364    heuristic6a.setRensType(1 + 16);
1365    model->addHeuristic(&heuristic6a);
1366    heuristic6a.setHeuristicName("RENSub");
1367    heuristic6a.setFractionSmall(0.4);
1368    heuristic6a.setFeasibilityPumpOptions(1008003);
1369    heuristic6a.setNumberNodes(50);
1370    heuristic6a.setWhereFrom(4 * 256 + 4 * 1);
1371    heuristic6a.setWhen(2);
1372    heuristic6a.setRensType(2 + 16);
1373    model->addHeuristic(&heuristic6a);
1374  }
1375  if ((useRENS >= kType && useRENS <= kType + 1) || useRENS > 2) {
1376    CbcHeuristicRENS heuristic6(*model);
1377    heuristic6.setHeuristicName("RENS");
1378    heuristic6.setFractionSmall(0.4);
1379    heuristic6.setFeasibilityPumpOptions(1008003);
1380    int nodes[] = { -2, 50, 50, 50, 200, 1000, 10000, -1, -1, 200 };
1381    heuristic6.setNumberNodes(nodes[useRENS]);
1382    heuristic6.setRensType(useRENS != 9 ? 0 : 32);
1383    model->addHeuristic(&heuristic6);
1384    anyToDo = true;
1385  }
1386  if (useVND >= kType && useVND <= kType + 1) {
1387    CbcHeuristicVND heuristic6b(*model);
1388    heuristic6b.setHeuristicName("VND");
1389    heuristic6b.setFractionSmall(0.4);
1390    heuristic6b.setFeasibilityPumpOptions(1008003);
1391    int nodes[] = { -2, 50, 50, 50, 200, 1000, 10000 };
1392    heuristic6b.setNumberNodes(nodes[useVND]);
1393    model->addHeuristic(&heuristic6b);
1394    anyToDo = true;
1395  }
1396  if (useNaive >= kType && useNaive <= kType + 1) {
1397    CbcHeuristicNaive heuristic5b(*model);
1398    heuristic5b.setHeuristicName("Naive");
1399    heuristic5b.setFractionSmall(0.4);
1400    heuristic5b.setNumberNodes(50);
1401    model->addHeuristic(&heuristic5b);
1402    anyToDo = true;
1403  }
1404  int useDIVING = 0;
1405  {
1406    int useD;
1407    useD = parameters_[whichParam(CBC_PARAM_STR_DIVINGV, parameters_)].currentOptionAsInteger();
1408    useDIVING |= 1 * ((useD >= kType) ? 1 : 0);
1409    useD = parameters_[whichParam(CBC_PARAM_STR_DIVINGG, parameters_)].currentOptionAsInteger();
1410    useDIVING |= 2 * ((useD >= kType) ? 1 : 0);
1411    useD = parameters_[whichParam(CBC_PARAM_STR_DIVINGF, parameters_)].currentOptionAsInteger();
1412    useDIVING |= 4 * ((useD >= kType) ? 1 : 0);
1413    useD = parameters_[whichParam(CBC_PARAM_STR_DIVINGC, parameters_)].currentOptionAsInteger();
1414    useDIVING |= 8 * ((useD >= kType) ? 1 : 0);
1415    useD = parameters_[whichParam(CBC_PARAM_STR_DIVINGL, parameters_)].currentOptionAsInteger();
1416    useDIVING |= 16 * ((useD >= kType) ? 1 : 0);
1417    useD = parameters_[whichParam(CBC_PARAM_STR_DIVINGP, parameters_)].currentOptionAsInteger();
1418    useDIVING |= 32 * ((useD >= kType) ? 1 : 0);
1419  }
1420  if (useDIVING2 >= kType && useDIVING2 <= kType + 1) {
1421    int diveOptions = parameters_[whichParam(CBC_PARAM_INT_DIVEOPT, parameters_)].intValue();
1422    if (diveOptions < 0 || diveOptions > 10)
1423      diveOptions = 2;
1424    CbcHeuristicJustOne heuristicJustOne(*model);
1425    heuristicJustOne.setHeuristicName("DiveAny");
1426    heuristicJustOne.setWhen(diveOptions);
1427    // add in others
1428    CbcHeuristicDiveCoefficient heuristicDC(*model);
1429    heuristicDC.setHeuristicName("DiveCoefficient");
1430    heuristicJustOne.addHeuristic(&heuristicDC, 1.0);
1431    CbcHeuristicDiveFractional heuristicDF(*model);
1432    heuristicDF.setHeuristicName("DiveFractional");
1433    heuristicJustOne.addHeuristic(&heuristicDF, 1.0);
1434    CbcHeuristicDiveGuided heuristicDG(*model);
1435    heuristicDG.setHeuristicName("DiveGuided");
1436    heuristicJustOne.addHeuristic(&heuristicDG, 1.0);
1437    CbcHeuristicDiveLineSearch heuristicDL(*model);
1438    heuristicDL.setHeuristicName("DiveLineSearch");
1439    heuristicJustOne.addHeuristic(&heuristicDL, 1.0);
1440    CbcHeuristicDivePseudoCost heuristicDP(*model);
1441    heuristicDP.setHeuristicName("DivePseudoCost");
1442    heuristicJustOne.addHeuristic(&heuristicDP, 1.0);
1443    CbcHeuristicDiveVectorLength heuristicDV(*model);
1444    heuristicDV.setHeuristicName("DiveVectorLength");
1445    heuristicJustOne.addHeuristic(&heuristicDV, 1.0);
1446    // Now normalize probabilities
1447    heuristicJustOne.normalizeProbabilities();
1448    model->addHeuristic(&heuristicJustOne);
1449  }
1450
1451  if (useDIVING > 0) {
1452    int majorIterations = parameters_[whichParam(CBC_PARAM_INT_DIVEOPTSOLVES, parameters_)].intValue();
1453    int diveOptions2 = parameters_[whichParam(CBC_PARAM_INT_DIVEOPT, parameters_)].intValue();
1454    int diveOptions;
1455    if (diveOptions2 > 99) {
1456      // switch on various active set stuff
1457      diveOptions = diveOptions2 % 100;
1458      diveOptions2 /= 100;
1459    } else {
1460      diveOptions = diveOptions2;
1461      diveOptions2 = 0;
1462    }
1463    if (diveOptions < 0 || diveOptions > 29)
1464      diveOptions = 2;
1465    int diveOptionsNotC = diveOptions;
1466    if (diveOptions > 10) {
1467      if (diveOptions > 20) {
1468        diveOptions -= 20;
1469        diveOptionsNotC -= 20;
1470      } else {
1471        diveOptions -= 10;
1472        diveOptionsNotC = 4;
1473      }
1474      useDIVING = 63;
1475    }
1476    if ((useDIVING & 1) != 0) {
1477      CbcHeuristicDiveVectorLength heuristicDV(*model);
1478      heuristicDV.setHeuristicName("DiveVectorLength");
1479      heuristicDV.setWhen(diveOptionsNotC);
1480      heuristicDV.setMaxIterations(majorIterations);
1481      if (diveOptions2) {
1482        heuristicDV.setPercentageToFix(0.0);
1483        heuristicDV.setMaxSimplexIterations(COIN_INT_MAX);
1484        heuristicDV.setMaxSimplexIterationsAtRoot(COIN_INT_MAX - (diveOptions2 - 1));
1485      }
1486      model->addHeuristic(&heuristicDV);
1487    }
1488    if ((useDIVING & 2) != 0) {
1489      CbcHeuristicDiveGuided heuristicDG(*model);
1490      heuristicDG.setHeuristicName("DiveGuided");
1491      heuristicDG.setWhen(diveOptionsNotC);
1492      heuristicDG.setMaxIterations(majorIterations);
1493      if (diveOptions2) {
1494        heuristicDG.setPercentageToFix(0.0);
1495        heuristicDG.setMaxSimplexIterations(COIN_INT_MAX);
1496        heuristicDG.setMaxSimplexIterationsAtRoot(COIN_INT_MAX - (diveOptions2 - 1));
1497      }
1498      model->addHeuristic(&heuristicDG);
1499    }
1500    if ((useDIVING & 4) != 0) {
1501      CbcHeuristicDiveFractional heuristicDF(*model);
1502      heuristicDF.setHeuristicName("DiveFractional");
1503      heuristicDF.setWhen(diveOptionsNotC);
1504      heuristicDF.setMaxIterations(majorIterations);
1505      if (diveOptions2) {
1506        heuristicDF.setPercentageToFix(0.0);
1507        heuristicDF.setMaxSimplexIterations(COIN_INT_MAX);
1508        heuristicDF.setMaxSimplexIterationsAtRoot(COIN_INT_MAX - (diveOptions2 - 1));
1509      }
1510      model->addHeuristic(&heuristicDF);
1511    }
1512    if ((useDIVING & 8) != 0) {
1513      CbcHeuristicDiveCoefficient heuristicDC(*model);
1514      heuristicDC.setHeuristicName("DiveCoefficient");
1515      heuristicDC.setWhen(diveOptions);
1516      heuristicDC.setMaxIterations(majorIterations);
1517      if (diveOptions2) {
1518        heuristicDC.setPercentageToFix(0.0);
1519        heuristicDC.setMaxSimplexIterations(COIN_INT_MAX);
1520        heuristicDC.setMaxSimplexIterationsAtRoot(COIN_INT_MAX - (diveOptions2 - 1));
1521      }
1522      model->addHeuristic(&heuristicDC);
1523    }
1524    if ((useDIVING & 16) != 0) {
1525      CbcHeuristicDiveLineSearch heuristicDL(*model);
1526      heuristicDL.setHeuristicName("DiveLineSearch");
1527      heuristicDL.setWhen(diveOptionsNotC);
1528      heuristicDL.setMaxIterations(majorIterations);
1529      if (diveOptions2) {
1530        heuristicDL.setPercentageToFix(0.0);
1531        heuristicDL.setMaxSimplexIterations(COIN_INT_MAX);
1532        heuristicDL.setMaxSimplexIterationsAtRoot(COIN_INT_MAX - (diveOptions2 - 1));
1533      }
1534      model->addHeuristic(&heuristicDL);
1535    }
1536    if ((useDIVING & 32) != 0) {
1537      CbcHeuristicDivePseudoCost heuristicDP(*model);
1538      heuristicDP.setHeuristicName("DivePseudoCost");
1539      heuristicDP.setWhen(diveOptionsNotC /*+ diveOptions2*/);
1540      heuristicDP.setMaxIterations(majorIterations);
1541      if (diveOptions2) {
1542        heuristicDP.setPercentageToFix(0.0);
1543        heuristicDP.setMaxSimplexIterations(COIN_INT_MAX);
1544        heuristicDP.setMaxSimplexIterationsAtRoot(COIN_INT_MAX - (diveOptions2 - 1));
1545      }
1546      model->addHeuristic(&heuristicDP);
1547    }
1548    anyToDo = true;
1549  }
1550#ifdef JJF_ZERO
1551  if (usePivotC >= type && usePivotC <= kType + 1) {
1552    CbcHeuristicPivotAndComplement heuristic(*model);
1553    heuristic.setHeuristicName("pivot and complement");
1554    heuristic.setFractionSmall(10.0); // normally 0.5
1555    model->addHeuristic(&heuristic);
1556    anyToDo = true;
1557  }
1558#endif
1559  if (usePivotF >= type && usePivotF <= kType + 1) {
1560    CbcHeuristicPivotAndFix heuristic(*model);
1561    heuristic.setHeuristicName("pivot and fix");
1562    heuristic.setFractionSmall(10.0); // normally 0.5
1563    model->addHeuristic(&heuristic);
1564    anyToDo = true;
1565  }
1566  if (useRand >= type && useRand <= kType + 1) {
1567    CbcHeuristicRandRound heuristic(*model);
1568    heuristic.setHeuristicName("randomized rounding");
1569    heuristic.setFractionSmall(10.0); // normally 0.5
1570    model->addHeuristic(&heuristic);
1571    anyToDo = true;
1572  }
1573  if (useDINS >= kType && useDINS <= kType + 1) {
1574    CbcHeuristicDINS heuristic5a(*model);
1575    heuristic5a.setHeuristicName("DINS");
1576    heuristic5a.setFractionSmall(0.6);
1577    if (useDINS < 4)
1578      heuristic5a.setDecayFactor(5.0);
1579    else
1580      heuristic5a.setDecayFactor(1.5);
1581    heuristic5a.setNumberNodes(1000);
1582    model->addHeuristic(&heuristic5a);
1583    anyToDo = true;
1584  }
1585  if (useRINS >= kType && useRINS <= kType + 1) {
1586    CbcHeuristicRINS heuristic5(*model);
1587    heuristic5.setHeuristicName("RINS");
1588    if (useRINS < 4) {
1589      heuristic5.setFractionSmall(0.5);
1590      heuristic5.setDecayFactor(5.0);
1591    } else {
1592      heuristic5.setFractionSmall(0.6);
1593      heuristic5.setDecayFactor(1.5);
1594    }
1595    model->addHeuristic(&heuristic5);
1596    anyToDo = true;
1597  }
1598  if (useDW >= kType && useDW <= kType + 1) {
1599    CbcHeuristicDW heuristic13(*model);
1600    heuristic13.setHeuristicName("Dantzig-Wolfe");
1601    heuristic13.setNumberPasses(100);
1602    heuristic13.setNumberBadPasses(10);
1603    int numberIntegers = 0;
1604    const OsiSolverInterface *solver = model->solver();
1605    int numberColumns = solver->getNumCols();
1606    for (int i = 0; i < numberColumns; i++) {
1607      if (solver->isInteger(i))
1608        numberIntegers++;
1609    }
1610    heuristic13.setNumberNeeded(CoinMin(200, numberIntegers / 10));
1611    model->addHeuristic(&heuristic13);
1612    anyToDo = true;
1613  }
1614  if (useCombine >= kType && (useCombine - 1) % 3 <= kType) {
1615    CbcHeuristicLocal heuristic2(*model);
1616    heuristic2.setHeuristicName("combine solutions");
1617    heuristic2.setFractionSmall(0.5);
1618    int searchType = 1;
1619    if (useCombine > 3)
1620      searchType += 10; // experiment
1621    heuristic2.setSearchType(searchType);
1622    model->addHeuristic(&heuristic2);
1623    anyToDo = true;
1624  }
1625  if ((useProximity >= kType && useProximity <= kType + 1) || (kType == 1 && useProximity > 3)) {
1626    CbcHeuristicProximity heuristic2a(*model);
1627    heuristic2a.setHeuristicName("Proximity Search");
1628    heuristic2a.setFractionSmall(9999999.0);
1629    heuristic2a.setNumberNodes(30);
1630    heuristic2a.setFeasibilityPumpOptions(-2);
1631    if (useProximity >= 4) {
1632      const int nodes[] = { 10, 100, 300 };
1633      heuristic2a.setNumberNodes(nodes[useProximity - 4]);
1634      // more print out and stronger feasibility pump
1635      if (useProximity == 6)
1636        heuristic2a.setFeasibilityPumpOptions(-3);
1637    } else {
1638      int proximityNumber;
1639      parameters_[whichParam(CBC_PARAM_STR_PROXIMITY, parameters_)].currentOptionAsInteger(proximityNumber);
1640      if (proximityNumber > 0) {
1641        heuristic2a.setNumberNodes(proximityNumber);
1642        // more print out and stronger feasibility pump
1643        if (proximityNumber >= 300)
1644          heuristic2a.setFeasibilityPumpOptions(-3);
1645      }
1646    }
1647    model->addHeuristic(&heuristic2a);
1648    anyToDo = true;
1649  }
1650  if (useCrossover >= kType && useCrossover <= kType + 1) {
1651    CbcHeuristicCrossover heuristic2a(*model);
1652    heuristic2a.setHeuristicName("crossover");
1653    heuristic2a.setFractionSmall(0.3);
1654    // just fix at lower
1655    heuristic2a.setWhen(11);
1656    model->addHeuristic(&heuristic2a);
1657    model->setMaximumSavedSolutions(5);
1658    anyToDo = true;
1659  }
1660  int heurSwitches = parameters_[whichParam(CBC_PARAM_INT_HOPTIONS, parameters_)].intValue() % 100;
1661  if (heurSwitches) {
1662    for (int iHeur = 0; iHeur < model->numberHeuristics(); iHeur++) {
1663      CbcHeuristic *heuristic = model->heuristic(iHeur);
1664      heuristic->setSwitches(heurSwitches);
1665    }
1666  }
1667  if (type == 2 && anyToDo) {
1668    // Do heuristics
1669#ifndef JJF_ONE
1670    // clean copy
1671    CbcModel model2(*model);
1672    // But get rid of heuristics in model
1673    model->doHeuristicsAtRoot(2);
1674    if (logLevel <= 1)
1675      model2.solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
1676    OsiBabSolver defaultC;
1677    //solver_->setAuxiliaryInfo(&defaultC);
1678    model2.passInSolverCharacteristics(&defaultC);
1679    // Save bounds
1680    int numberColumns = model2.solver()->getNumCols();
1681    model2.createContinuousSolver();
1682    bool cleanModel = !model2.numberIntegers() && !model2.numberObjects();
1683    model2.findIntegers(false);
1684    int heurOptions = (parameters_[whichParam(CBC_PARAM_INT_HOPTIONS, parameters_)].intValue() / 100) % 100;
1685    if (heurOptions == 0 || heurOptions == 2) {
1686      model2.doHeuristicsAtRoot(1);
1687    } else if (heurOptions == 1 || heurOptions == 3) {
1688      model2.setMaximumNodes(-1);
1689      CbcStrategyDefault strategy(0, 5, 5);
1690      strategy.setupPreProcessing(1, 0);
1691      model2.setStrategy(strategy);
1692      model2.branchAndBound();
1693    }
1694    if (cleanModel)
1695      model2.zapIntegerInformation(false);
1696    if (model2.bestSolution()) {
1697      double value = model2.getMinimizationObjValue();
1698      model->setCutoff(value);
1699      model->setBestSolution(model2.bestSolution(), numberColumns, value);
1700      model->setSolutionCount(1);
1701      model->setNumberHeuristicSolutions(1);
1702    }
1703#else
1704    if (logLevel <= 1)
1705      model->solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
1706    OsiBabSolver defaultC;
1707    //solver_->setAuxiliaryInfo(&defaultC);
1708    model->passInSolverCharacteristics(&defaultC);
1709    // Save bounds
1710    int numberColumns = model->solver()->getNumCols();
1711    model->createContinuousSolver();
1712    bool cleanModel = !model->numberIntegers() && !model->numberObjects();
1713    model->findIntegers(false);
1714    model->doHeuristicsAtRoot(1);
1715    if (cleanModel)
1716      model->zapIntegerInformation(false);
1717#endif
1718    return 0;
1719  } else {
1720    return 0;
1721  }
1722}
1723
1724/* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2
1725*/
Note: See TracBrowser for help on using the repository browser.