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

Last change on this file since 1018 was 1018, checked in by forrest, 11 years ago

fix bug when threaded

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