source: stable/BSP/Cbc/src/CbcModel.cpp @ 1185

Last change on this file since 1185 was 1185, checked in by stefan, 11 years ago

fix compiler warnings

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