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

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

changes

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