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

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

tweaks to heuristics

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