source: stable/2.0/Cbc/src/CbcNode.cpp @ 844

Last change on this file since 844 was 844, checked in by forrest, 13 years ago

make useSolution work better

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