source: trunk/Cbc/src/CbcSolverHeuristics.cpp @ 1852

Last change on this file since 1852 was 1802, checked in by forrest, 7 years ago

add Proximity heuristic (Fischetti and Monaci) - shouldn't break anything

File size: 74.5 KB
Line 
1/* $Id$ */
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 pass[MAXPROB];
639        int kPass = -1;
640        int kLayer = 0;
641        int skipZero = 0;
642        if (skipZero2 == -1)
643            skipZero2 = 40; //-1;
644        /* 0 fixed to 0 by choice
645           1 lb of 1 by choice
646           2 fixed to 0 by another
647           3 as 2 but this go
648           -1 free
649        */
650        char * state = new char [numberColumns];
651        for (iColumn = 0; iColumn < numberColumns; iColumn++)
652            state[iColumn] = -1;
653        while (true) {
654            double largest = -0.1;
655            double smallest = 1.1;
656            int iLargest = -1;
657            int iSmallest = -1;
658            int atZero = 0;
659            int atOne = 0;
660            int toZero = 0;
661            int toOne = 0;
662            int numberFree = 0;
663            int numberGreater = 0;
664            columnLower = lpSolver->columnLower();
665            columnUpper = lpSolver->columnUpper();
666            fullSolution = lpSolver->primalColumnSolution();
667            if (doAction == 11) {
668                {
669                    double * columnLower = lpSolver->columnLower();
670                    double * columnUpper = lpSolver->columnUpper();
671                    //    lpSolver->dual();
672                    memcpy(columnLower, saveColumnLower, numberColumns*sizeof(double));
673                    memcpy(columnUpper, saveColumnUpper, numberColumns*sizeof(double));
674                    //    lpSolver->dual();
675                    int iColumn;
676                    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
677                        if (columnUpper[iColumn] > columnLower[iColumn] + 1.0e-8) {
678                            if (clpSolver->isInteger(iColumn)) {
679                                double value = lastSolution[iColumn];
680                                int iValue = static_cast<int> (value + 0.5);
681                                assert (fabs(value - static_cast<double> (iValue)) < 1.0e-3);
682                                assert (iValue >= columnLower[iColumn] &&
683                                        iValue <= columnUpper[iColumn]);
684                                columnLower[iColumn] = iValue;
685                                columnUpper[iColumn] = iValue;
686                            }
687                        }
688                    }
689                    lpSolver->initialSolve(solveOptions);
690                    memcpy(columnLower, saveColumnLower, numberColumns*sizeof(double));
691                    memcpy(columnUpper, saveColumnUpper, numberColumns*sizeof(double));
692                }
693                for (iColumn = 0; iColumn < numberColumns; iColumn++) {
694                    if (columnUpper[iColumn] > columnLower[iColumn] + 1.0e-8) {
695                        if (clpSolver->isInteger(iColumn)) {
696                            double value = lastSolution[iColumn];
697                            int iValue = static_cast<int> (value + 0.5);
698                            assert (fabs(value - static_cast<double> (iValue)) < 1.0e-3);
699                            assert (iValue >= columnLower[iColumn] &&
700                                    iValue <= columnUpper[iColumn]);
701                            if (!fix[iColumn]) {
702                                if (iValue == 0) {
703                                    state[iColumn] = 0;
704                                    assert (!columnLower[iColumn]);
705                                    columnUpper[iColumn] = 0.0;
706                                } else if (iValue == 1) {
707                                    state[iColumn] = 1;
708                                    columnLower[iColumn] = 1.0;
709                                } else {
710                                    // leave fixed
711                                    columnLower[iColumn] = iValue;
712                                    columnUpper[iColumn] = iValue;
713                                }
714                            } else if (iValue == 0) {
715                                state[iColumn] = 10;
716                                columnUpper[iColumn] = 0.0;
717                            } else {
718                                // leave fixed
719                                columnLower[iColumn] = iValue;
720                                columnUpper[iColumn] = iValue;
721                            }
722                        }
723                    }
724                }
725                int jLayer = 0;
726                int nFixed = -1;
727                int nTotalFixed = 0;
728                while (nFixed) {
729                    nFixed = 0;
730                    for ( iColumn = 0; iColumn < numberColumns; iColumn++) {
731                        if (columnUpper[iColumn] == 0.0 && fix[iColumn] == jLayer) {
732                            for (int i = fixColumn[iColumn]; i < fixColumn[iColumn+1]; i++) {
733                                int jColumn = otherColumn[i];
734                                if (columnUpper[jColumn]) {
735                                    bool canFix = true;
736                                    for (int k = fixColumn2[jColumn]; k < fixColumn2[jColumn+1]; k++) {
737                                        int kColumn = otherColumn2[k];
738                                        if (state[kColumn] == 1) {
739                                            canFix = false;
740                                            break;
741                                        }
742                                    }
743                                    if (canFix) {
744                                        columnUpper[jColumn] = 0.0;
745                                        nFixed++;
746                                    }
747                                }
748                            }
749                        }
750                    }
751                    nTotalFixed += nFixed;
752                    jLayer += 100;
753                }
754                COIN_DETAIL_PRINT(printf("This fixes %d variables in lower priorities\n", nTotalFixed));
755                break;
756            }
757            for ( iColumn = 0; iColumn < numberColumns; iColumn++) {
758                if (!clpSolver->isInteger(iColumn) || fix[iColumn] > kLayer)
759                    continue;
760                // skip if fixes nothing
761                if (fixColumn[iColumn+1] - fixColumn[iColumn] <= skipZero2)
762                    continue;
763                double value = fullSolution[iColumn];
764                if (value > 1.00001) {
765                    numberGreater++;
766                    continue;
767                }
768                double lower = columnLower[iColumn];
769                double upper = columnUpper[iColumn];
770                if (lower == upper) {
771                    if (lower)
772                        atOne++;
773                    else
774                        atZero++;
775                    continue;
776                }
777                if (value < 1.0e-7) {
778                    toZero++;
779                    columnUpper[iColumn] = 0.0;
780                    state[iColumn] = 10;
781                    continue;
782                }
783                if (value > 1.0 - 1.0e-7) {
784                    toOne++;
785                    columnLower[iColumn] = 1.0;
786                    state[iColumn] = 1;
787                    continue;
788                }
789                numberFree++;
790                // skip if fixes nothing
791                if (fixColumn[iColumn+1] - fixColumn[iColumn] <= skipZero)
792                    continue;
793                if (value < smallest) {
794                    smallest = value;
795                    iSmallest = iColumn;
796                }
797                if (value > largest) {
798                    largest = value;
799                    iLargest = iColumn;
800                }
801            }
802            if (toZero || toOne)
803              COIN_DETAIL_PRINT(printf("%d at 0 fixed and %d at one fixed\n", toZero, toOne));
804            COIN_DETAIL_PRINT(printf("%d variables free, %d fixed to 0, %d to 1 - smallest %g, largest %g\n",
805                                     numberFree, atZero, atOne, smallest, largest));
806            if (numberGreater && !iPass)
807              COIN_DETAIL_PRINT(printf("%d variables have value > 1.0\n", numberGreater));
808            //skipZero2=0; // leave 0 fixing
809            int jLayer = 0;
810            int nFixed = -1;
811            int nTotalFixed = 0;
812            while (nFixed) {
813                nFixed = 0;
814                for ( iColumn = 0; iColumn < numberColumns; iColumn++) {
815                    if (columnUpper[iColumn] == 0.0 && fix[iColumn] == jLayer) {
816                        for (int i = fixColumn[iColumn]; i < fixColumn[iColumn+1]; i++) {
817                            int jColumn = otherColumn[i];
818                            if (columnUpper[jColumn]) {
819                                bool canFix = true;
820                                for (int k = fixColumn2[jColumn]; k < fixColumn2[jColumn+1]; k++) {
821                                    int kColumn = otherColumn2[k];
822                                    if (state[kColumn] == 1) {
823                                        canFix = false;
824                                        break;
825                                    }
826                                }
827                                if (canFix) {
828                                    columnUpper[jColumn] = 0.0;
829                                    nFixed++;
830                                }
831                            }
832                        }
833                    }
834                }
835                nTotalFixed += nFixed;
836                jLayer += 100;
837            }
838            COIN_DETAIL_PRINT(printf("This fixes %d variables in lower priorities\n", nTotalFixed));
839            if (iLargest < 0 || numberFree <= leaveIntFree)
840                break;
841            double movement;
842            int way;
843            if (smallest <= 1.0 - largest && smallest < 0.2 && largest < fixAboveValue) {
844                columnUpper[iSmallest] = 0.0;
845                state[iSmallest] = 0;
846                movement = smallest;
847                way = -1;
848            } else {
849                columnLower[iLargest] = 1.0;
850                state[iLargest] = 1;
851                movement = 1.0 - largest;
852                way = 1;
853            }
854            double saveObj = lpSolver->objectiveValue();
855            iPass++;
856            kPass = iPass % MAXPROB;
857            models[kPass] = *lpSolver;
858            if (way == -1) {
859                // fix others
860                for (int i = fixColumn[iSmallest]; i < fixColumn[iSmallest+1]; i++) {
861                    int jColumn = otherColumn[i];
862                    if (state[jColumn] == -1) {
863                        columnUpper[jColumn] = 0.0;
864                        state[jColumn] = 3;
865                    }
866                }
867            }
868            pass[kPass] = iPass;
869            double maxCostUp = COIN_DBL_MAX;
870            objective = lpSolver->getObjCoefficients() ;
871            if (way == -1)
872                maxCostUp = (1.0 - movement) * objective[iSmallest];
873            lpSolver->setDualObjectiveLimit(saveObj + maxCostUp);
874            crunchIt(lpSolver);
875            double moveObj = lpSolver->objectiveValue() - saveObj;
876            COIN_DETAIL_PRINT(printf("movement %s was %g costing %g\n",
877                                     (way == -1) ? "down" : "up", movement, moveObj));
878            if (way == -1 && (moveObj >= maxCostUp || lpSolver->status())) {
879                // go up
880                columnLower = models[kPass].columnLower();
881                columnUpper = models[kPass].columnUpper();
882                columnLower[iSmallest] = 1.0;
883                columnUpper[iSmallest] = saveColumnUpper[iSmallest];
884                *lpSolver = models[kPass];
885                columnLower = lpSolver->columnLower();
886                columnUpper = lpSolver->columnUpper();
887                fullSolution = lpSolver->primalColumnSolution();
888                dj = lpSolver->dualColumnSolution();
889                columnLower[iSmallest] = 1.0;
890                columnUpper[iSmallest] = saveColumnUpper[iSmallest];
891                state[iSmallest] = 1;
892                // unfix others
893                for (int i = fixColumn[iSmallest]; i < fixColumn[iSmallest+1]; i++) {
894                    int jColumn = otherColumn[i];
895                    if (state[jColumn] == 3) {
896                        columnUpper[jColumn] = saveColumnUpper[jColumn];
897                        state[jColumn] = -1;
898                    }
899                }
900                crunchIt(lpSolver);
901            }
902            models[kPass] = *lpSolver;
903        }
904        lpSolver->dual();
905        COIN_DETAIL_PRINT(printf("Fixing took %g seconds\n", CoinCpuTime() - time1));
906        columnLower = lpSolver->columnLower();
907        columnUpper = lpSolver->columnUpper();
908        fullSolution = lpSolver->primalColumnSolution();
909        dj = lpSolver->dualColumnSolution();
910        int * sort = new int[numberColumns];
911        double * dsort = new double[numberColumns];
912        int chunk = 20;
913        int iRelax = 0;
914        //double fractionFixed=6.0/8.0;
915        // relax while lots fixed
916        while (true) {
917            if (skipZero2 > 10 && doAction < 10)
918                break;
919            iRelax++;
920            int n = 0;
921            double sum0 = 0.0;
922            double sum00 = 0.0;
923            double sum1 = 0.0;
924            for ( iColumn = 0; iColumn < numberColumns; iColumn++) {
925                if (!clpSolver->isInteger(iColumn) || fix[iColumn] > kLayer)
926                    continue;
927                // skip if fixes nothing
928                if (fixColumn[iColumn+1] - fixColumn[iColumn] == 0 && doAction < 10)
929                    continue;
930                double djValue = dj[iColumn];
931                if (state[iColumn] == 1) {
932                    assert (columnLower[iColumn]);
933                    assert (fullSolution[iColumn] > 0.1);
934                    if (djValue > 0.0) {
935                        //printf("YY dj of %d at %g is %g\n",iColumn,value,djValue);
936                        sum1 += djValue;
937                        sort[n] = iColumn;
938                        dsort[n++] = -djValue;
939                    } else {
940                        //printf("dj of %d at %g is %g\n",iColumn,value,djValue);
941                    }
942                } else if (state[iColumn] == 0 || state[iColumn] == 10) {
943                    assert (fullSolution[iColumn] < 0.1);
944                    assert (!columnUpper[iColumn]);
945                    double otherValue = 0.0;
946                    int nn = 0;
947                    for (int i = fixColumn[iColumn]; i < fixColumn[iColumn+1]; i++) {
948                        int jColumn = otherColumn[i];
949                        if (columnUpper[jColumn] == 0.0) {
950                            if (dj[jColumn] < -1.0e-5) {
951                                nn++;
952                                otherValue += dj[jColumn]; // really need to look at rest
953                            }
954                        }
955                    }
956                    if (djValue < -1.0e-2 || otherValue < -1.0e-2) {
957                        //printf("XX dj of %d at %g is %g - %d out of %d contribute %g\n",iColumn,value,djValue,
958                        // nn,fixColumn[iColumn+1]-fixColumn[iColumn],otherValue);
959                        if (djValue < 1.0e-8) {
960                            sum0 -= djValue;
961                            sum00 -= otherValue;
962                            sort[n] = iColumn;
963                            if (djValue < -1.0e-2)
964                                dsort[n++] = djValue + otherValue;
965                            else
966                                dsort[n++] = djValue + 0.001 * otherValue;
967                        }
968                    } else {
969                        //printf("dj of %d at %g is %g - no contribution from %d\n",iColumn,value,djValue,
970                        //   fixColumn[iColumn+1]-fixColumn[iColumn]);
971                    }
972                }
973            }
974            CoinSort_2(dsort, dsort + n, sort);
975            double * originalColumnLower = saveColumnLower;
976            double * originalColumnUpper = saveColumnUpper;
977            double * lo = CoinCopyOfArray(columnLower, numberColumns);
978            double * up = CoinCopyOfArray(columnUpper, numberColumns);
979            for (int k = 0; k < CoinMin(chunk, n); k++) {
980                iColumn = sort[k];
981                state[iColumn] = -2;
982            }
983            memcpy(columnLower, originalColumnLower, numberColumns*sizeof(double));
984            memcpy(columnUpper, originalColumnUpper, numberColumns*sizeof(double));
985            int nFixed = 0;
986            int nFixed0 = 0;
987            int nFixed1 = 0;
988            for ( iColumn = 0; iColumn < numberColumns; iColumn++) {
989                if (state[iColumn] == 0 || state[iColumn] == 10) {
990                    columnUpper[iColumn] = 0.0;
991                    assert (lo[iColumn] == 0.0);
992                    nFixed++;
993                    nFixed0++;
994                    for (int i = fixColumn[iColumn]; i < fixColumn[iColumn+1]; i++) {
995                        int jColumn = otherColumn[i];
996                        if (columnUpper[jColumn]) {
997                            bool canFix = true;
998                            for (int k = fixColumn2[jColumn]; k < fixColumn2[jColumn+1]; k++) {
999                                int kColumn = otherColumn2[k];
1000                                if (state[kColumn] == 1 || state[kColumn] == -2) {
1001                                    canFix = false;
1002                                    break;
1003                                }
1004                            }
1005                            if (canFix) {
1006                                columnUpper[jColumn] = 0.0;
1007                                assert (lo[jColumn] == 0.0);
1008                                nFixed++;
1009                            }
1010                        }
1011                    }
1012                } else if (state[iColumn] == 1) {
1013                    columnLower[iColumn] = 1.0;
1014                    nFixed1++;
1015                }
1016            }
1017            COIN_DETAIL_PRINT(printf("%d fixed %d orig 0 %d 1\n", nFixed, nFixed0, nFixed1));
1018            int jLayer = 0;
1019            nFixed = -1;
1020            int nTotalFixed = 0;
1021            while (nFixed) {
1022                nFixed = 0;
1023                for ( iColumn = 0; iColumn < numberColumns; iColumn++) {
1024                    if (columnUpper[iColumn] == 0.0 && fix[iColumn] == jLayer) {
1025                        for (int i = fixColumn[iColumn]; i < fixColumn[iColumn+1]; i++) {
1026                            int jColumn = otherColumn[i];
1027                            if (columnUpper[jColumn]) {
1028                                bool canFix = true;
1029                                for (int k = fixColumn2[jColumn]; k < fixColumn2[jColumn+1]; k++) {
1030                                    int kColumn = otherColumn2[k];
1031                                    if (state[kColumn] == 1 || state[kColumn] == -2) {
1032                                        canFix = false;
1033                                        break;
1034                                    }
1035                                }
1036                                if (canFix) {
1037                                    columnUpper[jColumn] = 0.0;
1038                                    assert (lo[jColumn] == 0.0);
1039                                    nFixed++;
1040                                }
1041                            }
1042                        }
1043                    }
1044                }
1045                nTotalFixed += nFixed;
1046                jLayer += 100;
1047            }
1048            nFixed = 0;
1049            int nFixedI = 0;
1050            for ( iColumn = 0; iColumn < numberColumns; iColumn++) {
1051                if (columnLower[iColumn] == columnUpper[iColumn]) {
1052                    if (clpSolver->isInteger(iColumn))
1053                        nFixedI++;
1054                    nFixed++;
1055                }
1056            }
1057            COIN_DETAIL_PRINT(printf("This fixes %d variables in lower priorities - total %d (%d integer) - all target %d, int target %d\n",
1058                                     nTotalFixed, nFixed, nFixedI, static_cast<int>(fractionFixed*numberColumns), static_cast<int> (fractionIntFixed*numberInteger)));
1059            int nBad = 0;
1060            int nRelax = 0;
1061            for ( iColumn = 0; iColumn < numberColumns; iColumn++) {
1062                if (lo[iColumn] < columnLower[iColumn] ||
1063                        up[iColumn] > columnUpper[iColumn]) {
1064                    COIN_DETAIL_PRINT(printf("bad %d old %g %g, new %g %g\n", iColumn, lo[iColumn], up[iColumn],
1065                                             columnLower[iColumn], columnUpper[iColumn]));
1066                    nBad++;
1067                }
1068                if (lo[iColumn] > columnLower[iColumn] ||
1069                        up[iColumn] < columnUpper[iColumn]) {
1070                    nRelax++;
1071                }
1072            }
1073            COIN_DETAIL_PRINT(printf("%d relaxed\n", nRelax));
1074            if (iRelax > 20 && nRelax == chunk)
1075                nRelax = 0;
1076            if (iRelax > 50)
1077                nRelax = 0;
1078            assert (!nBad);
1079            delete [] lo;
1080            delete [] up;
1081            lpSolver->primal(1);
1082            if (nFixed < fractionFixed*numberColumns || nFixedI < fractionIntFixed*numberInteger || !nRelax)
1083                break;
1084        }
1085        delete [] state;
1086        delete [] sort;
1087        delete [] dsort;
1088    }
1089    delete [] fix;
1090    delete [] fixColumn;
1091    delete [] otherColumn;
1092    delete [] otherColumn2;
1093    delete [] fixColumn2;
1094    // See if was presolved
1095    if (originalColumns) {
1096        columnLower = lpSolver->columnLower();
1097        columnUpper = lpSolver->columnUpper();
1098        for ( iColumn = 0; iColumn < numberColumns; iColumn++) {
1099            saveColumnLower[iColumn] = columnLower[iColumn];
1100            saveColumnUpper[iColumn] = columnUpper[iColumn];
1101        }
1102        pinfo.postsolve(true);
1103        columnLower = originalLpSolver->columnLower();
1104        columnUpper = originalLpSolver->columnUpper();
1105        double * newColumnLower = lpSolver->columnLower();
1106        double * newColumnUpper = lpSolver->columnUpper();
1107        for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1108            int jColumn = originalColumns[iColumn];
1109            columnLower[jColumn] = CoinMax(columnLower[jColumn], newColumnLower[iColumn]);
1110            columnUpper[jColumn] = CoinMin(columnUpper[jColumn], newColumnUpper[iColumn]);
1111        }
1112        numberColumns = originalLpSolver->numberColumns();
1113        delete [] originalColumns;
1114    }
1115    delete [] saveColumnLower;
1116    delete [] saveColumnUpper;
1117    if (!originalColumns) {
1118        // Basis
1119        memcpy(originalLpSolver->statusArray(), lpSolver->statusArray(), numberRows + numberColumns);
1120        memcpy(originalLpSolver->primalColumnSolution(), lpSolver->primalColumnSolution(), numberColumns*sizeof(double));
1121        memcpy(originalLpSolver->primalRowSolution(), lpSolver->primalRowSolution(), numberRows*sizeof(double));
1122        // Fix in solver
1123        columnLower = lpSolver->columnLower();
1124        columnUpper = lpSolver->columnUpper();
1125    }
1126    double * originalColumnLower = originalLpSolver->columnLower();
1127    double * originalColumnUpper = originalLpSolver->columnUpper();
1128    // number fixed
1129    doAction = 0;
1130    for ( iColumn = 0; iColumn < numberColumns; iColumn++) {
1131        originalColumnLower[iColumn] = columnLower[iColumn];
1132        originalColumnUpper[iColumn] = columnUpper[iColumn];
1133        if (columnLower[iColumn] == columnUpper[iColumn])
1134            doAction++;
1135    }
1136    COIN_DETAIL_PRINT(printf("%d fixed by vub preprocessing\n", doAction));
1137    if (originalColumns) {
1138        originalLpSolver->initialSolve();
1139    }
1140    delete clpSolver;
1141    return NULL;
1142}
1143
1144int doHeuristics(CbcModel * model, int type, CbcOrClpParam* parameters_,
1145                 int numberParameters_,int noPrinting_,int initialPumpTune)
1146{
1147#ifdef JJF_ZERO //NEW_STYLE_SOLVER==0
1148    CbcOrClpParam * parameters_ = parameters;
1149    int numberParameters_ = numberParameters;
1150    bool noPrinting_ = noPrinting_;
1151#endif
1152    char generalPrint[10000];
1153    CoinMessages generalMessages = model->messages();
1154    CoinMessageHandler * generalMessageHandler = model->messageHandler();
1155    //generalMessageHandler->setPrefix(false);
1156    bool anyToDo = false;
1157    int logLevel = parameters_[whichParam(CLP_PARAM_INT_LOGLEVEL, numberParameters_, parameters_)].intValue();
1158    int useFpump = parameters_[whichParam(CBC_PARAM_STR_FPUMP, numberParameters_, parameters_)].currentOptionAsInteger();
1159    int useRounding = parameters_[whichParam(CBC_PARAM_STR_ROUNDING, numberParameters_, parameters_)].currentOptionAsInteger();
1160    int useGreedy = parameters_[whichParam(CBC_PARAM_STR_GREEDY, numberParameters_, parameters_)].currentOptionAsInteger();
1161    int useCombine = parameters_[whichParam(CBC_PARAM_STR_COMBINE, numberParameters_, parameters_)].currentOptionAsInteger();
1162    int useProximity = parameters_[whichParam(CBC_PARAM_STR_PROXIMITY, numberParameters_, parameters_)].currentOptionAsInteger();
1163    int useCrossover = parameters_[whichParam(CBC_PARAM_STR_CROSSOVER2, numberParameters_, parameters_)].currentOptionAsInteger();
1164    //int usePivotC = parameters_[whichParam(CBC_PARAM_STR_PIVOTANDCOMPLEMENT, numberParameters_, parameters_)].currentOptionAsInteger();
1165    int usePivotF = parameters_[whichParam(CBC_PARAM_STR_PIVOTANDFIX, numberParameters_, parameters_)].currentOptionAsInteger();
1166    int useRand = parameters_[whichParam(CBC_PARAM_STR_RANDROUND, numberParameters_, parameters_)].currentOptionAsInteger();
1167    int useRINS = parameters_[whichParam(CBC_PARAM_STR_RINS, numberParameters_, parameters_)].currentOptionAsInteger();
1168    int useRENS = parameters_[whichParam(CBC_PARAM_STR_RENS, numberParameters_, parameters_)].currentOptionAsInteger();
1169    int useDINS = parameters_[whichParam(CBC_PARAM_STR_DINS, numberParameters_, parameters_)].currentOptionAsInteger();
1170    int useDIVING2 = parameters_[whichParam(CBC_PARAM_STR_DIVINGS, numberParameters_, parameters_)].currentOptionAsInteger();
1171    int useNaive = parameters_[whichParam(CBC_PARAM_STR_NAIVE, numberParameters_, parameters_)].currentOptionAsInteger();
1172    int kType = (type < 10) ? type : 1;
1173    assert (kType == 1 || kType == 2);
1174    // FPump done first as it only works if no solution
1175    if (useFpump >= kType && useFpump <= kType + 1) {
1176        anyToDo = true;
1177        CbcHeuristicFPump heuristic4(*model);
1178        double dextra3 = parameters_[whichParam(CBC_PARAM_DBL_SMALLBAB, numberParameters_, parameters_)].doubleValue();
1179        heuristic4.setFractionSmall(dextra3);
1180        double dextra1 = parameters_[whichParam(CBC_PARAM_DBL_ARTIFICIALCOST, numberParameters_, parameters_)].doubleValue();
1181        if (dextra1)
1182            heuristic4.setArtificialCost(dextra1);
1183        heuristic4.setMaximumPasses(parameters_[whichParam(CBC_PARAM_INT_FPUMPITS, numberParameters_, parameters_)].intValue());
1184        if (parameters_[whichParam(CBC_PARAM_INT_FPUMPITS, numberParameters_, parameters_)].intValue() == 21)
1185            heuristic4.setIterationRatio(1.0);
1186        int pumpTune = parameters_[whichParam(CBC_PARAM_INT_FPUMPTUNE, numberParameters_, parameters_)].intValue();
1187        int pumpTune2 = parameters_[whichParam(CBC_PARAM_INT_FPUMPTUNE2, numberParameters_, parameters_)].intValue();
1188        if (pumpTune > 0) {
1189            bool printStuff = (pumpTune != initialPumpTune || logLevel > 1 || pumpTune2 > 0)
1190                              && !noPrinting_;
1191            if (printStuff) {
1192                generalMessageHandler->message(CBC_GENERAL, generalMessages)
1193                << "Options for feasibility pump - "
1194                << CoinMessageEol;
1195            }
1196            /*
1197            >=10000000 for using obj
1198            >=1000000 use as accumulate switch
1199            >=1000 use index+1 as number of large loops
1200            >=100 use dextra1 as cutoff
1201            %100 == 10,20 etc for experimentation
1202            1 == fix ints at bounds, 2 fix all integral ints, 3 and continuous at bounds
1203            4 and static continuous, 5 as 3 but no internal integers
1204            6 as 3 but all slack basis!
1205            */
1206            double value = model->solver()->getObjSense() * model->solver()->getObjValue();
1207            int w = pumpTune / 10;
1208            int i = w % 10;
1209            w /= 10;
1210            int c = w % 10;
1211            w /= 10;
1212            int r = w;
1213            int accumulate = r / 1000;
1214            r -= 1000 * accumulate;
1215            if (accumulate >= 10) {
1216                int which = accumulate / 10;
1217                accumulate -= 10 * which;
1218                which--;
1219                // weights and factors
1220                double weight[] = {0.01, 0.01, 0.1, 0.1, 0.5, 0.5, 1.0, 1.0, 5.0, 5.0};
1221                double factor[] = {0.1, 0.5, 0.1, 0.5, 0.1, 0.5, 0.1, 0.5, 0.1, 0.5};
1222                heuristic4.setInitialWeight(weight[which]);
1223                heuristic4.setWeightFactor(factor[which]);
1224                if (printStuff) {
1225                    sprintf(generalPrint, "Initial weight for objective %g, decay factor %g",
1226                            weight[which], factor[which]);
1227                    generalMessageHandler->message(CBC_GENERAL, generalMessages)
1228                    << generalPrint
1229                    << CoinMessageEol;
1230                }
1231
1232            }
1233            // fake cutoff
1234            if (c) {
1235                double cutoff;
1236                model->solver()->getDblParam(OsiDualObjectiveLimit, cutoff);
1237                cutoff = CoinMin(cutoff, value + 0.05 * fabs(value) * c);
1238                double fakeCutoff = parameters_[whichParam(CBC_PARAM_DBL_FAKECUTOFF, numberParameters_, parameters_)].doubleValue();
1239                if (fakeCutoff)
1240                    cutoff = fakeCutoff;
1241                heuristic4.setFakeCutoff(cutoff);
1242                if (printStuff) {
1243                    sprintf(generalPrint, "Fake cutoff of %g", cutoff);
1244                    generalMessageHandler->message(CBC_GENERAL, generalMessages)
1245                    << generalPrint
1246                    << CoinMessageEol;
1247                }
1248            }
1249            int offRandomEtc = 0;
1250            if (pumpTune2) {
1251                if ((pumpTune2 / 1000) != 0) {
1252                    offRandomEtc = 1000000 * (pumpTune2 / 1000);
1253                    if (printStuff) {
1254                        generalMessageHandler->message(CBC_GENERAL, generalMessages)
1255                        << "Feasibility pump may run twice"
1256                        << CoinMessageEol;
1257                    }
1258                    pumpTune2 = pumpTune2 % 1000;
1259                }
1260                if ((pumpTune2 / 100) != 0) {
1261                    offRandomEtc += 100 * (pumpTune2 / 100);
1262                    if (printStuff) {
1263                        generalMessageHandler->message(CBC_GENERAL, generalMessages)
1264                        << "Not using randomized objective"
1265                        << CoinMessageEol;
1266                    }
1267                }
1268                int maxAllowed = pumpTune2 % 100;
1269                if (maxAllowed) {
1270                    offRandomEtc += 1000 * maxAllowed;
1271                    if (printStuff) {
1272                        sprintf(generalPrint, "Fixing if same for %d passes",
1273                                maxAllowed);
1274                        generalMessageHandler->message(CBC_GENERAL, generalMessages)
1275                        << generalPrint
1276                        << CoinMessageEol;
1277                    }
1278                }
1279            }
1280            if (accumulate) {
1281                heuristic4.setAccumulate(accumulate);
1282                if (printStuff) {
1283                    if (accumulate) {
1284                        sprintf(generalPrint, "Accumulate of %d", accumulate);
1285                        generalMessageHandler->message(CBC_GENERAL, generalMessages)
1286                        << generalPrint
1287                        << CoinMessageEol;
1288                    }
1289                }
1290            }
1291            if (r) {
1292                // also set increment
1293                //double increment = (0.01*i+0.005)*(fabs(value)+1.0e-12);
1294                double increment = 0.0;
1295                double fakeIncrement = parameters_[whichParam(CBC_PARAM_DBL_FAKEINCREMENT, numberParameters_, parameters_)].doubleValue();
1296                if (fakeIncrement)
1297                    increment = fakeIncrement;
1298                heuristic4.setAbsoluteIncrement(increment);
1299                heuristic4.setMaximumRetries(r + 1);
1300                if (printStuff) {
1301                    if (increment) {
1302                        sprintf(generalPrint, "Increment of %g", increment);
1303                        generalMessageHandler->message(CBC_GENERAL, generalMessages)
1304                        << generalPrint
1305                        << CoinMessageEol;
1306                    }
1307                    sprintf(generalPrint, "%d retries", r + 1);
1308                    generalMessageHandler->message(CBC_GENERAL, generalMessages)
1309                    << generalPrint
1310                    << CoinMessageEol;
1311                }
1312            }
1313            if (i + offRandomEtc) {
1314                heuristic4.setFeasibilityPumpOptions(i*10 + offRandomEtc);
1315                if (printStuff) {
1316                    sprintf(generalPrint, "Feasibility pump options of %d",
1317                            i*10 + offRandomEtc);
1318                    generalMessageHandler->message(CBC_GENERAL, generalMessages)
1319                    << generalPrint
1320                    << CoinMessageEol;
1321                }
1322            }
1323            pumpTune = pumpTune % 100;
1324            if (pumpTune == 6)
1325                pumpTune = 13;
1326            heuristic4.setWhen((pumpTune % 10) + 10);
1327            if (printStuff) {
1328                sprintf(generalPrint, "Tuning (fixing) %d", pumpTune % 10);
1329                generalMessageHandler->message(CBC_GENERAL, generalMessages)
1330                << generalPrint
1331                << CoinMessageEol;
1332            }
1333        }
1334        heuristic4.setHeuristicName("feasibility pump");
1335        //#define ROLF
1336#ifdef ROLF
1337        CbcHeuristicFPump pump(*model);
1338        pump.setMaximumTime(60);
1339        pump.setMaximumPasses(100);
1340        pump.setMaximumRetries(1);
1341        pump.setFixOnReducedCosts(0);
1342        pump.setHeuristicName("Feasibility pump");
1343        pump.setFractionSmall(1.0);
1344        pump.setWhen(13);
1345        model->addHeuristic(&pump);
1346#else
1347        model->addHeuristic(&heuristic4);
1348#endif
1349    }
1350    if (useRounding >= type && useRounding >= kType && useRounding <= kType + 1) {
1351        CbcRounding heuristic1(*model);
1352        heuristic1.setHeuristicName("rounding");
1353        model->addHeuristic(&heuristic1) ;
1354        anyToDo = true;
1355    }
1356    if (useGreedy >= type && useGreedy >= kType && useGreedy <= kType + 1) {
1357        CbcHeuristicGreedyCover heuristic3(*model);
1358        heuristic3.setHeuristicName("greedy cover");
1359        CbcHeuristicGreedyEquality heuristic3a(*model);
1360        heuristic3a.setHeuristicName("greedy equality");
1361        model->addHeuristic(&heuristic3);
1362        model->addHeuristic(&heuristic3a);
1363        anyToDo = true;
1364    }
1365    if ((useRENS==7 && kType==1) || (useRENS==8 && kType==2)) {
1366        useRENS=1+2*(useRENS-7);
1367        CbcHeuristicRENS heuristic6a(*model);
1368        heuristic6a.setHeuristicName("RENSdj");
1369        heuristic6a.setFractionSmall(0.6/*3.4*/);
1370        heuristic6a.setFeasibilityPumpOptions(3);
1371        heuristic6a.setNumberNodes(10);
1372        heuristic6a.setWhereFrom(4*256+4*1);
1373        heuristic6a.setWhen(2);
1374        heuristic6a.setRensType(1+16);
1375        model->addHeuristic(&heuristic6a) ;
1376        heuristic6a.setHeuristicName("RENSub");
1377        heuristic6a.setFractionSmall(0.4);
1378        heuristic6a.setFeasibilityPumpOptions(1008003);
1379        heuristic6a.setNumberNodes(50);
1380        heuristic6a.setWhereFrom(4*256+4*1);
1381        heuristic6a.setWhen(2);
1382        heuristic6a.setRensType(2+16);
1383        model->addHeuristic(&heuristic6a) ;
1384    }
1385    if (useRENS >= kType && useRENS <= kType + 1) {
1386#ifndef JJF_ONE
1387        CbcHeuristicRENS heuristic6(*model);
1388        heuristic6.setHeuristicName("RENS");
1389        heuristic6.setFractionSmall(0.4);
1390        heuristic6.setFeasibilityPumpOptions(1008003);
1391        int nodes [] = { -2, 50, 50, 50, 200, 1000, 10000};
1392        heuristic6.setNumberNodes(nodes[useRENS]);
1393#else
1394        CbcHeuristicVND heuristic6(*model);
1395        heuristic6.setHeuristicName("VND");
1396        heuristic5.setFractionSmall(0.5);
1397        heuristic5.setDecayFactor(5.0);
1398#endif
1399        model->addHeuristic(&heuristic6) ;
1400        anyToDo = true;
1401    }
1402    if (useNaive >= kType && useNaive <= kType + 1) {
1403        CbcHeuristicNaive heuristic5b(*model);
1404        heuristic5b.setHeuristicName("Naive");
1405        heuristic5b.setFractionSmall(0.4);
1406        heuristic5b.setNumberNodes(50);
1407        model->addHeuristic(&heuristic5b) ;
1408        anyToDo = true;
1409    }
1410    int useDIVING = 0;
1411    {
1412        int useD;
1413        useD = parameters_[whichParam(CBC_PARAM_STR_DIVINGV, numberParameters_, parameters_)].currentOptionAsInteger();
1414        useDIVING |= 1 * ((useD >= kType) ? 1 : 0);
1415        useD = parameters_[whichParam(CBC_PARAM_STR_DIVINGG, numberParameters_, parameters_)].currentOptionAsInteger();
1416        useDIVING |= 2 * ((useD >= kType) ? 1 : 0);
1417        useD = parameters_[whichParam(CBC_PARAM_STR_DIVINGF, numberParameters_, parameters_)].currentOptionAsInteger();
1418        useDIVING |= 4 * ((useD >= kType) ? 1 : 0);
1419        useD = parameters_[whichParam(CBC_PARAM_STR_DIVINGC, numberParameters_, parameters_)].currentOptionAsInteger();
1420        useDIVING |= 8 * ((useD >= kType) ? 1 : 0);
1421        useD = parameters_[whichParam(CBC_PARAM_STR_DIVINGL, numberParameters_, parameters_)].currentOptionAsInteger();
1422        useDIVING |= 16 * ((useD >= kType) ? 1 : 0);
1423        useD = parameters_[whichParam(CBC_PARAM_STR_DIVINGP, numberParameters_, parameters_)].currentOptionAsInteger();
1424        useDIVING |= 32 * ((useD >= kType) ? 1 : 0);
1425    }
1426    if (useDIVING2 >= kType && useDIVING2 <= kType + 1) {
1427        int diveOptions = parameters_[whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_)].intValue();
1428        if (diveOptions < 0 || diveOptions > 10)
1429            diveOptions = 2;
1430        CbcHeuristicJustOne heuristicJustOne(*model);
1431        heuristicJustOne.setHeuristicName("DiveAny");
1432        heuristicJustOne.setWhen(diveOptions);
1433        // add in others
1434        CbcHeuristicDiveCoefficient heuristicDC(*model);
1435        heuristicDC.setHeuristicName("DiveCoefficient");
1436        heuristicJustOne.addHeuristic(&heuristicDC, 1.0) ;
1437        CbcHeuristicDiveFractional heuristicDF(*model);
1438        heuristicDF.setHeuristicName("DiveFractional");
1439        heuristicJustOne.addHeuristic(&heuristicDF, 1.0) ;
1440        CbcHeuristicDiveGuided heuristicDG(*model);
1441        heuristicDG.setHeuristicName("DiveGuided");
1442        heuristicJustOne.addHeuristic(&heuristicDG, 1.0) ;
1443        CbcHeuristicDiveLineSearch heuristicDL(*model);
1444        heuristicDL.setHeuristicName("DiveLineSearch");
1445        heuristicJustOne.addHeuristic(&heuristicDL, 1.0) ;
1446        CbcHeuristicDivePseudoCost heuristicDP(*model);
1447        heuristicDP.setHeuristicName("DivePseudoCost");
1448        heuristicJustOne.addHeuristic(&heuristicDP, 1.0) ;
1449        CbcHeuristicDiveVectorLength heuristicDV(*model);
1450        heuristicDV.setHeuristicName("DiveVectorLength");
1451        heuristicJustOne.addHeuristic(&heuristicDV, 1.0) ;
1452        // Now normalize probabilities
1453        heuristicJustOne.normalizeProbabilities();
1454        model->addHeuristic(&heuristicJustOne) ;
1455    }
1456
1457    if (useDIVING > 0) {
1458        int diveOptions2 = parameters_[whichParam(CBC_PARAM_INT_DIVEOPT, numberParameters_, parameters_)].intValue();
1459        int diveOptions;
1460        if (diveOptions2 > 99) {
1461            // switch on various active set stuff
1462            diveOptions = diveOptions2 % 100;
1463            diveOptions2 -= diveOptions;
1464        } else {
1465            diveOptions = diveOptions2;
1466            diveOptions2 = 0;
1467        }
1468        if (diveOptions < 0 || diveOptions > 9)
1469            diveOptions = 2;
1470        if ((useDIVING&1) != 0) {
1471            CbcHeuristicDiveVectorLength heuristicDV(*model);
1472            heuristicDV.setHeuristicName("DiveVectorLength");
1473            heuristicDV.setWhen(diveOptions);
1474            model->addHeuristic(&heuristicDV) ;
1475        }
1476        if ((useDIVING&2) != 0) {
1477            CbcHeuristicDiveGuided heuristicDG(*model);
1478            heuristicDG.setHeuristicName("DiveGuided");
1479            heuristicDG.setWhen(diveOptions);
1480            model->addHeuristic(&heuristicDG) ;
1481        }
1482        if ((useDIVING&4) != 0) {
1483            CbcHeuristicDiveFractional heuristicDF(*model);
1484            heuristicDF.setHeuristicName("DiveFractional");
1485            heuristicDF.setWhen(diveOptions);
1486            model->addHeuristic(&heuristicDF) ;
1487        }
1488        if ((useDIVING&8) != 0) {
1489            CbcHeuristicDiveCoefficient heuristicDC(*model);
1490            heuristicDC.setHeuristicName("DiveCoefficient");
1491            heuristicDC.setWhen(diveOptions);
1492            model->addHeuristic(&heuristicDC) ;
1493        }
1494        if ((useDIVING&16) != 0) {
1495            CbcHeuristicDiveLineSearch heuristicDL(*model);
1496            heuristicDL.setHeuristicName("DiveLineSearch");
1497            heuristicDL.setWhen(diveOptions);
1498            model->addHeuristic(&heuristicDL) ;
1499        }
1500        if ((useDIVING&32) != 0) {
1501            CbcHeuristicDivePseudoCost heuristicDP(*model);
1502            heuristicDP.setHeuristicName("DivePseudoCost");
1503            heuristicDP.setWhen(diveOptions + diveOptions2);
1504            model->addHeuristic(&heuristicDP) ;
1505        }
1506        anyToDo = true;
1507    }
1508#ifdef JJF_ZERO
1509    if (usePivotC >= type && usePivotC <= kType + 1) {
1510        CbcHeuristicPivotAndComplement heuristic(*model);
1511        heuristic.setHeuristicName("pivot and complement");
1512        heuristic.setFractionSmall(10.0); // normally 0.5
1513        model->addHeuristic(&heuristic);
1514        anyToDo = true;
1515    }
1516#endif
1517    if (usePivotF >= type && usePivotF <= kType + 1) {
1518        CbcHeuristicPivotAndFix heuristic(*model);
1519        heuristic.setHeuristicName("pivot and fix");
1520        heuristic.setFractionSmall(10.0); // normally 0.5
1521        model->addHeuristic(&heuristic);
1522        anyToDo = true;
1523    }
1524    if (useRand >= type && useRand <= kType + 1) {
1525        CbcHeuristicRandRound heuristic(*model);
1526        heuristic.setHeuristicName("randomized rounding");
1527        heuristic.setFractionSmall(10.0); // normally 0.5
1528        model->addHeuristic(&heuristic);
1529        anyToDo = true;
1530    }
1531    if (useDINS >= kType && useDINS <= kType + 1) {
1532        CbcHeuristicDINS heuristic5a(*model);
1533        heuristic5a.setHeuristicName("DINS");
1534        heuristic5a.setFractionSmall(0.6);
1535        if (useDINS < 4)
1536            heuristic5a.setDecayFactor(5.0);
1537        else
1538            heuristic5a.setDecayFactor(1.5);
1539        heuristic5a.setNumberNodes(1000);
1540        model->addHeuristic(&heuristic5a) ;
1541        anyToDo = true;
1542    }
1543    if (useRINS >= kType && useRINS <= kType + 1) {
1544        CbcHeuristicRINS heuristic5(*model);
1545        heuristic5.setHeuristicName("RINS");
1546        if (useRINS < 4) {
1547            heuristic5.setFractionSmall(0.5);
1548            heuristic5.setDecayFactor(5.0);
1549        } else {
1550            heuristic5.setFractionSmall(0.6);
1551            heuristic5.setDecayFactor(1.5);
1552        }
1553        model->addHeuristic(&heuristic5) ;
1554        anyToDo = true;
1555    }
1556    if (useCombine >= kType && useCombine <= kType + 1) {
1557        CbcHeuristicLocal heuristic2(*model);
1558        heuristic2.setHeuristicName("combine solutions");
1559        heuristic2.setFractionSmall(0.5);
1560        heuristic2.setSearchType(1);
1561        model->addHeuristic(&heuristic2);
1562        anyToDo = true;
1563    }
1564    if ((useProximity >= kType && useProximity <= kType + 1)||
1565        (kType == 1 && useProximity >= 4)) {
1566        CbcHeuristicProximity heuristic2a(*model);
1567        heuristic2a.setHeuristicName("Proximity Search");
1568        heuristic2a.setFractionSmall(9999999.0);
1569        heuristic2a.setNumberNodes(30);
1570        heuristic2a.setFeasibilityPumpOptions(-2);
1571        if (useProximity>=4) {
1572          const int nodes[]={10,100,300};
1573          heuristic2a.setNumberNodes(nodes[useProximity-4]);
1574          // more print out and stronger feasibility pump
1575          if (useProximity==6)
1576            heuristic2a.setFeasibilityPumpOptions(-3);
1577        }
1578        model->addHeuristic(&heuristic2a);
1579        anyToDo = true;
1580    }
1581    if (useCrossover >= kType && useCrossover <= kType + 1) {
1582        CbcHeuristicCrossover heuristic2a(*model);
1583        heuristic2a.setHeuristicName("crossover");
1584        heuristic2a.setFractionSmall(0.3);
1585        // just fix at lower
1586        heuristic2a.setWhen(11);
1587        model->addHeuristic(&heuristic2a);
1588        model->setMaximumSavedSolutions(5);
1589        anyToDo = true;
1590    }
1591    int heurSwitches = parameters_[whichParam(CBC_PARAM_INT_HOPTIONS, numberParameters_, parameters_)].intValue() % 100;
1592    if (heurSwitches) {
1593        for (int iHeur = 0; iHeur < model->numberHeuristics(); iHeur++) {
1594            CbcHeuristic * heuristic = model->heuristic(iHeur);
1595            heuristic->setSwitches(heurSwitches);
1596        }
1597    }
1598    if (type == 2 && anyToDo) {
1599        // Do heuristics
1600#ifndef JJF_ONE
1601        // clean copy
1602        CbcModel model2(*model);
1603        // But get rid of heuristics in model
1604        model->doHeuristicsAtRoot(2);
1605        if (logLevel <= 1)
1606            model2.solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
1607        OsiBabSolver defaultC;
1608        //solver_->setAuxiliaryInfo(&defaultC);
1609        model2.passInSolverCharacteristics(&defaultC);
1610        // Save bounds
1611        int numberColumns = model2.solver()->getNumCols();
1612        model2.createContinuousSolver();
1613        bool cleanModel = !model2.numberIntegers() && !model2.numberObjects();
1614        model2.findIntegers(false);
1615        int heurOptions = (parameters_[whichParam(CBC_PARAM_INT_HOPTIONS, numberParameters_, parameters_)].intValue() / 100) % 100;
1616        if (heurOptions == 0 || heurOptions == 2) {
1617            model2.doHeuristicsAtRoot(1);
1618        } else if (heurOptions == 1 || heurOptions == 3) {
1619            model2.setMaximumNodes(-1);
1620            CbcStrategyDefault strategy(0, 5, 5);
1621            strategy.setupPreProcessing(1, 0);
1622            model2.setStrategy(strategy);
1623            model2.branchAndBound();
1624        }
1625        if (cleanModel)
1626            model2.zapIntegerInformation(false);
1627        if (model2.bestSolution()) {
1628            double value = model2.getMinimizationObjValue();
1629            model->setCutoff(value);
1630            model->setBestSolution(model2.bestSolution(), numberColumns, value);
1631            model->setSolutionCount(1);
1632            model->setNumberHeuristicSolutions(1);
1633        }
1634#else
1635        if (logLevel <= 1)
1636            model->solver()->setHintParam(OsiDoReducePrint, true, OsiHintTry);
1637        OsiBabSolver defaultC;
1638        //solver_->setAuxiliaryInfo(&defaultC);
1639        model->passInSolverCharacteristics(&defaultC);
1640        // Save bounds
1641        int numberColumns = model->solver()->getNumCols();
1642        model->createContinuousSolver();
1643        bool cleanModel = !model->numberIntegers() && !model->numberObjects();
1644        model->findIntegers(false);
1645        model->doHeuristicsAtRoot(1);
1646        if (cleanModel)
1647            model->zapIntegerInformation(false);
1648#endif
1649        return 0;
1650    } else {
1651        return 0;
1652    }
1653}
1654
Note: See TracBrowser for help on using the repository browser.