source: stable/2.2/Cbc/src/CbcModel.cpp @ 1068

Last change on this file since 1068 was 1068, checked in by ladanyi, 11 years ago

result of run_autotools

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