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

Last change on this file since 1157 was 1157, checked in by forrest, 10 years ago

fix bug which had been fixed in 2.3

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