source: trunk/Cbc/src/CbcNode.cpp @ 310

Last change on this file since 310 was 310, checked in by andreasw, 13 years ago

first commit for autotools conversion to be able to move more files

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 131.8 KB
Line 
1// Copyright (C) 2002, International Business Machines
2// Corporation and others.  All Rights Reserved.
3#if defined(_MSC_VER)
4// Turn off compiler warning about long names
5#  pragma warning(disable:4786)
6#endif
7#include <string>
8//#define CBC_DEBUG 1
9//#define CHECK_CUT_COUNTS
10//#define CHECK_NODE
11#define CBC_WEAK_STRONG
12#include <cassert>
13#include <cfloat>
14#define CUTS
15#include "OsiSolverInterface.hpp"
16#include "OsiAuxInfo.hpp"
17#include "OsiSolverBranch.hpp"
18#include "CoinWarmStartBasis.hpp"
19#include "CoinTime.hpp"
20#include "CbcModel.hpp"
21#include "CbcNode.hpp"
22#include "CbcStatistics.hpp"
23#include "CbcStrategy.hpp"
24#include "CbcBranchActual.hpp"
25#include "CbcBranchDynamic.hpp"
26#include "OsiRowCut.hpp"
27#include "OsiRowCutDebugger.hpp"
28#include "OsiCuts.hpp"
29#include "CbcCountRowCut.hpp"
30#include "CbcFeasibilityBase.hpp"
31#include "CbcMessage.hpp"
32#ifdef CBC_USE_CLP
33#include "OsiClpSolverInterface.hpp"
34#include "ClpSimplexOther.hpp"
35#endif
36using namespace std;
37#include "CglCutGenerator.hpp"
38// Default Constructor
39CbcNodeInfo::CbcNodeInfo ()
40  :
41  numberPointingToThis_(0),
42  parent_(NULL),
43  owner_(NULL),
44  numberCuts_(0),
45  nodeNumber_(0),
46  cuts_(NULL),
47  numberRows_(0),
48  numberBranchesLeft_(0)
49{
50#ifdef CHECK_NODE
51  printf("CbcNodeInfo %x Constructor\n",this);
52#endif
53}
54// Constructor given parent
55CbcNodeInfo::CbcNodeInfo (CbcNodeInfo * parent)
56  :
57  numberPointingToThis_(2),
58  parent_(parent),
59  owner_(NULL),
60  numberCuts_(0),
61  nodeNumber_(0),
62  cuts_(NULL),
63  numberRows_(0),
64  numberBranchesLeft_(2)
65{
66#ifdef CHECK_NODE
67  printf("CbcNodeInfo %x Constructor from parent %x\n",this,parent_);
68#endif
69  if (parent_) {
70    numberRows_ = parent_->numberRows_+parent_->numberCuts_;
71  }
72}
73// Copy Constructor
74CbcNodeInfo::CbcNodeInfo (const CbcNodeInfo & rhs)
75  :
76  numberPointingToThis_(rhs.numberPointingToThis_),
77  parent_(rhs.parent_),
78  owner_(rhs.owner_),
79  numberCuts_(rhs.numberCuts_),
80  nodeNumber_(rhs.nodeNumber_),
81  cuts_(NULL),
82  numberRows_(rhs.numberRows_),
83  numberBranchesLeft_(rhs.numberBranchesLeft_)
84{
85#ifdef CHECK_NODE
86  printf("CbcNodeInfo %x Copy constructor\n",this);
87#endif
88  if (numberCuts_) {
89    cuts_ = new CbcCountRowCut * [numberCuts_];
90    int n=0;
91    for (int i=0;i<numberCuts_;i++) {
92      CbcCountRowCut * thisCut = rhs.cuts_[i];
93      if (thisCut) {
94        // I think this is correct - new one should take priority
95        thisCut->setInfo(this,n);
96        thisCut->increment(numberBranchesLeft_); 
97        cuts_[n++] = thisCut;
98      }
99    }
100    numberCuts_=n;
101  }
102}
103// Constructor given parent and owner
104CbcNodeInfo::CbcNodeInfo (CbcNodeInfo * parent, CbcNode * owner)
105  :
106  numberPointingToThis_(2),
107  parent_(parent),
108  owner_(owner),
109  numberCuts_(0),
110  nodeNumber_(0),
111  cuts_(NULL),
112  numberRows_(0),
113  numberBranchesLeft_(2)
114{
115#ifdef CHECK_NODE
116  printf("CbcNodeInfo %x Constructor from parent %x\n",this,parent_);
117#endif
118  if (parent_) {
119    numberRows_ = parent_->numberRows_+parent_->numberCuts_;
120  }
121}
122
123/**
124  Take care to detach from the owning CbcNode and decrement the reference
125  count in the parent.  If this is the last nodeInfo object pointing to the
126  parent, make a recursive call to delete the parent.
127*/
128CbcNodeInfo::~CbcNodeInfo()
129{
130#ifdef CHECK_NODE
131  printf("CbcNodeInfo %x Destructor parent %x\n",this,parent_);
132#endif
133
134  assert(!numberPointingToThis_);
135  // But they may be some left (max nodes?)
136  for (int i=0;i<numberCuts_;i++) 
137    delete cuts_[i];
138
139  delete [] cuts_;
140  if (owner_) 
141    owner_->nullNodeInfo();
142  if (parent_) {
143    int numberLinks = parent_->decrement();
144    if (!numberLinks) delete parent_;
145  }
146}
147
148
149//#define ALLCUTS
150void
151CbcNodeInfo::decrementCuts(int change)
152{
153  int i;
154  // get rid of all remaining if negative
155  int changeThis;
156  if (change<0)
157    changeThis = numberBranchesLeft_;
158  else
159    changeThis = change;
160 // decrement cut counts
161  for (i=0;i<numberCuts_;i++) {
162    if (cuts_[i]) {
163      int number = cuts_[i]->decrement(changeThis);
164      if (!number) {
165        //printf("info %x del cut %d %x\n",this,i,cuts_[i]);
166        delete cuts_[i];
167        cuts_[i]=NULL;
168      }
169    }
170  }
171}
172void
173CbcNodeInfo::decrementParentCuts(int change)
174{
175  if (parent_) {
176    // get rid of all remaining if negative
177    int changeThis;
178    if (change<0)
179      changeThis = numberBranchesLeft_;
180    else
181      changeThis = change;
182    int i;
183    // Get over-estimate of space needed for basis
184    CoinWarmStartBasis dummy;
185    dummy.setSize(0,numberRows_+numberCuts_);
186    buildRowBasis(dummy);
187    /* everything is zero (i.e. free) so we can use to see
188       if latest basis */
189    CbcNodeInfo * thisInfo = parent_;
190    while (thisInfo) 
191      thisInfo = thisInfo->buildRowBasis(dummy);
192    // decrement cut counts
193    thisInfo = parent_;
194    int numberRows=numberRows_;
195    while (thisInfo) {
196      for (i=thisInfo->numberCuts_-1;i>=0;i--) {
197        CoinWarmStartBasis::Status status = dummy.getArtifStatus(--numberRows);
198#ifdef ALLCUTS
199        status = CoinWarmStartBasis::isFree;
200#endif
201        if (thisInfo->cuts_[i]) {
202          int number=1;
203          if (status!=CoinWarmStartBasis::basic) {
204            // tight - drop 1 or 2
205            if (change<0)
206              number = thisInfo->cuts_[i]->decrement(changeThis);
207            else
208              number = thisInfo->cuts_[i]->decrement(change);
209          }
210          if (!number) {
211            delete thisInfo->cuts_[i];
212            thisInfo->cuts_[i]=NULL;
213          }
214        }
215      }
216      thisInfo = thisInfo->parent_;
217    }
218  }
219}
220
221void
222CbcNodeInfo::incrementParentCuts(int change)
223{
224  if (parent_) {
225    int i;
226    // Get over-estimate of space needed for basis
227    CoinWarmStartBasis dummy;
228    dummy.setSize(0,numberRows_+numberCuts_);
229    /* everything is zero (i.e. free) so we can use to see
230       if latest basis */
231    buildRowBasis(dummy);
232    CbcNodeInfo * thisInfo = parent_;
233    while (thisInfo) 
234      thisInfo = thisInfo->buildRowBasis(dummy);
235    // increment cut counts
236    thisInfo = parent_;
237    int numberRows=numberRows_;
238    while (thisInfo) {
239      for (i=thisInfo->numberCuts_-1;i>=0;i--) {
240        CoinWarmStartBasis::Status status = dummy.getArtifStatus(--numberRows);
241#ifdef ALLCUTS
242        status = CoinWarmStartBasis::isFree;
243#endif
244        if (thisInfo->cuts_[i]&&status!=CoinWarmStartBasis::basic) {
245          thisInfo->cuts_[i]->increment(change);
246        }
247      }
248      thisInfo = thisInfo->parent_;
249    }
250  }
251}
252
253/*
254  Append cuts to the cuts_ array in a nodeInfo. The initial reference count
255  is set to numberToBranchOn, which will normally be the number of arms
256  defined for the CbcBranchingObject attached to the CbcNode that owns this
257  CbcNodeInfo.
258*/
259void
260CbcNodeInfo::addCuts (OsiCuts & cuts, int numberToBranchOn,
261                      int * whichGenerator)
262{
263  int numberCuts = cuts.sizeRowCuts();
264  if (numberCuts) {
265    int i;
266    if (!numberCuts_) {
267      cuts_ = new CbcCountRowCut * [numberCuts];
268    } else {
269      CbcCountRowCut ** temp = new CbcCountRowCut * [numberCuts+numberCuts_];
270      memcpy(temp,cuts_,numberCuts_*sizeof(CbcCountRowCut *));
271      delete [] cuts_;
272      cuts_ = temp;
273    }
274    for (i=0;i<numberCuts;i++) {
275      CbcCountRowCut * thisCut = new CbcCountRowCut(*cuts.rowCutPtr(i),
276                                                    this,numberCuts_);
277      thisCut->increment(numberToBranchOn); 
278      cuts_[numberCuts_++] = thisCut;
279#ifdef CBC_DEBUG
280#if CBC_DEBUG>1
281      int n=thisCut->row().getNumElements();
282      printf("Cut %d has %d entries, rhs %g %g =>",i,n,thisCut->lb(),
283             thisCut->ub());
284      int j;
285      const int * index = thisCut->row().getIndices();
286      const double * element = thisCut->row().getElements();
287      for (j=0;j<n;j++) {
288        printf(" (%d,%g)",index[j],element[j]);
289        assert(fabs(element[j])>1.00e-12);
290      }
291      printf("\n");
292#else
293      int n=thisCut->row().getNumElements();
294      int j;
295      const double * element = thisCut->row().getElements();
296      for (j=0;j<n;j++) {
297        assert(fabs(element[j])>1.00e-12);
298      }
299#endif
300#endif
301    }
302  }
303}
304
305void
306CbcNodeInfo::addCuts(int numberCuts, CbcCountRowCut ** cut, 
307                     int numberToBranchOn)
308{
309  if (numberCuts) {
310    int i;
311    if (!numberCuts_) {
312      cuts_ = new CbcCountRowCut * [numberCuts];
313    } else {
314      CbcCountRowCut ** temp = new CbcCountRowCut * [numberCuts+numberCuts_];
315      memcpy(temp,cuts_,numberCuts_*sizeof(CbcCountRowCut *));
316      delete [] cuts_;
317      cuts_ = temp;
318    }
319    for (i=0;i<numberCuts;i++) {
320      CbcCountRowCut * thisCut = cut[i];
321      thisCut->setInfo(this,numberCuts_);
322      //printf("info %x cut %d %x\n",this,i,thisCut);
323      thisCut->increment(numberToBranchOn); 
324      cuts_[numberCuts_++] = thisCut;
325#ifdef CBC_DEBUG
326      int n=thisCut->row().getNumElements();
327#if CBC_DEBUG>1
328      printf("Cut %d has %d entries, rhs %g %g =>",i,n,thisCut->lb(),
329             thisCut->ub());
330#endif
331      int j;
332#if CBC_DEBUG>1
333      const int * index = thisCut->row().getIndices();
334#endif
335      const double * element = thisCut->row().getElements();
336      for (j=0;j<n;j++) {
337#if CBC_DEBUG>1
338        printf(" (%d,%g)",index[j],element[j]);
339#endif
340        assert(fabs(element[j])>1.00e-12);
341      }
342      printf("\n");
343#endif
344    }
345  }
346}
347
348// delete cuts
349void
350CbcNodeInfo::deleteCuts(int numberToDelete, CbcCountRowCut ** cuts)
351{
352  int i;
353  int j;
354  int last=-1;
355  for (i=0;i<numberToDelete;i++) {
356    CbcCountRowCut * next = cuts[i];
357    for (j=last+1;j<numberCuts_;j++) {
358      if (next==cuts_[j])
359        break;
360    }
361    if (j==numberCuts_) {
362      // start from beginning
363      for (j=0;j<last;j++) {
364        if (next==cuts_[j])
365          break;
366      }
367      assert(j<last);
368    }
369    last=j;
370    int number = cuts_[j]->decrement();
371    if (!number)
372      delete cuts_[j];
373    cuts_[j]=NULL;
374  }
375  j=0;
376  for (i=0;i<numberCuts_;i++) {
377    if (cuts_[i])
378      cuts_[j++]=cuts_[i];
379  }
380  numberCuts_ = j;
381}
382
383// delete cuts
384void
385CbcNodeInfo::deleteCuts(int numberToDelete, int * which)
386{
387  int i;
388  for (i=0;i<numberToDelete;i++) {
389    int iCut=which[i];
390    int number = cuts_[iCut]->decrement();
391    if (!number)
392      delete cuts_[iCut];
393    cuts_[iCut]=NULL;
394  }
395  int j=0;
396  for (i=0;i<numberCuts_;i++) {
397    if (cuts_[i])
398      cuts_[j++]=cuts_[i];
399  }
400  numberCuts_ = j;
401}
402
403// Really delete a cut
404void 
405CbcNodeInfo::deleteCut(int whichOne)
406{
407  assert(whichOne<numberCuts_);
408  cuts_[whichOne]=NULL;
409}
410
411CbcFullNodeInfo::CbcFullNodeInfo() :
412  CbcNodeInfo(),
413  basis_(),
414  numberIntegers_(0),
415  lower_(NULL),
416  upper_(NULL)
417{
418}
419CbcFullNodeInfo::CbcFullNodeInfo(CbcModel * model,
420                                 int numberRowsAtContinuous) :
421  CbcNodeInfo()
422{
423  OsiSolverInterface * solver = model->solver();
424  numberRows_ = numberRowsAtContinuous;
425  numberIntegers_ = model->numberIntegers();
426  int numberColumns = model->getNumCols();
427  lower_ = new double [numberColumns];
428  upper_ = new double [numberColumns];
429  const double * lower = solver->getColLower();
430  const double * upper = solver->getColUpper();
431  int i;
432
433  for (i=0;i<numberColumns;i++) {
434    lower_[i]=lower[i];
435    upper_[i]=upper[i];
436  }
437
438  basis_ =  dynamic_cast<CoinWarmStartBasis*>(solver->getWarmStart());
439}
440
441CbcFullNodeInfo::CbcFullNodeInfo(const CbcFullNodeInfo & rhs) :
442  CbcNodeInfo(rhs)
443{ 
444  basis_= dynamic_cast<CoinWarmStartBasis *>(rhs.basis_->clone()) ;
445  numberIntegers_=rhs.numberIntegers_;
446  lower_=NULL;
447  upper_=NULL;
448  if (rhs.lower_!=NULL) {
449    int numberColumns = basis_->getNumStructural();
450    lower_ = new double [numberColumns];
451    upper_ = new double [numberColumns];
452    assert (upper_!=NULL);
453    memcpy(lower_,rhs.lower_,numberColumns*sizeof(double));
454    memcpy(upper_,rhs.upper_,numberColumns*sizeof(double));
455  }
456}
457
458CbcNodeInfo * 
459CbcFullNodeInfo::clone() const
460{ 
461  return (new CbcFullNodeInfo(*this));
462}
463
464CbcFullNodeInfo::~CbcFullNodeInfo ()
465{
466  delete basis_ ;
467  delete [] lower_;
468  delete [] upper_;
469}
470
471/*
472   The basis supplied as a parameter is deleted and replaced with a new basis
473   appropriate for the node, and lower and upper bounds on variables are
474   reset according to the stored bounds arrays. Any cuts associated with this
475   node are added to the list in addCuts, but not actually added to the
476   constraint system in the model.
477
478   Why pass in a basis at all? The short answer is ``We need the parameter to
479   pass out a basis, so might as well use it to pass in the size.''
480   
481   A longer answer is that in practice we take a memory allocation hit up in
482   addCuts1 (the only place applyToModel is called) when we setSize() the
483   basis that's passed in. It's immediately tossed here in favour of a clone
484   of the basis attached to this nodeInfo. This can probably be fixed, given
485   a bit of thought.
486*/
487
488void CbcFullNodeInfo::applyToModel (CbcModel *model,
489                                    CoinWarmStartBasis *&basis,
490                                    CbcCountRowCut **addCuts,
491                                    int &currentNumberCuts) const 
492
493{ OsiSolverInterface *solver = model->solver() ;
494
495  // branch - do bounds
496  int i;
497  solver->setColLower(lower_);
498  solver->setColUpper(upper_);
499  int numberColumns = model->getNumCols();
500  // move basis - but make sure size stays
501  // for bon-min - should not be needed int numberRows = model->getNumRows();
502  int numberRows=basis->getNumArtificial();
503  delete basis ;
504  if (basis_) {
505    basis = dynamic_cast<CoinWarmStartBasis *>(basis_->clone()) ;
506    basis->resize(numberRows,numberColumns);
507  } else {
508    // We have a solver without a basis
509    basis=NULL;
510  }
511  for (i=0;i<numberCuts_;i++) 
512    addCuts[currentNumberCuts+i]= cuts_[i];
513  currentNumberCuts += numberCuts_;
514  assert(!parent_);
515  return ;
516}
517
518/* Builds up row basis backwards (until original model).
519   Returns NULL or previous one to apply .
520   Depends on Free being 0 and impossible for cuts
521*/
522CbcNodeInfo * 
523CbcFullNodeInfo::buildRowBasis(CoinWarmStartBasis & basis ) const 
524{
525  const unsigned int * saved = 
526    (const unsigned int *) basis_->getArtificialStatus();
527  unsigned int * now = 
528    (unsigned int *) basis.getArtificialStatus();
529  int number=basis_->getNumArtificial()>>4;;
530  int i;
531  for (i=0;i<number;i++) { 
532    if (!now[i])
533      now[i] = saved[i];
534  }
535  return NULL;
536}
537
538// Default constructor
539CbcPartialNodeInfo::CbcPartialNodeInfo()
540
541  : CbcNodeInfo(),
542    basisDiff_(NULL),
543    variables_(NULL),
544    newBounds_(NULL),
545    numberChangedBounds_(0)
546
547{ /* this space intentionally left blank */ }
548
549// Constructor from current state
550CbcPartialNodeInfo::CbcPartialNodeInfo (CbcNodeInfo *parent, CbcNode *owner,
551                                        int numberChangedBounds,
552                                        const int *variables,
553                                        const double *boundChanges,
554                                        const CoinWarmStartDiff *basisDiff)
555 : CbcNodeInfo(parent,owner)
556{
557  basisDiff_ = basisDiff->clone() ;
558
559  numberChangedBounds_ = numberChangedBounds;
560  variables_ = new int [numberChangedBounds_];
561  newBounds_ = new double [numberChangedBounds_];
562
563  int i ;
564  for (i=0;i<numberChangedBounds_;i++) {
565    variables_[i]=variables[i];
566    newBounds_[i]=boundChanges[i];
567  }
568}
569
570CbcPartialNodeInfo::CbcPartialNodeInfo (const CbcPartialNodeInfo & rhs)
571
572  : CbcNodeInfo(rhs.parent_)
573
574{ basisDiff_ = rhs.basisDiff_->clone() ;
575
576  numberChangedBounds_ = rhs.numberChangedBounds_;
577  variables_ = new int [numberChangedBounds_];
578  newBounds_ = new double [numberChangedBounds_];
579
580  int i ;
581  for (i=0;i<numberChangedBounds_;i++) {
582    variables_[i]=rhs.variables_[i];
583    newBounds_[i]=rhs.newBounds_[i];
584  }
585}
586
587CbcNodeInfo * 
588CbcPartialNodeInfo::clone() const
589{ 
590  return (new CbcPartialNodeInfo(*this));
591}
592
593
594CbcPartialNodeInfo::~CbcPartialNodeInfo ()
595{
596  delete basisDiff_ ;
597  delete [] variables_;
598  delete [] newBounds_;
599}
600
601
602/**
603   The basis supplied as a parameter is incrementally modified, and lower and
604   upper bounds on variables in the model are incrementally modified. Any
605   cuts associated with this node are added to the list in addCuts.
606*/
607
608void CbcPartialNodeInfo::applyToModel (CbcModel *model,
609                                       CoinWarmStartBasis *&basis,
610                                       CbcCountRowCut **addCuts,
611                                       int &currentNumberCuts) const 
612
613{ OsiSolverInterface *solver = model->solver();
614
615  basis->applyDiff(basisDiff_) ;
616
617  // branch - do bounds
618  int i;
619  for (i=0;i<numberChangedBounds_;i++) {
620    int variable = variables_[i];
621    if ((variable&0x80000000)==0) {
622      // lower bound changing
623      solver->setColLower(variable,newBounds_[i]);
624    } else {
625      // upper bound changing
626      solver->setColUpper(variable&0x7fffffff,newBounds_[i]);
627    }
628  }
629  for (i=0;i<numberCuts_;i++) {
630    addCuts[currentNumberCuts+i]= cuts_[i];
631    if (cuts_[i]&&model->messageHandler()->logLevel()>2) {
632      cuts_[i]->print();
633    }
634  }
635   
636  currentNumberCuts += numberCuts_;
637  return ;
638}
639
640/* Builds up row basis backwards (until original model).
641   Returns NULL or previous one to apply .
642   Depends on Free being 0 and impossible for cuts
643*/
644
645CbcNodeInfo * 
646CbcPartialNodeInfo::buildRowBasis(CoinWarmStartBasis & basis ) const 
647
648{ basis.applyDiff(basisDiff_) ;
649
650  return parent_ ; }
651
652
653CbcNode::CbcNode() :
654  nodeInfo_(NULL),
655  objectiveValue_(1.0e100),
656  guessedObjectiveValue_(1.0e100),
657  branch_(NULL),
658  depth_(-1),
659  numberUnsatisfied_(0)
660{
661#ifdef CHECK_NODE
662  printf("CbcNode %x Constructor\n",this);
663#endif
664}
665
666CbcNode::CbcNode(CbcModel * model,
667                 CbcNode * lastNode) :
668  nodeInfo_(NULL),
669  objectiveValue_(1.0e100),
670  guessedObjectiveValue_(1.0e100),
671  branch_(NULL),
672  depth_(-1),
673  numberUnsatisfied_(0)
674{
675#ifdef CHECK_NODE
676  printf("CbcNode %x Constructor from model\n",this);
677#endif
678  model->setObjectiveValue(this,lastNode);
679
680  if (lastNode)
681    lastNode->nodeInfo_->increment();
682}
683
684
685void
686CbcNode::createInfo (CbcModel *model,
687                     CbcNode *lastNode,
688                     const CoinWarmStartBasis *lastws,
689                     const double *lastLower, const double *lastUpper,
690                     int numberOldActiveCuts,int numberNewCuts)
691{ OsiSolverInterface * solver = model->solver();
692 CbcStrategy * strategy = model->strategy();
693/*
694  The root --- no parent. Create full basis and bounds information.
695*/
696  if (!lastNode)
697  { 
698    if (!strategy)
699      nodeInfo_=new CbcFullNodeInfo(model,solver->getNumRows());
700    else
701      nodeInfo_ = strategy->fullNodeInfo(model,solver->getNumRows());
702  }
703/*
704  Not the root. Create an edit from the parent's basis & bound information.
705  This is not quite as straightforward as it seems. We need to reintroduce
706  cuts we may have dropped out of the basis, in the correct position, because
707  this whole process is strictly positional. Start by grabbing the current
708  basis.
709*/
710  else
711  { const CoinWarmStartBasis* ws =
712      dynamic_cast<const CoinWarmStartBasis*>(solver->getWarmStart());
713    assert(ws!=NULL); // make sure not volume
714    //int numberArtificials = lastws->getNumArtificial();
715    int numberColumns = solver->getNumCols();
716   
717    const double * lower = solver->getColLower();
718    const double * upper = solver->getColUpper();
719
720    int i;
721/*
722  Create a clone and resize it to hold all the structural constraints, plus
723  all the cuts: old cuts, both active and inactive (currentNumberCuts), and
724  new cuts (numberNewCuts).
725
726  TODO: You'd think that the set of constraints (logicals) in the expanded
727        basis should match the set represented in lastws. At least, that's
728        what I thought. But at the point I first looked hard at this bit of
729        code, it turned out that lastws was the stripped basis produced at
730        the end of addCuts(), rather than the raw basis handed back by
731        addCuts1(). The expanded basis here is equivalent to the raw basis of
732        addCuts1(). I said ``whoa, that's not good, I must have introduced a
733        bug'' and went back to John's code to see where I'd gone wrong.
734        And discovered the same `error' in his code.
735
736        After a bit of thought, my conclusion is that correctness is not
737        affected by whether lastws is the stripped or raw basis. The diffs
738        have no semantics --- just a set of changes that need to be made
739        to convert lastws into expanded. I think the only effect is that we
740        store a lot more diffs (everything in expanded that's not covered by
741        the stripped basis). But I need to give this more thought. There
742        may well be some subtle error cases.
743
744        In the mean time, I've twiddled addCuts() to set lastws to the raw
745        basis. Makes me (Lou) less nervous to compare apples to apples.
746*/
747    CoinWarmStartBasis *expanded = 
748      dynamic_cast<CoinWarmStartBasis *>(ws->clone()) ;
749    int numberRowsAtContinuous = model->numberRowsAtContinuous();
750    int iFull = numberRowsAtContinuous+model->currentNumberCuts()+
751      numberNewCuts;
752    //int numberArtificialsNow = iFull;
753    //int maxBasisLength = ((iFull+15)>>4)+((numberColumns+15)>>4);
754    //printf("l %d full %d\n",maxBasisLength,iFull);
755    if (expanded) 
756      expanded->resize(iFull,numberColumns);
757#ifdef CBC_CHECK_BASIS
758    printf("Before expansion: orig %d, old %d, new %d, current %d\n",
759           numberRowsAtContinuous,numberOldActiveCuts,numberNewCuts,
760           model->currentNumberCuts()) ;
761    ws->print();
762#endif
763/*
764  Now fill in the expanded basis. Any indices beyond nPartial must
765  be cuts created while processing this node --- they can be copied directly
766  into the expanded basis. From nPartial down, pull the status of active cuts
767  from ws, interleaving with a B entry for the deactivated (loose) cuts.
768*/
769    int numberDropped = model->currentNumberCuts()-numberOldActiveCuts;
770    int iCompact=iFull-numberDropped;
771    CbcCountRowCut ** cut = model->addedCuts();
772    int nPartial = model->currentNumberCuts()+numberRowsAtContinuous;
773    iFull--;
774    for (;iFull>=nPartial;iFull--) {
775      CoinWarmStartBasis::Status status = ws->getArtifStatus(--iCompact);
776      //assert (status != CoinWarmStartBasis::basic); // may be permanent cut
777      expanded->setArtifStatus(iFull,status);
778    }
779    for (;iFull>=numberRowsAtContinuous;iFull--) {
780      if (cut[iFull-numberRowsAtContinuous]) {
781        CoinWarmStartBasis::Status status = ws->getArtifStatus(--iCompact);
782        // If no cut generator being used then we may have basic variables
783        //if (model->getMaximumCutPasses()&&
784        //  status == CoinWarmStartBasis::basic)
785        //printf("cut basic\n");
786        expanded->setArtifStatus(iFull,status);
787      } else {
788        expanded->setArtifStatus(iFull,CoinWarmStartBasis::basic);
789      }
790    }
791#ifdef CBC_CHECK_BASIS
792    printf("Expanded basis\n");
793    expanded->print() ;
794    printf("Diffing against\n") ;
795    lastws->print() ;
796#endif   
797/*
798  Now that we have two bases in proper positional correspondence, creating
799  the actual diff is dead easy.
800*/
801
802    CoinWarmStartDiff *basisDiff = expanded->generateDiff(lastws) ;
803/*
804  Diff the bound vectors. It's assumed the number of structural variables is
805  not changing. Assuming that branching objects all involve integer variables,
806  we should see at least one bound change as a consequence of processing this
807  subproblem. Different types of branching objects could break this assertion.
808  Not true at all - we have not applied current branch - JJF.
809*/
810    double *boundChanges = new double [2*numberColumns] ;
811    int *variables = new int [2*numberColumns] ;
812    int numberChangedBounds=0;
813    for (i=0;i<numberColumns;i++) {
814      if (lower[i]!=lastLower[i]) {
815        variables[numberChangedBounds]=i;
816        boundChanges[numberChangedBounds++]=lower[i];
817      }
818      if (upper[i]!=lastUpper[i]) {
819        variables[numberChangedBounds]=i|0x80000000;
820        boundChanges[numberChangedBounds++]=upper[i];
821      }
822#ifdef CBC_DEBUG
823      if (lower[i]!=lastLower[i])
824        printf("lower on %d changed from %g to %g\n",
825               i,lastLower[i],lower[i]);
826      if (upper[i]!=lastUpper[i])
827        printf("upper on %d changed from %g to %g\n",
828               i,lastUpper[i],upper[i]);
829#endif
830    }
831#ifdef CBC_DEBUG
832    printf("%d changed bounds\n",numberChangedBounds) ;
833#endif
834    //if (lastNode->branchingObject()->boundBranch())
835    //assert (numberChangedBounds);
836/*
837  Hand the lot over to the CbcPartialNodeInfo constructor, then clean up and
838  return.
839*/
840    if (!strategy)
841      nodeInfo_ =
842        new CbcPartialNodeInfo(lastNode->nodeInfo_,this,numberChangedBounds,
843                               variables,boundChanges,basisDiff) ;
844    else
845      nodeInfo_ = strategy->partialNodeInfo(model, lastNode->nodeInfo_,this,numberChangedBounds,
846                               variables,boundChanges,basisDiff) ;
847    delete basisDiff ;
848    delete [] boundChanges;
849    delete [] variables;
850    delete expanded ;
851    delete ws;
852  }
853  // Set node number
854  nodeInfo_->setNodeNumber(model->getNodeCount2());
855}
856
857/*
858  The routine scans through the object list of the model looking for objects
859  that indicate infeasibility. It tests each object using strong branching
860  and selects the one with the least objective degradation.  A corresponding
861  branching object is left attached to lastNode.
862
863  If strong branching is disabled, a candidate object is chosen essentially
864  at random (whatever object ends up in pos'n 0 of the candidate array).
865
866  If a branching candidate is found to be monotone, bounds are set to fix the
867  variable and the routine immediately returns (the caller is expected to
868  reoptimize).
869
870  If a branching candidate is found to result in infeasibility in both
871  directions, the routine immediately returns an indication of infeasibility.
872
873  Returns:  0   both branch directions are feasible
874           -1   branching variable is monotone
875           -2   infeasible
876
877  Original comments:
878    Here could go cuts etc etc
879    For now just fix on objective from strong branching.
880*/
881
882int CbcNode::chooseBranch (CbcModel *model, CbcNode *lastNode,int numberPassesLeft)
883
884{ if (lastNode)
885    depth_ = lastNode->depth_+1;
886  else
887    depth_ = 0;
888  delete branch_;
889  branch_=NULL;
890  OsiSolverInterface * solver = model->solver();
891  double saveObjectiveValue = solver->getObjValue();
892  double objectiveValue = CoinMax(solver->getObjSense()*saveObjectiveValue,objectiveValue_);
893  const double * lower = solver->getColLower();
894  const double * upper = solver->getColUpper();
895  // See what user thinks
896  int anyAction=model->problemFeasibility()->feasible(model,0);
897  if (anyAction) {
898    // will return -2 if infeasible , 0 if treat as integer
899    return anyAction-1;
900  }
901  double integerTolerance = 
902    model->getDblParam(CbcModel::CbcIntegerTolerance);
903  int i;
904  bool beforeSolution = model->getSolutionCount()==0;
905  int numberStrong=model->numberStrong();
906  // switch off strong if hotstart
907  if (model->hotstartSolution())
908    numberStrong=0;
909  int numberStrongDone=0;
910  int numberUnfinished=0;
911  int numberStrongInfeasible=0;
912  int numberStrongIterations=0;
913  int saveNumberStrong=numberStrong;
914  int numberObjects = model->numberObjects();
915  bool checkFeasibility = numberObjects>model->numberIntegers();
916  int maximumStrong = CoinMax(CoinMin(model->numberStrong(),numberObjects),1);
917  int numberColumns = model->getNumCols();
918  double * saveUpper = new double[numberColumns];
919  double * saveLower = new double[numberColumns];
920
921  // Save solution in case heuristics need good solution later
922 
923  double * saveSolution = new double[numberColumns];
924  memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
925  model->reserveCurrentSolution(saveSolution);
926  /*
927    Get a branching decision object. Use the default decision criteria unless
928    the user has loaded a decision method into the model.
929  */
930  CbcBranchDecision *decision = model->branchingMethod();
931  if (!decision)
932    decision = new CbcBranchDefaultDecision();
933
934  CbcStrongInfo * choice = new CbcStrongInfo[maximumStrong];
935  for (i=0;i<numberColumns;i++) {
936    saveLower[i] = lower[i];
937    saveUpper[i] = upper[i];
938  }
939  // May go round twice if strong branching fixes all local candidates
940  bool finished=false;
941  double estimatedDegradation=0.0; 
942  while(!finished) {
943    finished=true;
944    // Some objects may compute an estimate of best solution from here
945    estimatedDegradation=0.0; 
946    //int numberIntegerInfeasibilities=0; // without odd ones
947    numberStrongDone=0;
948    numberUnfinished=0;
949    numberStrongInfeasible=0;
950    numberStrongIterations=0;
951   
952    // We may go round this loop twice (only if we think we have solution)
953    for (int iPass=0;iPass<2;iPass++) {
954     
955      // compute current state
956      //int numberObjectInfeasibilities; // just odd ones
957      //model->feasibleSolution(
958      //                      numberIntegerInfeasibilities,
959      //                      numberObjectInfeasibilities);
960      const double * hotstartSolution = model->hotstartSolution();
961      const int * hotstartPriorities = model->hotstartPriorities();
962     
963      // Some objects may compute an estimate of best solution from here
964      estimatedDegradation=0.0; 
965      numberUnsatisfied_ = 0;
966      int bestPriority=INT_MAX;
967      /*
968        Scan for branching objects that indicate infeasibility. Choose the best
969        maximumStrong candidates, using priority as the first criteria, then
970        integer infeasibility.
971       
972        The algorithm is to fill the choice array with a set of good candidates (by
973        infeasibility) with priority bestPriority.  Finding a candidate with
974        priority better (less) than bestPriority flushes the choice array. (This
975        serves as initialization when the first candidate is found.)
976       
977        A new candidate is added to choices only if its infeasibility exceeds the
978        current max infeasibility (mostAway). When a candidate is added, it
979        replaces the candidate with the smallest infeasibility (tracked by
980        iSmallest).
981      */
982      int iSmallest = 0;
983      double mostAway = 1.0e-100;
984      for (i = 0 ; i < maximumStrong ; i++)
985        choice[i].possibleBranch = NULL ;
986      numberStrong=0;
987      bool canDoOneHot=false;
988      for (i=0;i<numberObjects;i++) {
989        CbcObject * object = model->modifiableObject(i);
990        int preferredWay;
991        double infeasibility = object->infeasibility(preferredWay);
992        int priorityLevel = object->priority();
993        if (hotstartSolution) {
994          // we are doing hot start
995          const CbcSimpleInteger * thisOne = dynamic_cast <const CbcSimpleInteger *> (object);
996          if (thisOne) {
997            int iColumn = thisOne->modelSequence();
998            bool canDoThisHot=true;
999            double targetValue = hotstartSolution[iColumn];
1000            if (saveUpper[iColumn]>saveLower[iColumn]) {
1001              double value = saveSolution[iColumn];
1002              if (hotstartPriorities)
1003                priorityLevel=hotstartPriorities[iColumn]; 
1004              //double originalLower = thisOne->originalLower();
1005              //double originalUpper = thisOne->originalUpper();
1006              // switch off if not possible
1007              if (targetValue>=saveLower[iColumn]&&targetValue<=saveUpper[iColumn]) {
1008                /* priority outranks rest always if negative
1009                   otherwise can be downgraded if at correct level.
1010                   Infeasibility may be increased to choose 1.0 values first.
1011                   choose one near wanted value
1012                */
1013                if (fabs(value-targetValue)>integerTolerance) {
1014                  infeasibility = 1.0-fabs(value-targetValue);
1015                  if (targetValue==1.0)
1016                    infeasibility += 1.0;
1017                  if (value>targetValue) {
1018                    preferredWay=-1;
1019                  } else {
1020                    preferredWay=1;
1021                  }
1022                  priorityLevel = CoinAbs(priorityLevel);
1023                } else if (priorityLevel<0) {
1024                  priorityLevel = CoinAbs(priorityLevel);
1025                  if (targetValue==saveLower[iColumn]) {
1026                    infeasibility = integerTolerance+1.0e-12;
1027                    preferredWay=-1;
1028                  } else if (targetValue==saveUpper[iColumn]) {
1029                    infeasibility = integerTolerance+1.0e-12;
1030                    preferredWay=1;
1031                  } else {
1032                    // can't
1033                    priorityLevel += 10000000;
1034                    canDoThisHot=false;
1035                  }
1036                } else {
1037                  priorityLevel += 10000000;
1038                  canDoThisHot=false;
1039                }
1040              } else {
1041                // switch off if not possible
1042                canDoThisHot=false;
1043              }
1044              if (canDoThisHot)
1045                canDoOneHot=true;
1046            } else if (targetValue<saveLower[iColumn]||targetValue>saveUpper[iColumn]) {
1047            }
1048          } else {
1049            priorityLevel += 10000000;
1050          }
1051        }
1052        if (infeasibility) {
1053          // Increase estimated degradation to solution
1054          estimatedDegradation += CoinMin(object->upEstimate(),object->downEstimate());
1055          numberUnsatisfied_++;
1056          // Better priority? Flush choices.
1057          if (priorityLevel<bestPriority) {
1058            int j;
1059            iSmallest=0;
1060            for (j=0;j<maximumStrong;j++) {
1061              choice[j].upMovement=0.0;
1062              delete choice[j].possibleBranch;
1063              choice[j].possibleBranch=NULL;
1064            }
1065            bestPriority = priorityLevel;
1066            mostAway=1.0e-100;
1067            numberStrong=0;
1068          } else if (priorityLevel>bestPriority) {
1069            continue;
1070          }
1071          // Check for suitability based on infeasibility.
1072          if (infeasibility>mostAway) {
1073            //add to list
1074            choice[iSmallest].upMovement=infeasibility;
1075            delete choice[iSmallest].possibleBranch;
1076            choice[iSmallest].possibleBranch=object->createBranch(preferredWay);
1077            numberStrong = CoinMax(numberStrong,iSmallest+1);
1078            // Save which object it was
1079            choice[iSmallest].objectNumber=i;
1080            int j;
1081            iSmallest=-1;
1082            mostAway = 1.0e50;
1083            for (j=0;j<maximumStrong;j++) {
1084              if (choice[j].upMovement<mostAway) {
1085                mostAway=choice[j].upMovement;
1086                iSmallest=j;
1087              }
1088            }
1089          }
1090        }
1091      }
1092      if (!canDoOneHot&&hotstartSolution) {
1093        // switch off as not possible
1094        hotstartSolution=NULL;
1095        model->setHotstartSolution(NULL,NULL);
1096      }
1097      if (numberUnsatisfied_) {
1098        // some infeasibilities - go to next steps
1099        break;
1100      } else if (!iPass) {
1101        // looks like a solution - get paranoid
1102        bool roundAgain=false;
1103        // get basis
1104        CoinWarmStartBasis * ws = dynamic_cast<CoinWarmStartBasis*>(solver->getWarmStart());
1105        if (!ws)
1106          break;
1107        for (i=0;i<numberColumns;i++) {
1108          double value = saveSolution[i];
1109          if (value<lower[i]) {
1110            saveSolution[i]=lower[i];
1111            roundAgain=true;
1112            ws->setStructStatus(i,CoinWarmStartBasis::atLowerBound);
1113          } else if (value>upper[i]) {
1114            saveSolution[i]=upper[i];
1115            roundAgain=true;
1116            ws->setStructStatus(i,CoinWarmStartBasis::atUpperBound);
1117          } 
1118        }
1119        if (roundAgain&&saveNumberStrong) {
1120          // restore basis
1121          solver->setWarmStart(ws);
1122          delete ws;
1123          solver->resolve();
1124          memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
1125          model->reserveCurrentSolution(saveSolution);
1126          if (!solver->isProvenOptimal()) {
1127            // infeasible
1128            anyAction=-2;
1129            break;
1130          }
1131        } else {
1132          delete ws;
1133          break;
1134        }
1135      }
1136    }
1137    /* Some solvers can do the strong branching calculations faster if
1138       they do them all at once.  At present only Clp does for ordinary
1139       integers but I think this coding would be easy to modify
1140    */
1141    bool allNormal=true; // to say if we can do fast strong branching
1142    // Say which one will be best
1143    int bestChoice=0;
1144    double worstInfeasibility=0.0;
1145    for (i=0;i<numberStrong;i++) {
1146      choice[i].numIntInfeasUp = numberUnsatisfied_;
1147      choice[i].numIntInfeasDown = numberUnsatisfied_;
1148      choice[i].fix=0; // say not fixed
1149      if (!dynamic_cast <const CbcSimpleInteger *> (model->object(choice[i].objectNumber)))
1150        allNormal=false; // Something odd so lets skip clever fast branching
1151      if ( !model->object(choice[i].objectNumber)->boundBranch())
1152        numberStrong=0; // switch off
1153      if ( choice[i].possibleBranch->numberBranches()>2)
1154        numberStrong=0; // switch off
1155      // Do best choice in case switched off
1156      if (choice[i].upMovement>worstInfeasibility) {
1157        worstInfeasibility=choice[i].upMovement;
1158        bestChoice=i;
1159      }
1160    }
1161    // If we have hit max time don't do strong branching
1162    bool hitMaxTime = ( CoinCpuTime()-model->getDblParam(CbcModel::CbcStartSeconds) > 
1163                        model->getDblParam(CbcModel::CbcMaximumSeconds));
1164    // also give up if we are looping round too much
1165    if (hitMaxTime||numberPassesLeft<=0)
1166      numberStrong=0;
1167    /*
1168      Is strong branching enabled? If so, set up and do it. Otherwise, we'll
1169      fall through to simple branching.
1170     
1171      Setup for strong branching involves saving the current basis (for restoration
1172      afterwards) and setting up for hot starts.
1173    */
1174    if (numberStrong&&saveNumberStrong) {
1175     
1176      bool solveAll=false; // set true to say look at all even if some fixed (experiment)
1177      solveAll=true;
1178      // worth trying if too many times
1179      // Save basis
1180      CoinWarmStart * ws = solver->getWarmStart();
1181      // save limit
1182      int saveLimit;
1183      solver->getIntParam(OsiMaxNumIterationHotStart,saveLimit);
1184      if (beforeSolution&&saveLimit<100)
1185        solver->setIntParam(OsiMaxNumIterationHotStart,100); // go to end
1186#     ifdef CBC_USE_CLP     
1187      /* If we are doing all strong branching in one go then we create new arrays
1188         to store information.  If clp NULL then doing old way.
1189         Going down -
1190         outputSolution[2*i] is final solution.
1191         outputStuff[2*i] is status (0 - finished, 1 infeas, other unknown
1192         outputStuff[2*i+numberStrong] is number iterations
1193         On entry newUpper[i] is new upper bound, on exit obj change
1194         Going up -
1195         outputSolution[2*i+1] is final solution.
1196         outputStuff[2*i+1] is status (0 - finished, 1 infeas, other unknown
1197         outputStuff[2*i+1+numberStrong] is number iterations
1198       On entry newLower[i] is new lower bound, on exit obj change
1199      */
1200      OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver);
1201      ClpSimplex * clp=NULL;
1202      double * newLower = NULL;
1203      double * newUpper = NULL;
1204      double ** outputSolution=NULL;
1205      int * outputStuff=NULL;
1206      // Go back to normal way if user wants it
1207      if (osiclp&&(osiclp->specialOptions()&16)!=0&&osiclp->specialOptions()>0)
1208        allNormal=false;
1209      if (osiclp&&!allNormal) {
1210        // say do fast
1211        int easy=1;
1212        osiclp->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,&easy) ;
1213      }
1214      if (osiclp&& allNormal) {
1215        clp = osiclp->getModelPtr();
1216        // Clp - do a different way
1217        newLower = new double[numberStrong];
1218        newUpper = new double[numberStrong];
1219        outputSolution = new double * [2*numberStrong];
1220        outputStuff = new int [4*numberStrong];
1221        int * which = new int[numberStrong];
1222        int startFinishOptions;
1223        int specialOptions = osiclp->specialOptions();
1224        int clpOptions = clp->specialOptions();
1225        int returnCode=0;
1226#define CRUNCH
1227#ifdef CRUNCH
1228        // Crunch down problem
1229        int numberRows = clp->numberRows();
1230        // Use dual region
1231        double * rhs = clp->dualRowSolution();
1232        int * whichRow = new int[3*numberRows];
1233        int * whichColumn = new int[2*numberColumns];
1234        int nBound;
1235        ClpSimplex * small = ((ClpSimplexOther *) clp)->crunch(rhs,whichRow,whichColumn,nBound,true);
1236        if (!small) {
1237          anyAction=-2;
1238          //printf("XXXX Inf by inspection\n");
1239          delete [] whichColumn;
1240          whichColumn=NULL;
1241          delete [] whichRow;
1242          whichRow=NULL;
1243          break;
1244        } else {
1245          clp = small;
1246        }
1247#else
1248        int saveLogLevel = clp->logLevel();
1249        int saveMaxIts = clp->maximumIterations();
1250#endif
1251        clp->setLogLevel(0);
1252        if((specialOptions&1)==0) {
1253          startFinishOptions=0;
1254          clp->setSpecialOptions(clpOptions|(64|1024));
1255        } else {
1256          startFinishOptions=1+2+4;
1257          //startFinishOptions=1+4; // for moment re-factorize
1258          if((specialOptions&4)==0) 
1259            clp->setSpecialOptions(clpOptions|(64|128|512|1024|4096));
1260          else
1261            clp->setSpecialOptions(clpOptions|(64|128|512|1024|2048|4096));
1262        }
1263        // User may want to clean up before strong branching
1264        if ((clp->specialOptions()&32)!=0) {
1265          clp->primal(1);
1266          if (clp->numberIterations())
1267            model->messageHandler()->message(CBC_ITERATE_STRONG,model->messages())
1268              << clp->numberIterations()
1269              <<CoinMessageEol;
1270        }
1271        clp->setMaximumIterations(saveLimit);
1272#ifdef CRUNCH
1273        int * backColumn = whichColumn+numberColumns;
1274#endif
1275        for (i=0;i<numberStrong;i++) {
1276          int iObject = choice[i].objectNumber;
1277          const CbcObject * object = model->object(iObject);
1278          const CbcSimpleInteger * simple = dynamic_cast <const CbcSimpleInteger *> (object);
1279          int iSequence = simple->modelSequence();
1280          newLower[i]= ceil(saveSolution[iSequence]);
1281          newUpper[i]= floor(saveSolution[iSequence]);
1282#ifdef CRUNCH
1283          iSequence = backColumn[iSequence];
1284          assert (iSequence>=0);
1285#endif
1286          which[i]=iSequence;
1287          outputSolution[2*i]= new double [numberColumns];
1288          outputSolution[2*i+1]= new double [numberColumns];
1289        }
1290        //clp->writeMps("bad");
1291        returnCode=clp->strongBranching(numberStrong,which,
1292                                            newLower, newUpper,outputSolution,
1293                                            outputStuff,outputStuff+2*numberStrong,!solveAll,false,
1294                                            startFinishOptions);
1295#ifndef CRUNCH
1296        clp->setSpecialOptions(clpOptions); // restore
1297        clp->setMaximumIterations(saveMaxIts);
1298        clp->setLogLevel(saveLogLevel);
1299#endif
1300        if (returnCode==-2) {
1301          // bad factorization!!!
1302          // Doing normal way
1303          // Mark hot start
1304          solver->markHotStart();
1305          clp = NULL;
1306        } else {
1307#ifdef CRUNCH
1308          // extract solution
1309          //bool checkSol=true;
1310          for (i=0;i<numberStrong;i++) {
1311            int iObject = choice[i].objectNumber;
1312            const CbcObject * object = model->object(iObject);
1313            const CbcSimpleInteger * simple = dynamic_cast <const CbcSimpleInteger *> (object);
1314            int iSequence = simple->modelSequence();
1315            which[i]=iSequence;
1316            double * sol = outputSolution[2*i];
1317            double * sol2 = outputSolution[2*i+1];
1318            //bool x=true;
1319            //bool x2=true;
1320            for (int iColumn=numberColumns-1;iColumn>=0;iColumn--) {
1321              int jColumn = backColumn[iColumn];
1322              if (jColumn>=0) {
1323                sol[iColumn]=sol[jColumn];
1324                sol2[iColumn]=sol2[jColumn];
1325              } else {
1326                sol[iColumn]=saveSolution[iColumn];
1327                sol2[iColumn]=saveSolution[iColumn];
1328              }
1329            }
1330          }
1331#endif
1332        }
1333#ifdef CRUNCH
1334        delete [] whichColumn;
1335        delete [] whichRow;
1336        delete small;
1337#endif
1338        delete [] which;
1339      } else {
1340        // Doing normal way
1341        // Mark hot start
1342        solver->markHotStart();
1343      }
1344#     else      /* CBC_USE_CLP */
1345
1346      OsiSolverInterface *clp = NULL ;
1347      double **outputSolution = NULL ;
1348      int *outputStuff = NULL ;
1349      double * newLower = NULL ;
1350      double * newUpper = NULL ;
1351
1352      solver->markHotStart();
1353
1354#     endif     /* CBC_USE_CLP */
1355      /*
1356        Open a loop to do the strong branching LPs. For each candidate variable,
1357        solve an LP with the variable forced down, then up. If a direction turns
1358        out to be infeasible or monotonic (i.e., over the dual objective cutoff),
1359        force the objective change to be big (1.0e100). If we determine the problem
1360        is infeasible, or find a monotone variable, escape the loop.
1361       
1362        TODO: The `restore bounds' part might be better encapsulated as an
1363        unbranch() method. Branching objects more exotic than simple integers
1364        or cliques might not restrict themselves to variable bounds.
1365
1366        TODO: Virtuous solvers invalidate the current solution (or give bogus
1367        results :-) when the bounds are changed out from under them. So we
1368        need to do all the work associated with finding a new solution before
1369        restoring the bounds.
1370      */
1371      for (i = 0 ; i < numberStrong ; i++)
1372        { double objectiveChange ;
1373        double newObjectiveValue=1.0e100;
1374        // status is 0 finished, 1 infeasible and other
1375        int iStatus;
1376        /*
1377          Try the down direction first. (Specify the initial branching alternative as
1378          down with a call to way(-1). Each subsequent call to branch() performs the
1379          specified branch and advances the branch object state to the next branch
1380          alternative.)
1381        */
1382        if (!clp) {
1383          choice[i].possibleBranch->way(-1) ;
1384          choice[i].possibleBranch->branch() ;
1385          bool feasible=true;
1386          if (checkFeasibility) {
1387            // check branching did not make infeasible
1388            int iColumn;
1389            int numberColumns = solver->getNumCols();
1390            const double * columnLower = solver->getColLower();
1391            const double * columnUpper = solver->getColUpper();
1392            for (iColumn= 0;iColumn<numberColumns;iColumn++) {
1393              if (columnLower[iColumn]>columnUpper[iColumn]+1.0e-5)
1394                feasible=false;
1395            }
1396          }
1397          if (feasible) {
1398            solver->solveFromHotStart() ;
1399            numberStrongDone++;
1400            numberStrongIterations += solver->getIterationCount();
1401            /*
1402              We now have an estimate of objective degradation that we can use for strong
1403              branching. If we're over the cutoff, the variable is monotone up.
1404              If we actually made it to optimality, check for a solution, and if we have
1405              a good one, call setBestSolution to process it. Note that this may reduce the
1406              cutoff, so we check again to see if we can declare this variable monotone.
1407            */
1408            if (solver->isProvenOptimal())
1409              iStatus=0; // optimal
1410            else if (solver->isIterationLimitReached()
1411                     &&!solver->isDualObjectiveLimitReached())
1412              iStatus=2; // unknown
1413            else
1414              iStatus=1; // infeasible
1415            newObjectiveValue = solver->getObjSense()*solver->getObjValue();
1416            choice[i].numItersDown = solver->getIterationCount();
1417          } else {
1418            iStatus=1; // infeasible
1419            newObjectiveValue = 1.0e100;
1420            choice[i].numItersDown = 0;
1421          }
1422        } else {
1423          iStatus = outputStuff[2*i];
1424          choice[i].numItersDown = outputStuff[2*numberStrong+2*i];
1425          numberStrongDone++;
1426          numberStrongIterations += choice[i].numItersDown;
1427          newObjectiveValue = objectiveValue+newUpper[i];
1428          solver->setColSolution(outputSolution[2*i]);
1429        }
1430        objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
1431        if (!iStatus) {
1432          choice[i].finishedDown = true ;
1433          if (newObjectiveValue>=model->getCutoff()) {
1434            objectiveChange = 1.0e100; // say infeasible
1435            numberStrongInfeasible++;
1436          } else {
1437            // See if integer solution
1438            if (model->feasibleSolution(choice[i].numIntInfeasDown,
1439                                        choice[i].numObjInfeasDown)
1440                &&model->problemFeasibility()->feasible(model,-1)>=0) {
1441              model->setBestSolution(CBC_STRONGSOL,
1442                                     newObjectiveValue,
1443                                     solver->getColSolution()) ;
1444              // only needed for odd solvers
1445              newObjectiveValue = solver->getObjSense()*solver->getObjValue();
1446              objectiveChange = CoinMax(newObjectiveValue-objectiveValue_,0.0) ;
1447              model->setLastHeuristic(NULL);
1448              model->incrementUsed(solver->getColSolution());
1449              if (newObjectiveValue >= model->getCutoff()) {    //  *new* cutoff
1450                objectiveChange = 1.0e100 ;
1451                numberStrongInfeasible++;
1452              }
1453            }
1454          }
1455        } else if (iStatus==1) {
1456          objectiveChange = 1.0e100 ;
1457          numberStrongInfeasible++;
1458        } else {
1459          // Can't say much as we did not finish
1460          choice[i].finishedDown = false ;
1461          numberUnfinished++;
1462        }
1463        choice[i].downMovement = objectiveChange ;
1464       
1465        // restore bounds
1466        if (!clp)
1467          { for (int j=0;j<numberColumns;j++) {
1468            if (saveLower[j] != lower[j])
1469              solver->setColLower(j,saveLower[j]);
1470            if (saveUpper[j] != upper[j])
1471              solver->setColUpper(j,saveUpper[j]);
1472          }
1473          }
1474        //printf("Down on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
1475        //     choice[i].objectNumber,iStatus,newObjectiveValue,choice[i].numItersDown,
1476        //     choice[i].downMovement,choice[i].finishedDown,choice[i].numIntInfeasDown,
1477        //     choice[i].numObjInfeasDown);
1478       
1479        // repeat the whole exercise, forcing the variable up
1480        if (!clp) {
1481          bool feasible=true;
1482          // If odd branching then maybe just one possibility
1483          if(choice[i].possibleBranch->numberBranchesLeft()>0) {
1484            choice[i].possibleBranch->branch();
1485            if (checkFeasibility) {
1486              // check branching did not make infeasible
1487              int iColumn;
1488              int numberColumns = solver->getNumCols();
1489              const double * columnLower = solver->getColLower();
1490              const double * columnUpper = solver->getColUpper();
1491              for (iColumn= 0;iColumn<numberColumns;iColumn++) {
1492                if (columnLower[iColumn]>columnUpper[iColumn]+1.0e-5)
1493                  feasible=false;
1494              }
1495            }
1496          } else {
1497            // second branch infeasible
1498            feasible=false;
1499          }
1500          if (feasible) {
1501            solver->solveFromHotStart() ;
1502            numberStrongDone++;
1503            numberStrongIterations += solver->getIterationCount();
1504            /*
1505              We now have an estimate of objective degradation that we can use for strong
1506              branching. If we're over the cutoff, the variable is monotone up.
1507              If we actually made it to optimality, check for a solution, and if we have
1508              a good one, call setBestSolution to process it. Note that this may reduce the
1509              cutoff, so we check again to see if we can declare this variable monotone.
1510            */
1511            if (solver->isProvenOptimal())
1512              iStatus=0; // optimal
1513            else if (solver->isIterationLimitReached()
1514                     &&!solver->isDualObjectiveLimitReached())
1515              iStatus=2; // unknown
1516            else
1517              iStatus=1; // infeasible
1518            newObjectiveValue = solver->getObjSense()*solver->getObjValue();
1519            choice[i].numItersUp = solver->getIterationCount();
1520          } else {
1521            iStatus=1; // infeasible
1522            newObjectiveValue = 1.0e100;
1523            choice[i].numItersDown = 0;
1524          }
1525        } else {
1526          iStatus = outputStuff[2*i+1];
1527          choice[i].numItersUp = outputStuff[2*numberStrong+2*i+1];
1528          numberStrongDone++;
1529          numberStrongIterations += choice[i].numItersUp;
1530          newObjectiveValue = objectiveValue+newLower[i];
1531          solver->setColSolution(outputSolution[2*i+1]);
1532        }
1533        objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
1534        if (!iStatus) {
1535          choice[i].finishedUp = true ;
1536          if (newObjectiveValue>=model->getCutoff()) {
1537            objectiveChange = 1.0e100; // say infeasible
1538            numberStrongInfeasible++;
1539          } else {
1540            // See if integer solution
1541            if (model->feasibleSolution(choice[i].numIntInfeasUp,
1542                                        choice[i].numObjInfeasUp)
1543                &&model->problemFeasibility()->feasible(model,-1)>=0) {
1544              model->setBestSolution(CBC_STRONGSOL,
1545                                     newObjectiveValue,
1546                                     solver->getColSolution()) ;
1547              // only needed for odd solvers
1548              newObjectiveValue = solver->getObjSense()*solver->getObjValue();
1549              objectiveChange = CoinMax(newObjectiveValue-objectiveValue_,0.0) ;
1550              model->setLastHeuristic(NULL);
1551              model->incrementUsed(solver->getColSolution());
1552              if (newObjectiveValue >= model->getCutoff()) {    //  *new* cutoff
1553                objectiveChange = 1.0e100 ;
1554                numberStrongInfeasible++;
1555              }
1556            }
1557          }
1558        } else if (iStatus==1) {
1559          objectiveChange = 1.0e100 ;
1560          numberStrongInfeasible++;
1561        } else {
1562          // Can't say much as we did not finish
1563          choice[i].finishedUp = false ;
1564          numberUnfinished++;
1565        }
1566        choice[i].upMovement = objectiveChange ;
1567       
1568        // restore bounds
1569        if (!clp)
1570          { for (int j=0;j<numberColumns;j++) {
1571            if (saveLower[j] != lower[j])
1572              solver->setColLower(j,saveLower[j]);
1573            if (saveUpper[j] != upper[j])
1574              solver->setColUpper(j,saveUpper[j]);
1575          }
1576          }
1577       
1578        //printf("Up on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
1579        //     choice[i].objectNumber,iStatus,newObjectiveValue,choice[i].numItersUp,
1580        //     choice[i].upMovement,choice[i].finishedUp,choice[i].numIntInfeasUp,
1581        //     choice[i].numObjInfeasUp);
1582       
1583        /*
1584          End of evaluation for this candidate variable. Possibilities are:
1585          * Both sides below cutoff; this variable is a candidate for branching.
1586          * Both sides infeasible or above the objective cutoff: no further action
1587          here. Break from the evaluation loop and assume the node will be purged
1588          by the caller.
1589          * One side below cutoff: Install the branch (i.e., fix the variable). Break
1590          from the evaluation loop and assume the node will be reoptimised by the
1591          caller.
1592        */
1593        // reset
1594        choice[i].possibleBranch->resetNumberBranchesLeft();
1595        if (choice[i].upMovement<1.0e100) {
1596          if(choice[i].downMovement<1.0e100) {
1597            // feasible - no action
1598          } else {
1599            // up feasible, down infeasible
1600            anyAction=-1;
1601            //printf("Down infeasible for choice %d sequence %d\n",i,
1602            // model->object(choice[i].objectNumber)->columnNumber());
1603            if (!solveAll) {
1604              choice[i].possibleBranch->way(1);
1605              choice[i].possibleBranch->branch();
1606              break;
1607            } else {
1608              choice[i].fix=1;
1609            }
1610          }
1611        } else {
1612          if(choice[i].downMovement<1.0e100) {
1613            // down feasible, up infeasible
1614            anyAction=-1;
1615            //printf("Up infeasible for choice %d sequence %d\n",i,
1616            // model->object(choice[i].objectNumber)->columnNumber());
1617            if (!solveAll) {
1618              choice[i].possibleBranch->way(-1);
1619              choice[i].possibleBranch->branch();
1620              break;
1621            } else {
1622              choice[i].fix=-1;
1623            }
1624          } else {
1625            // neither side feasible
1626            anyAction=-2;
1627            //printf("Both infeasible for choice %d sequence %d\n",i,
1628            // model->object(choice[i].objectNumber)->columnNumber());
1629            break;
1630          }
1631        }
1632        bool hitMaxTime = ( CoinCpuTime()-model->getDblParam(CbcModel::CbcStartSeconds) > 
1633                            model->getDblParam(CbcModel::CbcMaximumSeconds));
1634        if (hitMaxTime) {
1635          numberStrong=i+1;
1636          break;
1637        }
1638        }
1639      if (!clp) {
1640        // Delete the snapshot
1641        solver->unmarkHotStart();
1642      } else {
1643        delete [] newLower;
1644        delete [] newUpper;
1645        delete [] outputStuff;
1646        int i;
1647        for (i=0;i<2*numberStrong;i++)
1648          delete [] outputSolution[i];
1649        delete [] outputSolution;
1650      }
1651      solver->setIntParam(OsiMaxNumIterationHotStart,saveLimit);
1652      // restore basis
1653      solver->setWarmStart(ws);
1654      // Unless infeasible we will carry on
1655      // But we could fix anyway
1656      if (anyAction==-1&&solveAll) {
1657        // apply and take off
1658        for (i = 0 ; i < numberStrong ; i++) {
1659          if (choice[i].fix) {
1660            choice[i].possibleBranch->way(choice[i].fix) ;
1661            choice[i].possibleBranch->branch() ;
1662          }
1663        }
1664        bool feasible=true;
1665        if (checkFeasibility) {
1666          // check branching did not make infeasible
1667          int iColumn;
1668          int numberColumns = solver->getNumCols();
1669          const double * columnLower = solver->getColLower();
1670          const double * columnUpper = solver->getColUpper();
1671          for (iColumn= 0;iColumn<numberColumns;iColumn++) {
1672            if (columnLower[iColumn]>columnUpper[iColumn]+1.0e-5)
1673              feasible=false;
1674          }
1675        }
1676        if (feasible) {
1677          // can do quick optimality check
1678          int easy=2;
1679          solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,&easy) ;
1680          solver->resolve() ;
1681          solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
1682          feasible = solver->isProvenOptimal();
1683        }
1684        if (feasible) {
1685          memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
1686          model->reserveCurrentSolution(saveSolution);
1687          memcpy(saveLower,solver->getColLower(),numberColumns*sizeof(double));
1688          memcpy(saveUpper,solver->getColUpper(),numberColumns*sizeof(double));
1689          // Clean up all candidates whih are fixed
1690          int numberLeft=0;
1691          for (i = 0 ; i < numberStrong ; i++) {
1692            CbcStrongInfo thisChoice = choice[i];
1693            choice[i].possibleBranch=NULL;
1694            const CbcObject * object = model->object(thisChoice.objectNumber);
1695            int preferredWay;
1696            double infeasibility = object->infeasibility(preferredWay);
1697            if (!infeasibility) {
1698              // take out
1699              delete thisChoice.possibleBranch;
1700            } else {
1701              choice[numberLeft++]=thisChoice;
1702            }
1703          }
1704          numberStrong=numberLeft;
1705          for (;i<maximumStrong;i++) {
1706            delete choice[i].possibleBranch;
1707            choice[i].possibleBranch=NULL;
1708          }
1709          // If all fixed then round again
1710          if (!numberLeft) {
1711            finished=false;
1712            numberStrong=0;
1713            saveNumberStrong=0;
1714            maximumStrong=1;
1715          } else {
1716            anyAction=0;
1717          }
1718          // If these two uncommented then different action
1719          anyAction=-1;
1720          finished=true;
1721          //printf("some fixed but continuing %d left\n",numberLeft);
1722        } else {
1723          anyAction=-2; // say infeasible
1724        }
1725      }
1726      delete ws;
1727      int numberNodes = model->getNodeCount();
1728      // update number of strong iterations etc
1729      model->incrementStrongInfo(numberStrongDone,numberStrongIterations,
1730                                 anyAction==-2 ? 0:numberStrongInfeasible,anyAction==-2);
1731     
1732      /*
1733        anyAction >= 0 indicates that strong branching didn't produce any monotone
1734        variables. Sift through the candidates for the best one.
1735       
1736        QUERY: Setting numberNodes looks to be a distributed noop. numberNodes is
1737        local to this code block. Perhaps should be numberNodes_ from model?
1738        Unclear what this calculation is doing.
1739      */
1740      if (anyAction>=0) {
1741       
1742        // get average cost per iteration and assume stopped ones
1743        // would stop after 50% more iterations at average cost??? !!! ???
1744        double averageCostPerIteration=0.0;
1745        double totalNumberIterations=1.0;
1746        int smallestNumberInfeasibilities=INT_MAX;
1747        for (i=0;i<numberStrong;i++) {
1748          totalNumberIterations += choice[i].numItersDown +
1749            choice[i].numItersUp ;
1750          averageCostPerIteration += choice[i].downMovement +
1751            choice[i].upMovement;
1752          smallestNumberInfeasibilities= 
1753            CoinMin(CoinMin(choice[i].numIntInfeasDown ,
1754                            choice[i].numIntInfeasUp ),
1755                    smallestNumberInfeasibilities);
1756        }
1757        //if (smallestNumberInfeasibilities>=numberIntegerInfeasibilities)
1758        //numberNodes=1000000; // switch off search for better solution
1759        numberNodes=1000000; // switch off anyway
1760        averageCostPerIteration /= totalNumberIterations;
1761        // all feasible - choose best bet
1762       
1763        // New method does all at once so it can be more sophisticated
1764        // in deciding how to balance actions.
1765        // But it does need arrays
1766        double * changeUp = new double [numberStrong];
1767        int * numberInfeasibilitiesUp = new int [numberStrong];
1768        double * changeDown = new double [numberStrong];
1769        int * numberInfeasibilitiesDown = new int [numberStrong];
1770        CbcBranchingObject ** objects = new CbcBranchingObject * [ numberStrong];
1771        for (i = 0 ; i < numberStrong ; i++) {
1772          int iColumn = choice[i].possibleBranch->variable() ;
1773          model->messageHandler()->message(CBC_STRONG,model->messages())
1774            << i << iColumn
1775            <<choice[i].downMovement<<choice[i].numIntInfeasDown
1776            <<choice[i].upMovement<<choice[i].numIntInfeasUp
1777            <<choice[i].possibleBranch->value()
1778            <<CoinMessageEol;
1779          changeUp[i]=choice[i].upMovement;
1780          numberInfeasibilitiesUp[i] = choice[i].numIntInfeasUp;
1781          changeDown[i]=choice[i].downMovement;
1782          numberInfeasibilitiesDown[i] = choice[i].numIntInfeasDown;
1783          objects[i] = choice[i].possibleBranch;
1784        }
1785        int whichObject = decision->bestBranch(objects,numberStrong,numberUnsatisfied_,
1786                                               changeUp,numberInfeasibilitiesUp,
1787                                               changeDown,numberInfeasibilitiesDown,
1788                                               objectiveValue_);
1789        // move branching object and make sure it will not be deleted
1790        if (whichObject>=0) {
1791          branch_ = objects[whichObject];
1792          if (model->messageHandler()->logLevel()>3) 
1793            printf("Choosing column %d\n",choice[whichObject].possibleBranch->variable()) ;
1794          choice[whichObject].possibleBranch=NULL;
1795        }
1796        delete [] changeUp;
1797        delete [] numberInfeasibilitiesUp;
1798        delete [] changeDown;
1799        delete [] numberInfeasibilitiesDown;
1800        delete [] objects;
1801      }
1802#     ifdef CBC_USE_CLP
1803      if (osiclp&&!allNormal) {
1804        // back to normal
1805        osiclp->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
1806      }
1807#     endif
1808    }
1809    /*
1810      Simple branching. Probably just one, but we may have got here
1811      because of an odd branch e.g. a cut
1812    */
1813    else {
1814      // not strong
1815      // C) create branching object
1816      branch_ = choice[bestChoice].possibleBranch;
1817      choice[bestChoice].possibleBranch=NULL;
1818    }
1819  }
1820  // Set guessed solution value
1821  guessedObjectiveValue_ = objectiveValue_+estimatedDegradation;
1822/*
1823  Cleanup, then we're outta here.
1824*/
1825  if (!model->branchingMethod())
1826    delete decision;
1827   
1828  for (i=0;i<maximumStrong;i++)
1829    delete choice[i].possibleBranch;
1830  delete [] choice;
1831  delete [] saveLower;
1832  delete [] saveUpper;
1833 
1834  // restore solution
1835  solver->setColSolution(saveSolution);
1836  delete [] saveSolution;
1837  return anyAction;
1838}
1839
1840/*
1841  Version for dynamic pseudo costs.
1842
1843  **** For now just return if anything odd
1844  later allow even if odd
1845
1846  The routine scans through the object list of the model looking for objects
1847  that indicate infeasibility. It tests each object using strong branching
1848  and selects the one with the least objective degradation.  A corresponding
1849  branching object is left attached to lastNode.
1850  This version gives preference in evaluation to variables which
1851  have not been evaluated many times.  It also uses numberStrong
1852  to say give up if last few tries have not changed incumbent.
1853  See Achterberg, Koch and Martin.
1854
1855  If strong branching is disabled, a candidate object is chosen essentially
1856  at random (whatever object ends up in pos'n 0 of the candidate array).
1857
1858  If a branching candidate is found to be monotone, bounds are set to fix the
1859  variable and the routine immediately returns (the caller is expected to
1860  reoptimize).
1861
1862  If a branching candidate is found to result in infeasibility in both
1863  directions, the routine immediately returns an indication of infeasibility.
1864
1865  Returns:  0   both branch directions are feasible
1866           -1   branching variable is monotone
1867           -2   infeasible
1868           -3   Use another method
1869
1870           For now just fix on objective from strong branching.
1871*/
1872
1873int CbcNode::chooseDynamicBranch (CbcModel *model, CbcNode *lastNode,
1874                                  OsiSolverBranch * & branches,int numberPassesLeft)
1875
1876{ if (lastNode)
1877    depth_ = lastNode->depth_+1;
1878  else
1879    depth_ = 0;
1880  delete branch_;
1881  branch_=NULL;
1882  OsiSolverInterface * solver = model->solver();
1883  // get information on solver type
1884  const OsiAuxInfo * auxInfo = solver->getAuxiliaryInfo();
1885  const OsiBabSolver * auxiliaryInfo = dynamic_cast<const OsiBabSolver *> (auxInfo);
1886  //assert(objectiveValue_ == solver->getObjSense()*solver->getObjValue());
1887  double cutoff =model->getCutoff();
1888  double distanceToCutoff=cutoff-objectiveValue_;
1889  const double * lower = solver->getColLower();
1890  const double * upper = solver->getColUpper();
1891  // See what user thinks
1892  int anyAction=model->problemFeasibility()->feasible(model,0);
1893  if (anyAction) {
1894    // will return -2 if infeasible , 0 if treat as integer
1895    return anyAction-1;
1896  }
1897  int i;
1898  int saveStateOfSearch = model->stateOfSearch();
1899  int numberStrong=model->numberStrong();
1900  if (!auxiliaryInfo->warmStart())
1901    numberStrong=0;
1902  // But make more likely to get out after some times
1903  int changeStrategy=numberStrong;
1904  double changeFactor=1.0;
1905  // Use minimum of this and one stored in objects
1906  //int numberBeforeTrust = model->numberBeforeTrust();
1907  int numberObjects = model->numberObjects();
1908  bool checkFeasibility = numberObjects>model->numberIntegers();
1909  // For now return if not simple
1910  if (checkFeasibility)
1911    return -3;
1912  // Return if doing hot start (in BAB sense)
1913  if (model->hotstartSolution()) 
1914    return -3;
1915#define RANGING
1916#ifdef RANGING
1917  // Pass number
1918  int kPass=0;
1919  int numberRows = solver->getNumRows();
1920#endif
1921  int numberColumns = model->getNumCols();
1922  double * saveUpper = new double[numberColumns];
1923  double * saveLower = new double[numberColumns];
1924
1925  // Save solution in case heuristics need good solution later
1926 
1927  double * saveSolution = new double[numberColumns];
1928  memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
1929  model->reserveCurrentSolution(saveSolution);
1930  /*
1931    Get a branching decision object. Use the default dynamic decision criteria unless
1932    the user has loaded a decision method into the model.
1933  */
1934  CbcBranchDecision *decision = model->branchingMethod();
1935  if (!decision)
1936    decision = new CbcBranchDynamicDecision();
1937  int numberMini=0;
1938  int xPen=0;
1939  int xMark=0;
1940  for (i=0;i<numberColumns;i++) {
1941    saveLower[i] = lower[i];
1942    saveUpper[i] = upper[i];
1943  }
1944  // Get arrays to sort
1945  double * sort = new double[numberObjects];
1946  int * whichObject = new int[numberObjects];
1947  int * objectMark = new int[2*numberObjects+1];
1948  // Arrays with movements
1949  double * upEstimate = new double[numberObjects];
1950  double * downEstimate = new double[numberObjects];
1951  CbcStrongInfo * fixObject = new CbcStrongInfo[numberObjects];
1952  double estimatedDegradation=0.0; 
1953  int numberNodes=model->getNodeCount();
1954  int numberBeforeTrust = model->numberBeforeTrust();
1955  int numberPenalties = model->numberPenalties();
1956  if (numberBeforeTrust>=1000000) {
1957    numberBeforeTrust = numberBeforeTrust % 1000000;
1958    numberPenalties=0;
1959  } else if (numberBeforeTrust<0) {
1960    numberPenalties=numberColumns;
1961    numberBeforeTrust=0;
1962  }
1963  // May go round twice if strong branching fixes all local candidates
1964  bool finished=false;
1965  int numberToFix=0;
1966# ifdef CBC_USE_CLP
1967  OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver);
1968  int saveClpOptions=0;
1969  if (osiclp) {
1970    // for faster hot start
1971    saveClpOptions = osiclp->specialOptions();
1972    osiclp->setSpecialOptions(saveClpOptions|1024);
1973  }
1974# else
1975  OsiSolverInterface *osiclp = 0 ;
1976# endif
1977  int saveSearchStrategy2 = model->searchStrategy();
1978  if (saveSearchStrategy2<999) {
1979    // Get average up and down costs
1980    double averageUp=0.0;
1981    double averageDown=0.0;
1982    {
1983      int numberUp=0;
1984      int numberDown=0;
1985      int i;
1986      for ( i=0;i<numberObjects;i++) {
1987        CbcObject * object = model->modifiableObject(i);
1988        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
1989          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
1990        assert(dynamicObject);
1991        if (dynamicObject->numberTimesUp()) {
1992          numberUp++;
1993          averageUp += dynamicObject->upDynamicPseudoCost();
1994        }
1995        if (dynamicObject->numberTimesDown()) {
1996          numberDown++;
1997          averageDown += dynamicObject->downDynamicPseudoCost();
1998        }
1999      }
2000      if (numberUp) 
2001        averageUp /= (double) numberUp;
2002      else
2003        averageUp=1.0;
2004      if (numberDown) 
2005        averageDown /= (double) numberDown;
2006      else
2007        averageDown=1.0;
2008      for ( i=0;i<numberObjects;i++) {
2009        CbcObject * object = model->modifiableObject(i);
2010        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
2011          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
2012        assert(dynamicObject);
2013        if (!dynamicObject->numberTimesUp()) 
2014          dynamicObject->setUpDynamicPseudoCost(averageUp);
2015      if (!dynamicObject->numberTimesDown()) 
2016        dynamicObject->setDownDynamicPseudoCost(averageDown);
2017      }
2018    }
2019  } else if (saveSearchStrategy2<1999) {
2020    // pseudo shadow prices
2021    model->pseudoShadow(NULL,NULL);
2022  } else if (saveSearchStrategy2<2999) {
2023    // leave old ones
2024  } else if (saveSearchStrategy2<3999) {
2025    // pseudo shadow prices at root
2026    if (!numberNodes)
2027      model->pseudoShadow(NULL,NULL);
2028  } else {
2029    abort();
2030  }
2031  if (saveSearchStrategy2>=0)
2032    saveSearchStrategy2 = saveSearchStrategy2 % 1000;
2033  if (saveSearchStrategy2==999)
2034    saveSearchStrategy2=-1;
2035  int px[4]={-1,-1,-1,-1};
2036  int saveSearchStrategy = saveSearchStrategy2<99 ? saveSearchStrategy2 : saveSearchStrategy2-100;
2037  bool newWay = saveSearchStrategy2>98;
2038  int numberNotTrusted=0;
2039  int numberStrongDone;
2040  int numberUnfinished;
2041  int numberStrongInfeasible;
2042  int numberStrongIterations;
2043  while(!finished) {
2044    finished=true;
2045    decision->initialize(model);
2046    // Some objects may compute an estimate of best solution from here
2047    estimatedDegradation=0.0; 
2048    numberToFix=0;
2049    int numberIntegerInfeasibilities=0; // without odd ones
2050    int numberToDo=0;
2051    int iBestNot=-1;
2052    int iBestGot=-1;
2053    double best=0.0;
2054    numberNotTrusted=0;
2055    numberStrongDone=0;
2056    numberUnfinished=0;
2057    numberStrongInfeasible=0;
2058    numberStrongIterations=0;
2059    int * which = objectMark+numberObjects+1;
2060    int neededPenalties;
2061    // We may go round this loop three times (only if we think we have solution)
2062    for (int iPass=0;iPass<3;iPass++) {
2063     
2064      // compute current state
2065      int numberObjectInfeasibilities; // just odd ones
2066      model->feasibleSolution(
2067                              numberIntegerInfeasibilities,
2068                              numberObjectInfeasibilities);
2069     
2070      // Some objects may compute an estimate of best solution from here
2071      estimatedDegradation=0.0; 
2072      numberUnsatisfied_ = 0;
2073      int bestPriority=INT_MAX;
2074      /*
2075        Scan for branching objects that indicate infeasibility. Choose candidates
2076        using priority as the first criteria, then integer infeasibility.
2077       
2078        The algorithm is to fill the array with a set of good candidates (by
2079        infeasibility) with priority bestPriority.  Finding a candidate with
2080        priority better (less) than bestPriority flushes the choice array. (This
2081        serves as initialization when the first candidate is found.)
2082       
2083      */
2084      numberToDo=0;
2085      neededPenalties=0;
2086      iBestNot=-1;
2087      double bestNot=0.0;
2088      iBestGot=-1;
2089      best=0.0;
2090#define PRINT_STUFF -1
2091      for (i=0;i<numberObjects;i++) {
2092        CbcObject * object = model->modifiableObject(i);
2093        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
2094          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
2095        assert(dynamicObject);
2096        int preferredWay;
2097        double infeasibility = object->infeasibility(preferredWay);
2098        int priorityLevel = object->priority();
2099#define ZERO_ONE 0
2100#define ZERO_FAKE 1.0e20;
2101#if ZERO_ONE==1
2102        // branch on 0-1 first (temp)
2103        if (fabs(saveSolution[dynamicObject->columnNumber()])<1.0)
2104          priorityLevel--;
2105#endif
2106#if ZERO_ONE==2
2107        if (fabs(saveSolution[dynamicObject->columnNumber()])<1.0)
2108          infeasibility *= ZERO_FAKE;
2109#endif
2110        if (infeasibility) {
2111          int iColumn = dynamicObject->columnNumber();
2112          double gap = saveUpper[iColumn]-saveLower[iColumn];
2113          // Give precedence to ones with gap of 1.0
2114          assert(gap>0.0);
2115          infeasibility /= CoinMin(gap,100.0);
2116          if (!depth_&&false) {
2117            // try closest to 0.5
2118            double part =saveSolution[iColumn]-floor(saveSolution[iColumn]);
2119            infeasibility = fabs(0.5-part);
2120          }
2121          bool gotDown=false;
2122          int numberThisDown = dynamicObject->numberTimesDown();
2123          if (numberThisDown>=numberBeforeTrust)
2124            gotDown=true;
2125          bool gotUp=false;
2126          int numberThisUp = dynamicObject->numberTimesUp();
2127          if (numberThisUp>=numberBeforeTrust)
2128            gotUp=true;
2129          if ((numberNodes%PRINT_STUFF)==0&&PRINT_STUFF>0)
2130            printf("%d down %d %g up %d %g - infeas %g\n",
2131                   i,numberThisDown,object->downEstimate(),numberThisUp,object->upEstimate(),
2132                   infeasibility);
2133          // Increase estimated degradation to solution
2134          estimatedDegradation += CoinMin(object->upEstimate(),object->downEstimate());
2135          downEstimate[i]=object->downEstimate();
2136          upEstimate[i]=object->upEstimate();
2137          numberUnsatisfied_++;
2138          // Better priority? Flush choices.
2139          if (priorityLevel<bestPriority) {
2140            numberToDo=0;
2141            bestPriority = priorityLevel;
2142            iBestGot=-1;
2143            best=0.0;
2144            numberNotTrusted=0;
2145          } else if (priorityLevel>bestPriority) {
2146            continue;
2147          }
2148          if (!gotUp||!gotDown)
2149            numberNotTrusted++;
2150          // Check for suitability based on infeasibility.
2151          if ((gotDown&&gotUp)&&numberStrong>0) {
2152            sort[numberToDo]=-infeasibility;
2153            if (infeasibility>best) {
2154              best=infeasibility;
2155              iBestGot=numberToDo;
2156            }
2157          } else {
2158            objectMark[neededPenalties]=numberToDo;
2159            which[neededPenalties++]=dynamicObject->columnNumber();
2160            int iColumn = dynamicObject->columnNumber();
2161            double part =saveSolution[iColumn]-floor(saveSolution[iColumn]);
2162            sort[numberToDo]=-10.0*infeasibility;
2163            if (!(numberThisUp+numberThisDown))
2164              sort[numberToDo] *= 100.0; // make even more likely
2165            if (1.0-fabs(part-0.5)>bestNot) {
2166              iBestNot=numberToDo;
2167              bestNot = 1.0-fabs(part-0.5);
2168            }
2169          }
2170          whichObject[numberToDo++]=i;
2171        } else {
2172          // for debug
2173          downEstimate[i]=-1.0;
2174          upEstimate[i]=-1.0;
2175        }
2176      }
2177      if (numberUnsatisfied_) {
2178        // some infeasibilities - go to next steps
2179        break;
2180      } else if (!iPass) {
2181        // may just need resolve
2182        solver->resolve();
2183        memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
2184        model->reserveCurrentSolution(saveSolution);
2185        if (!solver->isProvenOptimal()) {
2186          // infeasible
2187          anyAction=-2;
2188          break;
2189        }
2190      } else if (iPass==1) {
2191        // looks like a solution - get paranoid
2192        bool roundAgain=false;
2193        // get basis
2194        CoinWarmStartBasis * ws = dynamic_cast<CoinWarmStartBasis*>(solver->getWarmStart());
2195        if (!ws)
2196          break;
2197        double tolerance;
2198        solver->getDblParam(OsiPrimalTolerance,tolerance);
2199        for (i=0;i<numberColumns;i++) {
2200          double value = saveSolution[i];
2201          if (value<lower[i]-tolerance) {
2202            saveSolution[i]=lower[i];
2203            roundAgain=true;
2204            ws->setStructStatus(i,CoinWarmStartBasis::atLowerBound);
2205          } else if (value>upper[i]+tolerance) {
2206            saveSolution[i]=upper[i];
2207            roundAgain=true;
2208            ws->setStructStatus(i,CoinWarmStartBasis::atUpperBound);
2209          } 
2210        }
2211        if (roundAgain) {
2212          // restore basis
2213          solver->setWarmStart(ws);
2214          solver->setColSolution(saveSolution);
2215          delete ws;
2216          bool takeHint;
2217          OsiHintStrength strength;
2218          solver->getHintParam(OsiDoDualInResolve,takeHint,strength);
2219          solver->setHintParam(OsiDoDualInResolve,false,OsiHintDo) ;
2220          solver->resolve();
2221          solver->setHintParam(OsiDoDualInResolve,takeHint,strength) ;
2222          memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
2223          model->reserveCurrentSolution(saveSolution);
2224          if (!solver->isProvenOptimal()) {
2225            // infeasible
2226            anyAction=-2;
2227            break;
2228          }
2229        } else {
2230          delete ws;
2231          break;
2232        }
2233      }
2234    }
2235    if (anyAction==-2) {
2236      break;
2237    }
2238    bool solveAll=false; // set true to say look at all even if some fixed (experiment)
2239    solveAll=true;
2240    // skip if solution
2241    if (!numberUnsatisfied_)
2242      break;
2243    //bool skipAll = (numberBeforeTrust>20&&numberNodes>20000&&numberNotTrusted==0);
2244    bool skipAll = numberNotTrusted==0;
2245    bool doneHotStart=false;
2246#ifndef CBC_WEAK_STRONG
2247    if ((numberNodes%20)==0||(model->specialOptions()&8)!=0)
2248      skipAll=false;
2249#endif
2250    int searchStrategy = saveSearchStrategy>=0 ? (saveSearchStrategy%10) : -1;
2251    if (!newWay) {
2252    // 10 up always use %10, 20 up as 10 and allow penalties
2253    // But adjust depending on ratio of iterations
2254    if (searchStrategy>0&&saveSearchStrategy<10) {
2255      if (numberBeforeTrust>=5&&numberBeforeTrust<=10) {
2256        if (searchStrategy!=2) {
2257          int numberIterations = model->getIterationCount();
2258          int numberStrongIterations = model->numberStrongIterations();
2259          if (numberStrongIterations>numberIterations+10000) {
2260            searchStrategy=2;
2261            //skipAll=true;
2262          } else if (numberStrongIterations*4+1000<numberIterations||depth_<5) {
2263            searchStrategy=3;
2264            skipAll=false;
2265          }
2266        } else {
2267          skipAll=true;
2268        }
2269      }
2270    }
2271    } else {
2272    // But adjust depending on ratio of iterations
2273    if (saveSearchStrategy<0) {
2274      // unset
2275      if ((numberNodes%20)==0||(model->specialOptions()&8)!=0) {
2276        // Do numberStrong
2277        searchStrategy=3;
2278      } else if (depth_<5) {
2279        // Do numberStrong
2280        searchStrategy=2;
2281      } else {
2282        int numberIterations = model->getIterationCount();
2283        int numberStrongIterations = model->numberStrongIterations();
2284        int numberRows = solver->getNumRows();
2285        if (numberStrongIterations>numberIterations+CoinMin(10000,10*numberRows)) {
2286          // off
2287          searchStrategy=0;
2288        } else if (numberStrongIterations*4+1000<numberIterations) {
2289          // Do numberStrong if not trusted
2290          searchStrategy=2;
2291        } else {
2292          searchStrategy=1;
2293        }
2294      }
2295    }
2296    if (searchStrategy<3&&(!numberNotTrusted||!searchStrategy))
2297      skipAll=true;
2298    else
2299      skipAll=false;
2300    }
2301    // worth trying if too many times
2302    // Save basis
2303    CoinWarmStart * ws = NULL;
2304    // save limit
2305    int saveLimit=0;
2306    solver->getIntParam(OsiMaxNumIterationHotStart,saveLimit);
2307    if (!skipAll) {
2308      ws = solver->getWarmStart();
2309      int limit=100;
2310#if 0
2311      int averageBranchIterations = model->getIterationCount()/(model->getNodeCount()+1);
2312      if (numberNodes)
2313        limit = CoinMin(CoinMax(limit,2*averageBranchIterations),500);
2314      else
2315        limit = 500;
2316#endif
2317      if ((!saveStateOfSearch||searchStrategy>3)&&saveLimit<limit&&saveLimit==100)
2318        solver->setIntParam(OsiMaxNumIterationHotStart,limit); 
2319    }
2320    // Say which one will be best
2321    int whichChoice=0;
2322    int bestChoice;
2323    if (iBestGot>=0)
2324      bestChoice=iBestGot;
2325    else
2326      bestChoice=iBestNot;
2327    assert (bestChoice>=0);
2328    // If we have hit max time don't do strong branching
2329    bool hitMaxTime = ( CoinCpuTime()-model->getDblParam(CbcModel::CbcStartSeconds) > 
2330                        model->getDblParam(CbcModel::CbcMaximumSeconds));
2331    // also give up if we are looping round too much
2332    if (hitMaxTime||numberPassesLeft<=0||(!numberNotTrusted&&false)) {
2333      int iObject = whichObject[bestChoice];
2334      CbcObject * object = model->modifiableObject(iObject);
2335      int preferredWay;
2336      object->infeasibility(preferredWay);
2337      branch_=object->createBranch(preferredWay);
2338      branch_->way(preferredWay);
2339      delete ws;
2340      ws=NULL;
2341      break;
2342    } else {
2343      // say do fast
2344      int easy=1;
2345      if (!skipAll)
2346        solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,&easy) ;
2347      int iDo;
2348#ifdef RANGING
2349      if ((skipAll&&numberBeforeTrust&&saveSearchStrategy<20)||saveSearchStrategy<10)
2350        numberPenalties=0;
2351      {
2352        // off penalties if too much
2353        double needed = neededPenalties;
2354        needed *= numberRows;
2355        if (needed>1.0e6&&numberNodes&&saveSearchStrategy<20) {
2356          numberPenalties=0;
2357          neededPenalties=0;
2358        }
2359      }
2360#     ifdef CBC_USE_CLP
2361      if (osiclp&&numberPenalties&&neededPenalties) {
2362        xPen += neededPenalties;
2363        which--;
2364        which[0]=neededPenalties;
2365        osiclp->passInRanges(which);
2366        // Mark hot start and get ranges
2367        if (kPass) {
2368          // until can work out why solution can go funny
2369          int save = osiclp->specialOptions();
2370          osiclp->setSpecialOptions(save|256);
2371          solver->markHotStart();
2372          osiclp->setSpecialOptions(save);
2373        } else {
2374          solver->markHotStart();
2375        }
2376        assert (auxiliaryInfo->warmStart());
2377        doneHotStart=true;
2378        xMark++;
2379        kPass++;
2380        osiclp->passInRanges(NULL);
2381        const double * downCost=osiclp->upRange();
2382        const double * upCost=osiclp->downRange();
2383        //printf("numberTodo %d needed %d numberpenalties %d\n",numberToDo,neededPenalties,numberPenalties);
2384        double invTrust = 1.0/((double) numberBeforeTrust);
2385        for (int i=0;i<neededPenalties;i++) {
2386          int j = objectMark[i];
2387          int iObject = whichObject[j];
2388          CbcObject * object = model->modifiableObject(iObject);
2389          CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
2390            dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
2391          int iSequence=dynamicObject->columnNumber();
2392          double value = saveSolution[iSequence];
2393          value -= floor(value);
2394          double upPenalty = CoinMin(upCost[i],1.0e110)*(1.0-value);
2395          double downPenalty = CoinMin(downCost[i],1.0e110)*value;
2396          if (!numberBeforeTrust) {
2397            // override
2398            downEstimate[iObject]=downPenalty;
2399            upEstimate[iObject]=upPenalty;
2400          } else {
2401            int numberThisDown = dynamicObject->numberTimesDown();
2402            if (numberThisDown<numberBeforeTrust) {
2403              double fraction = ((double) numberThisDown)*invTrust;
2404              downEstimate[iObject] = fraction*downEstimate[iObject]+(1.0-fraction)*downPenalty;
2405            }
2406            int numberThisUp = dynamicObject->numberTimesUp();
2407            if (numberThisUp<numberBeforeTrust) {
2408              double fraction = ((double) numberThisUp)*invTrust;
2409              upEstimate[iObject] = fraction*upEstimate[iObject]+(1.0-fraction)*upPenalty;
2410            }
2411          }
2412          sort[j] = - CoinMin(downEstimate[iObject],upEstimate[iObject]);
2413#ifdef CBC_WEAK_STRONG
2414          sort[j] -= 1.0e10; // make more likely to be chosen
2415#endif
2416          //if ((numberNodes%PRINT_STUFF)==0&&PRINT_STUFF>0)
2417          if (!numberNodes)
2418            printf("%d pen down ps %g -> %g up ps %g -> %g\n",
2419                   iObject,downCost[i],downPenalty,upCost[i],upPenalty);
2420        }
2421      } else
2422#     endif     /* CBC_USE_CLP */
2423      {
2424        if (!skipAll) {
2425          // Mark hot start
2426          solver->markHotStart();
2427          doneHotStart=true;
2428          assert (auxiliaryInfo->warmStart());
2429          xMark++;
2430          //if (solver->isProvenPrimalInfeasible())
2431          //printf("**** Hot start says node infeasible\n");
2432        }
2433        // make sure best will be first
2434        if (iBestGot>=0)
2435          sort[iBestGot]=-1.0e120;
2436      }
2437#else           /* RANGING */
2438      if (!skipAll) {
2439        // Mark hot start
2440        doneHotStart=true;
2441        assert (auxiliaryInfo->warmStart());
2442        solver->markHotStart();
2443        xMark++;
2444      }
2445      // make sure best will be first
2446      if (iBestGot>=0)
2447        sort[iBestGot]=-COIN_DBL_MAX;
2448#endif          /* RANGING */
2449      // Actions 0 - exit for repeat, 1 resolve and try old choice,2 exit for continue
2450#define ACTION 0
2451#if ACTION<2
2452      if (anyAction)
2453        numberToDo=0; // skip as we will be trying again
2454#endif
2455      // Sort
2456      CoinSort_2(sort,sort+numberToDo,whichObject);
2457      // Change in objective opposite infeasible
2458      double worstFeasible=0.0;
2459      // Just first if strong off
2460      if (!numberStrong)
2461        numberToDo=CoinMin(numberToDo,1);
2462      iDo=0;
2463      int saveLimit2;
2464      solver->getIntParam(OsiMaxNumIterationHotStart,saveLimit2);
2465      bool doQuickly = false; // numberToDo>2*numberStrong;
2466      //printf("todo %d, strong %d\n",numberToDo,numberStrong);
2467      int numberTest=numberNotTrusted>0 ? numberStrong : (numberStrong+1)/2;
2468      int numberTest2 = 2*numberStrong;
2469      if (!newWay) {
2470      if (searchStrategy==3) {
2471        // Previously decided we need strong
2472        doQuickly=false;
2473        numberTest = numberStrong;
2474        //numberTest2 = 1000000;
2475      }
2476      if (searchStrategy<0||searchStrategy==1)
2477        //numberTest2 = 1000000;
2478#if 0
2479      if (numberBeforeTrust>20&&(numberNodes>20000||(numberNodes>200&&numberNotTrusted==0))) {
2480        if ((numberNodes%20)!=0) {
2481          numberTest=0;
2482          doQuickly=true;
2483        }
2484      }
2485#else
2486      // Try nearly always off
2487      if (searchStrategy<2) {
2488        if ((numberNodes%20)!=0) {
2489          if ((model->specialOptions()&8)==0) {
2490            numberTest=0;
2491            doQuickly=true;
2492          }
2493        } else {
2494          doQuickly=false;
2495          numberTest=2*numberStrong;
2496        }
2497      } else if (searchStrategy!=3) {
2498        doQuickly=true;
2499        numberTest=numberStrong;
2500      }
2501#endif
2502      if (depth_<10&&numberStrong) {
2503        if (searchStrategy!=2) {
2504          doQuickly=false;
2505          if (depth_<7)
2506            numberStrong *=3;
2507          if (!depth_) 
2508            numberStrong=CoinMin(6*numberStrong,numberToDo);
2509          numberTest=numberStrong;
2510        }
2511        model->setStateOfSearch(2); // use min min
2512      }
2513      // could adjust using average iterations per branch
2514      // double average = ((double)model->getIterationCount())/
2515      //((double) model->getNodeCount()+1.0);
2516      // if too many and big then just do 10 its
2517      if (!skipAll&&saveStateOfSearch) {
2518        //if (numberNotTrusted>3*numberStrong&&numberRows>250&&numberColumns>1000&&saveLimit==100)
2519          // off solver->setIntParam(OsiMaxNumIterationHotStart,10);
2520      }
2521      // make negative for test
2522      distanceToCutoff = - distanceToCutoff;
2523      if (numberObjects>-100) {
2524        // larger
2525        distanceToCutoff *= 100.0;
2526      }
2527        distanceToCutoff = -COIN_DBL_MAX;
2528      // Do at least 5 strong
2529      if (numberColumns<1000&&(depth_<15||numberNodes<1000000))
2530        numberTest = CoinMax(numberTest,5);
2531      if ((model->specialOptions()&8)==0) {
2532        if (skipAll) {
2533          numberTest=0;
2534          doQuickly=true;
2535        }
2536      } else {
2537        // do 5 as strong is fixing
2538        numberTest = CoinMax(numberTest,5);
2539      }
2540      } else {
2541      int numberTest=numberNotTrusted>0 ? numberStrong : (numberStrong+1)/2;
2542      int numberTest2 = 2*numberStrong;
2543      if (searchStrategy>=3) {
2544        // Previously decided we need strong
2545        doQuickly=false;
2546        if (depth_<7)
2547          numberStrong *=3;
2548        if (!depth_) 
2549          numberStrong=CoinMin(6*numberStrong,numberToDo);
2550        numberTest = numberStrong;
2551        numberTest2 *= 2;
2552      } else if (searchStrategy==2||(searchStrategy==1&&depth_<6)) {
2553        numberStrong *=2;
2554        if (!depth_) 
2555          numberStrong=CoinMin(2*numberStrong,numberToDo);
2556        numberTest = numberStrong;
2557      } else if (searchStrategy==1&&numberNotTrusted) {
2558        numberTest = numberStrong;
2559      } else {
2560        numberTest=0;
2561        skipAll=true;
2562      }
2563      distanceToCutoff=model->getCutoff()-objectiveValue_;
2564      // make negative for test
2565      distanceToCutoff = - distanceToCutoff;
2566      if (numberObjects>-100) {
2567        // larger
2568        distanceToCutoff *= 100.0;
2569      }
2570      distanceToCutoff = -COIN_DBL_MAX;
2571      if (skipAll) {
2572        numberTest=0;
2573        doQuickly=true;
2574      }
2575      }
2576      px[0]=numberTest;
2577      px[1]=numberTest2;
2578      px[2]= doQuickly ? 1 : -1;
2579      px[3]=numberStrong;
2580      //printf("skipAll %c doQuickly %c numberTest %d numberTest2 %d numberNot %d\n",
2581      //     skipAll ? 'Y' : 'N',doQuickly ? 'Y' : 'N',numberTest,numberTest2,numberNotTrusted);
2582      // See if we want mini tree
2583      bool wantMiniTree=false;
2584      if (model->sizeMiniTree()&&depth_>7&&saveStateOfSearch>0)
2585        wantMiniTree=true;
2586      numberMini=0;
2587      for ( iDo=0;iDo<numberToDo;iDo++) {
2588        CbcStrongInfo choice;
2589        int iObject = whichObject[iDo];
2590        CbcObject * object = model->modifiableObject(iObject);
2591        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
2592          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
2593        int iColumn = dynamicObject->columnNumber();
2594        int preferredWay;
2595        object->infeasibility(preferredWay);
2596        choice.possibleBranch=object->createBranch(preferredWay);
2597        // Save which object it was
2598        choice.objectNumber=iObject;
2599        choice.numIntInfeasUp = numberUnsatisfied_;
2600        choice.numIntInfeasDown = numberUnsatisfied_;
2601        choice.upMovement = upEstimate[iObject];
2602        choice.downMovement = downEstimate[iObject];
2603        assert (choice.upMovement>=0.0);
2604        assert (choice.downMovement>=0.0);
2605        choice.fix=0; // say not fixed
2606        // see if can skip strong branching
2607        int canSkip = choice.possibleBranch->fillStrongInfo(choice);
2608        if (!newWay) {
2609        if (!doQuickly||(numberTest>0&&searchStrategy!=2))
2610          canSkip=0;
2611        } else {
2612        if (skipAll)
2613          canSkip=1;
2614        else if (numberTest>0&&searchStrategy>=3)
2615          canSkip=0;
2616        }
2617        if (!numberBeforeTrust) {
2618          canSkip=1;
2619        }
2620        if (sort[iDo]<distanceToCutoff)
2621          canSkip=0;
2622        if (((numberTest2<=0&&numberTest<=0)||skipAll)&&sort[iDo]>distanceToCutoff) {
2623          canSkip=1; // always skip
2624          if (iDo>20) {
2625            delete choice.possibleBranch;
2626            choice.possibleBranch=NULL;
2627            break; // give up anyway
2628          }
2629        }
2630        if (model->messageHandler()->logLevel()>3&&numberBeforeTrust) 
2631          dynamicObject->print(1,choice.possibleBranch->value());
2632        // was if (!canSkip)
2633        if (newWay)
2634        numberTest2--;
2635        if (!canSkip) {
2636          numberTest--;
2637          if (!newWay)
2638          numberTest2--;
2639          // just do a few
2640          //if (canSkip)
2641          //solver->setIntParam(OsiMaxNumIterationHotStart,10);
2642          double objectiveChange ;
2643          double newObjectiveValue=1.0e100;
2644          int j;
2645          // status is 0 finished, 1 infeasible and other
2646          int iStatus;
2647          /*
2648            Try the down direction first. (Specify the initial branching alternative as
2649            down with a call to way(-1). Each subsequent call to branch() performs the
2650            specified branch and advances the branch object state to the next branch
2651            alternative.)
2652          */
2653          choice.possibleBranch->way(-1) ;
2654          decision->saveBranchingObject( choice.possibleBranch);
2655          choice.possibleBranch->branch() ;
2656          solver->solveFromHotStart() ;
2657          bool needHotStartUpdate=false;
2658          numberStrongDone++;
2659          numberStrongIterations += solver->getIterationCount();
2660          /*
2661            We now have an estimate of objective degradation that we can use for strong
2662            branching. If we're over the cutoff, the variable is monotone up.
2663            If we actually made it to optimality, check for a solution, and if we have
2664            a good one, call setBestSolution to process it. Note that this may reduce the
2665            cutoff, so we check again to see if we can declare this variable monotone.
2666          */
2667          if (solver->isProvenOptimal())
2668            iStatus=0; // optimal
2669          else if (solver->isIterationLimitReached()
2670                   &&!solver->isDualObjectiveLimitReached())
2671            iStatus=2; // unknown
2672          else
2673            iStatus=1; // infeasible
2674          newObjectiveValue = solver->getObjSense()*solver->getObjValue();
2675          choice.numItersDown = solver->getIterationCount();
2676          objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
2677          decision->updateInformation( solver,this);
2678          if (!iStatus) {
2679            choice.finishedDown = true ;
2680            if (newObjectiveValue>=cutoff) {
2681              objectiveChange = 1.0e100; // say infeasible
2682              numberStrongInfeasible++;
2683            } else {
2684              // See if integer solution
2685              if (model->feasibleSolution(choice.numIntInfeasDown,
2686                                          choice.numObjInfeasDown)
2687                  &&model->problemFeasibility()->feasible(model,-1)>=0) {
2688                if (auxiliaryInfo->solutionAddsCuts()) {
2689                  needHotStartUpdate=true;
2690                  solver->unmarkHotStart();
2691                }
2692                model->setBestSolution(CBC_STRONGSOL,
2693                                       newObjectiveValue,
2694                                       solver->getColSolution()) ;
2695                if (needHotStartUpdate) {
2696                  solver->resolve();
2697                  newObjectiveValue = solver->getObjSense()*solver->getObjValue();
2698                  objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
2699                  model->feasibleSolution(choice.numIntInfeasDown,
2700                                          choice.numObjInfeasDown);
2701                }
2702                model->setLastHeuristic(NULL);
2703                model->incrementUsed(solver->getColSolution());
2704                cutoff =model->getCutoff();
2705                if (newObjectiveValue >= cutoff) {      //  *new* cutoff
2706                  objectiveChange = 1.0e100 ;
2707                  numberStrongInfeasible++;
2708                }
2709              }
2710            }
2711          } else if (iStatus==1) {
2712            objectiveChange = 1.0e100 ;
2713            numberStrongInfeasible++;
2714          } else {
2715            // Can't say much as we did not finish
2716            choice.finishedDown = false ;
2717            numberUnfinished++;
2718          }
2719          choice.downMovement = objectiveChange ;
2720         
2721          // restore bounds
2722          for ( j=0;j<numberColumns;j++) {
2723            if (saveLower[j] != lower[j])
2724              solver->setColLower(j,saveLower[j]);
2725            if (saveUpper[j] != upper[j])
2726              solver->setColUpper(j,saveUpper[j]);
2727          }
2728          if(needHotStartUpdate) {
2729            needHotStartUpdate = false;
2730            solver->resolve();
2731            //we may again have an integer feasible solution
2732            int numberIntegerInfeasibilities;
2733            int numberObjectInfeasibilities;
2734            if (model->feasibleSolution(
2735                                        numberIntegerInfeasibilities,
2736                                        numberObjectInfeasibilities)) {
2737#ifdef BONMIN
2738              //In this case node has become integer feasible, let us exit the loop
2739              std::cout<<"Node has become integer feasible"<<std::endl;
2740              numberUnsatisfied_ = 0;
2741              break;
2742#endif
2743              double objValue = solver->getObjValue();
2744              model->setBestSolution(CBC_STRONGSOL,
2745                                     objValue,
2746                                     solver->getColSolution()) ;
2747              solver->resolve();
2748              cutoff =model->getCutoff();
2749            }
2750            solver->markHotStart();
2751          }
2752          //printf("Down on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
2753          //printf("Down on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
2754          //     choice.objectNumber,iStatus,newObjectiveValue,choice.numItersDown,
2755          //     choice.downMovement,choice.finishedDown,choice.numIntInfeasDown,
2756          //     choice.numObjInfeasDown);
2757         
2758          // repeat the whole exercise, forcing the variable up
2759          decision->saveBranchingObject( choice.possibleBranch);
2760          choice.possibleBranch->branch();
2761          solver->solveFromHotStart() ;
2762          numberStrongDone++;
2763          numberStrongIterations += solver->getIterationCount();
2764          /*
2765            We now have an estimate of objective degradation that we can use for strong
2766            branching. If we're over the cutoff, the variable is monotone up.
2767            If we actually made it to optimality, check for a solution, and if we have
2768            a good one, call setBestSolution to process it. Note that this may reduce the
2769            cutoff, so we check again to see if we can declare this variable monotone.
2770          */
2771          if (solver->isProvenOptimal())
2772            iStatus=0; // optimal
2773          else if (solver->isIterationLimitReached()
2774                   &&!solver->isDualObjectiveLimitReached())
2775            iStatus=2; // unknown
2776          else
2777            iStatus=1; // infeasible
2778          newObjectiveValue = solver->getObjSense()*solver->getObjValue();
2779          choice.numItersUp = solver->getIterationCount();
2780          objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
2781          decision->updateInformation( solver,this);
2782          if (!iStatus) {
2783            choice.finishedUp = true ;
2784            if (newObjectiveValue>=cutoff) {
2785              objectiveChange = 1.0e100; // say infeasible
2786              numberStrongInfeasible++;
2787            } else {
2788              // See if integer solution
2789              if (model->feasibleSolution(choice.numIntInfeasUp,
2790                                          choice.numObjInfeasUp)
2791                  &&model->problemFeasibility()->feasible(model,-1)>=0) {
2792#ifdef BONMIN
2793                std::cout<<"Node has become integer feasible"<<std::endl;
2794                numberUnsatisfied_ = 0;
2795                break;
2796#endif
2797                if (auxiliaryInfo->solutionAddsCuts()) {
2798                  needHotStartUpdate=true;
2799                  solver->unmarkHotStart();
2800                }
2801                model->setBestSolution(CBC_STRONGSOL,
2802                                       newObjectiveValue,
2803                                       solver->getColSolution()) ;
2804                if (needHotStartUpdate) {
2805                  solver->resolve();
2806                  newObjectiveValue = solver->getObjSense()*solver->getObjValue();
2807                  objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
2808                  model->feasibleSolution(choice.numIntInfeasDown,
2809                                          choice.numObjInfeasDown);
2810                }
2811                model->setLastHeuristic(NULL);
2812                model->incrementUsed(solver->getColSolution());
2813                cutoff =model->getCutoff();
2814                if (newObjectiveValue >= cutoff) {      //  *new* cutoff
2815                  objectiveChange = 1.0e100 ;
2816                  numberStrongInfeasible++;
2817                }
2818              }
2819            }
2820          } else if (iStatus==1) {
2821            objectiveChange = 1.0e100 ;
2822            numberStrongInfeasible++;
2823          } else {
2824            // Can't say much as we did not finish
2825            choice.finishedUp = false ;
2826            numberUnfinished++;
2827          }
2828          choice.upMovement = objectiveChange ;
2829         
2830          // restore bounds
2831          for ( j=0;j<numberColumns;j++) {
2832            if (saveLower[j] != lower[j])
2833              solver->setColLower(j,saveLower[j]);
2834            if (saveUpper[j] != upper[j])
2835              solver->setColUpper(j,saveUpper[j]);
2836          }
2837          if(needHotStartUpdate) {
2838            needHotStartUpdate = false;
2839            solver->resolve();
2840            //we may again have an integer feasible solution
2841            int numberIntegerInfeasibilities;
2842            int numberObjectInfeasibilities;
2843            if (model->feasibleSolution(
2844                                        numberIntegerInfeasibilities,
2845                                        numberObjectInfeasibilities)) {
2846              double objValue = solver->getObjValue();
2847              model->setBestSolution(CBC_STRONGSOL,
2848                                     objValue,
2849                                     solver->getColSolution()) ;
2850              solver->resolve();
2851              cutoff =model->getCutoff();
2852            }
2853            solver->markHotStart();
2854          }
2855         
2856          //printf("Up on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
2857          //     choice.objectNumber,iStatus,newObjectiveValue,choice.numItersUp,
2858          //     choice.upMovement,choice.finishedUp,choice.numIntInfeasUp,
2859          //     choice.numObjInfeasUp);
2860        }
2861   
2862        solver->setIntParam(OsiMaxNumIterationHotStart,saveLimit2); 
2863        /*
2864          End of evaluation for this candidate variable. Possibilities are:
2865          * Both sides below cutoff; this variable is a candidate for branching.
2866          * Both sides infeasible or above the objective cutoff: no further action
2867          here. Break from the evaluation loop and assume the node will be purged
2868          by the caller.
2869          * One side below cutoff: Install the branch (i.e., fix the variable). Break
2870          from the evaluation loop and assume the node will be reoptimised by the
2871          caller.
2872        */
2873        // reset
2874        choice.possibleBranch->resetNumberBranchesLeft();
2875        if (choice.upMovement<1.0e100) {
2876          if(choice.downMovement<1.0e100) {
2877            // In case solution coming in was odd
2878            choice.upMovement = CoinMax(0.0,choice.upMovement);
2879            choice.downMovement = CoinMax(0.0,choice.downMovement);
2880#if ZERO_ONE==2
2881            // branch on 0-1 first (temp)
2882            if (fabs(choice.possibleBranch->value())<1.0) {
2883              choice.upMovement *= ZERO_FAKE;
2884              choice.downMovement *= ZERO_FAKE;
2885            }
2886#endif
2887            // feasible - see which best
2888            if (!canSkip) {
2889              if (iColumn==-46) {
2890                printf("sort %g downest %g upest %g ",sort[iDo],downEstimate[iObject],
2891                     upEstimate[iObject]);
2892                printf("downMove %g upMove %g value %g current pseudo %g %g\n",
2893                       choice.downMovement,choice.upMovement,choice.possibleBranch->value(),
2894                       dynamicObject->downDynamicPseudoCost(),dynamicObject->upDynamicPseudoCost());
2895              }
2896              if (model->messageHandler()->logLevel()>3) 
2897                printf("sort %g downest %g upest %g ",sort[iDo],downEstimate[iObject],
2898                     upEstimate[iObject]);
2899              model->messageHandler()->message(CBC_STRONG,model->messages())
2900                << iObject << iColumn
2901                <<choice.downMovement<<choice.numIntInfeasDown
2902                <<choice.upMovement<<choice.numIntInfeasUp
2903                <<choice.possibleBranch->value()
2904                <<CoinMessageEol;
2905            }
2906            //if (!stateOfSearch)
2907            //choice.numIntInfeasDown=99999; // temp fudge
2908            if (wantMiniTree)
2909              decision->setBestCriterion(-1.0);
2910            double bestCriterion = -1.0;
2911            double gap = saveUpper[iColumn]-saveLower[iColumn];
2912            // Give precedence to ones with gap of 1.0
2913            assert(gap>0.0);
2914            double factor = changeFactor/CoinMin(gap,100.0);
2915            int betterWay = decision->betterBranch(choice.possibleBranch,
2916                                                   branch_,
2917                                                   choice.upMovement*factor,
2918                                                   choice.numIntInfeasUp ,
2919                                                   choice.downMovement*factor,
2920                                                   choice.numIntInfeasDown );
2921            if (wantMiniTree) {
2922              double criterion = decision->getBestCriterion();
2923              sort[numberMini]=-criterion;
2924              whichObject[numberMini++]=whichObject[iDo];
2925              assert (betterWay);
2926              if (criterion>bestCriterion) 
2927                bestCriterion=criterion;
2928              else
2929                betterWay=0;
2930            }
2931            if (iDo>=changeStrategy) {
2932              // make less likely
2933              changeStrategy+=numberStrong;
2934              changeFactor *= 0.9;
2935            }
2936            if (betterWay) {
2937              delete branch_;
2938              // C) create branching object
2939              branch_ = choice.possibleBranch;
2940              choice.possibleBranch=NULL;
2941              branch_->way(betterWay);
2942              bestChoice = choice.objectNumber;
2943              whichChoice = iDo;
2944              if (numberStrong<=1) {
2945                delete ws;
2946                ws=NULL;
2947                break;
2948              }
2949            } else {
2950              delete choice.possibleBranch;
2951              choice.possibleBranch=NULL;
2952              if (iDo>=2*numberStrong) {
2953                delete ws;
2954                ws=NULL;
2955                break;
2956              }
2957              if (!dynamicObject||dynamicObject->numberTimesUp()>1) {
2958                if (iDo-whichChoice>=numberStrong) {
2959                  delete choice.possibleBranch;
2960                  choice.possibleBranch=NULL;
2961                  break; // give up
2962                }
2963              } else {
2964                if (iDo-whichChoice>=2*numberStrong) {
2965                  delete ws;
2966                  ws=NULL;
2967                  delete choice.possibleBranch;
2968                  choice.possibleBranch=NULL;
2969                  break; // give up
2970                }
2971              }
2972            }
2973          } else {
2974            // up feasible, down infeasible
2975            anyAction=-1;
2976            worstFeasible = CoinMax(worstFeasible,choice.upMovement);
2977            //printf("Down infeasible for choice %d sequence %d\n",i,
2978            // model->object(choice.objectNumber)->columnNumber());
2979            if (!solveAll) {
2980              choice.possibleBranch->way(1);
2981              choice.possibleBranch->branch();
2982              delete choice.possibleBranch;
2983              choice.possibleBranch=NULL;
2984              delete ws;
2985              ws=NULL;
2986              break;
2987            } else {
2988              choice.fix=1;
2989              fixObject[numberToFix++]=choice;
2990              choice.possibleBranch=NULL;
2991#define FIXNOW
2992#ifdef FIXNOW
2993              double value = ceil(saveSolution[iColumn]);
2994              saveLower[iColumn]=value;
2995              solver->setColLower(iColumn,value);
2996              assert(doneHotStart);
2997              solver->unmarkHotStart();
2998              solver->markHotStart();
2999#endif
3000            }
3001          }
3002        } else {
3003          if(choice.downMovement<1.0e100) {
3004            // down feasible, up infeasible
3005            anyAction=-1;
3006            worstFeasible = CoinMax(worstFeasible,choice.downMovement);
3007            //printf("Up infeasible for choice %d sequence %d\n",i,
3008            // model->object(choice.objectNumber)->columnNumber());
3009            if (!solveAll) {
3010              choice.possibleBranch->way(-1);
3011              choice.possibleBranch->branch();
3012              delete choice.possibleBranch;
3013              choice.possibleBranch=NULL;
3014              delete ws;
3015              ws=NULL;
3016              break;
3017            } else {
3018              choice.fix=-1;
3019              fixObject[numberToFix++]=choice;
3020              choice.possibleBranch=NULL;
3021#ifdef FIXNOW
3022              double value = floor(saveSolution[iColumn]);
3023              saveUpper[iColumn]=value;
3024              solver->setColUpper(iColumn,value);
3025              assert(doneHotStart);
3026              solver->unmarkHotStart();
3027              solver->markHotStart();
3028#endif
3029            }
3030          } else {
3031            // neither side feasible
3032            anyAction=-2;
3033            delete choice.possibleBranch;
3034            choice.possibleBranch=NULL;
3035            //printf("Both infeasible for choice %d sequence %d\n",i,
3036            // model->object(choice.objectNumber)->columnNumber());
3037            delete ws;
3038            ws=NULL;
3039            break;
3040          }
3041        }
3042        // Check max time
3043        hitMaxTime = ( CoinCpuTime()-model->getDblParam(CbcModel::CbcStartSeconds) > 
3044                       model->getDblParam(CbcModel::CbcMaximumSeconds));
3045        if (hitMaxTime) {
3046          // make sure rest are fast
3047          doQuickly=true;
3048          for ( int jDo=iDo+1;jDo<numberToDo;jDo++) {
3049            int iObject = whichObject[iDo];
3050            CbcObject * object = model->modifiableObject(iObject);
3051            CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
3052              dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
3053            dynamicObject->setNumberBeforeTrust(0);
3054          }
3055          numberTest=0;
3056          distanceToCutoff=-COIN_DBL_MAX;
3057        }
3058        delete choice.possibleBranch;
3059      }
3060      double averageChange = model->sumChangeObjective()/((double) model->getNodeCount());
3061      if (depth_<10||worstFeasible>0.2*averageChange) 
3062        solveAll=false;
3063      if (model->messageHandler()->logLevel()>3||false) { 
3064        if (anyAction==-2)
3065          printf("infeasible\n");
3066        else if(anyAction==-1)
3067          if (!solveAll)
3068            printf("%d fixed\n",numberToFix);
3069          else
3070            printf("%d fixed AND choosing %d iDo %d iChosenWhen %d numberToDo %d\n",numberToFix,bestChoice,
3071                   iDo,whichChoice,numberToDo);
3072        else
3073          printf("choosing %d iDo %d iChosenWhen %d numberToDo %d\n",bestChoice,
3074                 iDo,whichChoice,numberToDo);
3075      }
3076      if (doneHotStart) {
3077        // Delete the snapshot
3078        solver->unmarkHotStart();
3079        // back to normal
3080        solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
3081        // restore basis
3082        solver->setWarmStart(ws);
3083      }
3084      solver->setIntParam(OsiMaxNumIterationHotStart,saveLimit);
3085      // Unless infeasible we will carry on
3086      // But we could fix anyway
3087      if (numberToFix&&!hitMaxTime) {
3088        if (anyAction==-2) {
3089          // take off
3090          for (i = 0 ; i < numberToFix ; i++) {
3091            delete fixObject[i].possibleBranch;
3092          }
3093        } else {
3094          // apply and take off
3095          for (i = 0 ; i < numberToFix ; i++) {
3096#ifndef FIXNOW
3097            fixObject[i].possibleBranch->way(fixObject[i].fix) ;
3098            fixObject[i].possibleBranch->branch() ;
3099#endif
3100            delete fixObject[i].possibleBranch;
3101          }
3102          bool feasible=true;
3103#if ACTION <2
3104          if (solveAll) {
3105            // can do quick optimality check
3106            int easy=2;
3107            solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,&easy) ;
3108            solver->resolve() ;
3109            solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
3110            feasible = solver->isProvenOptimal();
3111            if (feasible) {
3112              anyAction=0;
3113              numberMini=0;
3114              memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
3115              model->reserveCurrentSolution(saveSolution);
3116              memcpy(saveLower,solver->getColLower(),numberColumns*sizeof(double));
3117              memcpy(saveUpper,solver->getColUpper(),numberColumns*sizeof(double));
3118              model->setPointers(solver);
3119              // See if candidate still possible
3120              if (branch_) {
3121                const CbcObject * object = model->object(bestChoice);
3122                int preferredWay;
3123                double infeasibility = object->infeasibility(preferredWay);
3124                if (!infeasibility) {
3125                  // take out
3126                  delete branch_;
3127                  branch_=NULL;
3128                } else {
3129                  branch_->way(preferredWay);
3130                }
3131              }
3132            } else {
3133              anyAction=-2;
3134              finished=true;
3135            }
3136          }
3137#endif
3138          // If  fixed then round again
3139          if (!branch_&&anyAction!=-2) {
3140            finished=false;
3141          }
3142          // If these in then different action
3143#if ACTION == 1
3144          if (!anyAction)
3145            anyAction=-1;
3146          finished=true;
3147#endif
3148        }
3149      }
3150      delete ws;
3151    }
3152  }
3153  if (model->messageHandler()->logLevel()>2) 
3154    printf("%d strong, %d iters, %d pen, %d mark, %d fixed, action %d nnott %d nt %d, %d dq %s ns %d\n",
3155         numberStrongDone,numberStrongIterations,xPen,xMark,
3156           numberToFix,anyAction,numberNotTrusted,px[0],px[1],px[2]>0 ? "y" : "n",px[3]);
3157  // update number of strong iterations etc
3158  model->incrementStrongInfo(numberStrongDone,numberStrongIterations,
3159                             anyAction==-2 ? 0:numberToFix,anyAction==-2);
3160  if (!newWay) {
3161  if (((model->searchStrategy()+1)%1000)==0) {
3162    if (solver->messageHandler()->logLevel()>1)
3163      printf("%d strong, %d iters, %d inf, %d not finished, %d not trusted\n",
3164             numberStrongDone,numberStrongIterations,numberStrongInfeasible,numberUnfinished,
3165             numberNotTrusted);
3166    // decide what to do
3167    int strategy=1;
3168    if (numberUnfinished*4>numberStrongDone&&numberStrongInfeasible*10<numberStrongDone) {
3169      strategy=2;
3170      if (model->logLevel()>1)
3171        printf("going to strategy 2\n");
3172    }
3173    if (numberNodes)
3174      strategy=1;  // should only happen after hot start
3175    model->setSearchStrategy(strategy);
3176  }
3177  }
3178  //if (numberToFix&&depth_<5)
3179  //printf("%d fixed by strong at depth %d\n",numberToFix,depth_);
3180  // Set guessed solution value
3181  guessedObjectiveValue_ = objectiveValue_+estimatedDegradation;
3182 
3183  // Get collection of branches if mini tree wanted
3184  if (anyAction==0&&numberMini&&numberMini>1) {
3185    // Sort
3186    CoinSort_2(sort,sort+numberMini,whichObject);
3187    delete branch_;
3188    branch_=NULL;
3189    numberMini = CoinMin(numberMini,model->sizeMiniTree());
3190    anyAction=numberMini;
3191    branches = new OsiSolverBranch[numberMini];
3192    for (int iDo=0;iDo<numberMini;iDo++) {
3193      int iObject = whichObject[iDo];
3194      CbcObject * object = model->modifiableObject(iObject);
3195      OsiSolverBranch * oneBranch = object->solverBranch();
3196      branches[iDo]=*oneBranch;
3197      delete oneBranch;
3198    }
3199  }
3200/*
3201  Cleanup, then we're finished
3202*/
3203  if (!model->branchingMethod())
3204    delete decision;
3205   
3206  delete [] fixObject;
3207  delete [] sort;
3208  delete [] whichObject;
3209  delete [] objectMark;
3210  delete [] saveLower;
3211  delete [] saveUpper;
3212  delete [] upEstimate;
3213  delete [] downEstimate;
3214# ifdef CBC_USE_CLP
3215  if (osiclp) 
3216    osiclp->setSpecialOptions(saveClpOptions);
3217# endif
3218  // restore solution
3219  solver->setColSolution(saveSolution);
3220  model->reserveCurrentSolution(saveSolution);
3221  delete [] saveSolution;
3222  model->setStateOfSearch(saveStateOfSearch);
3223  return anyAction;
3224}
3225int CbcNode::analyze (CbcModel *model, double * results)
3226{
3227  int i;
3228  int numberIterationsAllowed = model->numberAnalyzeIterations();
3229  OsiSolverInterface * solver = model->solver();
3230  objectiveValue_ = solver->getObjSense()*solver->getObjValue();
3231  double cutoff =model->getCutoff();
3232  const double * lower = solver->getColLower();
3233  const double * upper = solver->getColUpper();
3234  const double * dj = solver->getReducedCost();
3235  int numberObjects = model->numberObjects();
3236  int numberColumns = model->getNumCols();
3237  // Initialize arrays
3238  int numberIntegers = model->numberIntegers();
3239  int * back = new int[numberColumns];
3240  const int * integerVariable = model->integerVariable();
3241  for (i=0;i<numberColumns;i++) 
3242    back[i]=-1;
3243  // What results is
3244  double * newLower = results;
3245  double * objLower = newLower+numberIntegers;
3246  double * newUpper = objLower+numberIntegers;
3247  double * objUpper = newUpper+numberIntegers;
3248  for (i=0;i<numberIntegers;i++) {
3249    int iColumn = integerVariable[i];
3250    back[iColumn]=i;
3251    newLower[i]=0.0;
3252    objLower[i]=-COIN_DBL_MAX;
3253    newUpper[i]=0.0;
3254    objUpper[i]=-COIN_DBL_MAX;
3255  }
3256  double * saveUpper = new double[numberColumns];
3257  double * saveLower = new double[numberColumns];
3258  int anyAction=0;
3259  // Save solution in case heuristics need good solution later
3260 
3261  double * saveSolution = new double[numberColumns];
3262  memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
3263  model->reserveCurrentSolution(saveSolution);
3264  for (i=0;i<numberColumns;i++) {
3265    saveLower[i] = lower[i];
3266    saveUpper[i] = upper[i];
3267  }
3268  // Get arrays to sort
3269  double * sort = new double[numberObjects];
3270  int * whichObject = new int[numberObjects];
3271  int numberToFix=0;
3272  int numberToDo=0;
3273     
3274  // compute current state
3275  int numberObjectInfeasibilities; // just odd ones
3276  int numberIntegerInfeasibilities;
3277  model->feasibleSolution(
3278                          numberIntegerInfeasibilities,
3279                          numberObjectInfeasibilities);
3280# ifdef CBC_USE_CLP
3281  OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver);
3282  int saveClpOptions=0;
3283  bool fastIterations = (model->specialOptions()&8)!=0;
3284  if (osiclp&&fastIterations) {
3285    // for faster hot start
3286    saveClpOptions = osiclp->specialOptions();
3287    osiclp->setSpecialOptions(saveClpOptions|1024);
3288  }
3289# else
3290  bool fastIterations = false ;
3291# endif
3292  /*
3293    Scan for branching objects that indicate infeasibility. Choose candidates
3294    using priority as the first criteria, then integer infeasibility.
3295   
3296    The algorithm is to fill the array with a set of good candidates (by
3297    infeasibility) with priority bestPriority.  Finding a candidate with
3298    priority better (less) than bestPriority flushes the choice array. (This
3299    serves as initialization when the first candidate is found.)
3300   
3301  */
3302  numberToDo=0;
3303  for (i=0;i<numberObjects;i++) {
3304    CbcObject * object = model->modifiableObject(i);
3305    CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
3306      dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
3307    if(!dynamicObject)
3308      continue;
3309    int preferredWay;
3310    double infeasibility = object->infeasibility(preferredWay);
3311    int iColumn = dynamicObject->columnNumber();
3312    if (saveUpper[iColumn]==saveLower[iColumn])
3313      continue;
3314    if (infeasibility)
3315      sort[numberToDo]=-1.0e10-infeasibility;
3316    else
3317      sort[numberToDo]=-fabs(dj[iColumn]);
3318    whichObject[numberToDo++]=i;
3319  }
3320  // Save basis
3321  CoinWarmStart * ws = solver->getWarmStart();
3322  int saveLimit;
3323  solver->getIntParam(OsiMaxNumIterationHotStart,saveLimit);
3324  int targetIterations = CoinMax(500,numberIterationsAllowed/numberObjects);
3325  if (saveLimit<targetIterations)
3326    solver->setIntParam(OsiMaxNumIterationHotStart,targetIterations); 
3327  // Mark hot start
3328  solver->markHotStart();
3329  // Sort
3330  CoinSort_2(sort,sort+numberToDo,whichObject);
3331  //double distanceToCutoff=model->getCutoff()-objectiveValue_;
3332  double * currentSolution = model->currentSolution();
3333  double integerTolerance = 
3334    model->getDblParam(CbcModel::CbcIntegerTolerance);
3335  double objMin = 1.0e50;
3336  double objMax = -1.0e50;
3337  bool needResolve=false;
3338  int iDo;
3339  for (iDo=0;iDo<numberToDo;iDo++) {
3340    CbcStrongInfo choice;
3341    int iObject = whichObject[iDo];
3342    CbcObject * object = model->modifiableObject(iObject);
3343    CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
3344      dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
3345    int iColumn = dynamicObject->columnNumber();
3346    int preferredWay;
3347    object->infeasibility(preferredWay);
3348    double value = currentSolution[iColumn];
3349    double nearest = floor(value+0.5);
3350    double lowerValue = floor(value);
3351    bool satisfied=false;
3352    if (fabs(value-nearest)<=integerTolerance||value<saveLower[iColumn]||value>saveUpper[iColumn]) {
3353      satisfied=true;
3354      double newValue;
3355      if (nearest<saveUpper[iColumn]) {
3356        newValue = nearest + 1.0001*integerTolerance;
3357        lowerValue = nearest;
3358      } else {
3359        newValue = nearest - 1.0001*integerTolerance;
3360        lowerValue = nearest-1;
3361      }
3362      currentSolution[iColumn]=newValue;
3363    }
3364    double upperValue = lowerValue+1.0;
3365    choice.possibleBranch=object->createBranch(preferredWay);
3366    currentSolution[iColumn]=value;
3367    // Save which object it was
3368    choice.objectNumber=iObject;
3369    choice.numIntInfeasUp = numberUnsatisfied_;
3370    choice.numIntInfeasDown = numberUnsatisfied_;
3371    choice.downMovement = 0.0;
3372    choice.upMovement = 0.0;
3373    choice.numItersDown = 0;
3374    choice.numItersUp = 0;
3375    choice.fix=0; // say not fixed
3376    double objectiveChange ;
3377    double newObjectiveValue=1.0e100;
3378    int j;
3379    // status is 0 finished, 1 infeasible and other
3380    int iStatus;
3381    /*
3382      Try the down direction first. (Specify the initial branching alternative as
3383      down with a call to way(-1). Each subsequent call to branch() performs the
3384      specified branch and advances the branch object state to the next branch
3385      alternative.)
3386    */
3387    choice.possibleBranch->way(-1) ;
3388    choice.possibleBranch->branch() ;
3389    if (fabs(value-lowerValue)>integerTolerance) {
3390      solver->solveFromHotStart() ;
3391      /*
3392        We now have an estimate of objective degradation that we can use for strong
3393        branching. If we're over the cutoff, the variable is monotone up.
3394        If we actually made it to optimality, check for a solution, and if we have
3395        a good one, call setBestSolution to process it. Note that this may reduce the
3396        cutoff, so we check again to see if we can declare this variable monotone.
3397      */
3398      if (solver->isProvenOptimal())
3399        iStatus=0; // optimal
3400      else if (solver->isIterationLimitReached()
3401               &&!solver->isDualObjectiveLimitReached())
3402        iStatus=2; // unknown
3403      else
3404        iStatus=1; // infeasible
3405      newObjectiveValue = solver->getObjSense()*solver->getObjValue();
3406      choice.numItersDown = solver->getIterationCount();
3407      numberIterationsAllowed -= choice.numItersDown;
3408      objectiveChange = newObjectiveValue  - objectiveValue_;
3409      if (!iStatus) {
3410        choice.finishedDown = true ;
3411        if (newObjectiveValue>=cutoff) {
3412          objectiveChange = 1.0e100; // say infeasible
3413        } else {
3414          // See if integer solution
3415          if (model->feasibleSolution(choice.numIntInfeasDown,
3416                                      choice.numObjInfeasDown)
3417              &&model->problemFeasibility()->feasible(model,-1)>=0) {
3418            model->setBestSolution(CBC_STRONGSOL,
3419                                   newObjectiveValue,
3420                                   solver->getColSolution()) ;
3421            model->setLastHeuristic(NULL);
3422            model->incrementUsed(solver->getColSolution());
3423            cutoff =model->getCutoff();
3424            if (newObjectiveValue >= cutoff)    //  *new* cutoff
3425              objectiveChange = 1.0e100 ;
3426          }
3427        }
3428      } else if (iStatus==1) {
3429        objectiveChange = 1.0e100 ;
3430      } else {
3431        // Can't say much as we did not finish
3432        choice.finishedDown = false ;
3433      }
3434      choice.downMovement = objectiveChange ;
3435    }
3436    // restore bounds
3437    for ( j=0;j<numberColumns;j++) {
3438      if (saveLower[j] != lower[j])
3439        solver->setColLower(j,saveLower[j]);
3440      if (saveUpper[j] != upper[j])
3441        solver->setColUpper(j,saveUpper[j]);
3442    }
3443    // repeat the whole exercise, forcing the variable up
3444    choice.possibleBranch->branch();
3445    if (fabs(value-upperValue)>integerTolerance) {
3446      solver->solveFromHotStart() ;
3447      /*
3448        We now have an estimate of objective degradation that we can use for strong
3449        branching. If we're over the cutoff, the variable is monotone up.
3450        If we actually made it to optimality, check for a solution, and if we have
3451        a good one, call setBestSolution to process it. Note that this may reduce the
3452        cutoff, so we check again to see if we can declare this variable monotone.
3453      */
3454      if (solver->isProvenOptimal())
3455        iStatus=0; // optimal
3456      else if (solver->isIterationLimitReached()
3457               &&!solver->isDualObjectiveLimitReached())
3458        iStatus=2; // unknown
3459      else
3460        iStatus=1; // infeasible
3461      newObjectiveValue = solver->getObjSense()*solver->getObjValue();
3462      choice.numItersUp = solver->getIterationCount();
3463      numberIterationsAllowed -= choice.numItersUp;
3464      objectiveChange = newObjectiveValue  - objectiveValue_;
3465      if (!iStatus) {
3466        choice.finishedUp = true ;
3467        if (newObjectiveValue>=cutoff) {
3468          objectiveChange = 1.0e100; // say infeasible
3469        } else {
3470          // See if integer solution
3471          if (model->feasibleSolution(choice.numIntInfeasUp,
3472                                      choice.numObjInfeasUp)
3473              &&model->problemFeasibility()->feasible(model,-1)>=0) {
3474            model->setBestSolution(CBC_STRONGSOL,
3475                                   newObjectiveValue,
3476                                   solver->getColSolution()) ;
3477            model->setLastHeuristic(NULL);
3478            model->incrementUsed(solver->getColSolution());
3479            cutoff =model->getCutoff();
3480            if (newObjectiveValue >= cutoff)    //  *new* cutoff
3481              objectiveChange = 1.0e100 ;
3482          }
3483        }
3484      } else if (iStatus==1) {
3485        objectiveChange = 1.0e100 ;
3486      } else {
3487        // Can't say much as we did not finish
3488        choice.finishedUp = false ;
3489      }
3490      choice.upMovement = objectiveChange ;
3491     
3492      // restore bounds
3493      for ( j=0;j<numberColumns;j++) {
3494        if (saveLower[j] != lower[j])
3495          solver->setColLower(j,saveLower[j]);
3496        if (saveUpper[j] != upper[j])
3497          solver->setColUpper(j,saveUpper[j]);
3498      }
3499    }
3500    // If objective goes above certain amount we can set bound
3501    int jInt = back[iColumn];
3502    newLower[jInt]=upperValue;
3503    if (choice.finishedDown||!fastIterations)
3504      objLower[jInt]=choice.downMovement+objectiveValue_;
3505    else
3506      objLower[jInt]=objectiveValue_;
3507    newUpper[jInt]=lowerValue;
3508    if (choice.finishedUp||!fastIterations)
3509      objUpper[jInt]=choice.upMovement+objectiveValue_;
3510    else
3511      objUpper[jInt]=objectiveValue_;
3512    objMin = CoinMin(CoinMin(objLower[jInt],objUpper[jInt]),objMin);
3513    /*
3514      End of evaluation for this candidate variable. Possibilities are:
3515      * Both sides below cutoff; this variable is a candidate for branching.
3516      * Both sides infeasible or above the objective cutoff: no further action
3517      here. Break from the evaluation loop and assume the node will be purged
3518      by the caller.
3519      * One side below cutoff: Install the branch (i.e., fix the variable). Break
3520      from the evaluation loop and assume the node will be reoptimised by the
3521      caller.
3522    */
3523    if (choice.upMovement<1.0e100) {
3524      if(choice.downMovement<1.0e100) {
3525        objMax = CoinMax(CoinMax(objLower[jInt],objUpper[jInt]),objMax);
3526        // In case solution coming in was odd
3527        choice.upMovement = CoinMax(0.0,choice.upMovement);
3528        choice.downMovement = CoinMax(0.0,choice.downMovement);
3529        // feasible -
3530        model->messageHandler()->message(CBC_STRONG,model->messages())
3531          << iObject << iColumn
3532          <<choice.downMovement<<choice.numIntInfeasDown
3533          <<choice.upMovement<<choice.numIntInfeasUp
3534          <<value
3535          <<CoinMessageEol;
3536      } else {
3537        // up feasible, down infeasible
3538        anyAction=-1;
3539        if (!satisfied)
3540          needResolve=true;
3541        choice.fix=1;
3542        numberToFix++;
3543        saveLower[iColumn]=upperValue;
3544        solver->setColLower(iColumn,upperValue);
3545      }
3546    } else {
3547      if(choice.downMovement<1.0e100) {
3548        // down feasible, up infeasible
3549        anyAction=-1;
3550        if (!satisfied)
3551          needResolve=true;
3552        choice.fix=-1;
3553        numberToFix++;
3554        saveUpper[iColumn]=lowerValue;
3555        solver->setColUpper(iColumn,lowerValue);
3556      } else {
3557        // neither side feasible
3558        anyAction=-2;
3559        printf("Both infeasible for choice %d sequence %d\n",i,
3560               model->object(choice.objectNumber)->columnNumber());
3561        delete ws;
3562        ws=NULL;
3563        solver->writeMps("bad");
3564        numberToFix=-1;
3565        delete choice.possibleBranch;
3566        choice.possibleBranch=NULL;
3567        break;
3568      }
3569    }
3570    delete choice.possibleBranch;
3571    if (numberIterationsAllowed<=0)
3572      break;
3573    //printf("obj %d, col %d, down %g up %g value %g\n",iObject,iColumn,
3574    //     choice.downMovement,choice.upMovement,value);
3575  }
3576  printf("Best possible solution %g, can fix more if solution of %g found - looked at %d variables in %d iterations\n",
3577         objMin,objMax,iDo,model->numberAnalyzeIterations()-numberIterationsAllowed);
3578  model->setNumberAnalyzeIterations(numberIterationsAllowed);
3579  // Delete the snapshot
3580  solver->unmarkHotStart();
3581  // back to normal
3582  solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
3583  solver->setIntParam(OsiMaxNumIterationHotStart,saveLimit);
3584  // restore basis
3585  solver->setWarmStart(ws);
3586  delete ws;
3587   
3588  delete [] sort;
3589  delete [] whichObject;
3590  delete [] saveLower;
3591  delete [] saveUpper;
3592  delete [] back;
3593  // restore solution
3594  solver->setColSolution(saveSolution);
3595# ifdef CBC_USE_CLP
3596  if (osiclp) 
3597    osiclp->setSpecialOptions(saveClpOptions);
3598# endif
3599  model->reserveCurrentSolution(saveSolution);
3600  delete [] saveSolution;
3601  if (needResolve)
3602    solver->resolve();
3603  return numberToFix;
3604}
3605
3606
3607CbcNode::CbcNode(const CbcNode & rhs) 
3608{ 
3609#ifdef CHECK_NODE
3610  printf("CbcNode %x Constructor from rhs %x\n",this,&rhs);
3611#endif
3612  if (rhs.nodeInfo_)
3613    nodeInfo_ = rhs.nodeInfo_->clone();
3614  else
3615    nodeInfo_=NULL;
3616  objectiveValue_=rhs.objectiveValue_;
3617  guessedObjectiveValue_ = rhs.guessedObjectiveValue_;
3618  if (rhs.branch_)
3619    branch_=rhs.branch_->clone();
3620  else
3621    branch_=NULL;
3622  depth_ = rhs.depth_;
3623  numberUnsatisfied_ = rhs.numberUnsatisfied_;
3624}
3625
3626CbcNode &
3627CbcNode::operator=(const CbcNode & rhs)
3628{
3629  if (this != &rhs) {
3630    delete nodeInfo_;
3631    if (nodeInfo_)
3632      nodeInfo_ = rhs.nodeInfo_->clone();
3633    else
3634      nodeInfo_ = NULL;
3635    objectiveValue_=rhs.objectiveValue_;
3636    guessedObjectiveValue_ = rhs.guessedObjectiveValue_;
3637    if (rhs.branch_)
3638      branch_=rhs.branch_->clone();
3639    else
3640      branch_=NULL,
3641    depth_ = rhs.depth_;
3642    numberUnsatisfied_ = rhs.numberUnsatisfied_;
3643  }
3644  return *this;
3645}
3646
3647
3648CbcNode::~CbcNode ()
3649{
3650#ifdef CHECK_NODE
3651  if (nodeInfo_) 
3652    printf("CbcNode %x Destructor nodeInfo %x (%d)\n",
3653         this,nodeInfo_,nodeInfo_->numberPointingToThis());
3654  else
3655    printf("CbcNode %x Destructor nodeInfo %x (?)\n",
3656         this,nodeInfo_);
3657#endif
3658  if (nodeInfo_) {
3659    nodeInfo_->nullOwner();
3660    int numberToDelete=nodeInfo_->numberBranchesLeft();
3661    //    CbcNodeInfo * parent = nodeInfo_->parent();
3662    if (nodeInfo_->decrement(numberToDelete)==0) {
3663      delete nodeInfo_;
3664    } else {
3665      //printf("node %x nodeinfo %x parent %x\n",this,nodeInfo_,parent);
3666      // anyway decrement parent
3667      //if (parent)
3668      ///parent->decrement(1);
3669    }
3670  }
3671  delete branch_;
3672}
3673// Decrement  active cut counts
3674void 
3675CbcNode::decrementCuts(int change)
3676{
3677  if(nodeInfo_) {
3678    nodeInfo_->decrementCuts(change);
3679  }
3680}
3681void 
3682CbcNode::decrementParentCuts(int change)
3683{
3684  if(nodeInfo_) {
3685    nodeInfo_->decrementParentCuts(change);
3686  }
3687}
3688
3689/*
3690  Initialize reference counts (numberPointingToThis, numberBranchesLeft_)
3691  in the attached nodeInfo_.
3692*/
3693void
3694CbcNode::initializeInfo()
3695{
3696  assert(nodeInfo_ && branch_) ;
3697  nodeInfo_->initializeInfo(branch_->numberBranches());
3698}
3699// Nulls out node info
3700void 
3701CbcNode::nullNodeInfo()
3702{
3703  nodeInfo_=NULL;
3704}
3705
3706int
3707CbcNode::branch()
3708{
3709  double changeInGuessed=branch_->branch(true);
3710  guessedObjectiveValue_+= changeInGuessed;
3711  //#define PRINTIT
3712#ifdef PRINTIT
3713  int numberLeft = nodeInfo_->numberBranchesLeft();
3714  CbcNodeInfo * parent = nodeInfo_->parent();
3715  int parentNodeNumber = -1;
3716  //CbcBranchingObject * object1 = branch_->object_;
3717  //CbcObject * object = object1->
3718  //int sequence = object->columnNumber);
3719  int id=-1;
3720  double value=0.0;
3721  if (branch_) {
3722    id = branch_->variable();
3723    value = branch_->value();
3724  }
3725  printf("id %d value %g objvalue %g\n",id,value,objectiveValue_);
3726  if (parent)
3727    parentNodeNumber = parent->nodeNumber();
3728  printf("Node number %d, %s, way %d, depth %d, parent node number %d\n",
3729         nodeInfo_->nodeNumber(),(numberLeft==2) ? "leftBranch" : "rightBranch",
3730         way(),depth_,parentNodeNumber);
3731#endif
3732  return nodeInfo_->branchedOn();
3733}
Note: See TracBrowser for help on using the repository browser.