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

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

for ratiogap

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