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

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

changes to heuristics and allow collection of more statistics

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