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

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

valgrind error

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