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

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

chnages to try and make faster

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