source: branches/sandbox/Cbc/src/CbcModel.cpp @ 1387

Last change on this file since 1387 was 1387, checked in by lou, 10 years ago

This commit removes remaining code associated with NEW_STYLE_SOLVER. See the notes in CbcLinkedUtils? for why the remaining code remains.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 714.4 KB
Line 
1/* $Id: CbcModel.cpp 1387 2009-12-09 21:46:30Z lou $ */
2// Copyright (C) 2002, International Business Machines
3// Corporation and others.  All Rights Reserved.
4#if defined(_MSC_VER)
5// Turn off compiler warning about long names
6#  pragma warning(disable:4786)
7#endif
8
9#include "CbcConfig.h"
10
11#include <string>
12//#define CBC_DEBUG 1
13//#define CHECK_CUT_COUNTS
14//#define CHECK_NODE_FULL
15//#define NODE_LOG
16//#define GLOBAL_CUTS_JUST_POINTERS
17#ifdef CGL_DEBUG_GOMORY
18extern int gomory_try;
19#endif
20#include <cassert>
21#include <cmath>
22#include <cfloat>
23
24#ifdef COIN_HAS_CLP
25// include Presolve from Clp
26#include "ClpPresolve.hpp"
27#include "OsiClpSolverInterface.hpp"
28#include "ClpNode.hpp"
29#include "ClpDualRowDantzig.hpp"
30#include "ClpSimplexPrimal.hpp"
31#endif
32
33#include "CbcEventHandler.hpp"
34
35#include "OsiSolverInterface.hpp"
36#include "OsiAuxInfo.hpp"
37#include "OsiSolverBranch.hpp"
38#include "OsiChooseVariable.hpp"
39#include "CoinWarmStartBasis.hpp"
40#include "CoinPackedMatrix.hpp"
41#include "CoinHelperFunctions.hpp"
42#include "CbcBranchActual.hpp"
43#include "CbcBranchDynamic.hpp"
44#include "CbcHeuristic.hpp"
45#include "CbcHeuristicFPump.hpp"
46#include "CbcHeuristicRINS.hpp"
47#include "CbcHeuristicDive.hpp"
48#include "CbcModel.hpp"
49#include "CbcTreeLocal.hpp"
50#include "CbcStatistics.hpp"
51#include "CbcStrategy.hpp"
52#include "CbcMessage.hpp"
53#include "OsiRowCut.hpp"
54#include "OsiColCut.hpp"
55#include "OsiRowCutDebugger.hpp"
56#include "OsiCuts.hpp"
57#include "CbcCountRowCut.hpp"
58#include "CbcCutGenerator.hpp"
59#include "CbcFeasibilityBase.hpp"
60#include "CbcFathom.hpp"
61// include Probing
62#include "CglProbing.hpp"
63#include "CglGomory.hpp"
64#include "CglTwomir.hpp"
65// include preprocessing
66#include "CglPreProcess.hpp"
67#include "CglDuplicateRow.hpp"
68#include "CglStored.hpp"
69#include "CglClique.hpp"
70
71#include "CoinTime.hpp"
72#include "CoinMpsIO.hpp"
73
74#include "CbcCompareActual.hpp"
75#include "CbcTree.hpp"
76#ifdef CBC_THREAD
77#include <pthread.h>
78#ifdef HAVE_CLOCK_GETTIME
79inline int my_gettime(struct timespec* tp)
80{
81    return clock_gettime(CLOCK_REALTIME, tp);
82}
83#else
84#ifndef _MSC_VER
85inline int my_gettime(struct timespec* tp)
86{
87    struct timeval tv;
88    int ret = gettimeofday(&tv, NULL);
89    tp->tv_sec = tv.tv_sec;
90    tp->tv_nsec = tv.tv_usec * 1000;
91    return ret;
92}
93#else
94inline int my_gettime(struct timespec* tp)
95{
96    double t = CoinGetTimeOfDay();
97    tp->tv_sec = (int)floor(t);
98    tp->tv_nsec = (int)((tp->tv_sec - floor(t)) / 1000000.0);
99    return 0;
100}
101#endif
102#endif
103
104struct Coin_pthread_t {
105    pthread_t   thr;
106    long                status;
107};
108
109// To Pass across to doOneNode
110typedef struct {
111    CbcModel * baseModel;
112    CbcModel * thisModel;
113    CbcNode * node; // filled in every time
114    CbcNode * createdNode; // filled in every time on return
115    Coin_pthread_t threadIdOfBase;
116    pthread_mutex_t * mutex; // for locking data
117    pthread_mutex_t * mutex2; // for waking up threads
118    pthread_cond_t * condition2; // for waking up thread
119    int returnCode; // -1 available, 0 busy, 1 finished , 2??
120    double timeLocked;
121    double timeWaitingToLock;
122    double timeWaitingToStart;
123    double timeInThread;
124    int numberTimesLocked;
125    int numberTimesUnlocked;
126    int numberTimesWaitingToStart;
127    int saveStuff[2];
128    int dantzigState; // 0 unset, -1 waiting to be set, 1 set
129    struct timespec absTime;
130    bool locked;
131    int nDeleteNode;
132    CbcNode ** delNode;
133    int maxDeleteNode;
134    int nodesThisTime;
135    int iterationsThisTime;
136} threadStruct;
137static void * doNodesThread(void * voidInfo);
138static void * doCutsThread(void * voidInfo);
139static void * doHeurThread(void * voidInfo);
140#endif
141/* Various functions local to CbcModel.cpp */
142
143namespace {
144
145//-------------------------------------------------------------------
146// Returns the greatest common denominator of two
147// positive integers, a and b, found using Euclid's algorithm
148//-------------------------------------------------------------------
149static int gcd(int a, int b)
150{
151    int remainder = -1;
152    // make sure a<=b (will always remain so)
153    if (a > b) {
154        // Swap a and b
155        int temp = a;
156        a = b;
157        b = temp;
158    }
159    // if zero then gcd is nonzero (zero may occur in rhs of packed)
160    if (!a) {
161        if (b) {
162            return b;
163        } else {
164            printf("**** gcd given two zeros!!\n");
165            abort();
166        }
167    }
168    while (remainder) {
169        remainder = b % a;
170        b = a;
171        a = remainder;
172    }
173    return b;
174}
175
176
177
178#ifdef CHECK_NODE_FULL
179
180/*
181  Routine to verify that tree linkage is correct. The invariant that is tested
182  is
183
184  reference count = (number of actual references) + (number of branches left)
185
186  The routine builds a set of paired arrays, info and count, by traversing the
187  tree. Each CbcNodeInfo is recorded in info, and the number of times it is
188  referenced (via the parent field) is recorded in count. Then a final check is
189  made to see if the numberPointingToThis_ field agrees.
190*/
191
192void verifyTreeNodes (const CbcTree * branchingTree, const CbcModel &model)
193
194{
195    if (model.getNodeCount() == 661) return;
196    printf("*** CHECKING tree after %d nodes\n", model.getNodeCount()) ;
197
198    int j ;
199    int nNodes = branchingTree->size() ;
200# define MAXINFO 1000
201    int *count = new int [MAXINFO] ;
202    CbcNodeInfo **info = new CbcNodeInfo*[MAXINFO] ;
203    int nInfo = 0 ;
204    /*
205      Collect all CbcNodeInfo objects in info, by starting from each live node and
206      traversing back to the root. Nodes in the live set should have unexplored
207      branches remaining.
208
209      TODO: The `while (nodeInfo)' loop could be made to break on reaching a
210        common ancester (nodeInfo is found in info[k]). Alternatively, the
211        check could change to signal an error if nodeInfo is not found above a
212        common ancestor.
213    */
214    for (j = 0 ; j < nNodes ; j++) {
215        CbcNode *node = branchingTree->nodePointer(j) ;
216        if (!node)
217            continue;
218        CbcNodeInfo *nodeInfo = node->nodeInfo() ;
219        int change = node->nodeInfo()->numberBranchesLeft() ;
220        assert(change) ;
221        while (nodeInfo) {
222            int k ;
223            for (k = 0 ; k < nInfo ; k++) {
224                if (nodeInfo == info[k]) break ;
225            }
226            if (k == nInfo) {
227                assert(nInfo < MAXINFO) ;
228                nInfo++ ;
229                info[k] = nodeInfo ;
230                count[k] = 0 ;
231            }
232            nodeInfo = nodeInfo->parent() ;
233        }
234    }
235    /*
236      Walk the info array. For each nodeInfo, look up its parent in info and
237      increment the corresponding count.
238    */
239    for (j = 0 ; j < nInfo ; j++) {
240        CbcNodeInfo *nodeInfo = info[j] ;
241        nodeInfo = nodeInfo->parent() ;
242        if (nodeInfo) {
243            int k ;
244            for (k = 0 ; k < nInfo ; k++) {
245                if (nodeInfo == info[k]) break ;
246            }
247            assert (k < nInfo) ;
248            count[k]++ ;
249        }
250    }
251    /*
252      Walk the info array one more time and check that the invariant holds. The
253      number of references (numberPointingToThis()) should equal the sum of the
254      number of actual references (held in count[]) plus the number of potential
255      references (unexplored branches, numberBranchesLeft()).
256    */
257    for (j = 0; j < nInfo; j++) {
258        CbcNodeInfo * nodeInfo = info[j] ;
259        if (nodeInfo) {
260            int k ;
261            for (k = 0; k < nInfo; k++)
262                if (nodeInfo == info[k])
263                    break ;
264            printf("Nodeinfo %x - %d left, %d count\n",
265                   nodeInfo,
266                   nodeInfo->numberBranchesLeft(),
267                   nodeInfo->numberPointingToThis()) ;
268            assert(nodeInfo->numberPointingToThis() ==
269                   count[k] + nodeInfo->numberBranchesLeft()) ;
270        }
271    }
272
273    delete [] count ;
274    delete [] info ;
275
276    return ;
277}
278
279#endif  /* CHECK_NODE_FULL */
280
281
282
283#ifdef CHECK_CUT_COUNTS
284
285/*
286  Routine to verify that cut reference counts are correct.
287*/
288void verifyCutCounts (const CbcTree * branchingTree, CbcModel &model)
289
290{
291    printf("*** CHECKING cuts after %d nodes\n", model.getNodeCount()) ;
292
293    int j ;
294    int nNodes = branchingTree->size() ;
295
296    /*
297      cut.tempNumber_ exists for the purpose of doing this verification. Clear it
298      in all cuts. We traverse the tree by starting from each live node and working
299      back to the root. At each CbcNodeInfo, check for cuts.
300    */
301    for (j = 0 ; j < nNodes ; j++) {
302        CbcNode *node = branchingTree->nodePointer(j) ;
303        CbcNodeInfo * nodeInfo = node->nodeInfo() ;
304        assert (node->nodeInfo()->numberBranchesLeft()) ;
305        while (nodeInfo) {
306            int k ;
307            for (k = 0 ; k < nodeInfo->numberCuts() ; k++) {
308                CbcCountRowCut *cut = nodeInfo->cuts()[k] ;
309                if (cut) cut->tempNumber_ = 0;
310            }
311            nodeInfo = nodeInfo->parent() ;
312        }
313    }
314    /*
315      Walk the live set again, this time collecting the list of cuts in use at each
316      node. addCuts1 will collect the cuts in model.addedCuts_. Take into account
317      that when we recreate the basis for a node, we compress out the slack cuts.
318    */
319    for (j = 0 ; j < nNodes ; j++) {
320        CoinWarmStartBasis *debugws = model.getEmptyBasis() ;
321        CbcNode *node = branchingTree->nodePointer(j) ;
322        CbcNodeInfo *nodeInfo = node->nodeInfo();
323        int change = node->nodeInfo()->numberBranchesLeft() ;
324        printf("Node %d %x (info %x) var %d way %d obj %g", j, node,
325               node->nodeInfo(), node->columnNumber(), node->way(),
326               node->objectiveValue()) ;
327
328        model.addCuts1(node, debugws) ;
329
330        int i ;
331        int numberRowsAtContinuous = model.numberRowsAtContinuous() ;
332        CbcCountRowCut **addedCuts = model.addedCuts() ;
333        for (i = 0 ; i < model.currentNumberCuts() ; i++) {
334            CoinWarmStartBasis::Status status =
335                debugws->getArtifStatus(i + numberRowsAtContinuous) ;
336            if (status != CoinWarmStartBasis::basic && addedCuts[i]) {
337                addedCuts[i]->tempNumber_ += change ;
338            }
339        }
340
341        while (nodeInfo) {
342            nodeInfo = nodeInfo->parent() ;
343            if (nodeInfo) printf(" -> %x", nodeInfo);
344        }
345        printf("\n") ;
346        delete debugws ;
347    }
348    /*
349      The moment of truth: We've tallied up the references by direct scan of the  search tree. Check for agreement with the count in the cut.
350
351      TODO: Rewrite to check and print mismatch only when tempNumber_ == 0?
352    */
353    for (j = 0 ; j < nNodes ; j++) {
354        CbcNode *node = branchingTree->nodePointer(j) ;
355        CbcNodeInfo *nodeInfo = node->nodeInfo();
356        while (nodeInfo) {
357            int k ;
358            for (k = 0 ; k < nodeInfo->numberCuts() ; k++) {
359                CbcCountRowCut *cut = nodeInfo->cuts()[k] ;
360                if (cut && cut->tempNumber_ >= 0) {
361                    if (cut->tempNumber_ != cut->numberPointingToThis())
362                        printf("mismatch %x %d %x %d %d\n", nodeInfo, k,
363                               cut, cut->tempNumber_, cut->numberPointingToThis()) ;
364                    else
365                        printf("   match %x %d %x %d %d\n", nodeInfo, k,
366                               cut, cut->tempNumber_, cut->numberPointingToThis()) ;
367                    cut->tempNumber_ = -1 ;
368                }
369            }
370            nodeInfo = nodeInfo->parent() ;
371        }
372    }
373
374    return ;
375}
376
377#endif /* CHECK_CUT_COUNTS */
378
379
380#ifdef CHECK_CUT_SIZE
381
382/*
383  Routine to verify that cut reference counts are correct.
384*/
385void verifyCutSize (const CbcTree * branchingTree, CbcModel &model)
386{
387
388    int j ;
389    int nNodes = branchingTree->size() ;
390    int totalCuts = 0;
391
392    /*
393      cut.tempNumber_ exists for the purpose of doing this verification. Clear it
394      in all cuts. We traverse the tree by starting from each live node and working
395      back to the root. At each CbcNodeInfo, check for cuts.
396    */
397    for (j = 0 ; j < nNodes ; j++) {
398        CbcNode *node = branchingTree->nodePointer(j) ;
399        CbcNodeInfo * nodeInfo = node->nodeInfo() ;
400        assert (node->nodeInfo()->numberBranchesLeft()) ;
401        while (nodeInfo) {
402            totalCuts += nodeInfo->numberCuts();
403            nodeInfo = nodeInfo->parent() ;
404        }
405    }
406    printf("*** CHECKING cuts (size) after %d nodes - %d cuts\n", model.getNodeCount(), totalCuts) ;
407    return ;
408}
409
410#endif /* CHECK_CUT_SIZE */
411
412}
413
414/* End unnamed namespace for CbcModel.cpp */
415
416
417void
418CbcModel::analyzeObjective ()
419/*
420  Try to find a minimum change in the objective function. The first scan
421  checks that there are no continuous variables with non-zero coefficients,
422  and grabs the largest objective coefficient associated with an unfixed
423  integer variable. The second scan attempts to scale up the objective
424  coefficients to a point where they are sufficiently close to integer that
425  we can pretend they are integer, and calculate a gcd over the coefficients
426  of interest. This will be the minimum increment for the scaled coefficients.
427  The final action is to scale the increment back for the original coefficients
428  and install it, if it's better than the existing value.
429
430  John's note: We could do better than this.
431
432  John's second note - apologies for changing s to z
433*/
434{
435    const double *objective = getObjCoefficients() ;
436    const double *lower = getColLower() ;
437    const double *upper = getColUpper() ;
438    /*
439      Scan continuous and integer variables to see if continuous
440      are cover or network with integral rhs.
441    */
442    double continuousMultiplier = 1.0;
443    double * coeffMultiplier = NULL;
444    double largestObj = 0.0;
445    double smallestObj = COIN_DBL_MAX;
446    {
447        const double *rowLower = getRowLower() ;
448        const double *rowUpper = getRowUpper() ;
449        int numberRows = solver_->getNumRows() ;
450        double * rhs = new double [numberRows];
451        memset(rhs, 0, numberRows*sizeof(double));
452        int iColumn;
453        int numberColumns = solver_->getNumCols() ;
454        // Column copy of matrix
455        bool allPlusOnes = true;
456        bool allOnes = true;
457        int problemType = -1;
458        const double * element = solver_->getMatrixByCol()->getElements();
459        const int * row = solver_->getMatrixByCol()->getIndices();
460        const CoinBigIndex * columnStart = solver_->getMatrixByCol()->getVectorStarts();
461        const int * columnLength = solver_->getMatrixByCol()->getVectorLengths();
462        int numberInteger = 0;
463        int numberIntegerObj = 0;
464        int numberGeneralIntegerObj = 0;
465        int numberIntegerWeight = 0;
466        int numberContinuousObj = 0;
467        double cost = COIN_DBL_MAX;
468        for (iColumn = 0; iColumn < numberColumns; iColumn++) {
469            if (upper[iColumn] == lower[iColumn]) {
470                CoinBigIndex start = columnStart[iColumn];
471                CoinBigIndex end = start + columnLength[iColumn];
472                for (CoinBigIndex j = start; j < end; j++) {
473                    int iRow = row[j];
474                    rhs[iRow] += lower[iColumn] * element[j];
475                }
476            } else {
477                double objValue = objective[iColumn];
478                if (solver_->isInteger(iColumn))
479                    numberInteger++;
480                if (objValue) {
481                    if (!solver_->isInteger(iColumn)) {
482                        numberContinuousObj++;
483                    } else {
484                        largestObj = CoinMax(largestObj, fabs(objValue));
485                        smallestObj = CoinMin(smallestObj, fabs(objValue));
486                        numberIntegerObj++;
487                        if (cost == COIN_DBL_MAX)
488                            cost = objValue;
489                        else if (cost != objValue)
490                            cost = -COIN_DBL_MAX;
491                        int gap = static_cast<int> (upper[iColumn] - lower[iColumn]);
492                        if (gap > 1) {
493                            numberGeneralIntegerObj++;
494                            numberIntegerWeight += gap;
495                        }
496                    }
497                }
498            }
499        }
500        int iType = 0;
501        if (!numberContinuousObj && numberIntegerObj <= 5 && numberIntegerWeight <= 100 &&
502                numberIntegerObj*3 < numberObjects_ && !parentModel_ && solver_->getNumRows() > 100)
503            iType = 3 + 4;
504        else if (!numberContinuousObj && numberIntegerObj <= 100 &&
505                 numberIntegerObj*5 < numberObjects_ && numberIntegerWeight <= 100 &&
506                 !parentModel_ &&
507                 solver_->getNumRows() > 100 && cost != -COIN_DBL_MAX)
508            iType = 2 + 4;
509        else if (!numberContinuousObj && numberIntegerObj <= 100 &&
510                 numberIntegerObj*5 < numberObjects_ &&
511                 !parentModel_ &&
512                 solver_->getNumRows() > 100 && cost != -COIN_DBL_MAX)
513            iType = 8;
514        int iTest = getMaximumNodes();
515        if (iTest >= 987654320 && iTest < 987654330 && numberObjects_ && !parentModel_) {
516            iType = iTest - 987654320;
517            printf("Testing %d integer variables out of %d objects (%d integer) have cost of %g - %d continuous\n",
518                   numberIntegerObj, numberObjects_, numberInteger, cost, numberContinuousObj);
519            if (iType == 9)
520                exit(77);
521            if (numberContinuousObj)
522                iType = 0;
523        }
524
525        //if (!numberContinuousObj&&(numberIntegerObj<=5||cost!=-COIN_DBL_MAX)&&
526        //numberIntegerObj*3<numberObjects_&&!parentModel_&&solver_->getNumRows()>100) {
527        if (iType) {
528            /*
529            A) put high priority on (if none)
530            B) create artificial objective (if clp)
531            */
532            int iPriority = -1;
533            for (int i = 0; i < numberObjects_; i++) {
534                int k = object_[i]->priority();
535                if (iPriority == -1)
536                    iPriority = k;
537                else if (iPriority != k)
538                    iPriority = -2;
539            }
540            bool branchOnSatisfied = ((iType & 1) != 0);
541            bool createFake = ((iType & 2) != 0);
542            bool randomCost = ((iType & 4) != 0);
543            if (iPriority >= 0) {
544                char general[200];
545                if (cost == -COIN_DBL_MAX) {
546                    sprintf(general, "%d integer variables out of %d objects (%d integer) have costs - high priority",
547                            numberIntegerObj, numberObjects_, numberInteger);
548                } else if (cost == COIN_DBL_MAX) {
549                    sprintf(general, "No integer variables out of %d objects (%d integer) have costs",
550                            numberObjects_, numberInteger);
551                    branchOnSatisfied = false;
552                } else {
553                    sprintf(general, "%d integer variables out of %d objects (%d integer) have cost of %g - high priority",
554                            numberIntegerObj, numberObjects_, numberInteger, cost);
555                }
556                messageHandler()->message(CBC_GENERAL,
557                                          messages())
558                << general << CoinMessageEol ;
559                sprintf(general, "branch on satisfied %c create fake objective %c random cost %c",
560                        branchOnSatisfied ? 'Y' : 'N',
561                        createFake ? 'Y' : 'N',
562                        randomCost ? 'Y' : 'N');
563                messageHandler()->message(CBC_GENERAL,
564                                          messages())
565                << general << CoinMessageEol ;
566                // switch off clp type branching
567                fastNodeDepth_ = -1;
568                int highPriority = (branchOnSatisfied) ? -999 : 100;
569                for (int i = 0; i < numberObjects_; i++) {
570                    CbcSimpleInteger * thisOne = dynamic_cast <CbcSimpleInteger *> (object_[i]);
571                    object_[i]->setPriority(1000);
572                    if (thisOne) {
573                        int iColumn = thisOne->columnNumber();
574                        if (objective[iColumn])
575                            thisOne->setPriority(highPriority);
576                    }
577                }
578            }
579#ifdef COIN_HAS_CLP
580            OsiClpSolverInterface * clpSolver
581            = dynamic_cast<OsiClpSolverInterface *> (solver_);
582            if (clpSolver && createFake) {
583                // Create artificial objective to be used when all else fixed
584                int numberColumns = clpSolver->getNumCols();
585                double * fakeObj = new double [numberColumns];
586                // Column copy
587                const CoinPackedMatrix  * matrixByCol = clpSolver->getMatrixByCol();
588                //const double * element = matrixByCol.getElements();
589                //const int * row = matrixByCol.getIndices();
590                //const CoinBigIndex * columnStart = matrixByCol.getVectorStarts();
591                const int * columnLength = matrixByCol->getVectorLengths();
592                const double * solution = clpSolver->getColSolution();
593#if 0
594                int nAtBound = 0;
595                for (int i = 0; i < numberColumns; i++) {
596                    double lowerValue = lower[i];
597                    double upperValue = upper[i];
598                    if (clpSolver->isInteger(i)) {
599                        double lowerValue = lower[i];
600                        double upperValue = upper[i];
601                        double value = solution[i];
602                        if (value < lowerValue + 1.0e-6 ||
603                                value > upperValue - 1.0e-6)
604                            nAtBound++;
605                    }
606                }
607#endif
608/*
609  Generate a random objective function for problems where the given objective
610  function is not terribly useful. (Nearly feasible, single integer variable,
611  that sort of thing.
612*/
613                CoinDrand48(true, 1234567);
614                for (int i = 0; i < numberColumns; i++) {
615                    double lowerValue = lower[i];
616                    double upperValue = upper[i];
617                    double value = (randomCost) ? ceil((CoinDrand48() + 0.5) * 1000)
618                                   : i + 1 + columnLength[i] * 1000;
619                    value *= 0.001;
620                    //value += columnLength[i];
621                    if (lowerValue > -1.0e5 || upperValue < 1.0e5) {
622                        if (fabs(lowerValue) > fabs(upperValue))
623                            value = - value;
624                        if (clpSolver->isInteger(i)) {
625                            double solValue = solution[i];
626                            // Better to add in 0.5 or 1.0??
627                            if (solValue < lowerValue + 1.0e-6)
628                                value = fabs(value) + 0.5; //fabs(value*1.5);
629                            else if (solValue > upperValue - 1.0e-6)
630                                value = -fabs(value) - 0.5; //-fabs(value*1.5);
631                        }
632                    } else {
633                        value = 0.0;
634                    }
635                    fakeObj[i] = value;
636                }
637                // pass to solver
638                clpSolver->setFakeObjective(fakeObj);
639                delete [] fakeObj;
640            }
641#endif
642        } else if (largestObj < smallestObj*5.0 && !parentModel_ &&
643                   !numberContinuousObj &&
644                   !numberGeneralIntegerObj &&
645                   numberIntegerObj*2 < numberColumns) {
646            // up priorities on costed
647            int iPriority = -1;
648            for (int i = 0; i < numberObjects_; i++) {
649                int k = object_[i]->priority();
650                if (iPriority == -1)
651                    iPriority = k;
652                else if (iPriority != k)
653                    iPriority = -2;
654            }
655            if (iPriority >= 100) {
656#ifdef CLP_INVESTIGATE
657                printf("Setting variables with obj to high priority\n");
658#endif
659                for (int i = 0; i < numberObjects_; i++) {
660                    CbcSimpleInteger * obj =
661                        dynamic_cast <CbcSimpleInteger *>(object_[i]) ;
662                    if (obj) {
663                        int iColumn = obj->columnNumber();
664                        if (objective[iColumn])
665                            object_[i]->setPriority(iPriority - 1);
666                    }
667                }
668            }
669        }
670        int iRow;
671        for (iRow = 0; iRow < numberRows; iRow++) {
672            if (rowLower[iRow] > -1.0e20 &&
673                    fabs(rowLower[iRow] - rhs[iRow] - floor(rowLower[iRow] - rhs[iRow] + 0.5)) > 1.0e-10) {
674                continuousMultiplier = 0.0;
675                break;
676            }
677            if (rowUpper[iRow] < 1.0e20 &&
678                    fabs(rowUpper[iRow] - rhs[iRow] - floor(rowUpper[iRow] - rhs[iRow] + 0.5)) > 1.0e-10) {
679                continuousMultiplier = 0.0;
680                break;
681            }
682            // set rhs to limiting value
683            if (rowLower[iRow] != rowUpper[iRow]) {
684                if (rowLower[iRow] > -1.0e20) {
685                    if (rowUpper[iRow] < 1.0e20) {
686                        // no good
687                        continuousMultiplier = 0.0;
688                        break;
689                    } else {
690                        rhs[iRow] = rowLower[iRow] - rhs[iRow];
691                        if (problemType < 0)
692                            problemType = 3; // set cover
693                        else if (problemType != 3)
694                            problemType = 4;
695                    }
696                } else {
697                    rhs[iRow] = rowUpper[iRow] - rhs[iRow];
698                    if (problemType < 0)
699                        problemType = 1; // set partitioning <=
700                    else if (problemType != 1)
701                        problemType = 4;
702                }
703            } else {
704                rhs[iRow] = rowUpper[iRow] - rhs[iRow];
705                if (problemType < 0)
706                    problemType = 3; // set partitioning ==
707                else if (problemType != 2)
708                    problemType = 2;
709            }
710            if (fabs(rhs[iRow] - 1.0) > 1.0e-12)
711                problemType = 4;
712        }
713        if (continuousMultiplier) {
714            // 1 network, 2 cover, 4 negative cover
715            int possible = 7;
716            bool unitRhs = true;
717            // See which rows could be set cover
718            for (iColumn = 0; iColumn < numberColumns; iColumn++) {
719                if (upper[iColumn] > lower[iColumn] + 1.0e-8) {
720                    CoinBigIndex start = columnStart[iColumn];
721                    CoinBigIndex end = start + columnLength[iColumn];
722                    for (CoinBigIndex j = start; j < end; j++) {
723                        double value = element[j];
724                        if (value == 1.0) {
725                        } else if (value == -1.0) {
726                            rhs[row[j]] = -0.5;
727                            allPlusOnes = false;
728                        } else {
729                            rhs[row[j]] = -COIN_DBL_MAX;
730                            allOnes = false;
731                        }
732                    }
733                }
734            }
735            for (iColumn = 0; iColumn < numberColumns; iColumn++) {
736                if (upper[iColumn] > lower[iColumn] + 1.0e-8) {
737                    if (!isInteger(iColumn)) {
738                        CoinBigIndex start = columnStart[iColumn];
739                        CoinBigIndex end = start + columnLength[iColumn];
740                        double rhsValue = 0.0;
741                        // 1 all ones, -1 all -1s, 2 all +- 1, 3 no good
742                        int type = 0;
743                        for (CoinBigIndex j = start; j < end; j++) {
744                            double value = element[j];
745                            if (fabs(value) != 1.0) {
746                                type = 3;
747                                break;
748                            } else if (value == 1.0) {
749                                if (!type)
750                                    type = 1;
751                                else if (type != 1)
752                                    type = 2;
753                            } else {
754                                if (!type)
755                                    type = -1;
756                                else if (type != -1)
757                                    type = 2;
758                            }
759                            int iRow = row[j];
760                            if (rhs[iRow] == -COIN_DBL_MAX) {
761                                type = 3;
762                                break;
763                            } else if (rhs[iRow] == -0.5) {
764                                // different values
765                                unitRhs = false;
766                            } else if (rhsValue) {
767                                if (rhsValue != rhs[iRow])
768                                    unitRhs = false;
769                            } else {
770                                rhsValue = rhs[iRow];
771                            }
772                        }
773                        // if no elements OK
774                        if (type == 3) {
775                            // no good
776                            possible = 0;
777                            break;
778                        } else if (type == 2) {
779                            if (end - start > 2) {
780                                // no good
781                                possible = 0;
782                                break;
783                            } else {
784                                // only network
785                                possible &= 1;
786                                if (!possible)
787                                    break;
788                            }
789                        } else if (type == 1) {
790                            // only cover
791                            possible &= 2;
792                            if (!possible)
793                                break;
794                        } else if (type == -1) {
795                            // only negative cover
796                            possible &= 4;
797                            if (!possible)
798                                break;
799                        }
800                    }
801                }
802            }
803            if ((possible == 2 || possible == 4) && !unitRhs) {
804#if COIN_DEVELOP>1
805                printf("XXXXXX Continuous all +1 but different rhs\n");
806#endif
807                possible = 0;
808            }
809            // may be all integer
810            if (possible != 7) {
811                if (!possible)
812                    continuousMultiplier = 0.0;
813                else if (possible == 1)
814                    continuousMultiplier = 1.0;
815                else
816                    continuousMultiplier = 0.0; // 0.5 was incorrect;
817#if COIN_DEVELOP>1
818                if (continuousMultiplier)
819                    printf("XXXXXX multiplier of %g\n", continuousMultiplier);
820#endif
821                if (continuousMultiplier == 0.5) {
822                    coeffMultiplier = new double [numberColumns];
823                    bool allOne = true;
824                    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
825                        coeffMultiplier[iColumn] = 1.0;
826                        if (upper[iColumn] > lower[iColumn] + 1.0e-8) {
827                            if (!isInteger(iColumn)) {
828                                CoinBigIndex start = columnStart[iColumn];
829                                int iRow = row[start];
830                                double value = rhs[iRow];
831                                assert (value >= 0.0);
832                                if (value != 0.0 && value != 1.0)
833                                    allOne = false;
834                                coeffMultiplier[iColumn] = 0.5 * value;
835                            }
836                        }
837                    }
838                    if (allOne) {
839                        // back to old way
840                        delete [] coeffMultiplier;
841                        coeffMultiplier = NULL;
842                    }
843                }
844            } else {
845                // all integer
846                problemType_ = problemType;
847#if COIN_DEVELOP>1
848                printf("Problem type is %d\n", problemType_);
849#endif
850            }
851        }
852
853        // But try again
854        if (continuousMultiplier < 1.0) {
855            memset(rhs, 0, numberRows*sizeof(double));
856            int * count = new int [numberRows];
857            memset(count, 0, numberRows*sizeof(int));
858            for (iColumn = 0; iColumn < numberColumns; iColumn++) {
859                CoinBigIndex start = columnStart[iColumn];
860                CoinBigIndex end = start + columnLength[iColumn];
861                if (upper[iColumn] == lower[iColumn]) {
862                    for (CoinBigIndex j = start; j < end; j++) {
863                        int iRow = row[j];
864                        rhs[iRow] += lower[iColumn] * element[j];
865                    }
866                } else if (solver_->isInteger(iColumn)) {
867                    for (CoinBigIndex j = start; j < end; j++) {
868                        int iRow = row[j];
869                        if (fabs(element[j] - floor(element[j] + 0.5)) > 1.0e-10)
870                            rhs[iRow]  = COIN_DBL_MAX;
871                    }
872                } else {
873                    for (CoinBigIndex j = start; j < end; j++) {
874                        int iRow = row[j];
875                        count[iRow]++;
876                        if (fabs(element[j]) != 1.0)
877                            rhs[iRow]  = COIN_DBL_MAX;
878                    }
879                }
880            }
881            // now look at continuous
882            bool allGood = true;
883            double direction = solver_->getObjSense() ;
884            int numberObj = 0;
885            for (iColumn = 0; iColumn < numberColumns; iColumn++) {
886                if (upper[iColumn] > lower[iColumn]) {
887                    double objValue = objective[iColumn] * direction;
888                    if (objValue && !solver_->isInteger(iColumn)) {
889                        numberObj++;
890                        CoinBigIndex start = columnStart[iColumn];
891                        CoinBigIndex end = start + columnLength[iColumn];
892                        if (objValue > 0.0) {
893                            // wants to be as low as possible
894                            if (lower[iColumn] < -1.0e10 || fabs(lower[iColumn] - floor(lower[iColumn] + 0.5)) > 1.0e-10) {
895                                allGood = false;
896                                break;
897                            } else if (upper[iColumn] < 1.0e10 && fabs(upper[iColumn] - floor(upper[iColumn] + 0.5)) > 1.0e-10) {
898                                allGood = false;
899                                break;
900                            }
901                            bool singletonRow = true;
902                            bool equality = false;
903                            for (CoinBigIndex j = start; j < end; j++) {
904                                int iRow = row[j];
905                                if (count[iRow] > 1)
906                                    singletonRow = false;
907                                else if (rowLower[iRow] == rowUpper[iRow])
908                                    equality = true;
909                                double rhsValue = rhs[iRow];
910                                double lowerValue = rowLower[iRow];
911                                double upperValue = rowUpper[iRow];
912                                if (rhsValue < 1.0e20) {
913                                    if (lowerValue > -1.0e20)
914                                        lowerValue -= rhsValue;
915                                    if (upperValue < 1.0e20)
916                                        upperValue -= rhsValue;
917                                }
918                                if (fabs(rhsValue) > 1.0e20 || fabs(rhsValue - floor(rhsValue + 0.5)) > 1.0e-10
919                                        || fabs(element[j]) != 1.0) {
920                                    // no good
921                                    allGood = false;
922                                    break;
923                                }
924                                if (element[j] > 0.0) {
925                                    if (lowerValue > -1.0e20 && fabs(lowerValue - floor(lowerValue + 0.5)) > 1.0e-10) {
926                                        // no good
927                                        allGood = false;
928                                        break;
929                                    }
930                                } else {
931                                    if (upperValue < 1.0e20 && fabs(upperValue - floor(upperValue + 0.5)) > 1.0e-10) {
932                                        // no good
933                                        allGood = false;
934                                        break;
935                                    }
936                                }
937                            }
938                            if (!singletonRow && end > start + 1 && !equality)
939                                allGood = false;
940                            if (!allGood)
941                                break;
942                        } else {
943                            // wants to be as high as possible
944                            if (upper[iColumn] > 1.0e10 || fabs(upper[iColumn] - floor(upper[iColumn] + 0.5)) > 1.0e-10) {
945                                allGood = false;
946                                break;
947                            } else if (lower[iColumn] > -1.0e10 && fabs(lower[iColumn] - floor(lower[iColumn] + 0.5)) > 1.0e-10) {
948                                allGood = false;
949                                break;
950                            }
951                            bool singletonRow = true;
952                            bool equality = false;
953                            for (CoinBigIndex j = start; j < end; j++) {
954                                int iRow = row[j];
955                                if (count[iRow] > 1)
956                                    singletonRow = false;
957                                else if (rowLower[iRow] == rowUpper[iRow])
958                                    equality = true;
959                                double rhsValue = rhs[iRow];
960                                double lowerValue = rowLower[iRow];
961                                double upperValue = rowUpper[iRow];
962                                if (rhsValue < 1.0e20) {
963                                    if (lowerValue > -1.0e20)
964                                        lowerValue -= rhsValue;
965                                    if (upperValue < 1.0e20)
966                                        upperValue -= rhsValue;
967                                }
968                                if (fabs(rhsValue) > 1.0e20 || fabs(rhsValue - floor(rhsValue + 0.5)) > 1.0e-10
969                                        || fabs(element[j]) != 1.0) {
970                                    // no good
971                                    allGood = false;
972                                    break;
973                                }
974                                if (element[j] < 0.0) {
975                                    if (lowerValue > -1.0e20 && fabs(lowerValue - floor(lowerValue + 0.5)) > 1.0e-10) {
976                                        // no good
977                                        allGood = false;
978                                        break;
979                                    }
980                                } else {
981                                    if (upperValue < 1.0e20 && fabs(upperValue - floor(upperValue + 0.5)) > 1.0e-10) {
982                                        // no good
983                                        allGood = false;
984                                        break;
985                                    }
986                                }
987                            }
988                            if (!singletonRow && end > start + 1 && !equality)
989                                allGood = false;
990                            if (!allGood)
991                                break;
992                        }
993                    }
994                }
995            }
996            delete [] count;
997            if (allGood) {
998#if COIN_DEVELOP>1
999                if (numberObj)
1000                    printf("YYYY analysis says all continuous with costs will be integer\n");
1001#endif
1002                continuousMultiplier = 1.0;
1003            }
1004        }
1005        delete [] rhs;
1006    }
1007    /*
1008      Take a first scan to see if there are unfixed continuous variables in the
1009      objective.  If so, the minimum objective change could be arbitrarily small.
1010      Also pick off the maximum coefficient of an unfixed integer variable.
1011
1012      If the objective is found to contain only integer variables, set the
1013      fathoming discipline to strict.
1014    */
1015    double maximumCost = 0.0 ;
1016    //double trueIncrement=0.0;
1017    int iColumn ;
1018    int numberColumns = getNumCols() ;
1019    double scaleFactor = 1.0; // due to rhs etc
1020/*
1021  Original model did not have integer bounds.
1022*/
1023    if ((specialOptions_&65536) == 0) {
1024        /* be on safe side (later look carefully as may be able to
1025           to get 0.5 say if bounds are multiples of 0.5 */
1026        for (iColumn = 0 ; iColumn < numberColumns ; iColumn++) {
1027            if (upper[iColumn] > lower[iColumn] + 1.0e-8) {
1028                double value;
1029                value = fabs(lower[iColumn]);
1030                if (floor(value + 0.5) != value) {
1031                    scaleFactor = CoinMin(scaleFactor, 0.5);
1032                    if (floor(2.0*value + 0.5) != 2.0*value) {
1033                        scaleFactor = CoinMin(scaleFactor, 0.25);
1034                        if (floor(4.0*value + 0.5) != 4.0*value) {
1035                            scaleFactor = 0.0;
1036                        }
1037                    }
1038                }
1039                value = fabs(upper[iColumn]);
1040                if (floor(value + 0.5) != value) {
1041                    scaleFactor = CoinMin(scaleFactor, 0.5);
1042                    if (floor(2.0*value + 0.5) != 2.0*value) {
1043                        scaleFactor = CoinMin(scaleFactor, 0.25);
1044                        if (floor(4.0*value + 0.5) != 4.0*value) {
1045                            scaleFactor = 0.0;
1046                        }
1047                    }
1048                }
1049            }
1050        }
1051    }
1052    bool possibleMultiple = continuousMultiplier != 0.0 && scaleFactor != 0.0 ;
1053    if (possibleMultiple) {
1054        for (iColumn = 0 ; iColumn < numberColumns ; iColumn++) {
1055            if (upper[iColumn] > lower[iColumn] + 1.0e-8) {
1056                maximumCost = CoinMax(maximumCost, fabs(objective[iColumn])) ;
1057            }
1058        }
1059    }
1060    setIntParam(CbcModel::CbcFathomDiscipline, possibleMultiple) ;
1061    /*
1062      If a nontrivial increment is possible, try and figure it out. We're looking
1063      for gcd(c<j>) for all c<j> that are coefficients of unfixed integer
1064      variables. Since the c<j> might not be integers, try and inflate them
1065      sufficiently that they look like integers (and we'll deflate the gcd
1066      later).
1067
1068      2520.0 is used as it is a nice multiple of 2,3,5,7
1069    */
1070    if (possibleMultiple && maximumCost) {
1071        int increment = 0 ;
1072        double multiplier = 2520.0 ;
1073        while (10.0*multiplier*maximumCost < 1.0e8)
1074            multiplier *= 10.0 ;
1075        int bigIntegers = 0; // Count of large costs which are integer
1076        for (iColumn = 0 ; iColumn < numberColumns ; iColumn++) {
1077            if (upper[iColumn] > lower[iColumn] + 1.0e-8) {
1078                double objValue = fabs(objective[iColumn]);
1079                if (!isInteger(iColumn)) {
1080                    if (!coeffMultiplier)
1081                        objValue *= continuousMultiplier;
1082                    else
1083                        objValue *= coeffMultiplier[iColumn];
1084                }
1085                if (objValue) {
1086                    double value = objValue * multiplier ;
1087                    if (value < 2.1e9) {
1088                        int nearest = static_cast<int> (floor(value + 0.5)) ;
1089                        if (fabs(value - floor(value + 0.5)) > 1.0e-8) {
1090                            increment = 0 ;
1091                            break ;
1092                        } else if (!increment) {
1093                            increment = nearest ;
1094                        } else {
1095                            increment = gcd(increment, nearest) ;
1096                        }
1097                    } else {
1098                        // large value - may still be multiple of 1.0
1099                        if (fabs(objValue - floor(objValue + 0.5)) > 1.0e-8) {
1100                            increment = 0;
1101                            break;
1102                        } else {
1103                            bigIntegers++;
1104                        }
1105                    }
1106                }
1107            }
1108        }
1109        delete [] coeffMultiplier;
1110        /*
1111          If the increment beats the current value for objective change, install it.
1112        */
1113        if (increment) {
1114            double value = increment ;
1115            double cutoff = getDblParam(CbcModel::CbcCutoffIncrement) ;
1116            if (bigIntegers) {
1117                // allow for 1.0
1118                increment = gcd(increment, static_cast<int> (multiplier));
1119                value = increment;
1120            }
1121            value /= multiplier ;
1122            value *= scaleFactor;
1123            //trueIncrement=CoinMax(cutoff,value);;
1124            if (value*0.999 > cutoff) {
1125                messageHandler()->message(CBC_INTEGERINCREMENT,
1126                                          messages())
1127                << value << CoinMessageEol ;
1128                setDblParam(CbcModel::CbcCutoffIncrement, value*0.999) ;
1129            }
1130        }
1131    }
1132
1133    return ;
1134}
1135
1136/*
1137saveModel called (carved out of) BranchandBound
1138*/
1139void CbcModel::saveModel(OsiSolverInterface * saveSolver, double * checkCutoffForRestart, bool * feasible)
1140{
1141    if (saveSolver && (specialOptions_&32768) != 0) {
1142        // See if worth trying reduction
1143        *checkCutoffForRestart = getCutoff();
1144        bool tryNewSearch = solverCharacteristics_->reducedCostsAccurate() &&
1145                            (*checkCutoffForRestart < 1.0e20);
1146        int numberColumns = getNumCols();
1147        if (tryNewSearch) {
1148#ifdef CLP_INVESTIGATE
1149            printf("after %d nodes, cutoff %g - looking\n",
1150                   numberNodes_, getCutoff());
1151#endif
1152            saveSolver->resolve();
1153            double direction = saveSolver->getObjSense() ;
1154            double gap = *checkCutoffForRestart - saveSolver->getObjValue() * direction ;
1155            double tolerance;
1156            saveSolver->getDblParam(OsiDualTolerance, tolerance) ;
1157            if (gap <= 0.0)
1158                gap = tolerance;
1159            gap += 100.0 * tolerance;
1160            double integerTolerance = getDblParam(CbcIntegerTolerance) ;
1161
1162            const double *lower = saveSolver->getColLower() ;
1163            const double *upper = saveSolver->getColUpper() ;
1164            const double *solution = saveSolver->getColSolution() ;
1165            const double *reducedCost = saveSolver->getReducedCost() ;
1166
1167            int numberFixed = 0 ;
1168            int numberFixed2 = 0;
1169            for (int i = 0 ; i < numberIntegers_ ; i++) {
1170                int iColumn = integerVariable_[i] ;
1171                double djValue = direction * reducedCost[iColumn] ;
1172                if (upper[iColumn] - lower[iColumn] > integerTolerance) {
1173                    if (solution[iColumn] < lower[iColumn] + integerTolerance && djValue > gap) {
1174                        saveSolver->setColUpper(iColumn, lower[iColumn]) ;
1175                        numberFixed++ ;
1176                    } else if (solution[iColumn] > upper[iColumn] - integerTolerance && -djValue > gap) {
1177                        saveSolver->setColLower(iColumn, upper[iColumn]) ;
1178                        numberFixed++ ;
1179                    }
1180                } else {
1181                    numberFixed2++;
1182                }
1183            }
1184#ifdef COIN_DEVELOP
1185/*
1186  We're debugging. (specialOptions 1)
1187*/
1188            if ((specialOptions_&1) != 0) {
1189                const OsiRowCutDebugger *debugger = saveSolver->getRowCutDebugger() ;
1190                if (debugger) {
1191                    printf("Contains optimal\n") ;
1192                    OsiSolverInterface * temp = saveSolver->clone();
1193                    const double * solution = debugger->optimalSolution();
1194                    const double *lower = temp->getColLower() ;
1195                    const double *upper = temp->getColUpper() ;
1196                    int n = temp->getNumCols();
1197                    for (int i = 0; i < n; i++) {
1198                        if (temp->isInteger(i)) {
1199                            double value = floor(solution[i] + 0.5);
1200                            assert (value >= lower[i] && value <= upper[i]);
1201                            temp->setColLower(i, value);
1202                            temp->setColUpper(i, value);
1203                        }
1204                    }
1205                    temp->writeMps("reduced_fix");
1206                    delete temp;
1207                    saveSolver->writeMps("reduced");
1208                } else {
1209                    abort();
1210                }
1211            }
1212            printf("Restart could fix %d integers (%d already fixed)\n",
1213                   numberFixed + numberFixed2, numberFixed2);
1214#endif
1215            numberFixed += numberFixed2;
1216            if (numberFixed*20 < numberColumns)
1217                tryNewSearch = false;
1218        }
1219        if (tryNewSearch) {
1220            // back to solver without cuts?
1221            OsiSolverInterface * solver2 = continuousSolver_->clone();
1222            const double *lower = saveSolver->getColLower() ;
1223            const double *upper = saveSolver->getColUpper() ;
1224            for (int i = 0 ; i < numberIntegers_ ; i++) {
1225                int iColumn = integerVariable_[i] ;
1226                solver2->setColLower(iColumn, lower[iColumn]);
1227                solver2->setColUpper(iColumn, upper[iColumn]);
1228            }
1229            // swap
1230            delete saveSolver;
1231            saveSolver = solver2;
1232            double * newSolution = new double[numberColumns];
1233            double objectiveValue = *checkCutoffForRestart;
1234            CbcSerendipity heuristic(*this);
1235            if (bestSolution_)
1236                heuristic.setInputSolution(bestSolution_, bestObjective_);
1237            heuristic.setFractionSmall(0.9);
1238            heuristic.setFeasibilityPumpOptions(1008013);
1239            // Use numberNodes to say how many are original rows
1240            heuristic.setNumberNodes(continuousSolver_->getNumRows());
1241#ifdef COIN_DEVELOP
1242            if (continuousSolver_->getNumRows() <
1243                    saveSolver->getNumRows())
1244                printf("%d rows added ZZZZZ\n",
1245                       solver_->getNumRows() - continuousSolver_->getNumRows());
1246#endif
1247            int returnCode = heuristic.smallBranchAndBound(saveSolver,
1248                             -1, newSolution,
1249                             objectiveValue,
1250                             *checkCutoffForRestart, "Reduce");
1251            if (returnCode < 0) {
1252#ifdef COIN_DEVELOP
1253                printf("Restart - not small enough to do search after fixing\n");
1254#endif
1255                delete [] newSolution;
1256            } else {
1257                if ((returnCode&1) != 0) {
1258                    // increment number of solutions so other heuristics can test
1259                    numberSolutions_++;
1260                    numberHeuristicSolutions_++;
1261                    lastHeuristic_ = NULL;
1262                    setBestSolution(CBC_ROUNDING, objectiveValue, newSolution) ;
1263                }
1264                delete [] newSolution;
1265                *feasible = false; // stop search
1266            }
1267        }
1268    }
1269}
1270/*
1271Adds integers, called from BranchandBound()
1272*/
1273void CbcModel::AddIntegers()
1274{
1275    int numberColumns = continuousSolver_->getNumCols();
1276    int numberRows = continuousSolver_->getNumRows();
1277    int * del = new int [CoinMax(numberColumns, numberRows)];
1278    int * original = new int [numberColumns];
1279    char * possibleRow = new char [numberRows];
1280    {
1281        const CoinPackedMatrix * rowCopy = continuousSolver_->getMatrixByRow();
1282        const int * column = rowCopy->getIndices();
1283        const int * rowLength = rowCopy->getVectorLengths();
1284        const CoinBigIndex * rowStart = rowCopy->getVectorStarts();
1285        const double * rowLower = continuousSolver_->getRowLower();
1286        const double * rowUpper = continuousSolver_->getRowUpper();
1287        const double * element = rowCopy->getElements();
1288        for (int i = 0; i < numberRows; i++) {
1289            int nLeft = 0;
1290            bool possible = false;
1291            if (rowLower[i] < -1.0e20) {
1292                double value = rowUpper[i];
1293                if (fabs(value - floor(value + 0.5)) < 1.0e-8)
1294                    possible = true;
1295            } else if (rowUpper[i] > 1.0e20) {
1296                double value = rowLower[i];
1297                if (fabs(value - floor(value + 0.5)) < 1.0e-8)
1298                    possible = true;
1299            } else {
1300                double value = rowUpper[i];
1301                if (rowLower[i] == rowUpper[i] &&
1302                        fabs(value - floor(value + 0.5)) < 1.0e-8)
1303                    possible = true;
1304            }
1305            for (CoinBigIndex j = rowStart[i];
1306                    j < rowStart[i] + rowLength[i]; j++) {
1307                int iColumn = column[j];
1308                if (continuousSolver_->isInteger(iColumn)) {
1309                    if (fabs(element[j]) != 1.0)
1310                        possible = false;
1311                } else {
1312                    nLeft++;
1313                }
1314            }
1315            if (possible || !nLeft)
1316                possibleRow[i] = 1;
1317            else
1318                possibleRow[i] = 0;
1319        }
1320    }
1321    int nDel = 0;
1322    for (int i = 0; i < numberColumns; i++) {
1323        original[i] = i;
1324        if (continuousSolver_->isInteger(i))
1325            del[nDel++] = i;
1326    }
1327    int nExtra = 0;
1328    OsiSolverInterface * copy1 = continuousSolver_->clone();
1329    int nPass = 0;
1330    while (nDel && nPass < 10) {
1331        nPass++;
1332        OsiSolverInterface * copy2 = copy1->clone();
1333        int nLeft = 0;
1334        for (int i = 0; i < nDel; i++)
1335            original[del[i]] = -1;
1336        for (int i = 0; i < numberColumns; i++) {
1337            int kOrig = original[i];
1338            if (kOrig >= 0)
1339                original[nLeft++] = kOrig;
1340        }
1341        assert (nLeft == numberColumns - nDel);
1342        copy2->deleteCols(nDel, del);
1343        numberColumns = copy2->getNumCols();
1344        const CoinPackedMatrix * rowCopy = copy2->getMatrixByRow();
1345        numberRows = rowCopy->getNumRows();
1346        const int * column = rowCopy->getIndices();
1347        const int * rowLength = rowCopy->getVectorLengths();
1348        const CoinBigIndex * rowStart = rowCopy->getVectorStarts();
1349        const double * rowLower = copy2->getRowLower();
1350        const double * rowUpper = copy2->getRowUpper();
1351        const double * element = rowCopy->getElements();
1352        const CoinPackedMatrix * columnCopy = copy2->getMatrixByCol();
1353        const int * columnLength = columnCopy->getVectorLengths();
1354        nDel = 0;
1355        // Could do gcd stuff on ones with costs
1356        for (int i = 0; i < numberRows; i++) {
1357            if (!rowLength[i]) {
1358                del[nDel++] = i;
1359                possibleRow[i] = 1;
1360            } else if (possibleRow[i]) {
1361                if (rowLength[i] == 1) {
1362                    int k = rowStart[i];
1363                    int iColumn = column[k];
1364                    if (!copy2->isInteger(iColumn)) {
1365                        double mult = 1.0 / fabs(element[k]);
1366                        if (rowLower[i] < -1.0e20) {
1367                            double value = rowUpper[i] * mult;
1368                            if (fabs(value - floor(value + 0.5)) < 1.0e-8) {
1369                                del[nDel++] = i;
1370                                if (columnLength[iColumn] == 1) {
1371                                    copy2->setInteger(iColumn);
1372                                    int kOrig = original[iColumn];
1373                                    setOptionalInteger(kOrig);
1374                                }
1375                            }
1376                        } else if (rowUpper[i] > 1.0e20) {
1377                            double value = rowLower[i] * mult;
1378                            if (fabs(value - floor(value + 0.5)) < 1.0e-8) {
1379                                del[nDel++] = i;
1380                                if (columnLength[iColumn] == 1) {
1381                                    copy2->setInteger(iColumn);
1382                                    int kOrig = original[iColumn];
1383                                    setOptionalInteger(kOrig);
1384                                }
1385                            }
1386                        } else {
1387                            double value = rowUpper[i] * mult;
1388                            if (rowLower[i] == rowUpper[i] &&
1389                                    fabs(value - floor(value + 0.5)) < 1.0e-8) {
1390                                del[nDel++] = i;
1391                                copy2->setInteger(iColumn);
1392                                int kOrig = original[iColumn];
1393                                setOptionalInteger(kOrig);
1394                            }
1395                        }
1396                    }
1397                } else {
1398                    // only if all singletons
1399                    bool possible = false;
1400                    if (rowLower[i] < -1.0e20) {
1401                        double value = rowUpper[i];
1402                        if (fabs(value - floor(value + 0.5)) < 1.0e-8)
1403                            possible = true;
1404                    } else if (rowUpper[i] > 1.0e20) {
1405                        double value = rowLower[i];
1406                        if (fabs(value - floor(value + 0.5)) < 1.0e-8)
1407                            possible = true;
1408                    } else {
1409                        double value = rowUpper[i];
1410                        if (rowLower[i] == rowUpper[i] &&
1411                                fabs(value - floor(value + 0.5)) < 1.0e-8)
1412                            possible = true;
1413                    }
1414                    if (possible) {
1415                        for (CoinBigIndex j = rowStart[i];
1416                                j < rowStart[i] + rowLength[i]; j++) {
1417                            int iColumn = column[j];
1418                            if (columnLength[iColumn] != 1 || fabs(element[j]) != 1.0) {
1419                                possible = false;
1420                                break;
1421                            }
1422                        }
1423                        if (possible) {
1424                            for (CoinBigIndex j = rowStart[i];
1425                                    j < rowStart[i] + rowLength[i]; j++) {
1426                                int iColumn = column[j];
1427                                if (!copy2->isInteger(iColumn)) {
1428                                    copy2->setInteger(iColumn);
1429                                    int kOrig = original[iColumn];
1430                                    setOptionalInteger(kOrig);
1431                                }
1432                            }
1433                            del[nDel++] = i;
1434                        }
1435                    }
1436                }
1437            }
1438        }
1439        if (nDel) {
1440            copy2->deleteRows(nDel, del);
1441        }
1442        if (nDel != numberRows) {
1443            nDel = 0;
1444            for (int i = 0; i < numberColumns; i++) {
1445                if (copy2->isInteger(i)) {
1446                    del[nDel++] = i;
1447                    nExtra++;
1448                }
1449            }
1450        } else {
1451            nDel = 0;
1452        }
1453        delete copy1;
1454        copy1 = copy2->clone();
1455        delete copy2;
1456    }
1457    // See if what's left is a network
1458    bool couldBeNetwork = false;
1459    if (copy1->getNumRows() && copy1->getNumCols()) {
1460#ifdef COIN_HAS_CLP
1461        OsiClpSolverInterface * clpSolver
1462        = dynamic_cast<OsiClpSolverInterface *> (copy1);
1463        if (false && clpSolver) {
1464            numberRows = clpSolver->getNumRows();
1465            char * rotate = new char[numberRows];
1466            int n = clpSolver->getModelPtr()->findNetwork(rotate, 1.0);
1467            delete [] rotate;
1468#ifdef CLP_INVESTIGATE
1469            printf("INTA network %d rows out of %d\n", n, numberRows);
1470#endif
1471            if (CoinAbs(n) == numberRows) {
1472                couldBeNetwork = true;
1473                for (int i = 0; i < numberRows; i++) {
1474                    if (!possibleRow[i]) {
1475                        couldBeNetwork = false;
1476#ifdef CLP_INVESTIGATE
1477                        printf("but row %d is bad\n", i);
1478#endif
1479                        break;
1480                    }
1481                }
1482            }
1483        } else
1484#endif
1485        {
1486            numberColumns = copy1->getNumCols();
1487            numberRows = copy1->getNumRows();
1488            const double * rowLower = copy1->getRowLower();
1489            const double * rowUpper = copy1->getRowUpper();
1490            couldBeNetwork = true;
1491            for (int i = 0; i < numberRows; i++) {
1492                if (rowLower[i] > -1.0e20 && fabs(rowLower[i] - floor(rowLower[i] + 0.5)) > 1.0e-12) {
1493                    couldBeNetwork = false;
1494                    break;
1495                }
1496                if (rowUpper[i] < 1.0e20 && fabs(rowUpper[i] - floor(rowUpper[i] + 0.5)) > 1.0e-12) {
1497                    couldBeNetwork = false;
1498                    break;
1499                }
1500            }
1501            if (couldBeNetwork) {
1502                const CoinPackedMatrix  * matrixByCol = copy1->getMatrixByCol();
1503                const double * element = matrixByCol->getElements();
1504                //const int * row = matrixByCol->getIndices();
1505                const CoinBigIndex * columnStart = matrixByCol->getVectorStarts();
1506                const int * columnLength = matrixByCol->getVectorLengths();
1507                for (int iColumn = 0; iColumn < numberColumns; iColumn++) {
1508                    CoinBigIndex start = columnStart[iColumn];
1509                    CoinBigIndex end = start + columnLength[iColumn];
1510                    if (end > start + 2) {
1511                        couldBeNetwork = false;
1512                        break;
1513                    }
1514                    int type = 0;
1515                    for (CoinBigIndex j = start; j < end; j++) {
1516                        double value = element[j];
1517                        if (fabs(value) != 1.0) {
1518                            couldBeNetwork = false;
1519                            break;
1520                        } else if (value == 1.0) {
1521                            if ((type&1) == 0)
1522                                type |= 1;
1523                            else
1524                                type = 7;
1525                        } else if (value == -1.0) {
1526                            if ((type&2) == 0)
1527                                type |= 2;
1528                            else
1529                                type = 7;
1530                        }
1531                    }
1532                    if (type > 3) {
1533                        couldBeNetwork = false;
1534                        break;
1535                    }
1536                }
1537            }
1538        }
1539    }
1540    if (couldBeNetwork) {
1541        for (int i = 0; i < numberColumns; i++)
1542            setOptionalInteger(original[i]);
1543    }
1544    if (nExtra || couldBeNetwork) {
1545        numberColumns = copy1->getNumCols();
1546        numberRows = copy1->getNumRows();
1547        if (!numberColumns || !numberRows) {
1548            int numberColumns = solver_->getNumCols();
1549            for (int i = 0; i < numberColumns; i++)
1550                assert(solver_->isInteger(i));
1551        }
1552#ifdef CLP_INVESTIGATE
1553        if (couldBeNetwork || nExtra)
1554            printf("INTA %d extra integers, %d left%s\n", nExtra,
1555                   numberColumns,
1556                   couldBeNetwork ? ", all network" : "");
1557#endif
1558        findIntegers(true, 2);
1559        convertToDynamic();
1560    }
1561#ifdef CLP_INVESTIGATE
1562    if (!couldBeNetwork && copy1->getNumCols() &&
1563            copy1->getNumRows()) {
1564        printf("INTA %d rows and %d columns remain\n",
1565               copy1->getNumRows(), copy1->getNumCols());
1566        if (copy1->getNumCols() < 200) {
1567            copy1->writeMps("moreint");
1568            printf("INTA Written remainder to moreint.mps.gz %d rows %d cols\n",
1569                   copy1->getNumRows(), copy1->getNumCols());
1570        }
1571    }
1572#endif
1573    delete copy1;
1574    delete [] del;
1575    delete [] original;
1576    delete [] possibleRow;
1577    // double check increment
1578    analyzeObjective();
1579}
1580/**
1581  \todo
1582  Normally, it looks like we enter here from command dispatch in the main
1583  routine, after calling the solver for an initial solution
1584  (CbcModel::initialSolve, which simply calls the solver's initialSolve
1585  routine.) The first thing we do is call resolve. Presumably there are
1586  circumstances where this is nontrivial? There's also a call from
1587  CbcModel::originalModel (tied up with integer presolve), which should be
1588  checked.
1589
1590*/
1591
1592/*
1593  The overall flow can be divided into three stages:
1594    * Prep: Check that the lp relaxation remains feasible at the root. If so,
1595      do all the setup for B&C.
1596    * Process the root node: Generate cuts, apply heuristics, and in general do
1597      the best we can to resolve the problem without B&C.
1598    * Do B&C search until we hit a limit or exhaust the search tree.
1599
1600  Keep in mind that in general there is no node in the search tree that
1601  corresponds to the active subproblem. The active subproblem is represented
1602  by the current state of the model,  of the solver, and of the constraint
1603  system held by the solver.
1604*/
1605#ifdef COIN_HAS_CPX
1606#include "OsiCpxSolverInterface.hpp"
1607#include "cplex.h"
1608#endif
1609void CbcModel::branchAndBound(int doStatistics)
1610
1611{
1612    /*
1613      Capture a time stamp before we start.
1614    */
1615    dblParam_[CbcStartSeconds] = CoinCpuTime();
1616    dblParam_[CbcSmallestChange] = COIN_DBL_MAX;
1617    dblParam_[CbcSumChange] = 0.0;
1618    dblParam_[CbcLargestChange] = 0.0;
1619    intParam_[CbcNumberBranches] = 0;
1620    // Double check optimization directions line up
1621    dblParam_[CbcOptimizationDirection] = solver_->getObjSense();
1622    strongInfo_[0] = 0;
1623    strongInfo_[1] = 0;
1624    strongInfo_[2] = 0;
1625    strongInfo_[3] = 0;
1626    strongInfo_[4] = 0;
1627    strongInfo_[5] = 0;
1628    strongInfo_[6] = 0;
1629    numberStrongIterations_ = 0;
1630    currentNode_ = NULL;
1631    // See if should do cuts old way
1632    if (parallelMode() < 0) {
1633        specialOptions_ |= 4096 + 8192;
1634    } else if (parallelMode() > 0) {
1635        specialOptions_ |= 4096;
1636    }
1637    int saveMoreSpecialOptions = moreSpecialOptions_;
1638    if (dynamic_cast<CbcTreeLocal *> (tree_))
1639        specialOptions_ |= 4096 + 8192;
1640#ifdef COIN_HAS_CLP
1641    {
1642        OsiClpSolverInterface * clpSolver
1643        = dynamic_cast<OsiClpSolverInterface *> (solver_);
1644        if (clpSolver) {
1645            // pass in disaster handler
1646            CbcDisasterHandler handler(this);
1647            clpSolver->passInDisasterHandler(&handler);
1648            // Initialise solvers seed
1649            clpSolver->getModelPtr()->setRandomSeed(1234567);
1650#if 0
1651            // reduce factorization frequency
1652            int frequency = clpSolver->getModelPtr()->factorizationFrequency();
1653            clpSolver->getModelPtr()->setFactorizationFrequency(CoinMin(frequency, 120));
1654#endif
1655        }
1656    }
1657#endif
1658    // original solver (only set if pre-processing)
1659    OsiSolverInterface * originalSolver = NULL;
1660    int numberOriginalObjects = numberObjects_;
1661    OsiObject ** originalObject = NULL;
1662    // Save whether there were any objects
1663    bool noObjects = (numberObjects_ == 0);
1664    // Set up strategies
1665/*
1666  See if the user has supplied a strategy object and deal with it if present.
1667  The call to setupOther will set numberStrong_ and numberBeforeTrust_, and
1668  perform integer preprocessing, if requested.
1669
1670  We need to hang on to a pointer to solver_. setupOther will assign a
1671  preprocessed solver to model, but will instruct assignSolver not to trash the
1672  existing one.
1673*/
1674    if (strategy_) {
1675        // May do preprocessing
1676        originalSolver = solver_;
1677        strategy_->setupOther(*this);
1678        if (strategy_->preProcessState()) {
1679            // pre-processing done
1680            if (strategy_->preProcessState() < 0) {
1681                // infeasible
1682                handler_->message(CBC_INFEAS, messages_) << CoinMessageEol ;
1683                status_ = 0 ;
1684                secondaryStatus_ = 1;
1685                originalContinuousObjective_ = COIN_DBL_MAX;
1686                return ;
1687            } else if (numberObjects_ && object_) {
1688                numberOriginalObjects = numberObjects_;
1689                // redo sequence
1690                numberIntegers_ = 0;
1691                int numberColumns = getNumCols();
1692                int nOrig = originalSolver->getNumCols();
1693                CglPreProcess * process = strategy_->process();
1694                assert (process);
1695                const int * originalColumns = process->originalColumns();
1696                // allow for cliques etc
1697                nOrig = CoinMax(nOrig, originalColumns[numberColumns-1] + 1);
1698                // try and redo debugger
1699                OsiRowCutDebugger * debugger = const_cast<OsiRowCutDebugger *> (solver_->getRowCutDebuggerAlways());
1700                if (debugger)
1701                    debugger->redoSolution(numberColumns, originalColumns);
1702                // User-provided solution might have been best. Synchronise.
1703                if (bestSolution_) {
1704                    // need to redo - in case no better found in BAB
1705                    // just get integer part right
1706                    for (int i = 0; i < numberColumns; i++) {
1707                        int jColumn = originalColumns[i];
1708                        bestSolution_[i] = bestSolution_[jColumn];
1709                    }
1710                }
1711                originalObject = object_;
1712                // object number or -1
1713                int * temp = new int[nOrig];
1714                int iColumn;
1715                for (iColumn = 0; iColumn < nOrig; iColumn++)
1716                    temp[iColumn] = -1;
1717                int iObject;
1718                int nNonInt = 0;
1719                for (iObject = 0; iObject < numberOriginalObjects; iObject++) {
1720                    iColumn = originalObject[iObject]->columnNumber();
1721                    if (iColumn < 0) {
1722                        nNonInt++;
1723                    } else {
1724                        temp[iColumn] = iObject;
1725                    }
1726                }
1727                int numberNewIntegers = 0;
1728                int numberOldIntegers = 0;
1729                int numberOldOther = 0;
1730                for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1731                    int jColumn = originalColumns[iColumn];
1732                    if (temp[jColumn] >= 0) {
1733                        int iObject = temp[jColumn];
1734                        CbcSimpleInteger * obj =
1735                            dynamic_cast <CbcSimpleInteger *>(originalObject[iObject]) ;
1736                        if (obj)
1737                            numberOldIntegers++;
1738                        else
1739                            numberOldOther++;
1740                    } else if (isInteger(iColumn)) {
1741                        numberNewIntegers++;
1742                    }
1743                }
1744                /*
1745                  Allocate an array to hold the indices of the integer variables.
1746                  Make a large enough array for all objects
1747                */
1748                numberObjects_ = numberNewIntegers + numberOldIntegers + numberOldOther + nNonInt;
1749                object_ = new OsiObject * [numberObjects_];
1750                delete [] integerVariable_;
1751                integerVariable_ = new int [numberNewIntegers+numberOldIntegers];
1752                /*
1753                  Walk the variables again, filling in the indices and creating objects for
1754                  the integer variables. Initially, the objects hold the index and upper &
1755                  lower bounds.
1756                */
1757                numberIntegers_ = 0;
1758                int n = originalColumns[numberColumns-1] + 1;
1759                int * backward = new int[n];
1760                int i;
1761                for ( i = 0; i < n; i++)
1762                    backward[i] = -1;
1763                for (i = 0; i < numberColumns; i++)
1764                    backward[originalColumns[i]] = i;
1765                for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1766                    int jColumn = originalColumns[iColumn];
1767                    if (temp[jColumn] >= 0) {
1768                        int iObject = temp[jColumn];
1769                        CbcSimpleInteger * obj =
1770                            dynamic_cast <CbcSimpleInteger *>(originalObject[iObject]) ;
1771                        if (obj) {
1772                            object_[numberIntegers_] = originalObject[iObject]->clone();
1773                            // redo ids etc
1774                            //object_[numberIntegers_]->resetSequenceEtc(numberColumns,originalColumns);
1775                            object_[numberIntegers_]->resetSequenceEtc(numberColumns, backward);
1776                            integerVariable_[numberIntegers_++] = iColumn;
1777                        }
1778                    } else if (isInteger(iColumn)) {
1779                        object_[numberIntegers_] =
1780                            new CbcSimpleInteger(this, iColumn);
1781                        integerVariable_[numberIntegers_++] = iColumn;
1782                    }
1783                }
1784                delete [] backward;
1785                numberObjects_ = numberIntegers_;
1786                // Now append other column stuff
1787                for (iColumn = 0; iColumn < numberColumns; iColumn++) {
1788                    int jColumn = originalColumns[iColumn];
1789                    if (temp[jColumn] >= 0) {
1790                        int iObject = temp[jColumn];
1791                        CbcSimpleInteger * obj =
1792                            dynamic_cast <CbcSimpleInteger *>(originalObject[iObject]) ;
1793                        if (!obj) {
1794                            object_[numberObjects_] = originalObject[iObject]->clone();
1795                            // redo ids etc
1796                            CbcObject * obj =
1797                                dynamic_cast <CbcObject *>(object_[numberObjects_]) ;
1798                            assert (obj);
1799                            obj->redoSequenceEtc(this, numberColumns, originalColumns);
1800                            numberObjects_++;
1801                        }
1802                    }
1803                }
1804                // now append non column stuff
1805                for (iObject = 0; iObject < numberOriginalObjects; iObject++) {
1806                    iColumn = originalObject[iObject]->columnNumber();
1807                    if (iColumn < 0) {
1808                        // already has column numbers changed
1809                        object_[numberObjects_] = originalObject[iObject]->clone();
1810#if 0
1811                        // redo ids etc
1812                        CbcObject * obj =
1813                            dynamic_cast <CbcObject *>(object_[numberObjects_]) ;
1814                        assert (obj);
1815                        obj->redoSequenceEtc(this, numberColumns, originalColumns);
1816#endif
1817                        numberObjects_++;
1818                    }
1819                }
1820                delete [] temp;
1821                if (!numberObjects_)
1822                    handler_->message(CBC_NOINT, messages_) << CoinMessageEol ;
1823            } else {
1824                int numberColumns = getNumCols();
1825                CglPreProcess * process = strategy_->process();
1826                assert (process);
1827                const int * originalColumns = process->originalColumns();
1828                // try and redo debugger
1829                OsiRowCutDebugger * debugger = const_cast<OsiRowCutDebugger *> (solver_->getRowCutDebuggerAlways());
1830                if (debugger)
1831                    debugger->redoSolution(numberColumns, originalColumns);
1832            }
1833        } else {
1834            //no preprocessing
1835            originalSolver = NULL;
1836        }
1837        strategy_->setupCutGenerators(*this);
1838        strategy_->setupHeuristics(*this);
1839        // Set strategy print level to models
1840        strategy_->setupPrinting(*this, handler_->logLevel());
1841    }
1842    eventHappened_ = false;
1843    CbcEventHandler *eventHandler = getEventHandler() ;
1844    if (eventHandler)
1845        eventHandler->setModel(this);
1846#define CLIQUE_ANALYSIS
1847#ifdef CLIQUE_ANALYSIS
1848    // set up for probing
1849    // If we're doing clever stuff with cliques, additional info here.
1850    if (!parentModel_)
1851        probingInfo_ = new CglTreeProbingInfo(solver_);
1852    else
1853        probingInfo_ = NULL;
1854#else
1855    probingInfo_ = NULL;
1856#endif
1857
1858    // Try for dominated columns
1859    if ((specialOptions_&64) != 0) {
1860        CglDuplicateRow dupcuts(solver_);
1861        dupcuts.setMode(2);
1862        CglStored * storedCuts = dupcuts.outDuplicates(solver_);
1863        if (storedCuts) {
1864            printf("adding dup cuts\n");
1865            addCutGenerator(storedCuts, 1, "StoredCuts from dominated",
1866                            true, false, false, -200);
1867        }
1868    }
1869    if (!nodeCompare_)
1870        nodeCompare_ = new CbcCompareDefault();;
1871    // See if hot start wanted
1872    CbcCompareBase * saveCompare = NULL;
1873    // User supplied hotstart. Adapt for preprocessing.
1874    if (hotstartSolution_) {
1875        if (strategy_ && strategy_->preProcessState() > 0) {
1876            CglPreProcess * process = strategy_->process();
1877            assert (process);
1878            int n = solver_->getNumCols();
1879            const int * originalColumns = process->originalColumns();
1880            // columns should be in order ... but
1881            double * tempS = new double[n];
1882            for (int i = 0; i < n; i++) {
1883                int iColumn = originalColumns[i];
1884                tempS[i] = hotstartSolution_[iColumn];
1885            }
1886            delete [] hotstartSolution_;
1887            hotstartSolution_ = tempS;
1888            if (hotstartPriorities_) {
1889                int * tempP = new int [n];
1890                for (int i = 0; i < n; i++) {
1891                    int iColumn = originalColumns[i];
1892                    tempP[i] = hotstartPriorities_[iColumn];
1893                }
1894                delete [] hotstartPriorities_;
1895                hotstartPriorities_ = tempP;
1896            }
1897        }
1898        saveCompare = nodeCompare_;
1899        // depth first
1900        nodeCompare_ = new CbcCompareDepth();
1901    }
1902    if (!problemFeasibility_)
1903        problemFeasibility_ = new CbcFeasibilityBase();
1904# ifdef CBC_DEBUG
1905    std::string problemName ;
1906    solver_->getStrParam(OsiProbName, problemName) ;
1907    printf("Problem name - %s\n", problemName.c_str()) ;
1908    solver_->setHintParam(OsiDoReducePrint, false, OsiHintDo, 0) ;
1909# endif
1910    /*
1911      Assume we're done, and see if we're proven wrong.
1912    */
1913    status_ = 0 ;
1914    secondaryStatus_ = 0;
1915    phase_ = 0;
1916    /*
1917      Scan the variables, noting the integer variables. Create an
1918      CbcSimpleInteger object for each integer variable.
1919    */
1920    findIntegers(false) ;
1921    // Say not dynamic pseudo costs
1922    ownership_ &= ~0x40000000;
1923    // If dynamic pseudo costs then do
1924    if (numberBeforeTrust_)
1925        convertToDynamic();
1926    // Set up char array to say if integer (speed)
1927    delete [] integerInfo_;
1928    {
1929        int n = solver_->getNumCols();
1930        integerInfo_ = new char [n];
1931        for (int i = 0; i < n; i++) {
1932            if (solver_->isInteger(i))
1933                integerInfo_[i] = 1;
1934            else
1935                integerInfo_[i] = 0;
1936        }
1937    }
1938    if (preferredWay_) {
1939        // set all unset ones
1940        for (int iObject = 0 ; iObject < numberObjects_ ; iObject++) {
1941            CbcObject * obj =
1942                dynamic_cast <CbcObject *>(object_[iObject]) ;
1943            if (obj && !obj->preferredWay())
1944                obj->setPreferredWay(preferredWay_);
1945        }
1946    }
1947    /*
1948      Ensure that objects on the lists of OsiObjects, heuristics, and cut
1949      generators attached to this model all refer to this model.
1950    */
1951    synchronizeModel() ;
1952    if (!solverCharacteristics_) {
1953        OsiBabSolver * solverCharacteristics = dynamic_cast<OsiBabSolver *> (solver_->getAuxiliaryInfo());
1954        if (solverCharacteristics) {
1955            solverCharacteristics_ = solverCharacteristics;
1956        } else {
1957            // replace in solver
1958            OsiBabSolver defaultC;
1959            solver_->setAuxiliaryInfo(&defaultC);
1960            solverCharacteristics_ = dynamic_cast<OsiBabSolver *> (solver_->getAuxiliaryInfo());
1961        }
1962    }
1963
1964    solverCharacteristics_->setSolver(solver_);
1965    // Set so we can tell we are in initial phase in resolve
1966    continuousObjective_ = -COIN_DBL_MAX ;
1967    /*
1968      Solve the relaxation.
1969
1970      Apparently there are circumstances where this will be non-trivial --- i.e.,
1971      we've done something since initialSolve that's trashed the solution to the
1972      continuous relaxation.
1973    */
1974    /* Tell solver we are in Branch and Cut
1975       Could use last parameter for subtle differences */
1976    solver_->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo, NULL) ;
1977#ifdef COIN_HAS_CLP
1978    {
1979        OsiClpSolverInterface * clpSolver
1980        = dynamic_cast<OsiClpSolverInterface *> (solver_);
1981        if (clpSolver) {
1982            ClpSimplex * clpSimplex = clpSolver->getModelPtr();
1983            if ((specialOptions_&32) == 0) {
1984                // take off names
1985                clpSimplex->dropNames();
1986            }
1987            // no crunch if mostly continuous
1988            if ((clpSolver->specialOptions()&(1 + 8)) != (1 + 8)) {
1989                int numberColumns = solver_->getNumCols();
1990                if (numberColumns > 1000 && numberIntegers_*4 < numberColumns)
1991                    clpSolver->setSpecialOptions(clpSolver->specialOptions()&(~1));
1992            }
1993            //#define NO_CRUNCH
1994#ifdef NO_CRUNCH
1995            printf("TEMP switching off crunch\n");
1996            int iOpt = clpSolver->specialOptions();
1997            iOpt &= ~1;
1998            iOpt |= 65536;
1999            clpSolver->setSpecialOptions(iOpt);
2000#endif
2001        }
2002    }
2003#endif
2004    bool feasible;
2005    // If NLP then we assume already solved outside branchAndbound
2006    if (!solverCharacteristics_->solverType() || solverCharacteristics_->solverType() == 4) {
2007        feasible = resolve(NULL, 0) != 0 ;
2008    } else {
2009        // pick up given status
2010        feasible = (solver_->isProvenOptimal() &&
2011                    !solver_->isDualObjectiveLimitReached()) ;
2012    }
2013    if (problemFeasibility_->feasible(this, 0) < 0) {
2014        feasible = false; // pretend infeasible
2015    }
2016    numberSavedSolutions_ = 0;
2017    int saveNumberStrong = numberStrong_;
2018    int saveNumberBeforeTrust = numberBeforeTrust_;
2019    /*
2020      If the linear relaxation of the root is infeasible, bail out now. Otherwise,
2021      continue with processing the root node.
2022    */
2023    if (!feasible) {
2024        status_ = 0 ;
2025        if (!solver_->isProvenDualInfeasible()) {
2026            handler_->message(CBC_INFEAS, messages_) << CoinMessageEol ;
2027            secondaryStatus_ = 1;
2028        } else {
2029            handler_->message(CBC_UNBOUNDED, messages_) << CoinMessageEol ;
2030            secondaryStatus_ = 7;
2031        }
2032        originalContinuousObjective_ = COIN_DBL_MAX;
2033        solverCharacteristics_ = NULL;
2034        return ;
2035    } else if (!numberObjects_) {
2036        // nothing to do
2037        solverCharacteristics_ = NULL;
2038        bestObjective_ = solver_->getObjValue() * solver_->getObjSense();
2039        int numberColumns = solver_->getNumCols();
2040        delete [] bestSolution_;
2041        bestSolution_ = new double[numberColumns];
2042        CoinCopyN(solver_->getColSolution(), numberColumns, bestSolution_);
2043        return ;
2044    }
2045/*
2046  See if we're using the Osi side of the branching hierarchy. If so, either
2047  convert existing CbcObjects to OsiObjects, or generate them fresh. In the
2048  first case, CbcModel owns the objects on the object_ list. In the second
2049  case, the solver holds the objects and object_ simply points to the
2050  solver's list.
2051
2052  080417 The conversion code here (the block protected by `if (obj)') cannot
2053  possibly be correct. On the Osi side, descent is OsiObject -> OsiObject2 ->
2054  all other Osi object classes. On the Cbc side, it's OsiObject -> CbcObject
2055  -> all other Cbc object classes. It's structurally impossible for any Osi
2056  object to descend from CbcObject. The only thing I can see is that this is
2057  really dead code, and object detection is now handled from the Osi side.
2058*/
2059    // Convert to Osi if wanted
2060    bool useOsiBranching = false;
2061    //OsiBranchingInformation * persistentInfo = NULL;
2062    if (branchingMethod_ && branchingMethod_->chooseMethod()) {
2063        useOsiBranching = true;
2064        //persistentInfo = new OsiBranchingInformation(solver_);
2065        if (numberOriginalObjects) {
2066            for (int iObject = 0 ; iObject < numberObjects_ ; iObject++) {
2067                CbcObject * obj =
2068                    dynamic_cast <CbcObject *>(object_[iObject]) ;
2069                if (obj) {
2070                    CbcSimpleInteger * obj2 =
2071                        dynamic_cast <CbcSimpleInteger *>(obj) ;
2072                    if (obj2) {
2073                        // back to Osi land
2074                        object_[iObject] = obj2->osiObject();
2075                        delete obj;
2076                    } else {
2077                        OsiSimpleInteger * obj3 =
2078                            dynamic_cast <OsiSimpleInteger *>(obj) ;
2079                        if (!obj3) {
2080                            OsiSOS * obj4 =
2081                                dynamic_cast <OsiSOS *>(obj) ;
2082                            if (!obj4) {
2083                                CbcSOS * obj5 =
2084                                    dynamic_cast <CbcSOS *>(obj) ;
2085                                if (obj5) {
2086                                    // back to Osi land
2087                                    object_[iObject] = obj5->osiObject(solver_);
2088                                } else {
2089                                    printf("Code up CbcObject type in Osi land\n");
2090                                    abort();
2091                                }
2092                            }
2093                        }
2094                    }
2095                }
2096            }
2097            // and add to solver
2098            //if (!solver_->numberObjects()) {
2099            solver_->addObjects(numberObjects_, object_);
2100            //} else {
2101            //if (solver_->numberObjects()!=numberOriginalObjects) {
2102            //printf("should have trapped that solver has objects before\n");
2103            //abort();
2104            //}
2105            //}
2106        } else {
2107/*
2108  As of 080104, findIntegersAndSOS is misleading --- the default OSI
2109  implementation finds only integers.
2110*/
2111            // do from solver
2112            deleteObjects(false);
2113            solver_->findIntegersAndSOS(false);
2114            numberObjects_ = solver_->numberObjects();
2115            object_ = solver_->objects();
2116            ownObjects_ = false;
2117        }
2118        branchingMethod_->chooseMethod()->setSolver(solver_);
2119    }
2120    // take off heuristics if have to (some do not work with SOS, for example)
2121    // object should know what's safe.
2122    {
2123        int numberOdd = 0;
2124        int numberSOS = 0;
2125        for (int i = 0; i < numberObjects_; i++) {
2126            if (!object_[i]->canDoHeuristics())
2127                numberOdd++;
2128            CbcSOS * obj =
2129                dynamic_cast <CbcSOS *>(object_[i]) ;
2130            if (obj)
2131                numberSOS++;
2132        }
2133        if (numberOdd) {
2134            if (numberHeuristics_) {
2135                int k = 0;
2136                for (int i = 0; i < numberHeuristics_; i++) {
2137                    if (!heuristic_[i]->canDealWithOdd())
2138                        delete heuristic_[i];
2139                    else
2140                        heuristic_[k++] = heuristic_[i];
2141                }
2142                if (!k) {
2143                    delete [] heuristic_;
2144                    heuristic_ = NULL;
2145                }
2146                numberHeuristics_ = k;
2147                handler_->message(CBC_HEURISTICS_OFF, messages_) << numberOdd << CoinMessageEol ;
2148            }
2149        } else if (numberSOS) {
2150            specialOptions_ |= 128; // say can do SOS in dynamic mode
2151            // switch off fast nodes for now
2152            fastNodeDepth_ = -1;
2153        }
2154        if (numberThreads_ > 0) {
2155            // switch off fast nodes for now
2156            fastNodeDepth_ = -1;
2157        }
2158    }
2159    // Save objective (just so user can access it)
2160    originalContinuousObjective_ = solver_->getObjValue();
2161    bestPossibleObjective_ = originalContinuousObjective_;
2162    sumChangeObjective1_ = 0.0;
2163    sumChangeObjective2_ = 0.0;
2164    /*
2165      OsiRowCutDebugger knows an optimal answer for a subset of MIP problems.
2166      Assuming it recognises the problem, when called upon it will check a cut to
2167      see if it cuts off the optimal answer.
2168    */
2169    // If debugger exists set specialOptions_ bit
2170    if (solver_->getRowCutDebuggerAlways()) {
2171        specialOptions_ |= 1;
2172    }
2173
2174# ifdef CBC_DEBUG
2175    if ((specialOptions_&1) == 0)
2176        solver_->activateRowCutDebugger(problemName.c_str()) ;
2177    if (solver_->getRowCutDebuggerAlways())
2178        specialOptions_ |= 1;
2179# endif
2180
2181    /*
2182      Begin setup to process a feasible root node.
2183    */
2184    bestObjective_ = CoinMin(bestObjective_, 1.0e50) ;
2185    if (!bestSolution_) {
2186        numberSolutions_ = 0 ;
2187        numberHeuristicSolutions_ = 0 ;
2188    }
2189    stateOfSearch_ = 0;
2190    // Everything is minimization
2191    {
2192        // needed to sync cutoffs
2193        double value ;
2194        solver_->getDblParam(OsiDualObjectiveLimit, value) ;
2195        dblParam_[CbcCurrentCutoff] = value * solver_->getObjSense();
2196    }
2197    double cutoff = getCutoff() ;
2198    double direction = solver_->getObjSense() ;
2199    dblParam_[CbcOptimizationDirection] = direction;
2200    if (cutoff < 1.0e20 && direction < 0.0)
2201        messageHandler()->message(CBC_CUTOFF_WARNING1,
2202                                  messages())
2203        << cutoff << -cutoff << CoinMessageEol ;
2204    if (cutoff > bestObjective_)
2205        cutoff = bestObjective_ ;
2206    setCutoff(cutoff) ;
2207    /*
2208      We probably already have a current solution, but just in case ...
2209    */
2210    int numberColumns = getNumCols() ;
2211    if (!currentSolution_)
2212        currentSolution_ = new double[numberColumns] ;
2213    testSolution_ = currentSolution_;
2214    /*
2215      Create a copy of the solver, thus capturing the original (root node)
2216      constraint system (aka the continuous system).
2217    */
2218    continuousSolver_ = solver_->clone() ;
2219
2220    numberRowsAtContinuous_ = getNumRows() ;
2221    solver_->saveBaseModel();
2222    /*
2223      Check the objective to see if we can deduce a nontrivial increment. If
2224      it's better than the current value for CbcCutoffIncrement, it'll be
2225      installed.
2226    */
2227    if (solverCharacteristics_->reducedCostsAccurate())
2228        analyzeObjective() ;
2229    {
2230        // may be able to change cutoff now
2231        double cutoff = getCutoff();
2232        double increment = getDblParam(CbcModel::CbcCutoffIncrement) ;
2233        if (cutoff > bestObjective_ - increment) {
2234            cutoff = bestObjective_ - increment ;
2235            setCutoff(cutoff) ;
2236        }
2237    }
2238#ifdef COIN_HAS_CLP
2239    // Possible save of pivot method
2240    ClpDualRowPivot * savePivotMethod = NULL;
2241    {
2242        // pass tolerance and increment to solver
2243        OsiClpSolverInterface * clpSolver
2244        = dynamic_cast<OsiClpSolverInterface *> (solver_);
2245        if (clpSolver)
2246            clpSolver->setStuff(getIntegerTolerance(), getCutoffIncrement());
2247    }
2248#endif
2249    /*
2250      Set up for cut generation. addedCuts_ holds the cuts which are relevant for
2251      the active subproblem. whichGenerator will be used to record the generator
2252      that produced a given cut.
2253    */
2254    maximumWhich_ = 1000 ;
2255    delete [] whichGenerator_;
2256    whichGenerator_ = new int[maximumWhich_] ;
2257    memset(whichGenerator_, 0, maximumWhich_*sizeof(int));
2258    maximumNumberCuts_ = 0 ;
2259    currentNumberCuts_ = 0 ;
2260    delete [] addedCuts_ ;
2261    addedCuts_ = NULL ;
2262    OsiObject ** saveObjects = NULL;
2263    maximumRows_ = numberRowsAtContinuous_;
2264    currentDepth_ = 0;
2265    workingBasis_.resize(maximumRows_, numberColumns);
2266    /*
2267      Set up an empty heap and associated data structures to hold the live set
2268      (problems which require further exploration).
2269    */
2270    CbcCompareDefault * compareActual
2271    = dynamic_cast<CbcCompareDefault *> (nodeCompare_);
2272    if (compareActual) {
2273        compareActual->setBestPossible(direction*solver_->getObjValue());
2274        compareActual->setCutoff(getCutoff());
2275#if 0
2276        if (false && !numberThreads_ && !parentModel_) {
2277            printf("CbcTreeArray ? threads ? parentArray\n");
2278            // Setup new style tree
2279            delete tree_;
2280            tree_ = new CbcTreeArray();
2281        }
2282#endif
2283    }
2284    tree_->setComparison(*nodeCompare_) ;
2285    /*
2286      Used to record the path from a node to the root of the search tree, so that
2287      we can then traverse from the root to the node when restoring a subproblem.
2288    */
2289    maximumDepth_ = 10 ;
2290    delete [] walkback_ ;
2291    walkback_ = new CbcNodeInfo * [maximumDepth_] ;
2292    lastDepth_ = 0;
2293    delete [] lastNodeInfo_ ;
2294    lastNodeInfo_ = new CbcNodeInfo * [maximumDepth_] ;
2295    delete [] lastNumberCuts_ ;
2296    lastNumberCuts_ = new int [maximumDepth_] ;
2297    maximumCuts_ = 100;
2298    lastNumberCuts2_ = 0;
2299    delete [] lastCut_;
2300    lastCut_ = new const OsiRowCut * [maximumCuts_];
2301    /*
2302      Used to generate bound edits for CbcPartialNodeInfo.
2303    */
2304    double * lowerBefore = new double [numberColumns] ;
2305    double * upperBefore = new double [numberColumns] ;
2306    /*
2307  Set up to run heuristics and generate cuts at the root node. The heavy
2308  lifting is hidden inside the calls to doHeuristicsAtRoot and solveWithCuts.
2309
2310  To start, tell cut generators they can be a bit more aggressive at the
2311  root node.
2312
2313  QUESTION: phase_ = 0 is documented as `initial solve', phase = 1 as `solve
2314            with cuts at root'. Is phase_ = 1 the correct indication when
2315            doHeurisiticsAtRoot is called to run heuristics outside of the main
2316            cut / heurisitc / reoptimise loop in solveWithCuts?
2317
2318      Generate cuts at the root node and reoptimise. solveWithCuts does the heavy
2319      lifting. It will iterate a generate/reoptimise loop (including reduced cost
2320      fixing) until no cuts are generated, the change in objective falls off,  or
2321      the limit on the number of rounds of cut generation is exceeded.
2322
2323      At the end of all this, any cuts will be recorded in cuts and also
2324      installed in the solver's constraint system. We'll have reoptimised, and
2325      removed any slack cuts (numberOldActiveCuts_ and numberNewCuts_ have been
2326      adjusted accordingly).
2327
2328      Tell cut generators they can be a bit more aggressive at root node
2329
2330      TODO: Why don't we make a copy of the solution after solveWithCuts?
2331      TODO: If numberUnsatisfied == 0, don't we have a solution?
2332    */
2333    phase_ = 1;
2334    int iCutGenerator;
2335    for (iCutGenerator = 0; iCutGenerator < numberCutGenerators_; iCutGenerator++) {
2336        CglCutGenerator * generator = generator_[iCutGenerator]->generator();
2337        generator->setAggressiveness(generator->getAggressiveness() + 100);
2338    }
2339    OsiCuts cuts ;
2340    int anyAction = -1 ;
2341    numberOldActiveCuts_ = 0 ;
2342    numberNewCuts_ = 0 ;
2343    // Array to mark solution
2344    delete [] usedInSolution_;
2345    usedInSolution_ = new int[numberColumns];
2346    CoinZeroN(usedInSolution_, numberColumns);
2347    /*
2348      For printing totals and for CbcNode (numberNodes_)
2349    */
2350    numberIterations_ = 0 ;
2351    numberSolves_ = 0 ;
2352    numberNodes_ = 0 ;
2353    numberNodes2_ = 0 ;
2354    maximumStatistics_ = 0;
2355    maximumDepthActual_ = 0;
2356    numberDJFixed_ = 0.0;
2357    if (!parentModel_) {
2358        if ((specialOptions_&262144) != 0) {
2359            // create empty stored cuts
2360            //storedRowCuts_ = new CglStored(solver_->getNumCols());
2361        } else if ((specialOptions_&524288) != 0 && storedRowCuts_) {
2362            // tighten and set best solution
2363            // A) tight bounds on integer variables
2364            /*
2365              storedRowCuts_ are coming in from outside, probably for nonlinear.
2366              John was unsure about origin.
2367            */
2368            const double * lower = solver_->getColLower();
2369            const double * upper = solver_->getColUpper();
2370            const double * tightLower = storedRowCuts_->tightLower();
2371            const double * tightUpper = storedRowCuts_->tightUpper();
2372            int nTightened = 0;
2373            for (int i = 0; i < numberIntegers_; i++) {
2374                int iColumn = integerVariable_[i];
2375                if (tightLower[iColumn] > lower[iColumn]) {
2376                    nTightened++;
2377                    solver_->setColLower(iColumn, tightLower[iColumn]);
2378                }
2379                if (tightUpper[iColumn] < upper[iColumn]) {
2380                    nTightened++;
2381                    solver_->setColUpper(iColumn, tightUpper[iColumn]);
2382                }
2383            }
2384            if (nTightened)
2385                printf("%d tightened by alternate cuts\n", nTightened);
2386            if (storedRowCuts_->bestObjective() < bestObjective_) {
2387                // B) best solution
2388                double objValue = storedRowCuts_->bestObjective();
2389                setBestSolution(CBC_SOLUTION, objValue,
2390                                storedRowCuts_->bestSolution()) ;
2391                // Do heuristics
2392                // Allow RINS
2393                for (int i = 0; i < numberHeuristics_; i++) {
2394                    CbcHeuristicRINS * rins
2395                    = dynamic_cast<CbcHeuristicRINS *> (heuristic_[i]);
2396                    if (rins) {
2397                        rins->setLastNode(-100);
2398                    }
2399                }
2400            }
2401        }
2402    }
2403/*
2404  Run heuristics at the root. This is the only opportunity to run FPump; it
2405  will be removed from the heuristics list by doHeuristicsAtRoot.
2406*/
2407    // Do heuristics
2408    doHeuristicsAtRoot();
2409/*
2410  Grepping through the code, it would appear that this is a command line
2411  debugging hook.  There's no obvious place in the code where this is set to
2412  a negative value.
2413
2414  User hook, says John.
2415*/
2416    if ( intParam_[CbcMaxNumNode] < 0)
2417        eventHappened_ = true; // stop as fast as possible
2418    stoppedOnGap_ = false ;
2419    // See if can stop on gap
2420    bestPossibleObjective_ = solver_->getObjValue() * solver_->getObjSense();
2421    double testGap = CoinMax(dblParam_[CbcAllowableGap],
2422                             CoinMax(fabs(bestObjective_), fabs(bestPossibleObjective_))
2423                             * dblParam_[CbcAllowableFractionGap]);
2424    if (bestObjective_ - bestPossibleObjective_ < testGap && getCutoffIncrement() >= 0.0) {
2425        if (bestPossibleObjective_ < getCutoff())
2426            stoppedOnGap_ = true ;
2427        feasible = false;
2428        //eventHappened_=true; // stop as fast as possible
2429    }
2430/*
2431  Set up for statistics collection, if requested. Standard values are
2432  documented in CbcModel.hpp. The magic number 100 will trigger a dump of
2433  CbcSimpleIntegerDynamicPseudoCost objects (no others). Looks like another
2434  command line debugging hook.
2435*/
2436    statistics_ = NULL;
2437    // Do on switch
2438    if (doStatistics > 0 && doStatistics <= 100) {
2439        maximumStatistics_ = 10000;
2440        statistics_ = new CbcStatistics * [maximumStatistics_];
2441        memset(statistics_, 0, maximumStatistics_*sizeof(CbcStatistics *));
2442    }
2443    // See if we can add integers
2444    if (noObjects && numberIntegers_ < solver_->getNumCols() && (specialOptions_&65536) != 0 && !parentModel_)
2445        AddIntegers();
2446/*
2447  Do an initial round of cut generation for the root node. Depending on the
2448  type of underlying solver, we may want to do this even if the initial query
2449  to the objects indicates they're satisfied.
2450
2451  solveWithCuts does the heavy lifting. It will iterate a generate/reoptimise
2452  loop (including reduced cost fixing) until no cuts are generated, the
2453  change in objective falls off,  or the limit on the number of rounds of cut
2454  generation is exceeded.
2455
2456  At the end of all this, any cuts will be recorded in cuts and also
2457  installed in the solver's constraint system. We'll have reoptimised, and
2458  removed any slack cuts (numberOldActiveCuts_ and numberNewCuts_ have been
2459  adjusted accordingly).
2460*/
2461    int iObject ;
2462    int preferredWay ;
2463    int numberUnsatisfied = 0 ;
2464    delete [] currentSolution_;
2465    currentSolution_ = new double [numberColumns];
2466    testSolution_ = currentSolution_;
2467    memcpy(currentSolution_, solver_->getColSolution(),
2468           numberColumns*sizeof(double)) ;
2469    // point to useful information
2470    OsiBranchingInformation usefulInfo = usefulInformation();
2471
2472    for (iObject = 0 ; iObject < numberObjects_ ; iObject++) {
2473        double infeasibility =
2474            object_[iObject]->infeasibility(&usefulInfo, preferredWay) ;
2475        if (infeasibility ) numberUnsatisfied++ ;
2476    }
2477    // replace solverType
2478    if (solverCharacteristics_->tryCuts())  {
2479
2480        if (numberUnsatisfied)   {
2481            // User event
2482            if (!eventHappened_ && feasible) {
2483                feasible = solveWithCuts(cuts, maximumCutPassesAtRoot_,
2484                                         NULL);
2485                if ((specialOptions_&524288) != 0 && !parentModel_
2486                        && storedRowCuts_) {
2487                    if (feasible) {
2488                        /* pick up stuff and try again
2489                        add cuts, maybe keep around
2490                        do best solution and if so new heuristics
2491                        obviously tighten bounds
2492                        */
2493                        // A and B probably done on entry
2494                        // A) tight bounds on integer variables
2495                        const double * lower = solver_->getColLower();
2496                        const double * upper = solver_->getColUpper();
2497                        const double * tightLower = storedRowCuts_->tightLower();
2498                        const double * tightUpper = storedRowCuts_->tightUpper();
2499                        int nTightened = 0;
2500                        for (int i = 0; i < numberIntegers_; i++) {
2501                            int iColumn = integerVariable_[i];
2502                            if (tightLower[iColumn] > lower[iColumn]) {
2503                                nTightened++;
2504                                solver_->setColLower(iColumn, tightLower[iColumn]);
2505                            }
2506                            if (tightUpper[iColumn] < upper[iColumn]) {
2507                                nTightened++;
2508                                solver_->setColUpper(iColumn, tightUpper[iColumn]);
2509                            }
2510                        }
2511                        if (nTightened)
2512                            printf("%d tightened by alternate cuts\n", nTightened);
2513                        if (storedRowCuts_->bestObjective() < bestObjective_) {
2514                            // B) best solution
2515                            double objValue = storedRowCuts_->bestObjective();
2516                            setBestSolution(CBC_SOLUTION, objValue,
2517                                            storedRowCuts_->bestSolution()) ;
2518                            // Do heuristics
2519                            // Allow RINS
2520                            for (int i = 0; i < numberHeuristics_; i++) {
2521                                CbcHeuristicRINS * rins
2522                                = dynamic_cast<CbcHeuristicRINS *> (heuristic_[i]);
2523                                if (rins) {
2524                                    rins->setLastNode(-100);
2525                                }
2526                            }
2527                            doHeuristicsAtRoot();
2528                        }
2529#if 0
2530                        int nCuts = storedRowCuts_->sizeRowCuts();
2531                        // add to global list
2532                        for (int i = 0; i < nCuts; i++) {
2533                            OsiRowCut newCut(*storedRowCuts_->rowCutPointer(i));
2534                            newCut.setGloballyValidAsInteger(2);
2535                            newCut.mutableRow().setTestForDuplicateIndex(false);
2536                            globalCuts_.insert(newCut) ;
2537                        }
2538#else
2539                        addCutGenerator(storedRowCuts_, -99, "Stored from previous run",
2540                                        true, false, false, -200);
2541#endif
2542                        // Set cuts as active
2543                        delete [] addedCuts_ ;
2544                        maximumNumberCuts_ = cuts.sizeRowCuts();
2545                        if (maximumNumberCuts_) {
2546                            addedCuts_ = new CbcCountRowCut * [maximumNumberCuts_];
2547                        } else {
2548                            addedCuts_ = NULL;
2549                        }
2550                        for (int i = 0; i < maximumNumberCuts_; i++)
2551                            addedCuts_[i] = new CbcCountRowCut(*cuts.rowCutPtr(i),
2552                                                               NULL, -1, -1, 2);
2553                        printf("size %d\n", cuts.sizeRowCuts());
2554                        cuts = OsiCuts();
2555                        currentNumberCuts_ = maximumNumberCuts_;
2556                        feasible = solveWithCuts(cuts, maximumCutPassesAtRoot_,
2557                                                 NULL);
2558                        for (int i = 0; i < maximumNumberCuts_; i++)
2559                            delete addedCuts_[i];
2560                    }
2561                    delete storedRowCuts_;
2562                    storedRowCuts_ = NULL;
2563                }
2564            } else {
2565                feasible = false;
2566            }
2567        }       else if (solverCharacteristics_->solutionAddsCuts() ||
2568                   solverCharacteristics_->alwaysTryCutsAtRootNode()) {
2569            // may generate cuts and turn the solution
2570            //to an infeasible one
2571            feasible = solveWithCuts(cuts, 1,
2572                                     NULL);
2573        }
2574    }
2575    // check extra info on feasibility
2576    if (!solverCharacteristics_->mipFeasible())
2577        feasible = false;
2578
2579    // make cut generators less aggressive
2580    for (iCutGenerator = 0; iCutGenerator < numberCutGenerators_; iCutGenerator++) {
2581        CglCutGenerator * generator = generator_[iCutGenerator]->generator();
2582        generator->setAggressiveness(generator->getAggressiveness() - 100);
2583    }
2584    currentNumberCuts_ = numberNewCuts_ ;
2585    // See if can stop on gap
2586    bestPossibleObjective_ = solver_->getObjValue() * solver_->getObjSense();
2587    testGap = CoinMax(dblParam_[CbcAllowableGap],
2588                      CoinMax(fabs(bestObjective_), fabs(bestPossibleObjective_))
2589                      * dblParam_[CbcAllowableFractionGap]);
2590    if (bestObjective_ - bestPossibleObjective_ < testGap && getCutoffIncrement() >= 0.0) {
2591        if (bestPossibleObjective_ < getCutoff())
2592            stoppedOnGap_ = true ;
2593        feasible = false;
2594    }
2595    // User event
2596    if (eventHappened_)
2597        feasible = false;
2598#if defined(COIN_HAS_CLP)&&defined(COIN_HAS_CPX)
2599/*
2600  This is the notion of using Cbc stuff to get going, then calling cplex to
2601  finish off.
2602*/
2603    if (feasible && (specialOptions_&16384) != 0 && fastNodeDepth_ == -2 && !parentModel_) {
2604        // Use Cplex to do search!
2605        double time1 = CoinCpuTime();
2606        OsiClpSolverInterface * clpSolver
2607        = dynamic_cast<OsiClpSolverInterface *> (solver_);
2608        OsiCpxSolverInterface cpxSolver;
2609        double direction = clpSolver->getObjSense();
2610        cpxSolver.setObjSense(direction);
2611        // load up cplex
2612        const CoinPackedMatrix * matrix = continuousSolver_->getMatrixByCol();
2613        const double * rowLower = continuousSolver_->getRowLower();
2614        const double * rowUpper = continuousSolver_->getRowUpper();
2615        const double * columnLower = continuousSolver_->getColLower();
2616        const double * columnUpper = continuousSolver_->getColUpper();
2617        const double * objective = continuousSolver_->getObjCoefficients();
2618        cpxSolver.loadProblem(*matrix, columnLower, columnUpper,
2619                              objective, rowLower, rowUpper);
2620        double * setSol = new double [numberIntegers_];
2621        int * setVar = new int [numberIntegers_];
2622        // cplex doesn't know about objective offset
2623        double offset = clpSolver->getModelPtr()->objectiveOffset();
2624        for (int i = 0; i < numberIntegers_; i++) {
2625            int iColumn = integerVariable_[i];
2626            cpxSolver.setInteger(iColumn);
2627            if (bestSolution_) {
2628                setSol[i] = bestSolution_[iColumn];
2629                setVar[i] = iColumn;
2630            }
2631        }
2632        CPXENVptr env = cpxSolver.getEnvironmentPtr();
2633        CPXLPptr lpPtr = cpxSolver.getLpPtr(OsiCpxSolverInterface::KEEPCACHED_ALL);
2634        cpxSolver.switchToMIP();
2635        if (bestSolution_) {
2636            CPXcopymipstart(env, lpPtr, numberIntegers_, setVar, setSol);
2637        }
2638        if (clpSolver->getNumRows() > continuousSolver_->getNumRows() && false) {
2639            // add cuts
2640            const CoinPackedMatrix * matrix = clpSolver->getMatrixByRow();
2641            const double * rhs = clpSolver->getRightHandSide();
2642            const char * rowSense = clpSolver->getRowSense();
2643            const double * elementByRow = matrix->getElements();
2644            const int * column = matrix->getIndices();
2645            const CoinBigIndex * rowStart = matrix->getVectorStarts();
2646            const int * rowLength = matrix->getVectorLengths();
2647            int nStart = continuousSolver_->getNumRows();
2648            int nRows = clpSolver->getNumRows();
2649            int size = rowStart[nRows-1] + rowLength[nRows-1] -
2650                       rowStart[nStart];
2651            int nAdd = 0;
2652            double * rmatval = new double [size];
2653            int * rmatind = new int [size];
2654            int * rmatbeg = new int [nRows-nStart+1];
2655            size = 0;
2656            rmatbeg[0] = 0;
2657            for (int i = nStart; i < nRows; i++) {
2658                for (int k = rowStart[i]; k < rowStart[i] + rowLength[i]; k++) {
2659                    rmatind[size] = column[k];
2660                    rmatval[size++] = elementByRow[k];
2661                }
2662                nAdd++;
2663                rmatbeg[nAdd] = size;
2664            }
2665            CPXaddlazyconstraints(env, lpPtr, nAdd, size,
2666                                  rhs, rowSense, rmatbeg,
2667                                  rmatind, rmatval, NULL);
2668            CPXsetintparam( env, CPX_PARAM_REDUCE,
2669                            // CPX_PREREDUCE_NOPRIMALORDUAL (0)
2670                            CPX_PREREDUCE_PRIMALONLY);
2671        }
2672        if (getCutoff() < 1.0e50) {
2673            double useCutoff = getCutoff() + offset;
2674            if (bestObjective_ < 1.0e50)
2675                useCutoff = bestObjective_ + offset + 1.0e-7;
2676            cpxSolver.setDblParam(OsiDualObjectiveLimit, useCutoff*
2677                                  direction);
2678            if ( direction > 0.0 )
2679                CPXsetdblparam( env, CPX_PARAM_CUTUP, useCutoff ) ; // min
2680            else
2681                CPXsetdblparam( env, CPX_PARAM_CUTLO, useCutoff ) ; // max
2682        }
2683        CPXsetdblparam(env, CPX_PARAM_EPGAP, dblParam_[CbcAllowableFractionGap]);
2684        delete [] setSol;
2685        delete [] setVar;
2686        char printBuffer[200];
2687        if (offset) {
2688            sprintf(printBuffer, "Add %g to all Cplex messages for true objective",
2689                    -offset);
2690            messageHandler()->message(CBC_GENERAL, messages())
2691            << printBuffer << CoinMessageEol ;
2692            cpxSolver.setDblParam(OsiObjOffset, offset);
2693        }
2694        cpxSolver.branchAndBound();
2695        double timeTaken = CoinCpuTime() - time1;
2696        sprintf(printBuffer, "Cplex took %g seconds",
2697                timeTaken);
2698        messageHandler()->message(CBC_GENERAL, messages())
2699        << printBuffer << CoinMessageEol ;
2700        numberExtraNodes_ = CPXgetnodecnt(env, lpPtr);
2701        numberExtraIterations_ = CPXgetmipitcnt(env, lpPtr);
2702        double value = cpxSolver.getObjValue() * direction;
2703        if (cpxSolver.isProvenOptimal() && value <= getCutoff()) {
2704            feasible = true;
2705            clpSolver->setWarmStart(NULL);
2706            // try and do solution
2707            double * newSolution =
2708                CoinCopyOfArray(cpxSolver.getColSolution(),
2709                                getNumCols());
2710            setBestSolution(CBC_STRONGSOL, value, newSolution) ;
2711            delete [] newSolution;
2712        }
2713        feasible = false;
2714    }
2715#endif
2716/*
2717  A hook to use clp to quickly explore some part of the tree.
2718*/
2719    if (fastNodeDepth_ == 1000 &&/*!parentModel_*/(specialOptions_&2048) == 0) {
2720        fastNodeDepth_ = -1;
2721        CbcObject * obj =
2722            new CbcFollowOn(this);
2723        obj->setPriority(1);
2724        addObjects(1, &obj);
2725    }
2726    int saveNumberSolves = numberSolves_;
2727    int saveNumberIterations = numberIterations_;
2728    if (fastNodeDepth_ >= 0 &&/*!parentModel_*/(specialOptions_&2048) == 0) {
2729        // add in a general depth object doClp
2730        int type = (fastNodeDepth_ <= 100) ? fastNodeDepth_ : -(fastNodeDepth_ - 100);
2731        CbcObject * obj =
2732            new CbcGeneralDepth(this, type);
2733        addObjects(1, &obj);
2734        // mark as done
2735        fastNodeDepth_ += 1000000;
2736        delete obj;
2737        // fake number of objects
2738        numberObjects_--;
2739        if (parallelMode() < -1) {
2740            // But make sure position is correct
2741            OsiObject * obj2 = object_[numberObjects_];
2742            obj = dynamic_cast<CbcObject *> (obj2);
2743            assert (obj);
2744            obj->setPosition(numberObjects_);
2745        }
2746    }
2747#ifdef COIN_HAS_CLP
2748#ifdef NO_CRUNCH
2749    if (true) {
2750        OsiClpSolverInterface * clpSolver
2751        = dynamic_cast<OsiClpSolverInterface *> (solver_);
2752        if (clpSolver && !parentModel_) {
2753            ClpSimplex * clpSimplex = clpSolver->getModelPtr();
2754            clpSimplex->setSpecialOptions(clpSimplex->specialOptions() | 131072);
2755            //clpSimplex->startPermanentArrays();
2756            clpSimplex->setPersistenceFlag(2);
2757        }
2758    }
2759#endif
2760#endif
2761// Save copy of solver
2762    OsiSolverInterface * saveSolver = NULL;
2763    if (!parentModel_ && (specialOptions_&(512 + 32768)) != 0)
2764        saveSolver = solver_->clone();
2765    double checkCutoffForRestart = 1.0e100;
2766    saveModel(saveSolver, &checkCutoffForRestart, &feasible);
2767    if ((specialOptions_&262144) != 0 && !parentModel_) {
2768        // Save stuff and return!
2769        storedRowCuts_->saveStuff(bestObjective_, bestSolution_,
2770                                  solver_->getColLower(),
2771                                  solver_->getColUpper());
2772        delete [] lowerBefore;
2773        delete [] upperBefore;
2774        delete saveSolver;
2775        return;
2776    }
2777    /*
2778      We've taken the continuous relaxation as far as we can. Time to branch.
2779      The first order of business is to actually create a node. chooseBranch
2780      currently uses strong branching to evaluate branch object candidates,
2781      unless forced back to simple branching. If chooseBranch concludes that a
2782      branching candidate is monotone (anyAction == -1) or infeasible (anyAction
2783      == -2) when forced to integer values, it returns here immediately.
2784
2785      Monotone variables trigger a call to resolve(). If the problem remains
2786      feasible, try again to choose a branching variable. At the end of the loop,
2787      resolved == true indicates that some variables were fixed.
2788
2789      Loss of feasibility will result in the deletion of newNode.
2790    */
2791
2792    bool resolved = false ;
2793    CbcNode *newNode = NULL ;
2794    numberFixedAtRoot_ = 0;
2795    numberFixedNow_ = 0;
2796    int numberIterationsAtContinuous = numberIterations_;
2797    //solverCharacteristics_->setSolver(solver_);
2798    if (feasible) {
2799        //#define HOTSTART -1
2800#if HOTSTART<0
2801        if (bestSolution_ && !parentModel_ && !hotstartSolution_ &&
2802                (moreSpecialOptions_&1024) != 0) {
2803            // Set priorities so only branch on ones we need to
2804            // use djs and see if only few branches needed
2805#ifndef NDEBUG
2806            double integerTolerance = getIntegerTolerance() ;
2807#endif
2808            bool possible = true;
2809            const double * saveLower = continuousSolver_->getColLower();
2810            const double * saveUpper = continuousSolver_->getColUpper();
2811            for (int i = 0; i < numberObjects_; i++) {
2812                const CbcSimpleInteger * thisOne = dynamic_cast <const CbcSimpleInteger *> (object_[i]);
2813                if (thisOne) {
2814                    int iColumn = thisOne->columnNumber();
2815                    if (saveUpper[iColumn] > saveLower[iColumn] + 1.5) {
2816                        possible = false;
2817                        break;
2818                    }
2819                } else {
2820                    possible = false;
2821                    break;
2822                }
2823            }
2824            if (possible) {
2825                OsiSolverInterface * solver = continuousSolver_->clone();
2826                int numberColumns = solver->getNumCols();
2827                for (int iColumn = 0 ; iColumn < numberColumns ; iColumn++) {
2828                    double value = bestSolution_[iColumn] ;
2829                    value = CoinMax(value, saveLower[iColumn]) ;
2830                    value = CoinMin(value, saveUpper[iColumn]) ;
2831                    value = floor(value + 0.5);
2832                    if (solver->isInteger(iColumn)) {
2833                        solver->setColLower(iColumn, value);
2834                        solver->setColUpper(iColumn, value);
2835                    }
2836                }
2837                solver->setHintParam(OsiDoDualInResolve, false, OsiHintTry);
2838                // objlim and all slack
2839                double direction = solver->getObjSense();
2840                solver->setDblParam(OsiDualObjectiveLimit, 1.0e50*direction);
2841                CoinWarmStartBasis * basis = dynamic_cast<CoinWarmStartBasis *> (solver->getEmptyWarmStart());
2842                solver->setWarmStart(basis);
2843                delete basis;
2844                bool changed = true;
2845                hotstartPriorities_ = new int [numberColumns];
2846                for (int iColumn = 0; iColumn < numberColumns; iColumn++)
2847                    hotstartPriorities_[iColumn] = 1;
2848                while (changed) {
2849                    changed = false;
2850                    solver->resolve();
2851                    if (!solver->isProvenOptimal()) {
2852                        possible = false;
2853                        break;
2854                    }
2855                    const double * dj = solver->getReducedCost();
2856                    const double * colLower = solver->getColLower();
2857                    const double * colUpper = solver->getColUpper();
2858                    const double * solution = solver->getColSolution();
2859                    int nAtLbNatural = 0;
2860                    int nAtUbNatural = 0;
2861                    int nZeroDj = 0;
2862                    int nForced = 0;
2863                    for (int iColumn = 0 ; iColumn < numberColumns ; iColumn++) {
2864                        double value = solution[iColumn] ;
2865                        value = CoinMax(value, saveLower[iColumn]) ;
2866                        value = CoinMin(value, saveUpper[iColumn]) ;
2867                        if (solver->isInteger(iColumn)) {
2868                            assert(fabs(value - solution[iColumn]) <= integerTolerance) ;
2869                            if (hotstartPriorities_[iColumn] == 1) {
2870                                if (dj[iColumn] < -1.0e-6) {
2871                                    // negative dj
2872                                    if (saveUpper[iColumn] == colUpper[iColumn]) {
2873                                        nAtUbNatural++;
2874                                        hotstartPriorities_[iColumn] = 2;
2875                                        solver->setColLower(iColumn, saveLower[iColumn]);
2876                                        solver->setColUpper(iColumn, saveUpper[iColumn]);
2877                                    } else {
2878                                        nForced++;
2879                                    }
2880                                } else if (dj[iColumn] > 1.0e-6) {
2881                                    // positive dj
2882                                    if (saveLower[iColumn] == colLower[iColumn]) {
2883                                        nAtLbNatural++;
2884                                        hotstartPriorities_[iColumn] = 2;
2885                                        solver->setColLower(iColumn, saveLower[iColumn]);
2886                                        solver->setColUpper(iColumn, saveUpper[iColumn]);
2887                                    } else {
2888                                        nForced++;
2889                                    }
2890                                } else {
2891                                    // zero dj
2892                                    nZeroDj++;
2893                                }
2894                            }
2895                        }
2896                    }
2897#ifdef CLP_INVESTIGATE
2898                    printf("%d forced, %d naturally at lower, %d at upper - %d zero dj\n",
2899                           nForced, nAtLbNatural, nAtUbNatural, nZeroDj);
2900#endif
2901                    if (nAtLbNatural || nAtUbNatural) {
2902                        changed = true;
2903                    } else {
2904                        if (nForced + nZeroDj > 50 ||
2905                                (nForced + nZeroDj)*4 > numberIntegers_)
2906                            possible = false;
2907                    }
2908                }
2909                delete solver;
2910            }
2911            if (possible) {
2912                setHotstartSolution(bestSolution_);
2913                if (!saveCompare) {
2914                    // create depth first comparison
2915                    saveCompare = nodeCompare_;
2916                    // depth first
2917                    nodeCompare_ = new CbcCompareDepth();
2918                    tree_->setComparison(*nodeCompare_) ;
2919                }
2920            } else {
2921                delete [] hotstartPriorities_;
2922                hotstartPriorities_ = NULL;
2923            }
2924        }
2925#endif
2926#if HOTSTART>0
2927        if (hotstartSolution_ && !hotstartPriorities_) {
2928            // Set up hot start
2929            OsiSolverInterface * solver = solver_->clone();
2930            double direction = solver_->getObjSense() ;
2931            int numberColumns = solver->getNumCols();
2932            double * saveLower = CoinCopyOfArray(solver->getColLower(), numberColumns);
2933            double * saveUpper = CoinCopyOfArray(solver->getColUpper(), numberColumns);
2934            // move solution
2935            solver->setColSolution(hotstartSolution_);
2936            // point to useful information
2937            const double * saveSolution = testSolution_;
2938            testSolution_ = solver->getColSolution();
2939            OsiBranchingInformation usefulInfo = usefulInformation();
2940            testSolution_ = saveSolution;
2941            /*
2942            Run through the objects and use feasibleRegion() to set variable bounds
2943            so as to fix the variables specified in the objects at their value in this
2944            solution. Since the object list contains (at least) one object for every
2945            integer variable, this has the effect of fixing all integer variables.
2946            */
2947            for (int i = 0; i < numberObjects_; i++)
2948                object_[i]->feasibleRegion(solver, &usefulInfo);
2949            solver->resolve();
2950            assert (solver->isProvenOptimal());
2951            double gap = CoinMax((solver->getObjValue() - solver_->getObjValue()) * direction, 0.0) ;
2952            const double * dj = solver->getReducedCost();
2953            const double * colLower = solver->getColLower();
2954            const double * colUpper = solver->getColUpper();
2955            const double * solution = solver->getColSolution();
2956            int nAtLbNatural = 0;
2957            int nAtUbNatural = 0;
2958            int nAtLbNaturalZero = 0;
2959            int nAtUbNaturalZero = 0;
2960            int nAtLbFixed = 0;
2961            int nAtUbFixed = 0;
2962            int nAtOther = 0;
2963            int nAtOtherNatural = 0;
2964            int nNotNeeded = 0;
2965            delete [] hotstartSolution_;
2966            hotstartSolution_ = new double [numberColumns];
2967            delete [] hotstartPriorities_;
2968            hotstartPriorities_ = new int [numberColumns];
2969            int * order = (int *) saveUpper;
2970            int nFix = 0;
2971            double bestRatio = COIN_DBL_MAX;
2972            for (int iColumn = 0 ; iColumn < numberColumns ; iColumn++) {
2973                double value = solution[iColumn] ;
2974                value = CoinMax(value, saveLower[iColumn]) ;
2975                value = CoinMin(value, saveUpper[iColumn]) ;
2976                double sortValue = COIN_DBL_MAX;
2977                if (solver->isInteger(iColumn)) {
2978                    assert(fabs(value - solution[iColumn]) <= 1.0e-5) ;
2979                    double value2 = floor(value + 0.5);
2980                    if (dj[iColumn] < -1.0e-6) {
2981                        // negative dj
2982                        //assert (value2==colUpper[iColumn]);
2983                        if (saveUpper[iColumn] == colUpper[iColumn]) {
2984                            nAtUbNatural++;
2985                            sortValue = 0.0;
2986                            double value = -dj[iColumn];
2987                            if (value > gap)
2988                                nFix++;
2989                            else if (gap < value*bestRatio)
2990                                bestRatio = gap / value;
2991                            if (saveLower[iColumn] != colLower[iColumn]) {
2992                                nNotNeeded++;
2993                                sortValue = 1.0e20;
2994                            }
2995                        } else if (saveLower[iColumn] == colUpper[iColumn]) {
2996                            nAtLbFixed++;
2997                            sortValue = dj[iColumn];
2998                        } else {
2999                            nAtOther++;
3000                            sortValue = 0.0;
3001                            if (saveLower[iColumn] != colLower[iColumn] &&
3002                                    saveUpper[iColumn] != colUpper[iColumn]) {
3003                                nNotNeeded++;
3004                                sortValue = 1.0e20;
3005                            }
3006                        }
3007                    } else if (dj[iColumn] > 1.0e-6) {
3008                        // positive dj
3009                        //assert (value2==colLower[iColumn]);
3010                        if (saveLower[iColumn] == colLower[iColumn]) {
3011                            nAtLbNatural++;
3012                            sortValue = 0.0;
3013                            double value = dj[iColumn];
3014                            if (value > gap)
3015                                nFix++;
3016                            else if (gap < value*bestRatio)
3017                                bestRatio = gap / value;
3018                            if (saveUpper[iColumn] != colUpper[iColumn]) {
3019                                nNotNeeded++;
3020                                sortValue = 1.0e20;
3021                            }
3022                        } else if (saveUpper[iColumn] == colLower[iColumn]) {
3023                            nAtUbFixed++;
3024                            sortValue = -dj[iColumn];
3025                        } else {
3026                            nAtOther++;
3027                            sortValue = 0.0;
3028                            if (saveLower[iColumn] != colLower[iColumn] &&
3029                                    saveUpper[iColumn] != colUpper[iColumn]) {
3030                                nNotNeeded++;
3031                                sortValue = 1.0e20;
3032                            }
3033                        }
3034                    } else {
3035                        // zero dj
3036                        if (value2 == saveUpper[iColumn]) {
3037                            nAtUbNaturalZero++;
3038                            sortValue = 0.0;
3039                            if (saveLower[iColumn] != colLower[iColumn]) {
3040                                nNotNeeded++;
3041                                sortValue = 1.0e20;
3042                            }
3043                        } else if (value2 == saveLower[iColumn]) {
3044                            nAtLbNaturalZero++;
3045                            sortValue = 0.0;
3046                        } else {
3047                            nAtOtherNatural++;
3048                            sortValue = 0.0;
3049                            if (saveLower[iColumn] != colLower[iColumn] &&
3050                                    saveUpper[iColumn] != colUpper[iColumn]) {
3051                                nNotNeeded++;
3052                                sortValue = 1.0e20;
3053                            }
3054                        }
3055                    }
3056#if HOTSTART==3
3057                    sortValue = -fabs(dj[iColumn]);
3058#endif
3059                }
3060                hotstartSolution_[iColumn] = value ;
3061                saveLower[iColumn] = sortValue;
3062                order[iColumn] = iColumn;
3063            }
3064            printf("** can fix %d columns - best ratio for others is %g on gap of %g\n",
3065                   nFix, bestRatio, gap);
3066            int nNeg = 0;
3067            CoinSort_2(saveLower, saveLower + numberColumns, order);
3068            for (int i = 0; i < numberColumns; i++) {
3069                if (saveLower[i] < 0.0) {
3070                    nNeg++;
3071#if HOTSTART==2||HOTSTART==3
3072                    // swap sign ?
3073                    saveLower[i] = -saveLower[i];
3074#endif
3075                }
3076            }
3077            CoinSort_2(saveLower, saveLower + nNeg, order);
3078            for (int i = 0; i < numberColumns; i++) {
3079#if HOTSTART==1
3080                hotstartPriorities_[order[i]] = 100;
3081#else
3082                hotstartPriorities_[order[i]] = -(i + 1);
3083#endif
3084            }
3085            printf("nAtLbNat %d,nAtUbNat %d,nAtLbNatZero %d,nAtUbNatZero %d,nAtLbFixed %d,nAtUbFixed %d,nAtOther %d,nAtOtherNat %d, useless %d %d\n",
3086                   nAtLbNatural,
3087                   nAtUbNatural,
3088                   nAtLbNaturalZero,
3089                   nAtUbNaturalZero,
3090                   nAtLbFixed,
3091                   nAtUbFixed,
3092                   nAtOther,
3093                   nAtOtherNatural, nNotNeeded, nNeg);
3094            delete [] saveLower;
3095            delete [] saveUpper;
3096            if (!saveCompare) {
3097                // create depth first comparison
3098                saveCompare = nodeCompare_;
3099                // depth first
3100                nodeCompare_ = new CbcCompareDepth();
3101                tree_->setComparison(*nodeCompare_) ;
3102            }
3103        }
3104#endif
3105        newNode = new CbcNode ;
3106        // Set objective value (not so obvious if NLP etc)
3107        setObjectiveValue(newNode, NULL);
3108        anyAction = -1 ;
3109        // To make depth available we may need a fake node
3110        CbcNode fakeNode;
3111        if (!currentNode_) {
3112            // Not true if sub trees assert (!numberNodes_);
3113            currentNode_ = &fakeNode;
3114        }
3115        phase_ = 3;
3116        // only allow 1000 passes
3117        int numberPassesLeft = 1000;
3118        // This is first crude step
3119        if (numberAnalyzeIterations_) {
3120            delete [] analyzeResults_;
3121            analyzeResults_ = new double [4*numberIntegers_];
3122            numberFixedAtRoot_ = newNode->analyze(this, analyzeResults_);
3123            if (numberFixedAtRoot_ > 0) {
3124                printf("%d fixed by analysis\n", numberFixedAtRoot_);
3125                setPointers(solver_);
3126                numberFixedNow_ = numberFixedAtRoot_;
3127            } else if (numberFixedAtRoot_ < 0) {
3128                printf("analysis found to be infeasible\n");
3129                anyAction = -2;
3130                delete newNode ;
3131                newNode = NULL ;
3132                feasible = false ;
3133            }
3134        }
3135        OsiSolverBranch * branches = NULL;
3136        anyAction = chooseBranch(newNode, numberPassesLeft, NULL, cuts, resolved,
3137                                 NULL, NULL, NULL, branches);
3138        if (anyAction == -2 || newNode->objectiveValue() >= cutoff) {
3139            if (anyAction != -2) {
3140                // zap parent nodeInfo
3141#ifdef COIN_DEVELOP
3142                printf("zapping CbcNodeInfo %x\n", reinterpret_cast<int>(newNode->nodeInfo()->parent()));
3143#endif
3144                if (newNode->nodeInfo())
3145                    newNode->nodeInfo()->nullParent();
3146            }
3147            delete newNode ;
3148            newNode = NULL ;
3149            feasible = false ;
3150        }
3151    }
3152    if (newNode && probingInfo_) {
3153        int number01 = probingInfo_->numberIntegers();
3154        //const fixEntry * entry = probingInfo_->fixEntries();
3155        const int * toZero = probingInfo_->toZero();
3156        //const int * toOne = probingInfo_->toOne();
3157        //const int * integerVariable = probingInfo_->integerVariable();
3158        if (toZero[number01]) {
3159            CglTreeProbingInfo info(*probingInfo_);
3160#if 0
3161/*
3162  Marginal idea. Further exploration probably good. Build some extra
3163  cliques from probing info. Not quite worth the effort?
3164*/
3165            OsiSolverInterface * fake = info.analyze(*solver_, 1);
3166            if (fake) {
3167                fake->writeMps("fake");
3168                CglFakeClique cliqueGen(fake);
3169                cliqueGen.setStarCliqueReport(false);
3170                cliqueGen.setRowCliqueReport(false);
3171                cliqueGen.setMinViolation(0.1);
3172                addCutGenerator(&cliqueGen, 1, "Fake cliques", true, false, false, -200);
3173                generator_[numberCutGenerators_-1]->setTiming(true);
3174            }
3175#endif
3176            if (probingInfo_->packDown()) {
3177#ifdef CLP_INVESTIGATE
3178                printf("%d implications on %d 0-1\n", toZero[number01], number01);
3179#endif
3180                // Create a cut generator that remembers implications discovered at root.
3181                CglImplication implication(probingInfo_);
3182                addCutGenerator(&implication, 1, "ImplicationCuts", true, false, false, -200);
3183            } else {
3184                delete probingInfo_;
3185                probingInfo_ = NULL;
3186            }
3187        } else {
3188            delete probingInfo_;
3189
3190            probingInfo_ = NULL;
3191        }
3192    }
3193    /*
3194      At this point, the root subproblem is infeasible or fathomed by bound
3195      (newNode == NULL), or we're live with an objective value that satisfies the
3196      current objective cutoff.
3197    */
3198    assert (!newNode || newNode->objectiveValue() <= cutoff) ;
3199    // Save address of root node as we don't want to delete it
3200    // initialize for print out
3201    int lastDepth = 0;
3202    int lastUnsatisfied = 0;
3203    if (newNode)
3204        lastUnsatisfied = newNode->numberUnsatisfied();
3205    /*
3206      The common case is that the lp relaxation is feasible but doesn't satisfy
3207      integrality (i.e., newNode->branchingObject(), indicating we've been able to
3208      select a branching variable). Remove any cuts that have gone slack due to
3209      forcing monotone variables. Then tack on an CbcFullNodeInfo object and full
3210      basis (via createInfo()) and stash the new cuts in the nodeInfo (via
3211      addCuts()). If, by some miracle, we have an integral solution at the root
3212      (newNode->branchingObject() is NULL), takeOffCuts() will ensure that the solver holds
3213      a valid solution for use by setBestSolution().
3214    */
3215    CoinWarmStartBasis *lastws = NULL ;
3216    if (feasible && newNode->branchingObject()) {
3217        if (resolved) {
3218            takeOffCuts(cuts, false, NULL) ;
3219#     ifdef CHECK_CUT_COUNTS
3220            { printf("Number of rows after chooseBranch fix (root)"
3221                         "(active only) %d\n",
3222                         numberRowsAtContinuous_ + numberNewCuts_ + numberOldActiveCuts_) ;
3223                const CoinWarmStartBasis* debugws =
3224                    dynamic_cast <const CoinWarmStartBasis*>(solver_->getWarmStart()) ;
3225                debugws->print() ;
3226                delete debugws ;
3227            }
3228#     endif
3229        }
3230        //newNode->createInfo(this,NULL,NULL,NULL,NULL,0,0) ;
3231        //newNode->nodeInfo()->addCuts(cuts,
3232        //                       newNode->numberBranches(),whichGenerator_) ;
3233        if (lastws) delete lastws ;
3234        lastws = dynamic_cast<CoinWarmStartBasis*>(solver_->getWarmStart()) ;
3235    }
3236    /*
3237      Continuous data to be used later
3238    */
3239    continuousObjective_ = solver_->getObjValue() * solver_->getObjSense();
3240    continuousInfeasibilities_ = 0 ;
3241    if (newNode) {
3242        continuousObjective_ = newNode->objectiveValue() ;
3243        delete [] continuousSolution_;
3244        continuousSolution_ = CoinCopyOfArray(solver_->getColSolution(),
3245                                              numberColumns);
3246        continuousInfeasibilities_ = newNode->numberUnsatisfied() ;
3247    }
3248    /*
3249      Bound may have changed so reset in objects
3250    */
3251    {
3252        int i ;
3253        for (i = 0; i < numberObjects_; i++)
3254            object_[i]->resetBounds(solver_) ;
3255    }
3256    /*
3257      Feasible? Then we should have either a live node prepped for future
3258      expansion (indicated by variable() >= 0), or (miracle of miracles) an
3259      integral solution at the root node.
3260
3261      initializeInfo sets the reference counts in the nodeInfo object.  Since
3262      this node is still live, push it onto the heap that holds the live set.
3263    */
3264    double bestValue = 0.0 ;
3265    if (newNode) {
3266        bestValue = newNode->objectiveValue();
3267        if (newNode->branchingObject()) {
3268            newNode->initializeInfo() ;
3269            tree_->push(newNode) ;
3270            if (statistics_) {
3271                if (numberNodes2_ == maximumStatistics_) {
3272                    maximumStatistics_ = 2 * maximumStatistics_;
3273                    CbcStatistics ** temp = new CbcStatistics * [maximumStatistics_];
3274                    memset(temp, 0, maximumStatistics_*sizeof(CbcStatistics *));
3275                    memcpy(temp, statistics_, numberNodes2_*sizeof(CbcStatistics *));
3276                    delete [] statistics_;
3277                    statistics_ = temp;
3278                }
3279                assert (!statistics_[numberNodes2_]);
3280                statistics_[numberNodes2_] = new CbcStatistics(newNode, this);
3281            }
3282            numberNodes2_++;
3283#     ifdef CHECK_NODE
3284            printf("Node %x on tree\n", newNode) ;
3285#     endif
3286        } else {
3287            // continuous is integer
3288            double objectiveValue = newNode->objectiveValue();
3289            setBestSolution(CBC_SOLUTION, objectiveValue,
3290                            solver_->getColSolution()) ;
3291            delete newNode ;
3292            newNode = NULL ;
3293        }
3294    }
3295
3296    if (printFrequency_ <= 0) {
3297        printFrequency_ = 1000 ;
3298        if (getNumCols() > 2000)
3299            printFrequency_ = 100 ;
3300    }
3301    /*
3302      It is possible that strong branching fixes one variable and then the code goes round
3303      again and again.  This can take too long.  So we need to warn user - just once.
3304    */
3305    numberLongStrong_ = 0;
3306    CbcNode * createdNode = NULL;
3307#ifdef CBC_THREAD
3308    CbcModel ** threadModel = NULL;
3309    Coin_pthread_t * threadId = NULL;
3310    int * threadCount = NULL;
3311    pthread_mutex_t mutex;
3312    pthread_cond_t condition_main;
3313    pthread_mutex_t condition_mutex;
3314    pthread_mutex_t * mutex2 = NULL;
3315    pthread_cond_t * condition2 = NULL;
3316    threadStruct * threadInfo = NULL;
3317    bool locked = false;
3318    int threadStats[6];
3319    int defaultParallelIterations = 400;
3320    int defaultParallelNodes = 2;
3321    memset(threadStats, 0, sizeof(threadStats));
3322    double timeWaiting = 0.0;
3323    // For now just one model
3324    if (numberThreads_) {
3325        nodeCompare_->sayThreaded(); // need to use addresses
3326        threadId = new Coin_pthread_t [numberThreads_];
3327        threadCount = new int [numberThreads_];
3328        CoinZeroN(threadCount, numberThreads_);
3329        pthread_mutex_init(&mutex, NULL);
3330        pthread_cond_init(&condition_main, NULL);
3331        pthread_mutex_init(&condition_mutex, NULL);
3332        threadModel = new CbcModel * [numberThreads_+1];
3333        threadInfo = new threadStruct [numberThreads_+1];
3334        mutex2 = new pthread_mutex_t [numberThreads_];
3335        condition2 = new pthread_cond_t [numberThreads_];
3336        if (parallelMode() < -1) {
3337            // May need for deterministic
3338            saveObjects = new OsiObject * [numberObjects_];
3339            for (int i = 0; i < numberObjects_; i++) {
3340                saveObjects[i] = object_[i]->clone();
3341            }
3342        }
3343        // we don't want a strategy object
3344        CbcStrategy * saveStrategy = strategy_;
3345        strategy_ = NULL;
3346        for (int i = 0; i < numberThreads_; i++) {
3347            pthread_mutex_init(mutex2 + i, NULL);
3348            pthread_cond_init(condition2 + i, NULL);
3349            threadId[i].status = 0;
3350            threadInfo[i].baseModel = this;
3351            threadModel[i] = new CbcModel(*this, true);
3352            threadModel[i]->synchronizeHandlers(1);
3353#ifdef COIN_HAS_CLP
3354            // Solver may need to know about model
3355            CbcModel * thisModel = threadModel[i];
3356            CbcOsiSolver * solver =
3357                dynamic_cast<CbcOsiSolver *>(thisModel->solver()) ;
3358            if (solver)
3359                solver->setCbcModel(thisModel);
3360#endif
3361            mutex_ = reinterpret_cast<void *> (threadInfo + i);
3362            threadModel[i]->moveToModel(this, -1);
3363            threadInfo[i].thisModel = threadModel[i];
3364            threadInfo[i].node = NULL;
3365            threadInfo[i].createdNode = NULL;
3366            threadInfo[i].threadIdOfBase.thr = pthread_self();
3367            threadInfo[i].mutex = &mutex;
3368            threadInfo[i].mutex2 = mutex2 + i;
3369            threadInfo[i].condition2 = condition2 + i;
3370            threadInfo[i].returnCode = -1;
3371            threadInfo[i].timeLocked = 0.0;
3372            threadInfo[i].timeWaitingToLock = 0.0;
3373            threadInfo[i].timeWaitingToStart = 0.0;
3374            threadInfo[i].timeInThread = 0.0;
3375            threadInfo[i].numberTimesLocked = 0;
3376            threadInfo[i].numberTimesUnlocked = 0;
3377            threadInfo[i].numberTimesWaitingToStart = 0;
3378            threadInfo[i].dantzigState = 0; // 0 unset, -1 waiting to be set, 1 set
3379            threadInfo[i].locked = false;
3380            threadInfo[i].delNode = NULL;
3381            threadInfo[i].maxDeleteNode = 0;
3382            threadInfo[i].nDeleteNode = 0;
3383            threadInfo[i].nodesThisTime = 0;
3384            threadInfo[i].iterationsThisTime = 0;
3385            pthread_create(&(threadId[i].thr), NULL, doNodesThread, threadInfo + i);
3386            threadId[i].status = 1;
3387        }
3388        strategy_ = saveStrategy;
3389        // Do a partial one for base model
3390        threadInfo[numberThreads_].baseModel = this;
3391        threadModel[numberThreads_] = this;
3392        mutex_ = reinterpret_cast<void *> (threadInfo + numberThreads_);
3393        threadInfo[numberThreads_].node = NULL;
3394        threadInfo[numberThreads_].mutex = &mutex;
3395        threadInfo[numberThreads_].condition2 = &condition_main;
3396        threadInfo[numberThreads_].mutex2 = &condition_mutex;
3397        threadInfo[numberThreads_].timeLocked = 0.0;
3398        threadInfo[numberThreads_].timeWaitingToLock = 0.0;
3399        threadInfo[numberThreads_].numberTimesLocked = 0;
3400        threadInfo[numberThreads_].numberTimesUnlocked = 0;
3401        threadInfo[numberThreads_].locked = false;
3402    }
3403#endif
3404#ifdef COIN_HAS_CLP
3405    {
3406        OsiClpSolverInterface * clpSolver
3407        = dynamic_cast<OsiClpSolverInterface *> (solver_);
3408        if (clpSolver && !parentModel_) {
3409            clpSolver->computeLargestAway();
3410        }
3411    }
3412#endif
3413    /*
3414      At last, the actual branch-and-cut search loop, which will iterate until
3415      the live set is empty or we hit some limit (integrality gap, time, node
3416      count, etc.). The overall flow is to rebuild a subproblem, reoptimise using
3417      solveWithCuts(), choose a branching pattern with chooseBranch(), and finally
3418      add the node to the live set.
3419
3420      The first action is to winnow the live set to remove nodes which are worse
3421      than the current objective cutoff.
3422    */
3423    if (solver_->getRowCutDebuggerAlways()) {
3424        OsiRowCutDebugger * debuggerX = const_cast<OsiRowCutDebugger *> (solver_->getRowCutDebuggerAlways());
3425        const OsiRowCutDebugger *debugger = solver_->getRowCutDebugger() ;
3426        if (!debugger) {
3427            // infeasible!!
3428            printf("before search\n");
3429            const double * lower = solver_->getColLower();
3430            const double * upper = solver_->getColUpper();
3431            const double * solution = debuggerX->optimalSolution();
3432            int numberColumns = solver_->getNumCols();
3433            for (int i = 0; i < numberColumns; i++) {
3434                if (solver_->isInteger(i)) {
3435                    if (solution[i] < lower[i] - 1.0e-6 || solution[i] > upper[i] + 1.0e-6)
3436                        printf("**** ");
3437                    printf("%d %g <= %g <= %g\n",
3438                           i, lower[i], solution[i], upper[i]);
3439                }
3440            }
3441            //abort();
3442        }
3443    }
3444    {
3445        // may be able to change cutoff now
3446        double cutoff = getCutoff();
3447        double increment = getDblParam(CbcModel::CbcCutoffIncrement) ;
3448        if (cutoff > bestObjective_ - increment) {
3449            cutoff = bestObjective_ - increment ;
3450            setCutoff(cutoff) ;
3451        }
3452    }
3453#ifdef CBC_THREAD
3454    bool goneParallel = false;
3455#endif
3456#define MAX_DEL_NODE 1
3457    CbcNode * delNode[MAX_DEL_NODE+1];
3458    int nDeleteNode = 0;
3459    // For Printing etc when parallel
3460    int lastEvery1000 = 0;
3461    int lastPrintEvery = 0;
3462    int numberConsecutiveInfeasible = 0;
3463    while (true) {
3464#ifdef CBC_THREAD
3465        if (parallelMode() > 0 && !locked) {
3466            lockThread();
3467            locked = true;
3468        }
3469#endif
3470#ifdef COIN_HAS_CLP
3471        // Possible change of pivot method
3472        if (!savePivotMethod && !parentModel_) {
3473            OsiClpSolverInterface * clpSolver
3474            = dynamic_cast<OsiClpSolverInterface *> (solver_);
3475            if (clpSolver && numberNodes_ >= 100 && numberNodes_ < 200) {
3476                if (numberIterations_ < (numberSolves_ + numberNodes_)*10) {
3477                    //if (numberIterations_<numberNodes_*20) {
3478                    ClpSimplex * simplex = clpSolver->getModelPtr();
3479                    ClpDualRowPivot * pivotMethod = simplex->dualRowPivot();
3480                    ClpDualRowDantzig * pivot =
3481                        dynamic_cast< ClpDualRowDantzig*>(pivotMethod);
3482                    if (!pivot) {
3483                        savePivotMethod = pivotMethod->clone(true);
3484                        ClpDualRowDantzig dantzig;
3485                        simplex->setDualRowPivotAlgorithm(dantzig);
3486#ifdef COIN_DEVELOP
3487                        printf("%d node, %d iterations ->Dantzig\n", numberNodes_,
3488                               numberIterations_);
3489#endif
3490#ifdef CBC_THREAD
3491                        for (int i = 0; i < numberThreads_; i++) {
3492                            threadInfo[i].dantzigState = -1;
3493                        }
3494#endif
3495                    }
3496                }
3497            }
3498        }
3499#endif
3500        if (tree_->empty()) {
3501#ifdef CBC_THREAD
3502            if (parallelMode() > 0) {
3503#ifdef COIN_DEVELOP
3504                printf("empty\n");
3505#endif
3506                // may still be outstanding nodes
3507                int iThread;
3508                for (iThread = 0; iThread < numberThreads_; iThread++) {
3509                    if (threadId[iThread].status) {
3510                        if (threadInfo[iThread].returnCode == 0)
3511                            break;
3512                    }
3513                }
3514                if (iThread < numberThreads_) {
3515#ifdef COIN_DEVELOP
3516                    printf("waiting for thread %d code 0\n", iThread);
3517#endif
3518                    if (parallelMode() > 0) {
3519                        unlockThread();
3520                        locked = false;
3521                    }
3522                    pthread_cond_signal(threadInfo[iThread].condition2); // unlock in case
3523                    while (true) {
3524                        pthread_mutex_lock(&condition_mutex);
3525                        struct timespec absTime;
3526                        my_gettime(&absTime);
3527                        double time = absTime.tv_sec + 1.0e-9 * absTime.tv_nsec;
3528                        absTime.tv_nsec += 1000000; // millisecond
3529                        if (absTime.tv_nsec >= 1000000000) {
3530                            absTime.tv_nsec -= 1000000000;
3531                            absTime.tv_sec++;
3532                        }
3533                        pthread_cond_timedwait(&condition_main, &condition_mutex, &absTime);
3534                        my_gettime(&absTime);
3535                        double time2 = absTime.tv_sec + 1.0e-9 * absTime.tv_nsec;
3536                        timeWaiting += time2 - time;
3537                        pthread_mutex_unlock(&condition_mutex);
3538                        if (threadInfo[iThread].returnCode != 0)
3539                            break;
3540                        pthread_cond_signal(threadInfo[iThread].condition2); // unlock
3541                    }
3542                    threadModel[iThread]->moveToModel(this, 1);
3543                    assert (threadInfo[iThread].returnCode == 1);
3544                    if (threadInfo[iThread].dantzigState == -1) {
3545                        // 0 unset, -1 waiting to be set, 1 set
3546                        threadInfo[iThread].dantzigState = 1;
3547                        CbcModel * model = threadInfo[iThread].thisModel;
3548                        OsiClpSolverInterface * clpSolver2
3549                        = dynamic_cast<OsiClpSolverInterface *> (model->solver());
3550                        assert (clpSolver2);
3551                        ClpSimplex * simplex2 = clpSolver2->getModelPtr();
3552                        ClpDualRowDantzig dantzig;
3553                        simplex2->setDualRowPivotAlgorithm(dantzig);
3554                    }
3555                    // say available
3556                    threadInfo[iThread].returnCode = -1;
3557                    threadStats[4]++;
3558#ifdef COIN_DEVELOP
3559                    printf("thread %d code now -1\n", iThread);
3560#endif
3561                    continue;
3562                } else {
3563#ifdef COIN_DEVELOP
3564                    printf("no threads at code 0 \n");
3565#endif
3566                    // now check if any have just finished
3567                    for (iThread = 0; iThread < numberThreads_; iThread++) {
3568                        if (threadId[iThread].status) {
3569                            if (threadInfo[iThread].returnCode == 1)
3570                                break;
3571                        }
3572                    }
3573                    if (iThread < numberThreads_) {
3574                        if (parallelMode() > 0) {
3575                            unlockThread();
3576                            locked = false;
3577                        }
3578                        threadModel[iThread]->moveToModel(this, 1);
3579                        assert (threadInfo[iThread].returnCode == 1);
3580                        // say available
3581                        threadInfo[iThread].returnCode = -1;
3582                        threadStats[4]++;
3583#ifdef COIN_DEVELOP
3584                        printf("thread %d code now -1\n", iThread);
3585#endif
3586                        continue;
3587                    }
3588                }
3589                if (!tree_->empty()) {
3590#ifdef COIN_DEVELOP
3591                    printf("tree not empty!!!!!!\n");
3592#endif
3593                    continue;
3594                }
3595                for (iThread = 0; iThread < numberThreads_; iThread++) {
3596                    if (threadId[iThread].status) {
3597                        if (threadInfo[iThread].returnCode != -1) {
3598                            printf("bad end of tree\n");
3599                            abort();
3600                        }
3601                    }
3602                }
3603#ifdef COIN_DEVELOP
3604                printf("finished ************\n");
3605#endif
3606                unlockThread();
3607                locked = false; // not needed as break
3608            }
3609#endif
3610            break;
3611        }
3612#ifdef CBC_THREAD
3613        if (parallelMode() > 0) {
3614            unlockThread();
3615            locked = false;
3616        }
3617#endif
3618        // If done 100 nodes see if worth trying reduction
3619        if (numberNodes_ == 50 || numberNodes_ == 100) {
3620#ifdef COIN_HAS_CLP
3621            OsiClpSolverInterface * clpSolver
3622            = dynamic_cast<OsiClpSolverInterface *> (solver_);
3623            if (clpSolver && ((specialOptions_&131072) == 0) && true) {
3624                ClpSimplex * simplex = clpSolver->getModelPtr();
3625                int perturbation = simplex->perturbation();
3626#ifdef CLP_INVESTIGATE
3627                printf("Testing its n,s %d %d solves n,s %d %d - pert %d\n",
3628                       numberIterations_, saveNumberIterations,
3629                       numberSolves_, saveNumberSolves, perturbation);
3630#endif
3631                if (perturbation == 50 && (numberIterations_ - saveNumberIterations) <
3632                        8*(numberSolves_ - saveNumberSolves)) {
3633                    // switch off perturbation
3634                    simplex->setPerturbation(100);
3635#ifdef PERTURB_IN_FATHOM
3636                    // but allow in fathom
3637                    specialOptions_ |= 131072;
3638#endif
3639#ifdef CLP_INVESTIGATE
3640                    printf("Perturbation switched off\n");
3641#endif
3642                }
3643            }
3644#endif
3645/*
3646  Decide if we want to do a restart.
3647*/
3648            if (saveSolver) {
3649                bool tryNewSearch = solverCharacteristics_->reducedCostsAccurate() &&
3650                                    (getCutoff() < 1.0e20 && getCutoff() < checkCutoffForRestart);
3651                int numberColumns = getNumCols();
3652                if (tryNewSearch) {
3653                    checkCutoffForRestart = getCutoff() ;
3654#ifdef CLP_INVESTIGATE
3655                    printf("after %d nodes, cutoff %g - looking\n",
3656                           numberNodes_, getCutoff());
3657#endif
3658                    saveSolver->resolve();
3659                    double direction = saveSolver->getObjSense() ;
3660                    double gap = checkCutoffForRestart - saveSolver->getObjValue() * direction ;
3661                    double tolerance;
3662                    saveSolver->getDblParam(OsiDualTolerance, tolerance) ;
3663                    if (gap <= 0.0)
3664                        gap = tolerance;
3665                    gap += 100.0 * tolerance;
3666                    double integerTolerance = getDblParam(CbcIntegerTolerance) ;
3667
3668                    const double *lower = saveSolver->getColLower() ;
3669                    const double *upper = saveSolver->getColUpper() ;
3670                    const double *solution = saveSolver->getColSolution() ;
3671                    const double *reducedCost = saveSolver->getReducedCost() ;
3672
3673                    int numberFixed = 0 ;
3674                    int numberFixed2 = 0;
3675#ifdef COIN_DEVELOP
3676                    printf("gap %g\n", gap);
3677#endif
3678                    for (int i = 0 ; i < numberIntegers_ ; i++) {
3679                        int iColumn = integerVariable_[i] ;
3680                        double djValue = direction * reducedCost[iColumn] ;
3681                        if (upper[iColumn] - lower[iColumn] > integerTolerance) {
3682                            if (solution[iColumn] < lower[iColumn] + integerTolerance && djValue > gap) {
3683                                //printf("%d to lb on dj of %g - bounds %g %g\n",
3684                                //     iColumn,djValue,lower[iColumn],upper[iColumn]);
3685                                saveSolver->setColUpper(iColumn, lower[iColumn]) ;
3686                                numberFixed++ ;
3687                            } else if (solution[iColumn] > upper[iColumn] - integerTolerance && -djValue > gap) {
3688                                //printf("%d to ub on dj of %g - bounds %g %g\n",
3689                                //     iColumn,djValue,lower[iColumn],upper[iColumn]);
3690                                saveSolver->setColLower(iColumn, upper[iColumn]) ;
3691                                numberFixed++ ;
3692                            }
3693                        } else {
3694                            //printf("%d has dj of %g - already fixed to %g\n",
3695                            //     iColumn,djValue,lower[iColumn]);
3696                            numberFixed2++;
3697                        }
3698                    }
3699#ifdef COIN_DEVELOP
3700                    if ((specialOptions_&1) != 0) {
3701                        const OsiRowCutDebugger *debugger = saveSolver->getRowCutDebugger() ;
3702                        if (debugger) {
3703                            printf("Contains optimal\n") ;
3704                            OsiSolverInterface * temp = saveSolver->clone();
3705                            const double * solution = debugger->optimalSolution();
3706                            const double *lower = temp->getColLower() ;
3707                            const double *upper = temp->getColUpper() ;
3708                            int n = temp->getNumCols();
3709                            for (int i = 0; i < n; i++) {
3710                                if (temp->isInteger(i)) {
3711                                    double value = floor(solution[i] + 0.5);
3712                                    assert (value >= lower[i] && value <= upper[i]);
3713                                    temp->setColLower(i, value);
3714                                    temp->setColUpper(i, value);
3715                                }
3716                            }
3717                            temp->writeMps("reduced_fix");
3718                            delete temp;
3719                            saveSolver->writeMps("reduced");
3720                        } else {
3721                            abort();
3722                        }
3723                    }
3724                    printf("Restart could fix %d integers (%d already fixed)\n",
3725                           numberFixed + numberFixed2, numberFixed2);
3726#endif
3727                    numberFixed += numberFixed2;
3728                    if (numberFixed*10 < numberColumns && numberFixed*4 < numberIntegers_)
3729                        tryNewSearch = false;
3730                }
3731                if (tryNewSearch) {
3732                    // back to solver without cuts?
3733                    OsiSolverInterface * solver2 = saveSolver->clone();
3734                    const double *lower = saveSolver->getColLower() ;
3735                    const double *upper = saveSolver->getColUpper() ;
3736                    for (int i = 0 ; i < numberIntegers_ ; i++) {
3737                        int iColumn = integerVariable_[i] ;
3738                        solver2->setColLower(iColumn, lower[iColumn]);
3739                        solver2->setColUpper(iColumn, upper[iColumn]);
3740                    }
3741                    // swap
3742                    delete saveSolver;
3743                    saveSolver = solver2;
3744                    double * newSolution = new double[numberColumns];
3745                    double objectiveValue = checkCutoffForRestart;
3746                    // Save the best solution so far.
3747                    CbcSerendipity heuristic(*this);
3748                    if (bestSolution_)
3749                        heuristic.setInputSolution(bestSolution_, bestObjective_);
3750                    // Magic number
3751                    heuristic.setFractionSmall(0.8);
3752                    // `pumpTune' to stand-alone solver for explanations.
3753                    heuristic.setFeasibilityPumpOptions(1008013);
3754                    // Use numberNodes to say how many are original rows
3755                    heuristic.setNumberNodes(continuousSolver_->getNumRows());
3756#ifdef COIN_DEVELOP
3757                    if (continuousSolver_->getNumRows() <
3758                            solver_->getNumRows())
3759                        printf("%d rows added ZZZZZ\n",
3760                               solver_->getNumRows() - continuousSolver_->getNumRows());
3761#endif
3762                    int returnCode = heuristic.smallBranchAndBound(saveSolver,
3763                                     -1, newSolution,
3764                                     objectiveValue,
3765                                     checkCutoffForRestart, "Reduce");
3766                    if (returnCode < 0) {
3767#ifdef COIN_DEVELOP
3768                        printf("Restart - not small enough to do search after fixing\n");
3769#endif
3770                        delete [] newSolution;
3771                    } else {
3772                        // 1 for sol'n, 2 for finished, 3 for both
3773                        if ((returnCode&1) != 0) {
3774                            // increment number of solutions so other heuristics can test
3775                            numberSolutions_++;
3776                            numberHeuristicSolutions_++;
3777                            lastHeuristic_ = NULL;
3778                            setBestSolution(CBC_ROUNDING, objectiveValue, newSolution) ;
3779                        }
3780                        delete [] newSolution;
3781                        if (tree_->size()) {
3782                            double dummyBest;
3783                            tree_->cleanTree(this, -COIN_DBL_MAX, dummyBest) ;
3784                        }
3785                        break;
3786                    }
3787                }
3788                delete saveSolver;
3789                saveSolver = NULL;
3790            }
3791        }
3792        /*
3793          Check for abort on limits: node count, solution count, time, integrality gap.
3794        */
3795        if (!(numberNodes_ < intParam_[CbcMaxNumNode] &&
3796                numberSolutions_ < intParam_[CbcMaxNumSol] &&
3797                !maximumSecondsReached() &&
3798                !stoppedOnGap_ && !eventHappened_ && (maximumNumberIterations_ < 0 ||
3799                                                      numberIterations_ < maximumNumberIterations_))) {
3800            // out of loop
3801            break;
3802        }
3803#ifdef BONMIN
3804        assert(!solverCharacteristics_->solutionAddsCuts() || solverCharacteristics_->mipFeasible());
3805#endif
3806// Sets percentage of time when we try diving. Diving requires a bit of heap reorganisation, because
3807// we need to replace the comparison function to dive, and that requires reordering to retain the
3808// heap property.
3809#define DIVE_WHEN 1000
3810#define DIVE_STOP 2000
3811        int kNode = numberNodes_ % 4000;
3812        if (numberNodes_<100000 && kNode>DIVE_WHEN && kNode <= DIVE_STOP) {
3813            if (!parallelMode()) {
3814                if (kNode == DIVE_WHEN + 1 || numberConsecutiveInfeasible > 1) {
3815                    CbcCompareDefault * compare = dynamic_cast<CbcCompareDefault *>
3816                                                  (nodeCompare_);
3817                    // Don't interfere if user has replaced the compare function.
3818                    if (compare) {
3819                        //printf("Redoing tree\n");
3820                        compare->startDive(this);
3821                        numberConsecutiveInfeasible = 0;
3822                    }
3823                }
3824            }
3825        }
3826        // replace current cutoff?
3827        if (cutoff > getCutoff()) {
3828            double newCutoff = getCutoff();
3829            if (analyzeResults_) {
3830                // see if we could fix any (more)
3831                int n = 0;
3832                double * newLower = analyzeResults_;
3833                double * objLower = newLower + numberIntegers_;
3834                double * newUpper = objLower + numberIntegers_;
3835                double * objUpper = newUpper + numberIntegers_;
3836                for (int i = 0; i < numberIntegers_; i++) {
3837                    if (objLower[i] > newCutoff) {
3838                        n++;
3839                        if (objUpper[i] > newCutoff) {
3840                            newCutoff = -COIN_DBL_MAX;
3841                            break;
3842                        }
3843                    } else if (objUpper[i] > newCutoff) {
3844                        n++;
3845                    }
3846                }
3847                if (newCutoff == -COIN_DBL_MAX) {
3848                    printf("Root analysis says finished\n");
3849                } else if (n > numberFixedNow_) {
3850                    printf("%d more fixed by analysis - now %d\n", n - numberFixedNow_, n);
3851                    numberFixedNow_ = n;
3852                }
3853            }
3854            if (eventHandler) {
3855                if (!eventHandler->event(CbcEventHandler::solution)) {
3856                    eventHappened_ = true; // exit
3857                }
3858                newCutoff = getCutoff();
3859            }
3860            if (parallelMode() > 0)
3861                lockThread();
3862            // Do from deepest (clean tree w.r.t. new solution)
3863            tree_->cleanTree(this, newCutoff, bestPossibleObjective_) ;
3864            nodeCompare_->newSolution(this) ;
3865            nodeCompare_->newSolution(this, continuousObjective_,
3866                                      continuousInfeasibilities_) ;
3867            // side effect: redo heap
3868            tree_->setComparison(*nodeCompare_) ;
3869            if (tree_->empty()) {
3870                if (parallelMode() > 0)
3871                    unlockThread();
3872                // For threads we need to check further
3873                //break; // finished
3874                continue;
3875            }
3876            if (parallelMode() > 0)
3877                unlockThread();
3878        }
3879        cutoff = getCutoff() ;
3880        /*
3881            Periodic activities: Opportunities to
3882            + tweak the nodeCompare criteria,
3883            + check if we've closed the integrality gap enough to quit,
3884            + print a summary line to let the user know we're working
3885        */
3886        if (numberNodes_ >= lastEvery1000) {
3887            if (parallelMode() > 0)
3888                lockThread();
3889#ifdef COIN_HAS_CLP
3890            // Possible change of pivot method
3891            if (!savePivotMethod && !parentModel_) {
3892                OsiClpSolverInterface * clpSolver
3893                = dynamic_cast<OsiClpSolverInterface *> (solver_);
3894                if (clpSolver && numberNodes_ >= 1000 && numberNodes_ < 2000) {
3895                    if (numberIterations_ < (numberSolves_ + numberNodes_)*10) {
3896                        //if (numberIterations_<numberNodes_*20) {
3897                        ClpSimplex * simplex = clpSolver->getModelPtr();
3898                        ClpDualRowPivot * pivotMethod = simplex->dualRowPivot();
3899                        ClpDualRowDantzig * pivot =
3900                            dynamic_cast< ClpDualRowDantzig*>(pivotMethod);
3901                        if (!pivot) {
3902                            savePivotMethod = pivotMethod->clone(true);
3903                            ClpDualRowDantzig dantzig;
3904                            simplex->setDualRowPivotAlgorithm(dantzig);
3905#ifdef COIN_DEVELOP
3906                            printf("%d node, %d iterations ->Dantzig\n", numberNodes_,
3907                                   numberIterations_);
3908#endif
3909#ifdef CBC_THREAD
3910                            for (int i = 0; i < numberThreads_; i++) {
3911                                threadInfo[i].dantzigState = -1;
3912                            }
3913#endif
3914                        }
3915                    }
3916                }
3917            }
3918#endif
3919            lastEvery1000 = numberNodes_ + 1000;
3920            bool redoTree = nodeCompare_->every1000Nodes(this, numberNodes_) ;
3921#ifdef CHECK_CUT_SIZE
3922            verifyCutSize (tree_, *this);
3923#endif
3924            // redo tree if requested
3925            if (redoTree)
3926                tree_->setComparison(*nodeCompare_) ;
3927            if (parallelMode() > 0)
3928                unlockThread();
3929        }
3930        // Had hotstart before, now switched off
3931        if (saveCompare && !hotstartSolution_) {
3932            // hotstart switched off
3933            delete nodeCompare_; // off depth first
3934            nodeCompare_ = saveCompare;
3935            saveCompare = NULL;
3936            // redo tree
3937            if (parallelMode() > 0)
3938                lockThread();
3939            tree_->setComparison(*nodeCompare_) ;
3940            if (parallelMode() > 0)
3941                unlockThread();
3942        }
3943        if (numberNodes_ >= lastPrintEvery) {
3944            lastPrintEvery = numberNodes_ + printFrequency_;
3945            if (parallelMode() > 0)
3946                lockThread();
3947            int nNodes = tree_->size() ;
3948
3949            //MODIF PIERRE
3950            bestPossibleObjective_ = tree_->getBestPossibleObjective();
3951            if (parallelMode() > 0)
3952                unlockThread();
3953#ifdef CLP_INVESTIGATE
3954            if (getCutoff() < 1.0e20) {
3955                if (fabs(getCutoff() - (bestObjective_ - getCutoffIncrement())) > 1.0e-6 &&
3956                        !parentModel_)
3957                    printf("model cutoff in status %g, best %g, increment %g\n",
3958                           getCutoff(), bestObjective_, getCutoffIncrement());
3959                assert (getCutoff() < bestObjective_ - getCutoffIncrement() +
3960                        1.0e-6 + 1.0e-10*fabs(bestObjective_));
3961            }
3962#endif
3963            if (!intParam_[CbcPrinting]) {
3964                messageHandler()->message(CBC_STATUS, messages())
3965                << numberNodes_ << nNodes << bestObjective_ << bestPossibleObjective_
3966                << getCurrentSeconds()
3967                << CoinMessageEol ;
3968            } else if (intParam_[CbcPrinting] == 1) {
3969                messageHandler()->message(CBC_STATUS2, messages())
3970                << numberNodes_ << nNodes << bestObjective_ << bestPossibleObjective_
3971                << lastDepth << lastUnsatisfied << numberIterations_
3972                << getCurrentSeconds()
3973                << CoinMessageEol ;
3974            } else if (!numberExtraIterations_) {
3975                messageHandler()->message(CBC_STATUS2, messages())
3976                << numberNodes_ << nNodes << bestObjective_ << bestPossibleObjective_
3977                << lastDepth << lastUnsatisfied << numberIterations_
3978                << getCurrentSeconds()
3979                << CoinMessageEol ;
3980            } else {
3981                messageHandler()->message(CBC_STATUS3, messages())
3982                << numberNodes_ << numberExtraNodes_ << nNodes << bestObjective_ << bestPossibleObjective_
3983                << lastDepth << lastUnsatisfied << numberIterations_ << numberExtraIterations_
3984                << getCurrentSeconds()
3985                << CoinMessageEol ;
3986            }
3987            if (eventHandler && !eventHandler->event(CbcEventHandler::treeStatus)) {
3988                eventHappened_ = true; // exit
3989            }
3990        }
3991        // See if can stop on gap
3992        double testGap = CoinMax(dblParam_[CbcAllowableGap],
3993                                 CoinMax(fabs(bestObjective_), fabs(bestPossibleObjective_))
3994                                 * dblParam_[CbcAllowableFractionGap]);
3995        if (bestObjective_ - bestPossibleObjective_ < testGap && getCutoffIncrement() >= 0.0) {
3996            stoppedOnGap_ = true ;
3997        }
3998
3999#ifdef CHECK_NODE_FULL
4000        verifyTreeNodes(tree_, *this) ;
4001#   endif
4002#   ifdef CHECK_CUT_COUNTS
4003        verifyCutCounts(tree_, *this) ;
4004#   endif
4005        /*
4006          Now we come to the meat of the loop. To create the active subproblem, we'll
4007          pop the most promising node in the live set, rebuild the subproblem it
4008          represents, and then execute the current arm of the branch to create the
4009          active subproblem.
4010        */
4011        CbcNode * node = NULL;
4012#ifdef CBC_THREAD
4013        if (!parallelMode() || parallelMode() == -1) {
4014#endif
4015            node = tree_->bestNode(cutoff) ;
4016            // Possible one on tree worse than cutoff
4017            // Wierd comparison function can leave ineligible nodes on tree
4018            if (!node || node->objectiveValue() > cutoff)
4019                continue;
4020            // Do main work of solving node here
4021            doOneNode(this, node, createdNode);
4022#if 0
4023            if (node) {
4024                if (createdNode) {
4025                    printf("Node %d depth %d, created %d depth %d\n",
4026                           node->nodeNumber(), node->depth(),
4027                           createdNode->nodeNumber(), createdNode->depth());
4028                } else {
4029                    printf("Node %d depth %d,  no created node\n",
4030                           node->nodeNumber(), node->depth());
4031                }
4032            } else if (createdNode) {
4033                printf("Node exhausted, created %d depth %d\n",
4034                       createdNode->nodeNumber(), createdNode->depth());
4035            } else {
4036                printf("Node exhausted,  no created node\n");
4037                numberConsecutiveInfeasible = 2;
4038            }
4039#endif
4040            //if (createdNode)
4041            //numberConsecutiveInfeasible=0;
4042            //else
4043            //numberConsecutiveInfeasible++;
4044#ifdef CBC_THREAD
4045        } else if (parallelMode() > 0) {
4046            node = tree_->bestNode(cutoff) ;
4047            // Possible one on tree worse than cutoff
4048            if (!node || node->objectiveValue() > cutoff)
4049                continue;
4050            threadStats[0]++;
4051            //need to think
4052            int iThread;
4053            // Start one off if any available
4054            for (iThread = 0; iThread < numberThreads_; iThread++) {
4055                if (threadInfo[iThread].returnCode == -1)
4056                    break;
4057            }
4058            if (iThread < numberThreads_) {
4059                threadInfo[iThread].node = node;
4060                assert (threadInfo[iThread].returnCode == -1);
4061                // say in use
4062                threadModel[iThread]->moveToModel(this, 0);
4063                // This has to be AFTER moveToModel
4064                threadInfo[iThread].returnCode = 0;
4065                pthread_cond_signal(threadInfo[iThread].condition2); // unlock
4066                threadCount[iThread]++;
4067            }
4068            lockThread();
4069            locked = true;
4070            // see if any finished
4071            for (iThread = 0; iThread < numberThreads_; iThread++) {
4072                if (threadInfo[iThread].returnCode > 0)
4073                    break;
4074            }
4075            unlockThread();
4076            locked = false;
4077            if (iThread < numberThreads_) {
4078                threadModel[iThread]->moveToModel(this, 1);
4079                assert (threadInfo[iThread].returnCode == 1);
4080                // say available
4081                threadInfo[iThread].returnCode = -1;
4082                // carry on
4083                threadStats[3]++;
4084            } else {
4085                // Start one off if any available
4086                for (iThread = 0; iThread < numberThreads_; iThread++) {
4087                    if (threadInfo[iThread].returnCode == -1)
4088                        break;
4089                }
4090                if (iThread < numberThreads_) {
4091                    lockThread();
4092                    locked = true;
4093                    // If any on tree get
4094                    if (!tree_->empty()) {
4095                        //node = tree_->bestNode(cutoff) ;
4096                        //assert (node);
4097                        threadStats[1]++;
4098                        continue; // ** get another node
4099                    }
4100                    unlockThread();
4101                    locked = false;
4102                }
4103                // wait (for debug could sleep and use test)
4104                bool finished = false;
4105                while (!finished) {
4106                    pthread_mutex_lock(&condition_mutex);
4107                    struct timespec absTime;
4108                    my_gettime(&absTime);
4109                    double time = absTime.tv_sec + 1.0e-9 * absTime.tv_nsec;
4110                    absTime.tv_nsec += 1000000; // millisecond
4111                    if (absTime.tv_nsec >= 1000000000) {
4112                        absTime.tv_nsec -= 1000000000;
4113                        absTime.tv_sec++;
4114                    }
4115                    pthread_cond_timedwait(&condition_main, &condition_mutex, &absTime);
4116                    my_gettime(&absTime);
4117                    double time2 = absTime.tv_sec + 1.0e-9 * absTime.tv_nsec;
4118                    timeWaiting += time2 - time;
4119                    pthread_mutex_unlock(&condition_mutex);
4120                    for (iThread = 0; iThread < numberThreads_; iThread++) {
4121                        if (threadInfo[iThread].returnCode > 0) {
4122                            finished = true;
4123                            break;
4124                        } else if (threadInfo[iThread].returnCode == 0) {
4125                            pthread_cond_signal(threadInfo[iThread].condition2); // unlock
4126                        }
4127                    }
4128                }
4129                assert (iThread < numberThreads_);
4130                // move information to model
4131                threadModel[iThread]->moveToModel(this, 1);
4132                node = threadInfo[iThread].node;
4133                threadInfo[iThread].node = NULL;
4134                assert (threadInfo[iThread].returnCode == 1);
4135                // say available
4136                threadInfo[iThread].returnCode = -1;
4137                // carry on
4138                threadStats[2]++;
4139            }
4140        } else {
4141            // Deterministic parallel
4142            if (tree_->size() < CoinMin(numberThreads_, 8) && !goneParallel) {
4143                node = tree_->bestNode(cutoff) ;
4144                // Possible one on tree worse than cutoff
4145                if (!node || node->objectiveValue() > cutoff)
4146                    continue;
4147                // Do main work of solving node here
4148                doOneNode(this, node, createdNode);
4149                assert (createdNode);
4150                if (!createdNode->active()) {
4151                    delete createdNode;
4152                    createdNode = NULL;
4153                } else {
4154                    // Say one more pointing to this
4155                    node->nodeInfo()->increment() ;
4156                    tree_->push(createdNode) ;
4157                }
4158                if (node->active()) {
4159                    assert (node->nodeInfo());
4160                    if (node->nodeInfo()->numberBranchesLeft()) {
4161                        tree_->push(node) ;
4162                    } else {
4163                        node->setActive(false);
4164                    }
4165                } else {
4166                    if (node->nodeInfo()) {
4167                        if (!node->nodeInfo()->numberBranchesLeft())
4168                            node->nodeInfo()->allBranchesGone(); // can clean up
4169                        // So will delete underlying stuff
4170                        node->setActive(true);
4171                    }
4172                    delNode[nDeleteNode++] = node;
4173                    node = NULL;
4174                }
4175                if (nDeleteNode >= MAX_DEL_NODE) {
4176                    for (int i = 0; i < nDeleteNode; i++) {
4177                        //printf("trying to del %d %x\n",i,delNode[i]);
4178                        delete delNode[i];
4179                        //printf("done to del %d %x\n",i,delNode[i]);
4180                    }
4181                    nDeleteNode = 0;
4182                }
4183            } else {
4184                // Split
4185                int saveTreeSize = tree_->size();
4186                goneParallel = true;
4187                int nAffected = splitModel(numberThreads_, threadModel, defaultParallelNodes);
4188                int iThread;
4189                // do all until finished
4190                for (iThread = 0; iThread < numberThreads_; iThread++) {
4191                    // obviously tune
4192                    threadInfo[iThread].nDeleteNode = defaultParallelIterations;
4193                }
4194                // Save current state
4195                int iObject;
4196                for (iObject = 0; iObject < numberObjects_; iObject++) {
4197                    saveObjects[iObject]->updateBefore(object_[iObject]);
4198                }
4199                for (iThread = 0; iThread < numberThreads_; iThread++) {
4200                    threadInfo[iThread].returnCode = 0;
4201                    pthread_cond_signal(threadInfo[iThread].condition2); // unlock
4202                }
4203                // wait
4204                bool finished = false;
4205                while (!finished) {
4206                    pthread_mutex_lock(&condition_mutex);
4207                    struct timespec absTime;
4208                    my_gettime(&absTime);
4209                    double time = absTime.tv_sec + 1.0e-9 * absTime.tv_nsec;
4210                    absTime.tv_nsec += 1000000; // millisecond
4211                    if (absTime.tv_nsec >= 1000000000) {
4212                        absTime.tv_nsec -= 1000000000;
4213                        absTime.tv_sec++;
4214                    }
4215                    pthread_cond_timedwait(&condition_main, &condition_mutex, &absTime);
4216                    my_gettime(&absTime);
4217                    double time2 = absTime.tv_sec + 1.0e-9 * absTime.tv_nsec;
4218                    timeWaiting += time2 - time;
4219                    pthread_mutex_unlock(&condition_mutex);
4220                    finished = true;
4221                    for (iThread = 0; iThread < numberThreads_; iThread++) {
4222                        if (threadInfo[iThread].returnCode <= 0) {
4223                            finished = false;
4224                        }
4225                    }
4226                }
4227                // Unmark marked
4228                for (int i = 0; i < nAffected; i++) {
4229                    walkback_[i]->unmark();
4230                }
4231                int iModel;
4232                double scaleFactor = 1.0;
4233                for (iModel = 0; iModel < numberThreads_; iModel++) {
4234                    //printf("model %d tree size %d\n",iModel,threadModel[iModel]->tree_->size());
4235                    if (saveTreeSize > 4*numberThreads_*defaultParallelNodes) {
4236                        if (!threadModel[iModel]->tree_->size()) {
4237                            scaleFactor *= 1.05;
4238                        }
4239                    }
4240                    threadModel[iModel]->moveToModel(this, 11);
4241                    // Update base model
4242                    OsiObject ** threadObject = threadModel[iModel]->object_;
4243                    for (iObject = 0; iObject < numberObjects_; iObject++) {
4244                        object_[iObject]->updateAfter(threadObject[iObject], saveObjects[iObject]);
4245                    }
4246                }
4247                if (scaleFactor != 1.0) {
4248                    int newNumber = static_cast<int> (defaultParallelNodes * scaleFactor + 0.5001);
4249                    if (newNumber*2 < defaultParallelIterations) {
4250                        if (defaultParallelNodes == 1)
4251                            newNumber = 2;
4252                        if (newNumber != defaultParallelNodes) {
4253                            char general[200];
4254                            sprintf(general, "Changing tree size from %d to %d",
4255                                    defaultParallelNodes, newNumber);
4256                            messageHandler()->message(CBC_GENERAL,
4257                                                      messages())
4258                            << general << CoinMessageEol ;
4259                            defaultParallelNodes = newNumber;
4260                        }
4261                    }
4262                }
4263                //printf("Tree sizes %d %d %d - affected %d\n",saveTreeSize,saveTreeSize2,tree_->size(),nAffected);
4264            }
4265        }
4266#endif
4267    }
4268    if (nDeleteNode) {
4269        for (int i = 0; i < nDeleteNode; i++) {
4270            delete delNode[i];
4271        }
4272        nDeleteNode = 0;
4273    }
4274#ifdef CBC_THREAD
4275    if (numberThreads_) {
4276        int i;
4277        // Seems to be bug in CoinCpu on Linux - does threads as well despite documentation
4278        double time = 0.0;
4279        for (i = 0; i < numberThreads_; i++)
4280            time += threadInfo[i].timeInThread;
4281        bool goodTimer = time < (getCurrentSeconds());
4282        for (i = 0; i < numberThreads_; i++) {
4283            while (threadInfo[i].returnCode == 0) {
4284                pthread_cond_signal(threadInfo[i].condition2); // unlock
4285                pthread_mutex_lock(&condition_mutex);
4286                struct timespec absTime;
4287                my_gettime(&absTime);
4288                absTime.tv_nsec += 1000000; // millisecond
4289                if (absTime.tv_nsec >= 1000000000) {
4290                    absTime.tv_nsec -= 1000000000;
4291                    absTime.tv_sec++;
4292                }
4293                pthread_cond_timedwait(&condition_main, &condition_mutex, &absTime);
4294                my_gettime(&absTime);
4295                pthread_mutex_unlock(&condition_mutex);
4296            }
4297            pthread_cond_signal(threadInfo[i].condition2); // unlock
4298            pthread_mutex_lock(&condition_mutex); // not sure necessary but have had one hang on interrupt
4299            threadModel[i]->numberThreads_ = 0; // say exit
4300            if (parallelMode() < 0)
4301                delete [] threadInfo[i].delNode;
4302            threadInfo[i].returnCode = 0;
4303            pthread_mutex_unlock(&condition_mutex);
4304            pthread_cond_signal(threadInfo[i].condition2); // unlock
4305            //if (!stopped)
4306            //pthread_join(threadId[i],NULL);
4307            int returnCode;
4308            returnCode = pthread_join(threadId[i].thr, NULL);
4309            threadId[i].status = 0;
4310            assert (!returnCode);
4311            //else
4312            //pthread_kill(threadId[i]); // kill rather than try and synchronize
4313            threadModel[i]->moveToModel(this, 2);
4314            pthread_mutex_destroy (threadInfo[i].mutex2);
4315            pthread_cond_destroy (threadInfo[i].condition2);
4316            assert (threadInfo[i].numberTimesLocked == threadInfo[i].numberTimesUnlocked);
4317            handler_->message(CBC_THREAD_STATS, messages_)
4318            << "Thread";
4319            handler_->printing(true)
4320            << i << threadCount[i] << threadInfo[i].timeWaitingToStart;
4321            handler_->printing(goodTimer) << threadInfo[i].timeInThread;
4322            handler_->printing(false) << 0.0;
4323            handler_->printing(true) << threadInfo[i].numberTimesLocked
4324            << threadInfo[i].timeLocked << threadInfo[i].timeWaitingToLock
4325            << CoinMessageEol;
4326        }
4327        assert (threadInfo[numberThreads_].numberTimesLocked == threadInfo[numberThreads_].numberTimesUnlocked);
4328        handler_->message(CBC_THREAD_STATS, messages_)
4329        << "Main thread";
4330        handler_->printing(false) << 0 << 0 << 0.0;
4331        handler_->printing(false) << 0.0;
4332        handler_->printing(true) << timeWaiting;
4333        handler_->printing(true) << threadInfo[numberThreads_].numberTimesLocked
4334        << threadInfo[numberThreads_].timeLocked << threadInfo[numberThreads_].timeWaitingToLock
4335        << CoinMessageEol;
4336        pthread_mutex_destroy (&mutex);
4337        pthread_cond_destroy (&condition_main);
4338        pthread_mutex_destroy (&condition_mutex);
4339        // delete models (here in case some point to others)
4340        for (i = 0; i < numberThreads_; i++) {
4341            // make sure handler will be deleted
4342            threadModel[i]->defaultHandler_ = true;
4343            delete threadModel[i];
4344        }
4345        delete [] mutex2;
4346        delete [] condition2;
4347        delete [] threadId;
4348        delete [] threadInfo;
4349        delete [] threadModel;
4350        delete [] threadCount;
4351        mutex_ = NULL;
4352        // adjust time to allow for children on some systems
4353        dblParam_[CbcStartSeconds] -= CoinCpuTimeJustChildren();
4354    }
4355#endif
4356    /*
4357      End of the non-abort actions. The next block of code is executed if we've
4358      aborted because we hit one of the limits. Clean up by deleting the live set
4359      and break out of the node processing loop. Note that on an abort, node may
4360      have been pushed back onto the tree for further processing, in which case
4361      it'll be deleted in cleanTree. We need to check.
4362    */
4363    if (!(numberNodes_ < intParam_[CbcMaxNumNode] &&
4364            numberSolutions_ < intParam_[CbcMaxNumSol] &&
4365            !maximumSecondsReached() &&
4366            !stoppedOnGap_ && !eventHappened_ && (maximumNumberIterations_ < 0 ||
4367                                                  numberIterations_ < maximumNumberIterations_))) {
4368        if (tree_->size()) {
4369            double dummyBest;
4370            tree_->cleanTree(this, -COIN_DBL_MAX, dummyBest) ;
4371        }
4372        delete nextRowCut_;
4373        if (stoppedOnGap_) {
4374            messageHandler()->message(CBC_GAP, messages())
4375            << bestObjective_ - bestPossibleObjective_
4376            << dblParam_[CbcAllowableGap]
4377            << dblParam_[CbcAllowableFractionGap]*100.0
4378            << CoinMessageEol ;
4379            secondaryStatus_ = 2;
4380            status_ = 0 ;
4381        } else if (isNodeLimitReached()) {
4382            handler_->message(CBC_MAXNODES, messages_) << CoinMessageEol ;
4383            secondaryStatus_ = 3;
4384            status_ = 1 ;
4385        } else if (maximumSecondsReached()) {
4386            handler_->message(CBC_MAXTIME, messages_) << CoinMessageEol ;
4387            secondaryStatus_ = 4;
4388            status_ = 1 ;
4389        } else if (eventHappened_) {
4390            handler_->message(CBC_EVENT, messages_) << CoinMessageEol ;
4391            secondaryStatus_ = 5;
4392            status_ = 5 ;
4393        } else {
4394            handler_->message(CBC_MAXSOLS, messages_) << CoinMessageEol ;
4395            secondaryStatus_ = 6;
4396            status_ = 1 ;
4397        }
4398    }
4399    /*
4400      That's it, we've exhausted the search tree, or broken out of the loop because
4401      we hit some limit on evaluation.
4402
4403      We may have got an intelligent tree so give it one more chance
4404    */
4405    // Tell solver we are not in Branch and Cut
4406    solver_->setHintParam(OsiDoInBranchAndCut, false, OsiHintDo, NULL) ;
4407    tree_->endSearch();
4408    //  If we did any sub trees - did we give up on any?
4409    if ( numberStoppedSubTrees_)
4410        status_ = 1;
4411    numberNodes_ += numberExtraNodes_;
4412    numberIterations_ += numberExtraIterations_;
4413    if (eventHandler) {
4414        eventHandler->event(CbcEventHandler::endSearch);
4415    }
4416    if (!status_) {
4417        // Set best possible unless stopped on gap
4418        if (secondaryStatus_ != 2)
4419            bestPossibleObjective_ = bestObjective_;
4420        handler_->message(CBC_END_GOOD, messages_)
4421        << bestObjective_ << numberIterations_ << numberNodes_ << getCurrentSeconds()
4422        << CoinMessageEol ;
4423    } else {
4424        handler_->message(CBC_END, messages_)
4425        << bestObjective_ << bestPossibleObjective_
4426        << numberIterations_ << numberNodes_ << getCurrentSeconds()
4427        << CoinMessageEol ;
4428    }
4429    if (numberStrongIterations_)
4430        handler_->message(CBC_STRONG_STATS, messages_)
4431        << strongInfo_[0] << numberStrongIterations_ << strongInfo_[2]
4432        << strongInfo_[1] << CoinMessageEol ;
4433    if (!numberExtraNodes_)
4434        handler_->message(CBC_OTHER_STATS, messages_)
4435        << maximumDepthActual_
4436        << numberDJFixed_ << CoinMessageEol ;
4437    else
4438        handler_->message(CBC_OTHER_STATS2, messages_)
4439        << maximumDepthActual_
4440        << numberDJFixed_ << numberExtraNodes_ << numberExtraIterations_
4441        << CoinMessageEol ;
4442    if (doStatistics == 100) {
4443        for (int i = 0; i < numberObjects_; i++) {
4444            CbcSimpleIntegerDynamicPseudoCost * obj =
4445                dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object_[i]) ;
4446            if (obj)
4447                obj->print();
4448        }
4449    }
4450    if (statistics_) {
4451        // report in some way
4452        int * lookup = new int[numberObjects_];
4453        int i;
4454        for (i = 0; i < numberObjects_; i++)
4455            lookup[i] = -1;
4456        bool goodIds = false; //true;
4457        for (i = 0; i < numberObjects_; i++) {
4458            int iColumn = object_[i]->columnNumber();
4459            if (iColumn >= 0 && iColumn < numberColumns) {
4460                if (lookup[i] == -1) {
4461                    lookup[i] = iColumn;
4462                } else {
4463                    goodIds = false;
4464                    break;
4465                }
4466            } else {
4467                goodIds = false;
4468                break;
4469            }
4470        }
4471        if (!goodIds) {
4472            delete [] lookup;
4473            lookup = NULL;
4474        }
4475        if (doStatistics >= 3) {
4476            printf("  node parent depth column   value                    obj      inf\n");
4477            for ( i = 0; i < numberNodes2_; i++) {
4478                statistics_[i]->print(lookup);
4479            }
4480        }
4481        if (doStatistics > 1) {
4482            // Find last solution
4483            int k;
4484            for (k = numberNodes2_ - 1; k >= 0; k--) {
4485                if (statistics_[k]->endingObjective() != COIN_DBL_MAX &&
4486                        !statistics_[k]->endingInfeasibility())
4487                    break;
4488            }
4489            if (k >= 0) {
4490                int depth = statistics_[k]->depth();
4491                int * which = new int[depth+1];
4492                for (i = depth; i >= 0; i--) {
4493                    which[i] = k;
4494                    k = statistics_[k]->parentNode();
4495                }
4496                printf("  node parent depth column   value                    obj      inf\n");
4497                for (i = 0; i <= depth; i++) {
4498                    statistics_[which[i]]->print(lookup);
4499                }
4500                delete [] which;
4501            }
4502        }
4503        // now summary
4504        int maxDepth = 0;
4505        double averageSolutionDepth = 0.0;
4506        int numberSolutions = 0;
4507        double averageCutoffDepth = 0.0;
4508        double averageSolvedDepth = 0.0;
4509        int numberCutoff = 0;
4510        int numberDown = 0;
4511        int numberFirstDown = 0;
4512        double averageInfDown = 0.0;
4513        double averageObjDown = 0.0;
4514        int numberCutoffDown = 0;
4515        int numberUp = 0;
4516        int numberFirstUp = 0;
4517        double averageInfUp = 0.0;
4518        double averageObjUp = 0.0;
4519        int numberCutoffUp = 0;
4520        double averageNumberIterations1 = 0.0;
4521        double averageValue = 0.0;
4522        for ( i = 0; i < numberNodes2_; i++) {
4523            int depth =  statistics_[i]->depth();
4524            int way =  statistics_[i]->way();
4525            double value = statistics_[i]->value();
4526            double startingObjective =  statistics_[i]->startingObjective();
4527            int startingInfeasibility = statistics_[i]->startingInfeasibility();
4528            double endingObjective = statistics_[i]->endingObjective();
4529            int endingInfeasibility = statistics_[i]->endingInfeasibility();
4530            maxDepth = CoinMax(depth, maxDepth);
4531            // Only for completed
4532            averageNumberIterations1 += statistics_[i]->numberIterations();
4533            averageValue += value;
4534            if (endingObjective != COIN_DBL_MAX && !endingInfeasibility) {
4535                numberSolutions++;
4536                averageSolutionDepth += depth;
4537            }
4538            if (endingObjective == COIN_DBL_MAX) {
4539                numberCutoff++;
4540                averageCutoffDepth += depth;
4541                if (way < 0) {
4542                    numberDown++;
4543                    numberCutoffDown++;
4544                    if (way == -1)
4545                        numberFirstDown++;
4546                } else {
4547                    numberUp++;
4548                    numberCutoffUp++;
4549                    if (way == 1)
4550                        numberFirstUp++;
4551                }
4552            } else {
4553                averageSolvedDepth += depth;
4554                if (way < 0) {
4555                    numberDown++;
4556                    averageInfDown += startingInfeasibility - endingInfeasibility;
4557                    averageObjDown += endingObjective - startingObjective;
4558                    if (way == -1)
4559                        numberFirstDown++;
4560                } else {
4561                    numberUp++;
4562                    averageInfUp += startingInfeasibility - endingInfeasibility;
4563                    averageObjUp += endingObjective - startingObjective;
4564                    if (way == 1)
4565                        numberFirstUp++;
4566                }
4567            }
4568        }
4569        // Now print
4570        if (numberSolutions)
4571            averageSolutionDepth /= static_cast<double> (numberSolutions);
4572        int numberSolved = numberNodes2_ - numberCutoff;
4573        double averageNumberIterations2 = numberIterations_ - averageNumberIterations1
4574                                          - numberIterationsAtContinuous;
4575        if (numberCutoff) {
4576            averageCutoffDepth /= static_cast<double> (numberCutoff);
4577            averageNumberIterations2 /= static_cast<double> (numberCutoff);
4578        }
4579        if (numberNodes2_)
4580            averageValue /= static_cast<double> (numberNodes2_);
4581        if (numberSolved) {
4582            averageNumberIterations1 /= static_cast<double> (numberSolved);
4583            averageSolvedDepth /= static_cast<double> (numberSolved);
4584        }
4585        printf("%d solution(s) were found (by branching) at an average depth of %g\n",
4586               numberSolutions, averageSolutionDepth);
4587        printf("average value of variable being branched on was %g\n",
4588               averageValue);
4589        printf("%d nodes were cutoff at an average depth of %g with iteration count of %g\n",
4590               numberCutoff, averageCutoffDepth, averageNumberIterations2);
4591        printf("%d nodes were solved at an average depth of %g with iteration count of %g\n",
4592               numberSolved, averageSolvedDepth, averageNumberIterations1);
4593        if (numberDown) {
4594            averageInfDown /= static_cast<double> (numberDown);
4595            averageObjDown /= static_cast<double> (numberDown);
4596        }
4597        printf("Down %d nodes (%d first, %d second) - %d cutoff, rest decrease numinf %g increase obj %g\n",
4598               numberDown, numberFirstDown, numberDown - numberFirstDown, numberCutoffDown,
4599               averageInfDown, averageObjDown);
4600        if (numberUp) {
4601            averageInfUp /= static_cast<double> (numberUp);
4602            averageObjUp /= static_cast<double> (numberUp);
4603        }
4604        printf("Up %d nodes (%d first, %d second) - %d cutoff, rest decrease numinf %g increase obj %g\n",
4605               numberUp, numberFirstUp, numberUp - numberFirstUp, numberCutoffUp,
4606               averageInfUp, averageObjUp);
4607        for ( i = 0; i < numberNodes2_; i++)
4608            delete statistics_[i];
4609        delete [] statistics_;
4610        statistics_ = NULL;
4611        maximumStatistics_ = 0;
4612        delete [] lookup;
4613    }
4614    /*
4615      If we think we have a solution, restore and confirm it with a call to
4616      setBestSolution().  We need to reset the cutoff value so as not to fathom
4617      the solution on bounds.  Note that calling setBestSolution( ..., true)
4618      leaves the continuousSolver_ bounds vectors fixed at the solution value.
4619
4620      Running resolve() here is a failsafe --- setBestSolution has already
4621      reoptimised using the continuousSolver_. If for some reason we fail to
4622      prove optimality, run the problem again after instructing the solver to
4623      tell us more.
4624
4625      If all looks good, replace solver_ with continuousSolver_, so that the
4626      outside world will be able to obtain information about the solution using
4627      public methods.
4628    */
4629    if (bestSolution_ && (solverCharacteristics_->solverType() < 2 || solverCharacteristics_->solverType() == 4)) {
4630        setCutoff(1.0e50) ; // As best solution should be worse than cutoff
4631        phase_ = 5;
4632        double increment = getDblParam(CbcModel::CbcCutoffIncrement) ;
4633        if ((specialOptions_&4) == 0)
4634            bestObjective_ += 100.0 * increment + 1.0e-3; // only set if we are going to solve
4635        setBestSolution(CBC_END_SOLUTION, bestObjective_, bestSolution_, 1) ;
4636        continuousSolver_->resolve() ;
4637        if (!continuousSolver_->isProvenOptimal()) {
4638            continuousSolver_->messageHandler()->setLogLevel(2) ;
4639            continuousSolver_->initialSolve() ;
4640        }
4641        delete solver_ ;
4642        // above deletes solverCharacteristics_
4643        solverCharacteristics_ = NULL;
4644        solver_ = continuousSolver_ ;
4645        setPointers(solver_);
4646        continuousSolver_ = NULL ;
4647    }
4648    /*
4649      Clean up dangling objects. continuousSolver_ may already be toast.
4650    */
4651    delete lastws ;
4652    if (saveObjects) {
4653        for (int i = 0; i < numberObjects_; i++)
4654            delete saveObjects[i];
4655        delete [] saveObjects;
4656    }
4657    numberStrong_ = saveNumberStrong;
4658    numberBeforeTrust_ = saveNumberBeforeTrust;
4659    delete [] whichGenerator_ ;
4660    whichGenerator_ = NULL;
4661    delete [] lowerBefore ;
4662    delete [] upperBefore ;
4663    delete [] walkback_ ;
4664    walkback_ = NULL ;
4665    delete [] lastNodeInfo_ ;
4666    lastNodeInfo_ = NULL;
4667    delete [] lastNumberCuts_ ;
4668    lastNumberCuts_ = NULL;
4669    delete [] lastCut_;
4670    lastCut_ = NULL;
4671    delete [] addedCuts_ ;
4672    addedCuts_ = NULL ;
4673    //delete persistentInfo;
4674    // Get rid of characteristics
4675    solverCharacteristics_ = NULL;
4676    if (continuousSolver_) {
4677        delete continuousSolver_ ;
4678        continuousSolver_ = NULL ;
4679    }
4680    /*
4681      Destroy global cuts by replacing with an empty OsiCuts object.
4682    */
4683    globalCuts_ = OsiCuts() ;
4684    if (!bestSolution_) {
4685        // make sure lp solver is infeasible
4686        int numberColumns = solver_->getNumCols();
4687        const double * columnLower = solver_->getColLower();
4688        int iColumn;
4689        for (iColumn = 0; iColumn < numberColumns; iColumn++) {
4690            if (solver_->isInteger(iColumn))
4691                solver_->setColUpper(iColumn, columnLower[iColumn]);
4692        }
4693        solver_->initialSolve();
4694    }
4695#ifdef COIN_HAS_CLP
4696    {
4697        OsiClpSolverInterface * clpSolver
4698        = dynamic_cast<OsiClpSolverInterface *> (solver_);
4699        if (clpSolver) {
4700            // Possible restore of pivot method
4701            if (savePivotMethod) {
4702                // model may have changed
4703                savePivotMethod->setModel(NULL);
4704                clpSolver->getModelPtr()->setDualRowPivotAlgorithm(*savePivotMethod);
4705                delete savePivotMethod;
4706            }
4707            clpSolver->setLargestAway(-1.0);
4708        }
4709    }
4710#endif
4711    if (fastNodeDepth_ >= 1000000 && !parentModel_) {
4712        // delete object off end
4713        delete object_[numberObjects_];
4714        fastNodeDepth_ -= 1000000;
4715    }
4716    delete saveSolver;
4717    // Undo preprocessing performed during BaB.
4718    if (strategy_ && strategy_->preProcessState() > 0) {
4719        // undo preprocessing
4720        CglPreProcess * process = strategy_->process();
4721        assert (process);
4722        int n = originalSolver->getNumCols();
4723        if (bestSolution_) {
4724            delete [] bestSolution_;
4725            bestSolution_ = new double [n];
4726            process->postProcess(*solver_);
4727        }
4728        strategy_->deletePreProcess();
4729        // Solution now back in originalSolver
4730        delete solver_;
4731        solver_ = originalSolver;
4732        if (bestSolution_) {
4733            bestObjective_ = solver_->getObjValue() * solver_->getObjSense();
4734            memcpy(bestSolution_, solver_->getColSolution(), n*sizeof(double));
4735        }
4736        // put back original objects if there were any
4737        if (originalObject) {
4738            int iColumn;
4739            assert (ownObjects_);
4740            for (iColumn = 0; iColumn < numberObjects_; iColumn++)
4741                delete object_[iColumn];
4742            delete [] object_;
4743            numberObjects_ = numberOriginalObjects;
4744            object_ = originalObject;
4745            delete [] integerVariable_;
4746            numberIntegers_ = 0;
4747            for (iColumn = 0; iColumn < n; iColumn++) {
4748                if (solver_->isInteger(iColumn))
4749                    numberIntegers_++;
4750            }
4751            integerVariable_ = new int[numberIntegers_];
4752            numberIntegers_ = 0;
4753            for (iColumn = 0; iColumn < n; iColumn++) {
4754                if (solver_->isInteger(iColumn))
4755                    integerVariable_[numberIntegers_++] = iColumn;
4756            }
4757        }
4758    }
4759#ifdef COIN_HAS_CLP
4760    {
4761        OsiClpSolverInterface * clpSolver
4762        = dynamic_cast<OsiClpSolverInterface *> (solver_);
4763        if (clpSolver)
4764            clpSolver->setFakeObjective(reinterpret_cast<double *> (NULL));
4765    }
4766#endif
4767    moreSpecialOptions_ = saveMoreSpecialOptions;
4768    return ;
4769}
4770
4771
4772// Solve the initial LP relaxation
4773void
4774CbcModel::initialSolve()
4775{
4776    assert (solver_);
4777    // Double check optimization directions line up
4778    dblParam_[CbcOptimizationDirection] = solver_->getObjSense();
4779    // Check if bounds are all integral (as may get messed up later)
4780    checkModel();
4781    if (!solverCharacteristics_) {
4782        OsiBabSolver * solverCharacteristics = dynamic_cast<OsiBabSolver *> (solver_->getAuxiliaryInfo());
4783        if (solverCharacteristics) {
4784            solverCharacteristics_ = solverCharacteristics;
4785        } else {
4786            // replace in solver
4787            OsiBabSolver defaultC;
4788            solver_->setAuxiliaryInfo(&defaultC);
4789            solverCharacteristics_ = dynamic_cast<OsiBabSolver *> (solver_->getAuxiliaryInfo());
4790        }
4791    }
4792    solverCharacteristics_->setSolver(solver_);
4793    solver_->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo, NULL) ;
4794    solver_->initialSolve();
4795    solver_->setHintParam(OsiDoInBranchAndCut, false, OsiHintDo, NULL) ;
4796    if (!solver_->isProvenOptimal())
4797        solver_->resolve();
4798    // But set up so Jon Lee will be happy
4799    status_ = -1;
4800    secondaryStatus_ = -1;
4801    originalContinuousObjective_ = solver_->getObjValue() * solver_->getObjSense();
4802    delete [] continuousSolution_;
4803    continuousSolution_ = CoinCopyOfArray(solver_->getColSolution(),
4804                                          solver_->getNumCols());
4805    setPointers(solver_);
4806    solverCharacteristics_ = NULL;
4807}
4808
4809/*! \brief Get an empty basis object
4810
4811  Return an empty CoinWarmStartBasis object with the requested capacity,
4812  appropriate for the current solver. The object is cloned from the object
4813  cached as emptyWarmStart_. If there is no cached object, the routine
4814  queries the solver for a warm start object, empties it, and caches the
4815  result.
4816*/
4817
4818CoinWarmStartBasis *CbcModel::getEmptyBasis (int ns, int na) const
4819
4820{
4821    CoinWarmStartBasis *emptyBasis ;
4822    /*
4823      Acquire an empty basis object, if we don't yet have one.
4824    */
4825    if (emptyWarmStart_ == 0) {
4826        if (solver_ == 0) {
4827            throw CoinError("Cannot construct basis without solver!",
4828                            "getEmptyBasis", "CbcModel") ;
4829        }
4830        emptyBasis =
4831            dynamic_cast<CoinWarmStartBasis *>(solver_->getEmptyWarmStart()) ;
4832        if (emptyBasis == 0) {
4833            throw CoinError(
4834                "Solver does not appear to use a basis-oriented warm start.",
4835                "getEmptyBasis", "CbcModel") ;
4836        }
4837        emptyBasis->setSize(0, 0) ;
4838        emptyWarmStart_ = dynamic_cast<CoinWarmStart *>(emptyBasis) ;
4839    }
4840    /*
4841      Clone the empty basis object, resize it as requested, and return.
4842    */
4843    emptyBasis = dynamic_cast<CoinWarmStartBasis *>(emptyWarmStart_->clone()) ;
4844    assert(emptyBasis) ;
4845    if (ns != 0 || na != 0) emptyBasis->setSize(ns, na) ;
4846
4847    return (emptyBasis) ;
4848}
4849
4850
4851/** Default Constructor
4852
4853  Creates an empty model without an associated solver.
4854*/
4855CbcModel::CbcModel()
4856
4857        :
4858        solver_(NULL),
4859        ownership_(0x80000000),
4860        continuousSolver_(NULL),
4861        referenceSolver_(NULL),
4862        defaultHandler_(true),
4863        emptyWarmStart_(NULL),
4864        bestObjective_(COIN_DBL_MAX),
4865        bestPossibleObjective_(COIN_DBL_MAX),
4866        sumChangeObjective1_(0.0),
4867        sumChangeObjective2_(0.0),
4868        bestSolution_(NULL),
4869        savedSolutions_(NULL),
4870        currentSolution_(NULL),
4871        testSolution_(NULL),
4872        minimumDrop_(1.0e-4),
4873        numberSolutions_(0),
4874        numberSavedSolutions_(0),
4875        maximumSavedSolutions_(0),
4876        stateOfSearch_(0),
4877        whenCuts_(-1),
4878        hotstartSolution_(NULL),
4879        hotstartPriorities_(NULL),
4880        numberHeuristicSolutions_(0),
4881        numberNodes_(0),
4882        numberNodes2_(0),
4883        numberIterations_(0),
4884        numberSolves_(0),
4885        status_(-1),
4886        secondaryStatus_(-1),
4887        numberIntegers_(0),
4888        numberRowsAtContinuous_(0),
4889        maximumNumberCuts_(0),
4890        phase_(0),
4891        currentNumberCuts_(0),
4892        maximumDepth_(0),
4893        walkback_(NULL),
4894        lastNodeInfo_(NULL),
4895        lastCut_(NULL),
4896        lastDepth_(0),
4897        lastNumberCuts2_(0),
4898        maximumCuts_(0),
4899        lastNumberCuts_(NULL),
4900        addedCuts_(NULL),
4901        nextRowCut_(NULL),
4902        currentNode_(NULL),
4903        integerVariable_(NULL),
4904        integerInfo_(NULL),
4905        continuousSolution_(NULL),
4906        usedInSolution_(NULL),
4907        specialOptions_(0),
4908        moreSpecialOptions_(0),
4909        subTreeModel_(NULL),
4910        numberStoppedSubTrees_(0),
4911        mutex_(NULL),
4912        presolve_(0),
4913        numberStrong_(5),
4914        numberBeforeTrust_(10),
4915        numberPenalties_(20),
4916        stopNumberIterations_(-1),
4917        penaltyScaleFactor_(3.0),
4918        numberAnalyzeIterations_(0),
4919        analyzeResults_(NULL),
4920        numberInfeasibleNodes_(0),
4921        problemType_(0),
4922        printFrequency_(0),
4923        numberCutGenerators_(0),
4924        generator_(NULL),
4925        virginGenerator_(NULL),
4926        numberHeuristics_(0),
4927        heuristic_(NULL),
4928        lastHeuristic_(NULL),
4929# ifdef COIN_HAS_CLP
4930        fastNodeDepth_(-1),
4931#endif
4932        eventHandler_(NULL),
4933        numberObjects_(0),
4934        object_(NULL),
4935        ownObjects_(true),
4936        originalColumns_(NULL),
4937        howOftenGlobalScan_(1),
4938        numberGlobalViolations_(0),
4939        numberExtraIterations_(0),
4940        numberExtraNodes_(0),
4941        continuousObjective_(COIN_DBL_MAX),
4942        originalContinuousObjective_(COIN_DBL_MAX),
4943        continuousInfeasibilities_(COIN_INT_MAX),
4944        maximumCutPassesAtRoot_(20),
4945        maximumCutPasses_(10),
4946        preferredWay_(0),
4947        currentPassNumber_(0),
4948        maximumWhich_(1000),
4949        maximumRows_(0),
4950        currentDepth_(0),
4951        whichGenerator_(NULL),
4952        maximumStatistics_(0),
4953        statistics_(NULL),
4954        maximumDepthActual_(0),
4955        numberDJFixed_(0.0),
4956        probingInfo_(NULL),
4957        numberFixedAtRoot_(0),
4958        numberFixedNow_(0),
4959        stoppedOnGap_(false),
4960        eventHappened_(false),
4961        numberLongStrong_(0),
4962        numberOldActiveCuts_(0),
4963        numberNewCuts_(0),
4964        searchStrategy_(-1),
4965        numberStrongIterations_(0),
4966        resolveAfterTakeOffCuts_(true),
4967        maximumNumberIterations_(-1),
4968        continuousPriority_(COIN_INT_MAX),
4969        numberUpdateItems_(0),
4970        maximumNumberUpdateItems_(0),
4971        updateItems_(NULL),
4972        storedRowCuts_(NULL),
4973        numberThreads_(0),
4974        threadMode_(0)
4975{
4976    memset(intParam_, 0, sizeof(intParam_));
4977    intParam_[CbcMaxNumNode] = 2147483647;
4978    intParam_[CbcMaxNumSol] = 9999999;
4979
4980    memset(dblParam_, 0, sizeof(dblParam_));
4981    dblParam_[CbcIntegerTolerance] = 1e-6;
4982    dblParam_[CbcCutoffIncrement] = 1e-5;
4983    dblParam_[CbcAllowableGap] = 1.0e-10;
4984    dblParam_[CbcMaximumSeconds] = 1.0e100;
4985    dblParam_[CbcCurrentCutoff] = 1.0e100;
4986    dblParam_[CbcOptimizationDirection] = 1.0;
4987    dblParam_[CbcCurrentObjectiveValue] = 1.0e100;
4988    dblParam_[CbcCurrentMinimizationObjectiveValue] = 1.0e100;
4989    strongInfo_[0] = 0;
4990    strongInfo_[1] = 0;
4991    strongInfo_[2] = 0;
4992    strongInfo_[3] = 0;
4993    strongInfo_[4] = 0;
4994    strongInfo_[5] = 0;
4995    strongInfo_[6] = 0;
4996    solverCharacteristics_ = NULL;
4997    nodeCompare_ = new CbcCompareDefault();;
4998    problemFeasibility_ = new CbcFeasibilityBase();
4999    tree_ = new CbcTree();
5000    branchingMethod_ = NULL;
5001    cutModifier_ = NULL;
5002    strategy_ = NULL;
5003    parentModel_ = NULL;
5004    cbcColLower_ = NULL;
5005    cbcColUpper_ = NULL;
5006    cbcRowLower_ = NULL;
5007    cbcRowUpper_ = NULL;
5008    cbcColSolution_ = NULL;
5009    cbcRowPrice_ = NULL;
5010    cbcReducedCost_ = NULL;
5011    cbcRowActivity_ = NULL;
5012    appData_ = NULL;
5013    handler_ = new CoinMessageHandler();
5014    handler_->setLogLevel(2);
5015    messages_ = CbcMessage();
5016    //eventHandler_ = new CbcEventHandler() ;
5017}
5018
5019/** Constructor from solver.
5020
5021  Creates a model complete with a clone of the solver passed as a parameter.
5022*/
5023
5024CbcModel::CbcModel(const OsiSolverInterface &rhs)
5025        :
5026        continuousSolver_(NULL),
5027        referenceSolver_(NULL),
5028        defaultHandler_(true),
5029        emptyWarmStart_(NULL),
5030        bestObjective_(COIN_DBL_MAX),
5031        bestPossibleObjective_(COIN_DBL_MAX),
5032        sumChangeObjective1_(0.0),
5033        sumChangeObjective2_(0.0),
5034        minimumDrop_(1.0e-4),
5035        numberSolutions_(0),
5036        numberSavedSolutions_(0),
5037        maximumSavedSolutions_(0),
5038        stateOfSearch_(0),
5039        whenCuts_(-1),
5040        hotstartSolution_(NULL),
5041        hotstartPriorities_(NULL),
5042        numberHeuristicSolutions_(0),
5043        numberNodes_(0),
5044        numberNodes2_(0),
5045        numberIterations_(0),
5046        numberSolves_(0),
5047        status_(-1),
5048        secondaryStatus_(-1),
5049        numberRowsAtContinuous_(0),
5050        maximumNumberCuts_(0),
5051        phase_(0),
5052        currentNumberCuts_(0),
5053        maximumDepth_(0),
5054        walkback_(NULL),
5055        lastNodeInfo_(NULL),
5056        lastCut_(NULL),
5057        lastDepth_(0),
5058        lastNumberCuts2_(0),
5059        maximumCuts_(0),
5060        lastNumberCuts_(NULL),
5061        addedCuts_(NULL),
5062        nextRowCut_(NULL),
5063        currentNode_(NULL),
5064        integerInfo_(NULL),
5065        specialOptions_(0),
5066        moreSpecialOptions_(0),
5067        subTreeModel_(NULL),
5068        numberStoppedSubTrees_(0),
5069        mutex_(NULL),
5070        presolve_(0),
5071        numberStrong_(5),
5072        numberBeforeTrust_(10),
5073        numberPenalties_(20),
5074        stopNumberIterations_(-1),
5075        penaltyScaleFactor_(3.0),
5076        numberAnalyzeIterations_(0),
5077        analyzeResults_(NULL),
5078        numberInfeasibleNodes_(0),
5079        problemType_(0),
5080        printFrequency_(0),
5081        numberCutGenerators_(0),
5082        generator_(NULL),
5083        virginGenerator_(NULL),
5084        numberHeuristics_(0),
5085        heuristic_(NULL),
5086        lastHeuristic_(NULL),
5087# ifdef COIN_HAS_CLP
5088        fastNodeDepth_(-1),
5089#endif
5090        eventHandler_(NULL),
5091        numberObjects_(0),
5092        object_(NULL),
5093        ownObjects_(true),
5094        originalColumns_(NULL),
5095        howOftenGlobalScan_(1),
5096        numberGlobalViolations_(0),
5097        numberExtraIterations_(0),
5098        numberExtraNodes_(0),
5099        continuousObjective_(COIN_DBL_MAX),
5100        originalContinuousObjective_(COIN_DBL_MAX),
5101        continuousInfeasibilities_(COIN_INT_MAX),
5102        maximumCutPassesAtRoot_(20),
5103        maximumCutPasses_(10),
5104        preferredWay_(0),
5105        currentPassNumber_(0),
5106        maximumWhich_(1000),
5107        maximumRows_(0),
5108        currentDepth_(0),
5109        whichGenerator_(NULL),
5110        maximumStatistics_(0),
5111        statistics_(NULL),
5112        maximumDepthActual_(0),
5113        numberDJFixed_(0.0),
5114        probingInfo_(NULL),
5115        numberFixedAtRoot_(0),
5116        numberFixedNow_(0),
5117        stoppedOnGap_(false),
5118        eventHappened_(false),
5119        numberLongStrong_(0),
5120        numberOldActiveCuts_(0),
5121        numberNewCuts_(0),
5122        searchStrategy_(-1),
5123        numberStrongIterations_(0),
5124        resolveAfterTakeOffCuts_(true),
5125        maximumNumberIterations_(-1),
5126        continuousPriority_(COIN_INT_MAX),
5127        numberUpdateItems_(0),
5128        maximumNumberUpdateItems_(0),
5129        updateItems_(NULL),
5130        storedRowCuts_(NULL),
5131        numberThreads_(0),
5132        threadMode_(0)
5133{
5134    memset(intParam_, 0, sizeof(intParam_));
5135    intParam_[CbcMaxNumNode] = 2147483647;
5136    intParam_[CbcMaxNumSol] = 9999999;
5137
5138    memset(dblParam_, 0, sizeof(dblParam_));
5139    dblParam_[CbcIntegerTolerance] = 1e-6;
5140    dblParam_[CbcCutoffIncrement] = 1e-5;
5141    dblParam_[CbcAllowableGap] = 1.0e-10;
5142    dblParam_[CbcMaximumSeconds] = 1.0e100;
5143    dblParam_[CbcCurrentCutoff] = 1.0e100;
5144    dblParam_[CbcOptimizationDirection] = 1.0;
5145    dblParam_[CbcCurrentObjectiveValue] = 1.0e100;
5146    dblParam_[CbcCurrentMinimizationObjectiveValue] = 1.0e100;
5147    strongInfo_[0] = 0;
5148    strongInfo_[1] = 0;
5149    strongInfo_[2] = 0;
5150    strongInfo_[3] = 0;
5151    strongInfo_[4] = 0;
5152    strongInfo_[5] = 0;
5153    strongInfo_[6] = 0;
5154    solverCharacteristics_ = NULL;
5155    nodeCompare_ = new CbcCompareDefault();;
5156    problemFeasibility_ = new CbcFeasibilityBase();
5157    tree_ = new CbcTree();
5158    branchingMethod_ = NULL;
5159    cutModifier_ = NULL;
5160    strategy_ = NULL;
5161    parentModel_ = NULL;
5162    appData_ = NULL;
5163    handler_ = new CoinMessageHandler();
5164    handler_->setLogLevel(2);
5165    messages_ = CbcMessage();
5166    //eventHandler_ = new CbcEventHandler() ;
5167    solver_ = rhs.clone();
5168    referenceSolver_ = solver_->clone();
5169    ownership_ = 0x80000000;
5170    cbcColLower_ = NULL;
5171    cbcColUpper_ = NULL;
5172    cbcRowLower_ = NULL;
5173    cbcRowUpper_ = NULL;
5174    cbcColSolution_ = NULL;
5175    cbcRowPrice_ = NULL;
5176    cbcReducedCost_ = NULL;
5177    cbcRowActivity_ = NULL;
5178
5179    // Initialize solution and integer variable vectors
5180    bestSolution_ = NULL; // to say no solution found
5181    savedSolutions_ = NULL;
5182    numberIntegers_ = 0;
5183    int numberColumns = solver_->getNumCols();
5184    int iColumn;
5185    if (numberColumns) {
5186        // Space for current solution
5187        currentSolution_ = new double[numberColumns];
5188        continuousSolution_ = new double[numberColumns];
5189        usedInSolution_ = new int[numberColumns];
5190        CoinZeroN(usedInSolution_, numberColumns);
5191        for (iColumn = 0; iColumn < numberColumns; iColumn++) {
5192            if ( solver_->isInteger(iColumn))
5193                numberIntegers_++;
5194        }
5195    } else {
5196        // empty model
5197        currentSolution_ = NULL;
5198        continuousSolution_ = NULL;
5199        usedInSolution_ = NULL;
5200    }
5201    testSolution_ = currentSolution_;
5202    if (numberIntegers_) {
5203        integerVariable_ = new int [numberIntegers_];
5204        numberIntegers_ = 0;
5205        for (iColumn = 0; iColumn < numberColumns; iColumn++) {
5206            if ( solver_->isInteger(iColumn))
5207                integerVariable_[numberIntegers_++] = iColumn;
5208        }
5209    } else {
5210        integerVariable_ = NULL;
5211    }
5212}
5213
5214/*
5215  Assign a solver to the model (model assumes ownership)
5216
5217  The integer variable vector is initialized if it's not already present.
5218  If deleteSolver then current solver deleted (if model owned)
5219
5220  Assuming ownership matches usage in OsiSolverInterface
5221  (cf. assignProblem, loadProblem).
5222
5223  TODO: What to do about solver parameters? A simple copy likely won't do it,
5224        because the SI must push the settings into the underlying solver. In
5225        the context of switching solvers in cbc, this means that command line
5226        settings will get lost. Stash the command line somewhere and reread it
5227        here, maybe?
5228
5229  TODO: More generally, how much state should be transferred from the old
5230        solver to the new solver? Best perhaps to see how usage develops.
5231        What's done here mimics the CbcModel(OsiSolverInterface) constructor.
5232*/
5233void
5234CbcModel::assignSolver(OsiSolverInterface *&solver, bool deleteSolver)
5235
5236{
5237    // resize best solution if exists
5238    if (bestSolution_ && solver && solver_) {
5239        int nOld = solver_->getNumCols();
5240        int nNew = solver->getNumCols();
5241        if (nNew > nOld) {
5242            double * temp = new double[nNew];
5243            memcpy(temp, bestSolution_, nOld*sizeof(double));
5244            memset(temp + nOld, 0, (nNew - nOld)*sizeof(double));
5245            delete [] bestSolution_;
5246            bestSolution_ = temp;
5247        }
5248    }
5249    // Keep the current message level for solver (if solver exists)
5250    if (solver_)
5251        solver->messageHandler()->setLogLevel(solver_->messageHandler()->logLevel()) ;
5252
5253    if (modelOwnsSolver() && deleteSolver) {
5254        solverCharacteristics_ = NULL;
5255        delete solver_ ;
5256    }
5257    solver_ = solver;
5258    solver = NULL ;
5259    setModelOwnsSolver(true) ;
5260    /*
5261      Basis information is solver-specific.
5262    */
5263    if (emptyWarmStart_) {
5264        delete emptyWarmStart_  ;
5265        emptyWarmStart_ = 0 ;
5266    }
5267    bestSolutionBasis_ = CoinWarmStartBasis();
5268    /*
5269      Initialize integer variable vector.
5270    */
5271    numberIntegers_ = 0;
5272    int numberColumns = solver_->getNumCols();
5273    int iColumn;
5274    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
5275        if ( solver_->isInteger(iColumn))
5276            numberIntegers_++;
5277    }
5278    delete [] integerVariable_;
5279    if (numberIntegers_) {
5280        integerVariable_ = new int [numberIntegers_];
5281        numberIntegers_ = 0;
5282        for (iColumn = 0; iColumn < numberColumns; iColumn++) {
5283            if ( solver_->isInteger(iColumn))
5284                integerVariable_[numberIntegers_++] = iColumn;
5285        }
5286    } else {
5287        integerVariable_ = NULL;
5288    }
5289
5290    return ;
5291}
5292
5293// Copy constructor.
5294
5295CbcModel::CbcModel(const CbcModel & rhs, bool cloneHandler)
5296        :
5297        continuousSolver_(NULL),
5298        referenceSolver_(NULL),
5299        defaultHandler_(rhs.defaultHandler_),
5300        emptyWarmStart_(NULL),
5301        bestObjective_(rhs.bestObjective_),
5302        bestPossibleObjective_(rhs.bestPossibleObjective_),
5303        sumChangeObjective1_(rhs.sumChangeObjective1_),
5304        sumChangeObjective2_(rhs.sumChangeObjective2_),
5305        minimumDrop_(rhs.minimumDrop_),
5306        numberSolutions_(rhs.numberSolutions_),
5307        numberSavedSolutions_(rhs.numberSavedSolutions_),
5308        maximumSavedSolutions_(rhs.maximumSavedSolutions_),
5309        stateOfSearch_(rhs.stateOfSearch_),
5310        whenCuts_(rhs.whenCuts_),
5311        numberHeuristicSolutions_(rhs.numberHeuristicSolutions_),
5312        numberNodes_(rhs.numberNodes_),
5313        numberNodes2_(rhs.numberNodes2_),
5314        numberIterations_(rhs.numberIterations_),
5315        numberSolves_(rhs.numberSolves_),
5316        status_(rhs.status_),
5317        secondaryStatus_(rhs.secondaryStatus_),
5318        specialOptions_(rhs.specialOptions_),
5319        moreSpecialOptions_(rhs.moreSpecialOptions_),
5320        subTreeModel_(rhs.subTreeModel_),
5321        numberStoppedSubTrees_(rhs.numberStoppedSubTrees_),
5322        mutex_(NULL),
5323        presolve_(rhs.presolve_),
5324        numberStrong_(rhs.numberStrong_),
5325        numberBeforeTrust_(rhs.numberBeforeTrust_),
5326        numberPenalties_(rhs.numberPenalties_),
5327        stopNumberIterations_(rhs.stopNumberIterations_),
5328        penaltyScaleFactor_(rhs.penaltyScaleFactor_),
5329        numberAnalyzeIterations_(rhs.numberAnalyzeIterations_),
5330        analyzeResults_(NULL),
5331        numberInfeasibleNodes_(rhs.numberInfeasibleNodes_),
5332        problemType_(rhs.problemType_),
5333        printFrequency_(rhs.printFrequency_),
5334# ifdef COIN_HAS_CLP
5335        fastNodeDepth_(rhs.fastNodeDepth_),
5336#endif
5337        howOftenGlobalScan_(rhs.howOftenGlobalScan_),
5338        numberGlobalViolations_(rhs.numberGlobalViolations_),
5339        numberExtraIterations_(rhs.numberExtraIterations_),
5340        numberExtraNodes_(rhs.numberExtraNodes_),
5341        continuousObjective_(rhs.continuousObjective_),
5342        originalContinuousObjective_(rhs.originalContinuousObjective_),
5343        continuousInfeasibilities_(rhs.continuousInfeasibilities_),
5344        maximumCutPassesAtRoot_(rhs.maximumCutPassesAtRoot_),
5345        maximumCutPasses_( rhs.maximumCutPasses_),
5346        preferredWay_(rhs.preferredWay_),
5347        currentPassNumber_(rhs.currentPassNumber_),
5348        maximumWhich_(rhs.maximumWhich_),
5349        maximumRows_(0),
5350        currentDepth_(0),
5351        whichGenerator_(NULL),
5352        maximumStatistics_(0),
5353        statistics_(NULL),
5354        maximumDepthActual_(0),
5355        numberDJFixed_(0.0),
5356        probingInfo_(NULL),
5357        numberFixedAtRoot_(rhs.numberFixedAtRoot_),
5358        numberFixedNow_(rhs.numberFixedNow_),
5359        stoppedOnGap_(rhs.stoppedOnGap_),
5360        eventHappened_(rhs.eventHappened_