source: stable/2.8/Cbc/src/CbcSolverHeuristics.cpp @ 2104

Last change on this file since 2104 was 1902, checked in by stefan, 7 years ago

sync with trunk rev 1901

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