source: trunk/Cbc/src/CbcModel.cpp @ 1053

Last change on this file since 1053 was 1053, checked in by forrest, 13 years ago

trying to make go faster

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