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

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

try and make faster

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