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

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

fix when bestSolution passed in and strategy_

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