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

Last change on this file since 979 was 979, checked in by forrest, 12 years ago

best obj fix

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