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

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

changes for heuristic clone

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