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

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

fix bug in gamstest

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