source: stable/2.3/Cbc/src/CbcModel.cpp @ 1254

Last change on this file since 1254 was 1254, checked in by forrest, 11 years ago

out double counting of cuts

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