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

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

changes to use heuristics with SOS etc

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 186.2 KB
Line 
1// Copyright (C) 2002, International Business Machines
2// Corporation and others.  All Rights Reserved.
3#if defined(_MSC_VER)
4// Turn off compiler warning about long names
5#  pragma warning(disable:4786)
6#endif
7
8#include "CbcConfig.h"
9
10#include <string>
11//#define CBC_DEBUG 1
12//#define CHECK_CUT_COUNTS
13//#define CHECK_NODE
14//#define CBC_CHECK_BASIS
15#define CBC_WEAK_STRONG
16#include <cassert>
17#include <cfloat>
18#define CUTS
19#include "OsiSolverInterface.hpp"
20#include "OsiChooseVariable.hpp"
21#include "OsiAuxInfo.hpp"
22#include "OsiSolverBranch.hpp"
23#include "CoinWarmStartBasis.hpp"
24#include "CoinTime.hpp"
25#include "CbcModel.hpp"
26#include "CbcNode.hpp"
27#include "CbcStatistics.hpp"
28#include "CbcStrategy.hpp"
29#include "CbcBranchActual.hpp"
30#include "CbcBranchDynamic.hpp"
31#include "OsiRowCut.hpp"
32#include "OsiRowCutDebugger.hpp"
33#include "OsiCuts.hpp"
34#include "CbcCountRowCut.hpp"
35#include "CbcFeasibilityBase.hpp"
36#include "CbcMessage.hpp"
37#ifdef COIN_HAS_CLP
38#include "OsiClpSolverInterface.hpp"
39#include "ClpSimplexOther.hpp"
40#endif
41using namespace std;
42#include "CglCutGenerator.hpp"
43// Default Constructor
44CbcNodeInfo::CbcNodeInfo ()
45  :
46  numberPointingToThis_(0),
47  parent_(NULL),
48  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 = false;
2413  if (numberObjects>model->numberIntegers()) {
2414    for (int i=model->numberIntegers();i<numberObjects;i++) {
2415      OsiObject * object = model->modifiableObject(i);
2416      CbcObject * obj = dynamic_cast <CbcObject *>(object) ;
2417      if (!obj || !obj->optionalObject()) {
2418        checkFeasibility=true;
2419        break;
2420      }
2421    }
2422  }
2423  if ((model->specialOptions()&128)!=0)
2424    checkFeasibility=false; // allow
2425  // For now return if not simple
2426  if (checkFeasibility)
2427    return -3;
2428  // point to useful information
2429  OsiBranchingInformation usefulInfo = model->usefulInformation();
2430  // and modify
2431  usefulInfo.depth_=depth_;
2432  if ((model->specialOptions()&128)!=0) {
2433    // SOS - shadow prices
2434    int numberRows = solver->getNumRows();
2435    const double * pi = usefulInfo.pi_;
2436    double sumPi=0.0;
2437    for (int i=0;i<numberRows;i++) 
2438      sumPi += fabs(pi[i]);
2439    sumPi /= static_cast<double> (numberRows);
2440    // and scale back
2441    sumPi *= 0.01;
2442    usefulInfo.defaultDual_ = sumPi; // switch on
2443    int numberColumns = solver->getNumCols();
2444    int size = CoinMax(numberColumns,2*numberRows);
2445    usefulInfo.usefulRegion_ = new double [size];
2446    CoinZeroN(usefulInfo.usefulRegion_,size);
2447    usefulInfo.indexRegion_ = new int [size];
2448    // pi may change
2449    usefulInfo.pi_=CoinCopyOfArray(usefulInfo.pi_,numberRows);
2450  }
2451  assert (auxiliaryInfo);
2452  //assert(objectiveValue_ == solver->getObjSense()*solver->getObjValue());
2453  double cutoff =model->getCutoff();
2454  double distanceToCutoff=cutoff-objectiveValue_;
2455  const double * lower = solver->getColLower();
2456  const double * upper = solver->getColUpper();
2457  //const double * objective = solver->getObjCoefficients();
2458  // See what user thinks
2459  int anyAction=model->problemFeasibility()->feasible(model,0);
2460  if (anyAction) {
2461    // will return -2 if infeasible , 0 if treat as integer
2462    return anyAction-1;
2463  }
2464  int i;
2465  int saveStateOfSearch = model->stateOfSearch()%10;
2466  int numberStrong=model->numberStrong();
2467  //if (!auxiliaryInfo->warmStart())
2468  //numberStrong=0;
2469  // But make more likely to get out after some times
2470  int changeStrategy=numberStrong;
2471  double changeFactor=1.0;
2472  // Use minimum of this and one stored in objects
2473  //int numberBeforeTrust = model->numberBeforeTrust();
2474  // Return if doing hot start (in BAB sense)
2475  if (model->hotstartSolution()) 
2476    return -3;
2477  //#define RANGING
2478#ifdef RANGING
2479  // Pass number
2480  int kPass=0;
2481  int numberRows = solver->getNumRows();
2482#endif
2483  int numberColumns = model->getNumCols();
2484  double * saveUpper = new double[numberColumns];
2485  double * saveLower = new double[numberColumns];
2486
2487  // Save solution in case heuristics need good solution later
2488 
2489  double * saveSolution = new double[numberColumns];
2490  memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
2491  model->reserveCurrentSolution(saveSolution);
2492  if (false) {
2493        OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver);
2494        const double * sol = osiclp->getColSolution();
2495        int n = osiclp->getNumCols();
2496        for (int i=0;i<n;i++) {
2497          double sC = sol[i];
2498          double sS = saveSolution[i];
2499          double sU = usefulInfo.solution_[i];
2500          if (fabs(sC-sS)>1.0e-5||fabs(sC-sU)>1.0e-5)
2501            printf("DiffA %d clp %g saved %g useful %g\n",
2502                   i,sC,sS,sU);
2503        }
2504  }
2505  /*
2506    Get a branching decision object. Use the default dynamic decision criteria unless
2507    the user has loaded a decision method into the model.
2508  */
2509  CbcBranchDecision *decision = model->branchingMethod();
2510  if (!decision)
2511    decision = new CbcBranchDynamicDecision();
2512  int numberMini=0;
2513  int xPen=0;
2514  int xMark=0;
2515  for (i=0;i<numberColumns;i++) {
2516    saveLower[i] = lower[i];
2517    saveUpper[i] = upper[i];
2518  }
2519  // Get arrays to sort
2520  double * sort = new double[numberObjects];
2521  int * whichObject = new int[numberObjects];
2522  int * objectMark = new int[2*numberObjects+1];
2523  // Arrays with movements
2524  double * upEstimate = new double[numberObjects];
2525  double * downEstimate = new double[numberObjects];
2526  CbcStrongInfo * fixObject = new CbcStrongInfo[numberObjects];
2527  double estimatedDegradation=0.0; 
2528  int numberNodes=model->getNodeCount();
2529  int saveLogLevel = model->logLevel();
2530  if ((numberNodes%500)==0&&false) {
2531    model->setLogLevel(6);
2532    // Get average up and down costs
2533    double averageUp=0.0;
2534    double averageDown=0.0;
2535    int numberUp=0;
2536    int numberDown=0;
2537    int i;
2538    for ( i=0;i<numberObjects;i++) {
2539      OsiObject * object = model->modifiableObject(i);
2540#ifndef NDEBUG
2541      CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
2542        dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
2543      assert(dynamicObject);
2544#else
2545      CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
2546        static_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
2547#endif
2548      int  numberUp2=0;
2549      int numberDown2=0;
2550      double up=0.0;
2551      double down=0.0;
2552      if (dynamicObject->numberTimesUp()) {
2553        numberUp++;
2554        averageUp += dynamicObject->upDynamicPseudoCost();
2555        numberUp2 += dynamicObject->numberTimesUp();
2556        up = dynamicObject->upDynamicPseudoCost();
2557      }
2558      if (dynamicObject->numberTimesDown()) {
2559        numberDown++;
2560        averageDown += dynamicObject->downDynamicPseudoCost();
2561        numberDown2 += dynamicObject->numberTimesDown();
2562        down = dynamicObject->downDynamicPseudoCost();
2563      }
2564      if (numberUp2||numberDown2)
2565        printf("col %d - up %d times cost %g, - down %d times cost %g\n",
2566               dynamicObject->columnNumber(),numberUp2,up,numberDown2,down);
2567    }
2568    if (numberUp) 
2569      averageUp /= static_cast<double> (numberUp);
2570    else
2571      averageUp=1.0;
2572    if (numberDown) 
2573      averageDown /= static_cast<double> (numberDown);
2574    else
2575      averageDown=1.0;
2576    printf("total - up %d vars average %g, - down %d vars average %g\n",
2577           numberUp,averageUp,numberDown,averageDown);
2578  }
2579  int numberBeforeTrust = model->numberBeforeTrust();
2580  int numberPenalties = model->numberPenalties();
2581  if (numberBeforeTrust>=1000000) {
2582    numberBeforeTrust = numberBeforeTrust % 1000000;
2583    numberPenalties=0;
2584  } else if (numberBeforeTrust<0) {
2585    if (numberBeforeTrust==-1)
2586      numberPenalties=numberColumns;
2587    else if (numberBeforeTrust==-2)
2588      numberPenalties=0;
2589    numberBeforeTrust=0;
2590  }
2591  // May go round twice if strong branching fixes all local candidates
2592  bool finished=false;
2593  int numberToFix=0;
2594# ifdef COIN_HAS_CLP
2595  OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver);
2596  int saveClpOptions=0;
2597  if (osiclp) {
2598    // for faster hot start
2599    saveClpOptions = osiclp->specialOptions();
2600    osiclp->setSpecialOptions(saveClpOptions|8192);
2601  }
2602# else
2603  OsiSolverInterface *osiclp = NULL ;
2604# endif
2605  const CglTreeProbingInfo * probingInfo = NULL; //model->probingInfo();
2606  int saveSearchStrategy2 = model->searchStrategy();
2607#define NODE_NEW  2
2608#ifdef RANGING
2609  bool useRanging;
2610#if NODE_NEW !=3
2611  useRanging = false;
2612#else
2613  useRanging = true;
2614#endif
2615  if (saveSearchStrategy2!=2)
2616    useRanging=false;
2617#endif
2618  if (saveSearchStrategy2<999) {
2619#if NODE_NEW ==4
2620    if (saveSearchStrategy2!=2) {
2621#endif
2622    // Get average up and down costs
2623    double averageUp=0.0;
2624    double averageDown=0.0;
2625    {
2626      int numberUp=0;
2627      int numberDown=0;
2628      int i;
2629      for ( i=0;i<numberObjects;i++) {
2630        OsiObject * object = model->modifiableObject(i);
2631        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
2632          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
2633        if (dynamicObject) {
2634          if (dynamicObject->numberTimesUp()) {
2635            numberUp++;
2636            averageUp += dynamicObject->upDynamicPseudoCost();
2637          }
2638          if (dynamicObject->numberTimesDown()) {
2639            numberDown++;
2640            averageDown += dynamicObject->downDynamicPseudoCost();
2641          }
2642        }
2643      }
2644      if (numberUp) 
2645        averageUp /= static_cast<double> (numberUp);
2646      else
2647        averageUp=1.0;
2648      if (numberDown) 
2649        averageDown /= static_cast<double> (numberDown);
2650      else
2651        averageDown=1.0;
2652      for ( i=0;i<numberObjects;i++) {
2653        OsiObject * object = model->modifiableObject(i);
2654        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
2655          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
2656        if (dynamicObject) {
2657          if (!dynamicObject->numberTimesUp()) 
2658            dynamicObject->setUpDynamicPseudoCost(averageUp);
2659          if (!dynamicObject->numberTimesDown()) 
2660            dynamicObject->setDownDynamicPseudoCost(averageDown);
2661        }
2662      }
2663    }
2664#if NODE_NEW ==4
2665    } else {
2666    // pseudo shadow prices
2667    model->pseudoShadow(NULL,NULL);
2668    }
2669#endif
2670  } else if (saveSearchStrategy2<1999) {
2671    // pseudo shadow prices
2672    model->pseudoShadow(NULL,NULL);
2673  } else if (saveSearchStrategy2<2999) {
2674    // leave old ones
2675  } else if (saveSearchStrategy2<3999) {
2676    // pseudo shadow prices at root
2677    if (!numberNodes)
2678      model->pseudoShadow(NULL,NULL);
2679  } else {
2680    abort();
2681  }
2682  if (saveSearchStrategy2>=0)
2683    saveSearchStrategy2 = saveSearchStrategy2 % 1000;
2684  if (saveSearchStrategy2==999)
2685    saveSearchStrategy2=-1;
2686  int px[4]={-1,-1,-1,-1};
2687  int saveSearchStrategy = saveSearchStrategy2<99 ? saveSearchStrategy2 : saveSearchStrategy2-100;
2688  bool newWay = saveSearchStrategy2>98;
2689  int numberNotTrusted=0;
2690  int numberStrongDone=0;
2691  int numberUnfinished=0;
2692  int numberStrongInfeasible=0;
2693  int numberStrongIterations=0;
2694  // so we can save lots of news
2695  CbcStrongInfo choice;
2696  CbcDynamicPseudoCostBranchingObject * choiceObject = NULL;
2697  if (model->allDynamic()) {
2698    CbcSimpleIntegerDynamicPseudoCost * object = NULL;
2699    choiceObject=new CbcDynamicPseudoCostBranchingObject(model,0,-1,0.5,object);
2700  }
2701  choice.possibleBranch=choiceObject;
2702  int kkPass=0;
2703  //#define CBC_NODE7 1
2704#ifdef CBC_NODE7
2705  double * weightModifier = new double [2*numberColumns];
2706  CoinZeroN(weightModifier,2*numberColumns);
2707  if (usefulInfo.columnLength_) {
2708#if CBC_NODE7>1
2709    double tolerance=1.0e-6;
2710    int numberRows = solver->getNumRows();
2711    double * activeWeight = new double [numberRows];
2712    for (int iRow = 0;iRow<numberRows;iRow++) {
2713      // could use pi to see if active or activity
2714#if 1
2715      if (usefulInfo.rowActivity_[iRow]>usefulInfo.rowUpper_[iRow]-tolerance
2716          ||usefulInfo.rowActivity_[iRow]<usefulInfo.rowLower_[iRow]+tolerance) {
2717        activeWeight[iRow]=0.0;
2718      } else {
2719        activeWeight[iRow]=-1.0;
2720      }
2721#else
2722      if (fabs(usefulInfo.pi_[iRow])>1.0e-6) {
2723        activeWeight[iRow]=0.0;
2724      } else {
2725        activeWeight[iRow]=-1.0;
2726      }
2727#endif
2728    }
2729    for (int iColumn=0;iColumn<numberColumns;iColumn++) {
2730      if (solver->isInteger(iColumn)) {
2731        double solValue = usefulInfo.solution_[iColumn];
2732        if (fabs(solValue-floor(solValue+0.5))>1.0e-6) {
2733          CoinBigIndex start = usefulInfo.columnStart_[iColumn];
2734          CoinBigIndex end = start + usefulInfo.columnLength_[iColumn];
2735#ifndef NDEBUG
2736          double value = usefulInfo.direction_*usefulInfo.objective_[iColumn];
2737#endif
2738          for (CoinBigIndex j=start;j<end;j++) {
2739            int iRow = usefulInfo.row_[j];
2740#ifndef NDEBUG
2741            value -= usefulInfo.pi_[iRow] * usefulInfo.elementByColumn_[j];
2742#endif
2743            if (activeWeight[iRow]>=0.0)
2744              activeWeight[iRow] += 1.0;
2745          }
2746          assert (fabs(value)<1.0e-4);
2747        }
2748      }
2749    }
2750    for (int iRow = 0;iRow<numberRows;iRow++) {
2751      if (activeWeight[iRow]>0.0) {
2752        // could use pi
2753        activeWeight[iRow] = 1.0/activeWeight[iRow];
2754#if 0
2755        activeWeight[iRow] *= fabs(usefulInfo.pi_[iRow]);
2756#endif
2757      } else {
2758        activeWeight[iRow]=0.0;
2759      }
2760    }
2761    for (int iColumn=0;iColumn<numberColumns;iColumn++) {
2762      if (solver->isInteger(iColumn)) {
2763        double solValue = usefulInfo.solution_[iColumn];
2764        if (fabs(solValue-floor(solValue+0.5))>1.0e-6) {
2765          CoinBigIndex start = usefulInfo.columnStart_[iColumn];
2766          CoinBigIndex end = start + usefulInfo.columnLength_[iColumn];
2767          solValue -= floor(solValue);
2768#if CBC_NODE7>=3
2769          double upValue = 0.0;
2770          double downValue = 0.0;
2771          double value = usefulInfo.direction_*usefulInfo.objective_[iColumn];
2772          // Bias cost
2773          if (value>0.0)
2774            upValue += 1.5*value;
2775          else
2776            downValue -= 1.5*value;
2777          for (CoinBigIndex j=start;j<end;j++) {
2778            int iRow = usefulInfo.row_[j];
2779#if CBC_NODE7<=3
2780            value = -usefulInfo.pi_[iRow];
2781            if (value) {
2782              value *= usefulInfo.elementByColumn_[j];
2783#if CBC_NODE7==3
2784              value *= activeWeight[iRow];
2785#endif
2786              if (value>0.0)
2787                upValue += value;
2788              else
2789                downValue -= value;
2790            }
2791#else
2792            value = usefulInfo.elementByColumn_[j];
2793            double downMove = -solValue*value;
2794            double upMove = (1.0-solValue)*value;
2795            if (usefulInfo.rowActivity_[iRow]+downMove>usefulInfo.rowUpper_[iRow]-tolerance
2796                ||usefulInfo.rowActivity_[iRow]+downMove<usefulInfo.rowLower_[iRow]+tolerance) 
2797              downMove = fabs(value);
2798            else
2799              downMove = 0.0;
2800            if (usefulInfo.rowActivity_[iRow]+upMove>usefulInfo.rowUpper_[iRow]-tolerance
2801                ||usefulInfo.rowActivity_[iRow]+upMove<usefulInfo.rowLower_[iRow]+tolerance) 
2802              upMove = fabs(value);
2803            else
2804              upMove = 0.0;
2805#if CBC_NODE7==5
2806            downMove *= activeWeight[iRow];
2807            upMove *= activeWeight[iRow];
2808#endif
2809            upValue += upMove;
2810            downValue += downMove;
2811#endif
2812          }
2813          downValue = CoinMax(downValue,1.0e-8);
2814          upValue = CoinMax(upValue,1.0e-8);
2815          int put = 2*iColumn;
2816          weightModifier[put]=downValue;
2817          weightModifier[put+1]=upValue;
2818#elif CBC_NODE7==2
2819          double value=1.0e-8;
2820          for (CoinBigIndex j=start;j<end;j++) {
2821            int iRow = usefulInfo.row_[j];
2822            if (activeWeight[iRow])
2823              value += fabs(usefulInfo.elementByColumn_[j])*activeWeight[iRow];
2824          }
2825          //downValue = value*solValue;
2826          //upValue = value*(1.0-solValue);
2827          int put = 2*iColumn;
2828          weightModifier[put]=value;
2829          weightModifier[put+1]=value;
2830#endif
2831        }
2832      }
2833    }
2834#if CBC_NODE7>1
2835    delete [] activeWeight;
2836#endif
2837#else
2838    for (int iColumn=0;iColumn<numberColumns;iColumn++) {
2839      if (solver->isInteger(iColumn)) {
2840        CoinBigIndex start = usefulInfo.columnStart_[iColumn];
2841        CoinBigIndex end = start + usefulInfo.columnLength_[iColumn];
2842        double upValue = 0.0;
2843        double downValue = 0.0;
2844        double solValue = usefulInfo.solution_[iColumn];
2845        if (fabs(solValue-floor(solValue+0.5))>1.0e-6) {
2846          solValue -= floor(solValue);
2847          double value = usefulInfo.direction_*usefulInfo.objective_[iColumn];
2848          // Bias cost
2849          if (value>0.0)
2850            upValue += 1.5*value;
2851          else
2852            downValue -= 1.5*value;
2853          for (CoinBigIndex j=start;j<end;j++) {
2854            int iRow = usefulInfo.row_[j];
2855            value = -usefulInfo.pi_[iRow];
2856            if (value) {
2857              value *= usefulInfo.elementByColumn_[j];
2858              if (value>0.0)
2859                upValue += value;
2860              else
2861                downValue -= value;
2862            }
2863          }
2864          downValue = CoinMax(downValue,1.0e-8);
2865          upValue = CoinMax(upValue,1.0e-8);
2866          int put = 2*iColumn;
2867          weightModifier[put]=downValue;
2868          weightModifier[put+1]=upValue;
2869        }
2870      }
2871    }
2872#endif
2873  } else {
2874    kkPass=-1000000;
2875  }
2876#endif
2877  while(!finished) {
2878    kkPass++;
2879    finished=true;
2880    decision->initialize(model);
2881    // Some objects may compute an estimate of best solution from here
2882    estimatedDegradation=0.0; 
2883    numberToFix=0;
2884    int numberIntegerInfeasibilities=0; // without odd ones
2885    int numberToDo=0;
2886    int iBestNot=-1;
2887    int iBestGot=-1;
2888    double best=0.0;
2889    numberNotTrusted=0;
2890    numberStrongDone=0;
2891    numberUnfinished=0;
2892    numberStrongInfeasible=0;
2893    numberStrongIterations=0;
2894    int * which = objectMark+numberObjects+1;
2895    int neededPenalties;
2896    int branchingMethod=-1;
2897    // We may go round this loop three times (only if we think we have solution)
2898    for (int iPass=0;iPass<3;iPass++) {
2899
2900      if (false) {
2901        const double * sol = osiclp->getColSolution();
2902        int n = osiclp->getNumCols();
2903        for (int i=0;i<n;i++) {
2904          double sC = sol[i];
2905          double sS = saveSolution[i];
2906          double sU = usefulInfo.solution_[i];
2907          if (fabs(sC-sS)>1.0e-5||fabs(sC-sU)>1.0e-5)
2908            printf("Diff %d clp %g saved %g useful %g\n",
2909                   i,sC,sS,sU);
2910        }
2911      }
2912      // compute current state
2913      int numberObjectInfeasibilities; // just odd ones
2914      model->feasibleSolution(
2915                              numberIntegerInfeasibilities,
2916                              numberObjectInfeasibilities);
2917     
2918      // Some objects may compute an estimate of best solution from here
2919      estimatedDegradation=0.0; 
2920      numberUnsatisfied_ = 0;
2921      // initialize sum of "infeasibilities"
2922      sumInfeasibilities_ = 0.0;
2923      int bestPriority=COIN_INT_MAX;
2924      int number01 = 0;
2925      const fixEntry * entry = NULL;
2926      const int * toZero = NULL;
2927      const int * toOne = NULL;
2928      const int * backward = NULL;
2929      int numberUnsatisProbed=0;
2930      int numberUnsatisNotProbed=0; // 0-1
2931      if (probingInfo) {
2932        number01 = probingInfo->numberIntegers();
2933        entry = probingInfo->fixEntries();
2934        toZero = probingInfo->toZero();
2935        toOne = probingInfo->toOne();
2936        backward = probingInfo->backward();
2937        if (!toZero[number01]||number01<numberObjects||true) {
2938          // no info
2939          probingInfo=NULL;
2940        }
2941      }
2942      /*
2943        Scan for branching objects that indicate infeasibility. Choose candidates
2944        using priority as the first criteria, then integer infeasibility.
2945       
2946        The algorithm is to fill the array with a set of good candidates (by
2947        infeasibility) with priority bestPriority.  Finding a candidate with
2948        priority better (less) than bestPriority flushes the choice array. (This
2949        serves as initialization when the first candidate is found.)
2950       
2951      */
2952      numberToDo=0;
2953      neededPenalties=0;
2954      iBestNot=-1;
2955      double bestNot=0.0;
2956      iBestGot=-1;
2957      best=0.0;
2958      /* Problem type as set by user or found by analysis.  This will be extended
2959         0 - not known
2960         1 - Set partitioning <=
2961         2 - Set partitioning ==
2962         3 - Set covering
2963         4 - all +- 1 or all +1 and odd
2964      */
2965      int problemType = model->problemType();
2966#define PRINT_STUFF -1
2967      for (i=0;i<numberObjects;i++) {
2968        OsiObject * object = model->modifiableObject(i);
2969        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
2970          dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
2971        int preferredWay;
2972        double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
2973        int priorityLevel = object->priority();
2974#define ZERO_ONE 0
2975#define ZERO_FAKE 1.0e20;
2976#if ZERO_ONE==1
2977        // branch on 0-1 first (temp)
2978        if (fabs(saveSolution[dynamicObject->columnNumber()])<1.0)
2979          priorityLevel--;
2980#endif
2981#if ZERO_ONE==2
2982        if (fabs(saveSolution[dynamicObject->columnNumber()])<1.0)
2983          infeasibility *= ZERO_FAKE;
2984#endif
2985        if (infeasibility) {
2986          int iColumn = numberColumns+i;
2987          bool gotDown=false;
2988          int numberThisDown = 0;
2989          bool gotUp=false;
2990          int numberThisUp = 0;
2991          double downGuess=object->downEstimate();
2992          double upGuess=object->upEstimate();
2993          // check branching method
2994          if (dynamicObject) {
2995            if (branchingMethod!=dynamicObject->method()) {
2996              if (branchingMethod==-1)
2997                branchingMethod = dynamicObject->method();
2998              else
2999                branchingMethod = 100;
3000            }
3001            iColumn = dynamicObject->columnNumber();
3002            gotDown=false;
3003            numberThisDown = dynamicObject->numberTimesDown();
3004            if (numberThisDown>=numberBeforeTrust)
3005              gotDown=true;
3006            gotUp=false;
3007            numberThisUp = dynamicObject->numberTimesUp();
3008            if (numberThisUp>=numberBeforeTrust)
3009              gotUp=true;
3010            //infeasibility += 10000.0*fabs(objective[iColumn]);
3011#ifdef CBC_NODE7
3012            /*
3013              Could do for kkPass>=1
3014              Could do max just if not fully trusted
3015            */
3016            if (weightModifier&&kkPass==1) {
3017              double solValue = usefulInfo.solution_[iColumn];
3018              solValue -= floor(solValue);
3019              int get = 2*iColumn;
3020              double downValue = weightModifier[get];
3021              double upValue = weightModifier[get+1];
3022              assert (downValue>0.0&&upValue>0.0);
3023              downGuess = downValue * solValue;
3024              upGuess = upValue * (1.0-solValue);
3025#if 0
3026              printf("%d inf %g ord %g %g shadow %g %g\n",
3027                     iColumn,infeasibility,
3028                     object->downEstimate(),object->upEstimate(),
3029                     downGuess,upGuess);
3030#endif
3031              double useInfeasibility = 0.9*CoinMin(downGuess,upGuess)
3032                + 0.1*CoinMax(downGuess,upGuess);
3033#if CBC_NODE7>=3
3034#if 1
3035              if (numberThisUp<10||numberThisDown<10)
3036                //if (!gotUp||!gotDown)
3037                infeasibility = CoinMax(useInfeasibility,infeasibility);
3038              else
3039                infeasibility = CoinMax(0.1*useInfeasibility,infeasibility);
3040#else
3041              if (!numberThisUp&&!numberThisDown)
3042                infeasibility = CoinMax(useInfeasibility,infeasibility);
3043              else
3044                infeasibility += 0.1*useInfeasibility;
3045#endif
3046#else
3047
3048#if 1
3049              infeasibility = useInfeasibility;
3050#else
3051#if 1
3052              if (numberThisUp<10||numberThisDown<10)
3053                infeasibility = CoinMax(useInfeasibility,infeasibility);
3054              else
3055                infeasibility = CoinMax(0.1*useInfeasibility,infeasibility);
3056#else
3057              infeasibility *= weightModifier[2*iColumn];
3058#endif
3059#endif
3060#endif
3061            }
3062#endif
3063            //double gap = saveUpper[iColumn]-saveLower[iColumn];
3064            // Give precedence to ones with gap of 1.0
3065            //assert(gap>0.0);
3066            //infeasibility /= CoinMin(gap,100.0);
3067            if (!depth_&&false) {
3068              // try closest to 0.5
3069              double part =saveSolution[iColumn]-floor(saveSolution[iColumn]);
3070              infeasibility = fabs(0.5-part);
3071            }
3072            if (problemType>0&&problemType<4&&false) {
3073              // try closest to 0.5
3074              double part =saveSolution[iColumn]-floor(saveSolution[iColumn]);
3075              infeasibility = 0.5-fabs(0.5-part);
3076            }
3077            if (probingInfo) {
3078              int iSeq = backward[iColumn];
3079              assert (iSeq>=0);
3080              infeasibility = 1.0 + (toZero[iSeq+1]-toZero[iSeq])+ 
3081                5.0*CoinMin(toOne[iSeq]-toZero[iSeq],toZero[iSeq+1]-toOne[iSeq]);
3082              if (toZero[iSeq+1]>toZero[iSeq]) {
3083                numberUnsatisProbed++;
3084              } else {
3085                numberUnsatisNotProbed++;
3086              }
3087            }
3088            if ((numberNodes%PRINT_STUFF)==0&&PRINT_STUFF>0)
3089              printf("%d down %d %g up %d %g - infeas %g\n",
3090                     i,numberThisDown,object->downEstimate(),numberThisUp,object->upEstimate(),
3091                     infeasibility);
3092          } else {
3093            // see if SOS
3094            CbcSOS * sosObject =
3095              dynamic_cast <CbcSOS *>(object) ;
3096            if (sosObject) {
3097              gotDown=false;
3098              numberThisDown = sosObject->numberTimesDown();
3099              if (numberThisDown>=numberBeforeTrust)
3100                gotDown=true;
3101              gotUp=false;
3102              numberThisUp = sosObject->numberTimesUp();
3103              if (numberThisUp>=numberBeforeTrust)
3104                gotUp=true;
3105            } else {
3106              gotDown=true;
3107              numberThisDown=999999;
3108              downGuess=1.0e20;
3109              gotUp=true;
3110              numberThisUp=999999;
3111              upGuess=1.0e20;
3112              numberPassesLeft=0;
3113            }
3114          }
3115          // Increase estimated degradation to solution
3116          estimatedDegradation += CoinMin(downGuess,upGuess);
3117          downEstimate[i]=downGuess;
3118          upEstimate[i]=upGuess;
3119          numberUnsatisfied_++;
3120          sumInfeasibilities_ += infeasibility;
3121          // Better priority? Flush choices.
3122          if (priorityLevel<bestPriority) {
3123            numberToDo=0;
3124            bestPriority = priorityLevel;
3125            iBestGot=-1;
3126            best=0.0;
3127            numberNotTrusted=0;
3128          } else if (priorityLevel>bestPriority) {
3129            continue;
3130          }
3131          if (!gotUp||!gotDown)
3132            numberNotTrusted++;
3133          // Check for suitability based on infeasibility.
3134          if ((gotDown&&gotUp)&&numberStrong>0) {
3135            sort[numberToDo]=-infeasibility;
3136            if (infeasibility>best) {
3137              best=infeasibility;
3138              iBestGot=numberToDo;
3139            }
3140          } else {
3141            objectMark[neededPenalties]=numberToDo;
3142            which[neededPenalties++]=iColumn;
3143            sort[numberToDo]=-10.0*infeasibility;
3144            if (!(numberThisUp+numberThisDown))
3145              sort[numberToDo] *= 100.0; // make even more likely
3146            if (iColumn<numberColumns) {
3147              double part =saveSolution[iColumn]-floor(saveSolution[iColumn]);
3148              if (1.0-fabs(part-0.5)>bestNot) {
3149                iBestNot=numberToDo;
3150                bestNot = 1.0-fabs(part-0.5);
3151              }
3152            } else {
3153              // SOS
3154              if (-sort[numberToDo]>bestNot) {
3155                iBestNot=numberToDo;
3156                bestNot = -sort[numberToDo];
3157              }
3158            }
3159          }
3160          if (model->messageHandler()->logLevel()>3) { 
3161            printf("%d (%d) down %d %g up %d %g - infeas %g - sort %g solution %g\n",
3162                   i,iColumn,numberThisDown,object->downEstimate(),numberThisUp,object->upEstimate(),
3163                   infeasibility,sort[numberToDo],saveSolution[iColumn]);
3164          }
3165          whichObject[numberToDo++]=i;
3166        } else {
3167          // for debug
3168          downEstimate[i]=-1.0;
3169          upEstimate[i]=-1.0;
3170        }
3171      }
3172      if (numberUnsatisfied_) {
3173        if (probingInfo&&false)
3174          printf("nunsat %d, %d probed, %d other 0-1\n",numberUnsatisfied_,
3175                 numberUnsatisProbed,numberUnsatisNotProbed);
3176        // some infeasibilities - go to next steps
3177        break;
3178      } else if (!iPass) {
3179        // may just need resolve
3180        model->resolve(NULL,11,saveSolution,saveLower,saveUpper);
3181        if (!solver->isProvenOptimal()) {
3182          // infeasible
3183          anyAction=-2;
3184          break;
3185        }
3186      } else if (iPass==1) {
3187        // looks like a solution - get paranoid
3188        bool roundAgain=false;
3189        // get basis
3190        CoinWarmStartBasis * ws = dynamic_cast<CoinWarmStartBasis*>(solver->getWarmStart());
3191        if (!ws)
3192          break;
3193        double tolerance;
3194        solver->getDblParam(OsiPrimalTolerance,tolerance);
3195        for (i=0;i<numberColumns;i++) {
3196          double value = saveSolution[i];
3197          if (value<lower[i]-tolerance) {
3198            saveSolution[i]=lower[i];
3199            roundAgain=true;
3200            ws->setStructStatus(i,CoinWarmStartBasis::atLowerBound);
3201          } else if (value>upper[i]+tolerance) {
3202            saveSolution[i]=upper[i];
3203            roundAgain=true;
3204            ws->setStructStatus(i,CoinWarmStartBasis::atUpperBound);
3205          } 
3206        }
3207        if (roundAgain) {
3208          // restore basis
3209          solver->setWarmStart(ws);
3210          solver->setColSolution(saveSolution);
3211          delete ws;
3212          bool takeHint;
3213          OsiHintStrength strength;
3214          solver->getHintParam(OsiDoDualInResolve,takeHint,strength);
3215          solver->setHintParam(OsiDoDualInResolve,false,OsiHintDo) ;
3216          model->resolve(NULL,11,saveSolution,saveLower,saveUpper);
3217          solver->setHintParam(OsiDoDualInResolve,takeHint,strength) ;
3218          if (!solver->isProvenOptimal()) {
3219            // infeasible
3220            anyAction=-2;
3221            break;
3222          }
3223        } else {
3224          delete ws;
3225          break;
3226        }
3227      }
3228    }
3229    if (anyAction==-2) {
3230      break;
3231    }
3232    bool solveAll=false; // set true to say look at all even if some fixed (experiment)
3233    solveAll=true;
3234    // skip if solution
3235    if (!numberUnsatisfied_)
3236      break;
3237    //bool skipAll = (numberBeforeTrust>20&&numberNodes>20000&&numberNotTrusted==0);
3238    int skipAll = (numberNotTrusted==0||numberToDo==1) ? 1 : 0;
3239    bool doneHotStart=false;
3240    int searchStrategy = saveSearchStrategy>=0 ? (saveSearchStrategy%10) : -1;
3241    if (0) {
3242      int numberIterations = model->getIterationCount();
3243      int numberStrongIterations = model->numberStrongIterations();
3244      printf("node %d saveSearch %d search %d - its %d strong %d\n",
3245             numberNodes,saveSearchStrategy,searchStrategy,
3246             numberIterations,numberStrongIterations);
3247    }
3248#ifndef CBC_WEAK_STRONG
3249    if (((numberNodes%20)==0&&searchStrategy!=2)||(model->specialOptions()&8)!=0)
3250      skipAll=0;
3251#endif
3252    if (!newWay) {
3253    // 10 up always use %10, 20 up as 10 and allow penalties
3254    // But adjust depending on ratio of iterations
3255    if (searchStrategy>0&&saveSearchStrategy<10) {
3256      if (numberBeforeTrust>=5&&numberBeforeTrust<=10) {
3257        if (searchStrategy!=2) {
3258          if (depth_>5) {
3259            int numberIterations = model->getIterationCount();
3260            int numberStrongIterations = model->numberStrongIterations();
3261            if (numberStrongIterations>numberIterations+10000) {
3262              searchStrategy=2;
3263              //skipAll=1;
3264            } else if (numberStrongIterations*4+1000<numberIterations||depth_<5) {
3265              searchStrategy=3;
3266              skipAll=0;
3267            }
3268          } else {
3269            searchStrategy=3;
3270            skipAll=0;
3271          }
3272        } else {
3273          //skipAll=1;
3274        }
3275      }
3276    }
3277    } else {
3278    // But adjust depending on ratio of iterations
3279    if (saveSearchStrategy<0) {
3280      // unset
3281      if ((numberNodes%20)==0||(model->specialOptions()&8)!=0) {
3282        // Do numberStrong
3283        searchStrategy=3;
3284      } else if (depth_<5) {
3285        // Do numberStrong
3286        searchStrategy=2;
3287      } else {
3288        int numberIterations = model->getIterationCount();
3289        int numberStrongIterations = model->numberStrongIterations();
3290        int numberRows = solver->getNumRows();
3291        if (numberStrongIterations>numberIterations+CoinMin(10000,10*numberRows)) {
3292          // off
3293          searchStrategy=0;
3294        } else if (numberStrongIterations*4+1000<numberIterations) {
3295          // Do numberStrong if not trusted
3296          searchStrategy=2;
3297        } else {
3298          searchStrategy=1;
3299        }
3300      }
3301    }
3302    if (searchStrategy<3&&(!numberNotTrusted||!searchStrategy))
3303      skipAll=1;
3304    else
3305      skipAll=0;
3306    }
3307    // worth trying if too many times
3308    // Save basis
3309    CoinWarmStart * ws = NULL;
3310    // save limit
3311    int saveLimit=0;
3312    solver->getIntParam(OsiMaxNumIterationHotStart,saveLimit);
3313    if (!numberPassesLeft)
3314      skipAll=1;
3315    if (!skipAll) {
3316      ws = solver->getWarmStart();
3317      int limit=100;
3318#if 0
3319      int averageBranchIterations = model->getIterationCount()/(model->getNodeCount()+1);
3320      if (numberNodes)
3321        limit = CoinMin(CoinMax(limit,2*averageBranchIterations),500);
3322      else
3323        limit = 500;
3324#endif
3325      if ((!saveStateOfSearch||searchStrategy>3)&&saveLimit<limit&&saveLimit==100)
3326        solver->setIntParam(OsiMaxNumIterationHotStart,limit); 
3327    }
3328    // Say which one will be best
3329    int whichChoice=0;
3330    int bestChoice;
3331    if (iBestGot>=0)
3332      bestChoice=iBestGot;
3333    else
3334      bestChoice=iBestNot;
3335    assert (bestChoice>=0);
3336    // If we have hit max time don't do strong branching
3337    bool hitMaxTime = ( CoinCpuTime()-model->getDblParam(CbcModel::CbcStartSeconds) > 
3338                        model->getDblParam(CbcModel::CbcMaximumSeconds));
3339    // also give up if we are looping round too much
3340    if (hitMaxTime||numberPassesLeft<=0||(!numberNotTrusted&&false)||branchingMethod==11) {
3341      int iObject = whichObject[bestChoice];
3342      OsiObject * object = model->modifiableObject(iObject);
3343      int preferredWay;
3344      object->infeasibility(&usefulInfo,preferredWay);
3345      CbcSimpleInteger * obj =
3346        dynamic_cast <CbcSimpleInteger *>(object) ;
3347      if (obj) {
3348        branch_=obj->createBranch(solver,&usefulInfo,preferredWay);
3349      } else {
3350        CbcObject * obj =
3351          dynamic_cast <CbcObject *>(object) ;
3352        assert (obj);
3353        branch_=obj->createBranch(preferredWay);
3354      }
3355      {
3356        CbcBranchingObject * branchObj =
3357          dynamic_cast <CbcBranchingObject *>(branch_) ;
3358        assert (branchObj);
3359        branchObj->way(preferredWay);
3360      }
3361      delete ws;
3362      ws=NULL;
3363      break;
3364    } else {
3365      // say do fast
3366      int easy=1;
3367      if (!skipAll)
3368        solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,&easy) ;
3369      int iDo;
3370#ifdef RANGING
3371      if (useRanging) {
3372      if ((skipAll&&numberBeforeTrust&&saveSearchStrategy<20)||saveSearchStrategy<10)
3373        numberPenalties=0;
3374      {
3375        // off penalties if too much
3376        double needed = neededPenalties;
3377        needed *= numberRows;
3378        if (needed>1.0e6&&numberNodes&&saveSearchStrategy<20) {
3379          numberPenalties=0;
3380          neededPenalties=0;
3381        }
3382      }
3383#     ifdef COIN_HAS_CLP
3384      if (osiclp&&numberPenalties&&neededPenalties) {
3385        xPen += neededPenalties;
3386        which--;
3387        which[0]=neededPenalties;
3388        osiclp->passInRanges(which);
3389        // Mark hot start and get ranges
3390        if (kPass) {
3391          // until can work out why solution can go funny
3392          int save = osiclp->specialOptions();
3393          osiclp->setSpecialOptions(save|256);
3394          solver->markHotStart();
3395          osiclp->setSpecialOptions(save);
3396        } else {
3397          solver->markHotStart();
3398        }
3399        doneHotStart=true;
3400        xMark++;
3401        kPass++;
3402        osiclp->passInRanges(NULL);
3403        const double * downCost=osiclp->upRange();
3404        const double * upCost=osiclp->downRange();
3405        //printf("numberTodo %d needed %d numberpenalties %d\n",numberToDo,neededPenalties,numberPenalties);
3406        double invTrust = 1.0/((double) numberBeforeTrust);
3407        for (int i=0;i<neededPenalties;i++) {
3408          int j = objectMark[i];
3409          int iObject = whichObject[j];
3410          OsiObject * object = model->modifiableObject(iObject);
3411          CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
3412            static_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
3413          int iSequence=dynamicObject->columnNumber();
3414          double value = saveSolution[iSequence];
3415          value -= floor(value);
3416          double upPenalty = CoinMin(upCost[i],1.0e110)*(1.0-value);
3417          double downPenalty = CoinMin(downCost[i],1.0e110)*value;
3418          if (!numberBeforeTrust) {
3419            // override
3420            downEstimate[iObject]=downPenalty;
3421            upEstimate[iObject]=upPenalty;
3422          } else {
3423            int numberThisDown = dynamicObject->numberTimesDown();
3424            if (numberThisDown<numberBeforeTrust) {
3425              double fraction = ((double) numberThisDown)*invTrust;
3426              downEstimate[iObject] = fraction*downEstimate[iObject]+(1.0-fraction)*downPenalty;
3427            }
3428            int numberThisUp = dynamicObject->numberTimesUp();
3429            if (numberThisUp<numberBeforeTrust) {
3430              double fraction = ((double) numberThisUp)*invTrust;
3431              upEstimate[iObject] = fraction*upEstimate[iObject]+(1.0-fraction)*upPenalty;
3432            }
3433          }
3434          sort[j] = - CoinMin(downEstimate[iObject],upEstimate[iObject]);
3435#ifdef CBC_WEAK_STRONG
3436          sort[j] -= 1.0e10; // make more likely to be chosen
3437#endif
3438          //if ((numberNodes%PRINT_STUFF)==0&&PRINT_STUFF>0)
3439          if (!numberNodes)
3440            printf("%d pen down ps %g -> %g up ps %g -> %g\n",
3441                   iObject,downCost[i],downPenalty,upCost[i],upPenalty);
3442        }
3443      } else
3444#     endif     /* COIN_HAS_CLP */
3445      {
3446        if (!skipAll) {
3447          // Mark hot start
3448          solver->markHotStart();
3449          doneHotStart=true;
3450          xMark++;
3451          //if (solver->isProvenPrimalInfeasible())
3452          //printf("**** Hot start says node infeasible\n");
3453        }
3454        // make sure best will be first
3455        if (iBestGot>=0)
3456          sort[iBestGot]=-1.0e120;
3457      }
3458      } else {
3459#endif          /* RANGING */
3460#define SKIPM1
3461#ifdef SKIPM1
3462        {
3463          int numberIterations = model->getIterationCount();
3464          //numberIterations += (model->numberExtraIterations()>>2);
3465          const int * strongInfo = model->strongInfo();
3466          //int numberDone = strongInfo[0]-strongInfo[3];
3467          int numberFixed = strongInfo[1]-strongInfo[4];
3468          int numberInfeasible = strongInfo[2]-strongInfo[5];
3469          assert (!strongInfo[3]);
3470          assert (!strongInfo[4]);
3471          assert (!strongInfo[5]);
3472          int numberStrongIterations = model->numberStrongIterations();
3473          int numberRows = solver->getNumRows();
3474          if (numberStrongIterations>numberIterations+CoinMin(100,10*numberRows)&&depth_>=4&&numberNodes>100) {
3475            if (20*numberInfeasible+4*numberFixed<numberNodes) {
3476              // Say never do
3477              skipAll=-1;
3478            }
3479          } 
3480          //if (model->parentModel()&&depth_>=4)
3481          //skipAll=-1;
3482        }
3483#endif
3484      if (!skipAll) {
3485        // Mark hot start
3486        doneHotStart=true;
3487        solver->markHotStart();
3488        xMark++;
3489#ifdef CLP_INVESTIGATE
3490        if (kkPass==1&&!solver->isProvenOptimal()) {
3491          printf("Solver says infeasible on markHotStart?\n");
3492        }
3493#endif
3494      }
3495      // make sure best will be first
3496      if (iBestGot>=0)
3497        sort[iBestGot]=-COIN_DBL_MAX;
3498#ifdef RANGING
3499      }
3500#endif          /* RANGING */
3501      // Actions 0 - exit for repeat, 1 resolve and try old choice,2 exit for continue
3502#define ACTION 0
3503#if ACTION<2
3504      if (anyAction)
3505        numberToDo=0; // skip as we will be trying again
3506#endif
3507      // Sort
3508      CoinSort_2(sort,sort+numberToDo,whichObject);
3509      // Change in objective opposite infeasible
3510      double worstFeasible=0.0;
3511      // Just first if strong off
3512      if (!numberStrong)
3513        numberToDo=CoinMin(numberToDo,1);
3514#if NODE_NEW
3515      if (searchStrategy==2)
3516        numberToDo=CoinMin(numberToDo,20);
3517#endif
3518      iDo=0;
3519      int saveLimit2;
3520      solver->getIntParam(OsiMaxNumIterationHotStart,saveLimit2);
3521      bool doQuickly = false; // numberToDo>2*numberStrong;
3522      if (searchStrategy==2)
3523        doQuickly=true;
3524      //printf("todo %d, strong %d\n",numberToDo,numberStrong);
3525      int numberTest=numberNotTrusted>0 ? numberStrong : (numberStrong+1)/2;
3526      //double distanceToCutoff2 = model->getCutoff()-objectiveValue_;
3527      if (!newWay) {
3528      if (searchStrategy==3) {
3529        // Previously decided we need strong
3530        doQuickly=false;
3531        numberTest = numberStrong;
3532      }
3533      //if (searchStrategy<0||searchStrategy==1)
3534#if 0
3535      if (numberBeforeTrust>20&&(numberNodes>20000||(numberNodes>200&&numberNotTrusted==0))) {
3536        if ((numberNodes%20)!=0) {
3537          numberTest=0;
3538          doQuickly=true;
3539        }
3540      }
3541#else
3542      // Try nearly always off
3543#ifdef SKIPM1
3544      if (skipAll>=0) {
3545#endif
3546        if (searchStrategy<2) {
3547          if ((numberNodes%20)!=0) {
3548            if ((model->specialOptions()&8)==0) {
3549              numberTest=0;
3550              doQuickly=true;
3551            }
3552          } else {
3553            doQuickly=false;
3554            numberTest=2*numberStrong;
3555            skipAll=0;
3556          }
3557        } else if (searchStrategy!=3) {
3558          doQuickly=true;
3559          numberTest=numberStrong;
3560        }
3561#ifdef SKIPM1
3562      } else {
3563        // Just take first
3564        doQuickly=true;
3565        numberTest=1;
3566      }
3567#endif
3568#endif
3569#ifdef SKIPM1
3570      int testDepth = (skipAll>=0) ? 8 : 4;
3571#else
3572      int testDepth = 8;
3573#endif
3574      if (depth_<testDepth&&numberStrong) {
3575        if (searchStrategy!=2) {
3576          doQuickly=false;
3577          int numberRows = solver->getNumRows();
3578          // whether to do this or not is important - think
3579          if (numberRows<300||numberRows+numberColumns<2500) {
3580            if (depth_<7)
3581              numberStrong = CoinMin(3*numberStrong,numberToDo);
3582            if (!depth_) 
3583              numberStrong=CoinMin(6*numberStrong,numberToDo);
3584          }
3585          numberTest=numberStrong;
3586          skipAll=0;
3587        }
3588        //model->setStateOfSearch(2); // use min min
3589      }
3590      // could adjust using average iterations per branch
3591      // double average = ((double)model->getIterationCount())/
3592      //((double) model->getNodeCount()+1.0);
3593      // if too many and big then just do 10 its
3594      if (!skipAll&&saveStateOfSearch) {
3595        //if (numberNotTrusted>3*numberStrong&&numberRows>250&&numberColumns>1000&&saveLimit==100)
3596          // off solver->setIntParam(OsiMaxNumIterationHotStart,10);
3597      }
3598      // make negative for test
3599      distanceToCutoff = - distanceToCutoff;
3600      if (numberObjects>-100) {
3601        // larger
3602        distanceToCutoff *= 100.0;
3603      }
3604      distanceToCutoff = -COIN_DBL_MAX;
3605      // Do at least 5 strong
3606      if (numberColumns<1000&&(depth_<15||numberNodes<1000000))
3607        numberTest = CoinMax(numberTest,5);
3608      if ((model->specialOptions()&8)==0) {
3609        if (skipAll) {
3610          numberTest=0;
3611          doQuickly=true;
3612        }
3613      } else {
3614        // do 5 as strong is fixing
3615        numberTest = CoinMax(numberTest,5);
3616      }
3617      } else {
3618        if (!depth_&&numberToDo<200&&solver->getNumRows()<2000&&
3619            numberColumns<2000&&false) {
3620          numberStrong = numberToDo;
3621          doQuickly = false;
3622        }
3623      int numberTest=numberNotTrusted>0 ? numberStrong : (numberStrong+1)/2;
3624      if (searchStrategy>=3) {
3625        // Previously decided we need strong
3626        doQuickly=false;
3627        if (depth_<7)
3628          numberStrong *=3;
3629        if (!depth_) 
3630          numberStrong=CoinMin(6*numberStrong,numberToDo);
3631        numberTest = numberStrong;
3632      } else if (searchStrategy==2||(searchStrategy==1&&depth_<6)) {
3633        numberStrong *=2;
3634        if (!depth_) 
3635          numberStrong=CoinMin(2*numberStrong,numberToDo);
3636        numberTest = numberStrong;
3637      } else if (searchStrategy==1&&numberNotTrusted) {
3638        numberTest = numberStrong;
3639      } else {
3640        numberTest=0;
3641#ifdef SKIPM1
3642        if (skipAll==0)
3643#endif
3644          skipAll=1;
3645      }
3646      distanceToCutoff=model->getCutoff()-objectiveValue_;
3647      // make negative for test
3648      distanceToCutoff = - distanceToCutoff;
3649      if (numberObjects>-100) {
3650        // larger
3651        distanceToCutoff *= 100.0;
3652      }
3653      distanceToCutoff = -COIN_DBL_MAX;
3654      if (skipAll) {
3655        numberTest=0;
3656        doQuickly=true;
3657      }
3658      }
3659#ifdef SKIPM1
3660      // see if switched off
3661      if (skipAll<0) {
3662        newWay=false;
3663        numberTest=0;
3664        doQuickly=true;
3665      }
3666#endif
3667#if 0
3668      // temp - always switch on
3669      if (0) {
3670        int numberIterations = model->getIterationCount();
3671        int numberStrongIterations = model->numberStrongIterations();
3672        if (2*numberStrongIterations<numberIterations||depth_<=5) {
3673          skipAll=0;
3674          newWay=false;
3675          numberTest=CoinMax(numberTest,numberStrong);
3676          doQuickly=false;
3677        }
3678      }
3679#endif
3680      px[0]=numberTest;
3681      px[1]=0;
3682      px[2]= doQuickly ? 1 : -1;
3683      px[3]=numberStrong;
3684      if (!newWay) {
3685        if (numberColumns>8*solver->getNumRows()&&false) {
3686          printf("skipAll %c doQuickly %c numberTest %d numberNot %d\n",
3687                 skipAll ? 'Y' : 'N',doQuickly ? 'Y' : 'N',numberTest,numberNotTrusted);
3688          numberTest = CoinMin(numberTest,model->numberStrong());
3689          printf("new test %d\n",numberTest);
3690        }
3691      }
3692      // See if we want mini tree
3693      bool wantMiniTree=false;
3694      if (model->sizeMiniTree()&&depth_>7&&saveStateOfSearch>0)
3695        wantMiniTree=true;
3696      numberMini=0;
3697      //if (skipAll&&numberTest==0&&doQuickly)
3698      //numberToDo = 1; // trust previous stuff
3699      bool couldChooseFirst = false ; //(skipAll&&numberTest==0&&doQuickly);
3700      //skipAll=false;
3701      int realMaxHotIterations=999999;
3702#if 0
3703      if (saveSearchStrategy==-1&&!model->parentModel()&&
3704          !depth_&&saveLimit==100) {
3705        realMaxHotIterations=saveLimit;
3706        saveLimit2=200;
3707        solver->setIntParam(OsiMaxNumIterationHotStart,saveLimit2);
3708      }
3709#endif
3710#ifdef SKIPM1
3711      if (skipAll<0)
3712        numberToDo=1;
3713#endif
3714#ifdef DO_ALL_AT_ROOT
3715      if (!numberNodes) {
3716        printf("DOX %d test %d unsat %d - nobj %d\n",
3717               numberToDo,numberTest,numberUnsatisfied_,
3718               numberObjects);
3719        numberTest=numberToDo;
3720      }
3721#endif
3722      for ( iDo=0;iDo<numberToDo;iDo++) {
3723        int iObject = whichObject[iDo];
3724        OsiObject * object = model->modifiableObject(iObject);
3725        CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
3726          static_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
3727        int iColumn = dynamicObject ? dynamicObject->columnNumber() : numberColumns+iObject;
3728        int preferredWay;
3729        double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
3730        // may have become feasible
3731        if (!infeasibility)
3732          continue;
3733        CbcSimpleInteger * obj =
3734          dynamic_cast <CbcSimpleInteger *>(object) ;
3735        if (obj) {
3736          if (choiceObject) {
3737            obj->fillCreateBranch(choiceObject,&usefulInfo,preferredWay);
3738            choiceObject->setObject(dynamicObject);
3739          } else {
3740            choice.possibleBranch=obj->createBranch(solver,&usefulInfo,preferredWay);
3741          }
3742        } else {
3743          CbcObject * obj =
3744            dynamic_cast <CbcObject *>(object) ;
3745          assert (obj);
3746          choice.possibleBranch=obj->createBranch(preferredWay);
3747        }
3748        // Save which object it was
3749        choice.objectNumber=iObject;
3750        choice.numIntInfeasUp = numberUnsatisfied_;
3751        choice.numIntInfeasDown = numberUnsatisfied_;
3752        choice.upMovement = upEstimate[iObject];
3753        choice.downMovement = downEstimate[iObject];
3754        assert (choice.upMovement>=0.0);
3755        assert (choice.downMovement>=0.0);
3756        choice.fix=0; // say not fixed
3757        double maxChange = 0.5*(choice.upMovement+choice.downMovement);
3758        maxChange = CoinMin(choice.upMovement,choice.downMovement);
3759        maxChange = CoinMax(choice.upMovement,choice.downMovement);
3760        if (searchStrategy==2)
3761          maxChange = COIN_DBL_MAX;
3762        //maxChange *= 5.0;
3763        if (dynamicObject&&dynamicObject->method()==1)
3764          maxChange *= 0.1; // probing
3765        // see if can skip strong branching
3766        int canSkip = choice.possibleBranch->fillStrongInfo(choice);
3767#if 0
3768        if (!newWay) {
3769          if ((maxChange>distanceToCutoff2)&&(!doQuickly||(numberTest>0&&searchStrategy!=2)))
3770          canSkip=0;
3771        } else {
3772        if (skipAll)
3773          canSkip=1;
3774        else if (numberTest>0&&searchStrategy>=3)
3775          canSkip=0;
3776        }
3777        if (!numberBeforeTrust) {
3778          canSkip=1;
3779        }
3780        if (sort[iDo]<distanceToCutoff)
3781          canSkip=0;
3782        if ((numberTest<=0||skipAll)&&sort[iDo]>distanceToCutoff) {
3783          canSkip=1; // always skip
3784          if (iDo>20) {
3785#ifdef DO_ALL_AT_ROOT
3786            if (!numberNodes)
3787              printf("DOY test %d - iDo %d\n",
3788                     numberTest,iDo);
3789#endif
3790            if (!choiceObject) {
3791              delete choice.possibleBranch;
3792              choice.possibleBranch=NULL;
3793            }
3794            break; // give up anyway
3795          }
3796        }
3797#else
3798        if ((numberTest<=0||skipAll)&&sort[iDo]>distanceToCutoff) {
3799          //canSkip=1; // always skip
3800          if (iDo>20) {
3801#ifdef DO_ALL_AT_ROOT
3802            if (!numberNodes)
3803              printf("DOY test %d - iDo %d\n",
3804                     numberTest,iDo);
3805#endif
3806            if (!choiceObject) {
3807              delete choice.possibleBranch;
3808              choice.possibleBranch=NULL;
3809            }
3810            break; // give up anyway
3811          }
3812        }
3813#endif
3814        if (model->messageHandler()->logLevel()>3&&numberBeforeTrust&&dynamicObject) 
3815          dynamicObject->print(1,choice.possibleBranch->value());
3816#ifdef SKIPM1
3817        if (skipAll<0)
3818          canSkip=true;
3819#endif
3820        if (!canSkip) {
3821          //#ifndef RANGING
3822          if (!doneHotStart) {
3823            // Mark hot start
3824            doneHotStart=true;
3825            solver->markHotStart();
3826            xMark++;
3827          }
3828          //#endif
3829          assert (!couldChooseFirst);
3830          numberTest--;
3831          // just do a few
3832#if NODE_NEW == 5  || NODE_NEW == 2
3833          //if (canSkip)
3834          if (searchStrategy==2)
3835            solver->setIntParam(OsiMaxNumIterationHotStart,10); 
3836#endif
3837          double objectiveChange ;
3838          double newObjectiveValue=1.0e100;
3839          int j;
3840          // status is 0 finished, 1 infeasible and other
3841          int iStatus;
3842          if (0) {
3843            CbcDynamicPseudoCostBranchingObject * cbcobj = dynamic_cast<CbcDynamicPseudoCostBranchingObject *> (choice.possibleBranch);
3844            if (cbcobj) {
3845              CbcSimpleIntegerDynamicPseudoCost * object = cbcobj->object();
3846              printf("strong %d ",iDo);
3847              object->print(1,0.5);
3848            }
3849          }
3850          /*
3851            Try the down direction first. (Specify the initial branching alternative as
3852            down with a call to way(-1). Each subsequent call to branch() performs the
3853            specified branch and advances the branch object state to the next branch
3854            alternative.)
3855          */
3856          choice.possibleBranch->way(-1) ;
3857#if NEW_UPDATE_OBJECT==0
3858          decision->saveBranchingObject( choice.possibleBranch);
3859#endif
3860          choice.possibleBranch->branch() ;
3861          solver->solveFromHotStart() ;
3862          bool needHotStartUpdate=false;
3863          numberStrongDone++;
3864          numberStrongIterations += solver->getIterationCount();
3865          /*
3866            We now have an estimate of objective degradation that we can use for strong
3867            branching. If we're over the cutoff, the variable is monotone up.
3868            If we actually made it to optimality, check for a solution, and if we have
3869            a good one, call setBestSolution to process it. Note that this may reduce the
3870            cutoff, so we check again to see if we can declare this variable monotone.
3871          */
3872          if (solver->isProvenOptimal())
3873            iStatus=0; // optimal
3874          else if (solver->isIterationLimitReached()
3875                   &&!solver->isDualObjectiveLimitReached())
3876            iStatus=2; // unknown
3877          else
3878            iStatus=1; // infeasible
3879          if (iStatus!=2&&solver->getIterationCount()>
3880              realMaxHotIterations)
3881            numberUnfinished++;
3882          newObjectiveValue = solver->getObjSense()*solver->getObjValue();
3883          choice.numItersDown = solver->getIterationCount();
3884          objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
3885          // Update branching information if wanted
3886#if NEW_UPDATE_OBJECT==0
3887          decision->updateInformation( solver,this);
3888#elif NEW_UPDATE_OBJECT<2
3889          CbcBranchingObject * cbcobj = dynamic_cast<CbcBranchingObject *> (choice.possibleBranch);
3890          if (cbcobj) {
3891            CbcObject * object = cbcobj->object();
3892            assert (object);
3893            CbcObjectUpdateData update = object->createUpdateInformation(solver,this,cbcobj);
3894            object->updateInformation(update);
3895          } else {
3896            decision->updateInformation( solver,this);
3897          }
3898#else
3899          CbcBranchingObject * cbcobj = dynamic_cast<CbcBranchingObject *> (choice.possibleBranch);
3900          if (cbcobj) {
3901            CbcObject * object = cbcobj->object();
3902            assert (object) ;
3903            CbcObjectUpdateData update = object->createUpdateInformation(solver,this,cbcobj);
3904            update.objectNumber_ = choice.objectNumber;
3905            model->addUpdateInformation(update);
3906          } else {
3907            decision->updateInformation( solver,this);
3908          }
3909#endif
3910          if (!iStatus) {
3911            choice.finishedDown = true ;
3912            if (newObjectiveValue>=cutoff) {
3913              objectiveChange = 1.0e100; // say infeasible
3914              numberStrongInfeasible++;
3915            } else {
3916              // See if integer solution
3917              if (model->feasibleSolution(choice.numIntInfeasDown,
3918                                          choice.numObjInfeasDown)
3919                  &&model->problemFeasibility()->feasible(model,-1)>=0) {
3920                if (auxiliaryInfo->solutionAddsCuts()) {
3921                  needHotStartUpdate=true;
3922                  solver->unmarkHotStart();
3923                }
3924                model->setBestSolution(CBC_STRONGSOL,
3925                                       newObjectiveValue,
3926                                       solver->getColSolution()) ;
3927                if (needHotStartUpdate) {
3928                  model->resolve(NULL,11,saveSolution,saveLower,saveUpper);
3929                  newObjectiveValue = solver->getObjSense()*solver->getObjValue();
3930                  objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
3931                  model->feasibleSolution(choice.numIntInfeasDown,
3932                                          choice.numObjInfeasDown);
3933                }
3934                model->setLastHeuristic(NULL);
3935                model->incrementUsed(solver->getColSolution());
3936                cutoff =model->getCutoff();
3937                if (newObjectiveValue >= cutoff) {      //  *new* cutoff
3938                  objectiveChange = 1.0e100 ;
3939                  numberStrongInfeasible++;
3940                }
3941              }
3942            }
3943          } else if (iStatus==1) {
3944            objectiveChange = 1.0e100 ;
3945            numberStrongInfeasible++;
3946          } else {
3947            // Can't say much as we did not finish
3948            choice.finishedDown = false ;
3949            numberUnfinished++;
3950          }
3951          choice.downMovement = objectiveChange ;
3952         
3953          // restore bounds
3954          for ( j=0;j<numberColumns;j++) {
3955            if (saveLower[j] != lower[j])
3956              solver->setColLower(j,saveLower[j]);
3957            if (saveUpper[j] != upper[j])
3958              solver->setColUpper(j,saveUpper[j]);
3959          }
3960          if(needHotStartUpdate) {
3961            needHotStartUpdate = false;
3962            model->resolve(NULL,11,saveSolution,saveLower,saveUpper);
3963            //we may again have an integer feasible solution
3964            int numberIntegerInfeasibilities;
3965            int numberObjectInfeasibilities;
3966            if (model->feasibleSolution(
3967                                        numberIntegerInfeasibilities,
3968                                        numberObjectInfeasibilities)) {
3969#ifdef BONMIN
3970              //In this case node has become integer feasible, let us exit the loop
3971              std::cout<<"Node has become integer feasible"<<std::endl;
3972              numberUnsatisfied_ = 0;
3973              break;
3974#endif
3975              double objValue = solver->getObjValue();
3976              model->setBestSolution(CBC_STRONGSOL,
3977                                     objValue,
3978                                     solver->getColSolution()) ;
3979              model->resolve(NULL,11,saveSolution,saveLower,saveUpper);
3980              cutoff =model->getCutoff();
3981            }
3982            solver->markHotStart();
3983          }
3984#ifdef DO_ALL_AT_ROOT
3985          if (!numberNodes)
3986          printf("Down on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
3987               choice.objectNumber,iStatus,newObjectiveValue,choice.numItersDown,
3988               choice.downMovement,choice.finishedDown,choice.numIntInfeasDown,
3989               choice.numObjInfeasDown);
3990#endif
3991         
3992          // repeat the whole exercise, forcing the variable up
3993#if NEW_UPDATE_OBJECT==0
3994          decision->saveBranchingObject( choice.possibleBranch);
3995#endif
3996          choice.possibleBranch->branch();
3997          solver->solveFromHotStart() ;
3998          numberStrongDone++;
3999          numberStrongIterations += solver->getIterationCount();
4000          /*
4001            We now have an estimate of objective degradation that we can use for strong
4002            branching. If we're over the cutoff, the variable is monotone up.
4003            If we actually made it to optimality, check for a solution, and if we have
4004            a good one, call setBestSolution to process it. Note that this may reduce the
4005            cutoff, so we check again to see if we can declare this variable monotone.
4006          */
4007          if (solver->isProvenOptimal())
4008            iStatus=0; // optimal
4009          else if (solver->isIterationLimitReached()
4010                   &&!solver->isDualObjectiveLimitReached())
4011            iStatus=2; // unknown
4012          else
4013            iStatus=1; // infeasible
4014          if (iStatus!=2&&solver->getIterationCount()>
4015              realMaxHotIterations)
4016            numberUnfinished++;
4017          newObjectiveValue = solver->getObjSense()*solver->getObjValue();
4018          choice.numItersUp = solver->getIterationCount();
4019          objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
4020          // Update branching information if wanted
4021#if NEW_UPDATE_OBJECT==0
4022          decision->updateInformation( solver,this);
4023#elif NEW_UPDATE_OBJECT<2
4024          cbcobj = dynamic_cast<CbcBranchingObject *> (choice.possibleBranch);
4025          if (cbcobj) {
4026            CbcObject * object = cbcobj->object();
4027            CbcObjectUpdateData update = object->createUpdateInformation(solver,this,cbcobj);
4028            object->updateInformation(update);
4029          } else {
4030            decision->updateInformation( solver,this);
4031          }
4032#else
4033          cbcobj = dynamic_cast<CbcBranchingObject *> (choice.possibleBranch);
4034          if (cbcobj) {
4035            CbcObject * object = cbcobj->object();
4036            assert (object) ;
4037            CbcObjectUpdateData update = object->createUpdateInformation(solver,this,cbcobj);
4038            update.objectNumber_ = choice.objectNumber;
4039            model->addUpdateInformation(update);
4040          } else {
4041            decision->updateInformation( solver,this);
4042          }
4043#endif
4044          if (!iStatus) {
4045            choice.finishedUp = true ;
4046            if (newObjectiveValue>=cutoff) {
4047              objectiveChange = 1.0e100; // say infeasible
4048              numberStrongInfeasible++;
4049            } else {
4050              // See if integer solution
4051              if (model->feasibleSolution(choice.numIntInfeasUp,
4052                                          choice.numObjInfeasUp)
4053                  &&model->problemFeasibility()->feasible(model,-1)>=0) {
4054#ifdef BONMIN
4055                std::cout<<"Node has become integer feasible"<<std::endl;
4056                numberUnsatisfied_ = 0;
4057                break;
4058#endif
4059                if (auxiliaryInfo->solutionAddsCuts()) {
4060                  needHotStartUpdate=true;
4061                  solver->unmarkHotStart();
4062                }
4063                model->setBestSolution(CBC_STRONGSOL,
4064                                       newObjectiveValue,
4065                                       solver->getColSolution()) ;
4066                if (needHotStartUpdate) {
4067                  model->resolve(NULL,11,saveSolution,saveLower,saveUpper);
4068                  newObjectiveValue = solver->getObjSense()*solver->getObjValue();
4069                  objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
4070                  model->feasibleSolution(choice.numIntInfeasDown,
4071                                          choice.numObjInfeasDown);
4072                }
4073                model->setLastHeuristic(NULL);
4074                model->incrementUsed(solver->getColSolution());
4075                cutoff =model->getCutoff();
4076                if (newObjectiveValue >= cutoff) {      //  *new* cutoff
4077                  objectiveChange = 1.0e100 ;
4078                  numberStrongInfeasible++;
4079                }
4080              }
4081            }
4082          } else if (iStatus==1) {
4083            objectiveChange = 1.0e100 ;
4084            numberStrongInfeasible++;
4085          } else {
4086            // Can't say much as we did not finish
4087            choice.finishedUp = false ;
4088            numberUnfinished++;
4089          }
4090          choice.upMovement = objectiveChange ;
4091         
4092          // restore bounds
4093          for ( j=0;j<numberColumns;j++) {
4094            if (saveLower[j] != lower[j])
4095              solver->setColLower(j,saveLower[j]);
4096            if (saveUpper[j] != upper[j])
4097              solver->setColUpper(j,saveUpper[j]);
4098          }
4099          if(needHotStartUpdate) {
4100            needHotStartUpdate = false;
4101            model->resolve(NULL,11,saveSolution,saveLower,saveUpper);
4102            //we may again have an integer feasible solution
4103            int numberIntegerInfeasibilities;
4104            int numberObjectInfeasibilities;
4105            if (model->feasibleSolution(
4106                                        numberIntegerInfeasibilities,
4107                                        numberObjectInfeasibilities)) {
4108              double objValue = solver->getObjValue();
4109              model->setBestSolution(CBC_STRONGSOL,
4110                                     objValue,
4111                                     solver->getColSolution()) ;
4112              model->resolve(NULL,11,saveSolution,saveLower,saveUpper);
4113              cutoff =model->getCutoff();
4114            }
4115            solver->markHotStart();
4116          }
4117         
4118#ifdef DO_ALL_AT_ROOT
4119          if (!numberNodes)
4120          printf("Up on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
4121               choice.objectNumber,iStatus,newObjectiveValue,choice.numItersUp,
4122               choice.upMovement,choice.finishedUp,choice.numIntInfeasUp,
4123               choice.numObjInfeasUp);
4124#endif
4125        }
4126   
4127        solver->setIntParam(OsiMaxNumIterationHotStart,saveLimit2); 
4128        /*
4129          End of evaluation for this candidate variable. Possibilities are:
4130          * Both sides below cutoff; this variable is a candidate for branching.
4131          * Both sides infeasible or above the objective cutoff: no further action
4132          here. Break from the evaluation loop and assume the node will be purged
4133          by the caller.
4134          * One side below cutoff: Install the branch (i.e., fix the variable). Break
4135          from the evaluation loop and assume the node will be reoptimised by the
4136          caller.
4137        */
4138        // reset
4139        choice.possibleBranch->resetNumberBranchesLeft();
4140        if (choice.upMovement<1.0e100) {
4141          if(choice.downMovement<1.0e100) {
4142            // In case solution coming in was odd
4143            choice.upMovement = CoinMax(0.0,choice.upMovement);
4144            choice.downMovement = CoinMax(0.0,choice.downMovement);
4145            if (couldChooseFirst)
4146              printf("candidate %d up %g down %g sort %g\n",iDo,choice.upMovement,choice.downMovement,sort[iDo]);
4147#if ZERO_ONE==2
4148            // branch on 0-1 first (temp)
4149            if (fabs(choice.possibleBranch->value())<1.0) {
4150              choice.upMovement *= ZERO_FAKE;
4151              choice.downMovement *= ZERO_FAKE;
4152            }
4153#endif
4154            // feasible - see which best
4155            if (!canSkip) {
4156              if (iColumn==-46) {
4157                printf("sort %g downest %g upest %g ",sort[iDo],downEstimate[iObject],
4158                     upEstimate[iObject]);
4159                printf("downMove %g upMove %g value %g current pseudo %g %g\n",
4160                       choice.downMovement,choice.upMovement,choice.possibleBranch->value(),
4161                       dynamicObject->downDynamicPseudoCost(),dynamicObject->upDynamicPseudoCost());
4162              }
4163              if (model->messageHandler()->logLevel()>3) 
4164                printf("sort %g downest %g upest %g ",sort[iDo],downEstimate[iObject],
4165                     upEstimate[iObject]);
4166              model->messageHandler()->message(CBC_STRONG,*model->messagesPointer())
4167                << iObject << iColumn
4168                <<choice.downMovement<<choice.numIntInfeasDown
4169                <<choice.upMovement<<choice.numIntInfeasUp
4170                <<choice.possibleBranch->value()
4171                <<CoinMessageEol;
4172            }
4173            //if (!stateOfSearch)
4174            //choice.numIntInfeasDown=99999; // temp fudge
4175            if (wantMiniTree)
4176              decision->setBestCriterion(-1.0);
4177            double bestCriterion = -1.0;
4178            //double gap = saveUpper[iColumn]-saveLower[iColumn];
4179            // Give precedence to ones with gap of 1.0
4180            //assert(gap>0.0);
4181            double factor = 1.0; //changeFactor/CoinMin(gap,100.0);
4182            int betterWay;
4183            {
4184              CbcBranchingObject * branchObj =
4185                dynamic_cast <CbcBranchingObject *>(branch_) ;
4186              if (branch_)
4187                assert (branchObj);
4188              betterWay = decision->betterBranch(choice.possibleBranch,
4189                                                     branchObj,
4190                                                     choice.upMovement*factor,
4191                                                     choice.numIntInfeasUp ,
4192                                                     choice.downMovement*factor,
4193                                                     choice.numIntInfeasDown );
4194            }
4195            if (wantMiniTree) {
4196              double criterion = decision->getBestCriterion();
4197              sort[numberMini]=-criterion;
4198              whichObject[numberMini++]=whichObject[iDo];
4199              assert (betterWay);
4200              if (criterion>bestCriterion) 
4201                bestCriterion=criterion;
4202              else
4203                betterWay=0;
4204            }
4205            if (iDo>=changeStrategy) {
4206              // make less likely
4207              changeStrategy+=numberStrong;
4208              changeFactor *= 0.9;
4209            }
4210            if (betterWay) {
4211              // C) create branching object
4212              if (choiceObject) {
4213                delete branch_;
4214                branch_ = choice.possibleBranch->clone();
4215              } else {
4216                delete branch_;
4217                branch_ = choice.possibleBranch;
4218                choice.possibleBranch=NULL;
4219              }
4220              {
4221                CbcBranchingObject * branchObj =
4222                  dynamic_cast <CbcBranchingObject *>(branch_) ;
4223                assert (branchObj);
4224                //branchObj->way(preferredWay);
4225                branchObj->way(betterWay);
4226              }
4227              if (couldChooseFirst)
4228                printf("choosing %d way %d\n",iDo,betterWay);
4229              bestChoice = choice.objectNumber;
4230              whichChoice = iDo;
4231              if (numberStrong<=1) {
4232                delete ws;
4233                ws=NULL;
4234                break;
4235              }
4236            } else {
4237              if (!choiceObject) {
4238                delete choice.possibleBranch;
4239                choice.possibleBranch=NULL;
4240              }
4241              if (iDo>=2*numberStrong) {
4242                delete ws;
4243                ws=NULL;
4244                break;
4245              }
4246              if (!dynamicObject||dynamicObject->numberTimesUp()>1) {
4247                if (iDo-whichChoice>=numberStrong) {
4248                  if (!choiceObject) {
4249                    delete choice.possibleBranch;
4250                    choice.possibleBranch=NULL;
4251                  }
4252                  break; // give up
4253                }
4254              } else {
4255                if (iDo-whichChoice>=2*numberStrong) {
4256                  delete ws;
4257                  ws=NULL;
4258                  if (!choiceObject) {
4259                    delete choice.possibleBranch;
4260                    choice.possibleBranch=NULL;
4261                  }
4262                  break; // give up
4263                }
4264              }
4265            }
4266          } else {
4267            // up feasible, down infeasible
4268            anyAction=-1;
4269            worstFeasible = CoinMax(worstFeasible,choice.upMovement);
4270            model->messageHandler()->message(CBC_STRONG,*model->messagesPointer())
4271              << iObject << iColumn
4272              <<choice.downMovement<<choice.numIntInfeasDown
4273              <<choice.upMovement<<choice.numIntInfeasUp
4274              <<choice.possibleBranch->value()
4275              <<CoinMessageEol;
4276            //printf("Down infeasible for choice %d sequence %d\n",i,
4277            // model->object(choice.objectNumber)->columnNumber());
4278            if (!solveAll) {
4279              choice.possibleBranch->way(1);
4280              choice.possibleBranch->branch();
4281              if (!choiceObject) {
4282                delete choice.possibleBranch;
4283                choice.possibleBranch=NULL;
4284              }
4285              delete ws;
4286              ws=NULL;
4287              break;
4288            } else {
4289              choice.fix=1;
4290              fixObject[numberToFix++]=choice;
4291#define FIXNOW
4292#ifdef FIXNOW
4293#if 0
4294              double value = ceil(saveSolution[iColumn]);
4295              saveLower[iColumn]=value;
4296              solver->setColLower(iColumn,value);
4297#else
4298              choice.possibleBranch->fix(solver,saveLower,saveUpper,1);
4299#endif
4300#endif
4301              if (!choiceObject) {
4302                choice.possibleBranch=NULL;
4303              } else {
4304                choiceObject = new CbcDynamicPseudoCostBranchingObject(*choiceObject);
4305                choice.possibleBranch=choiceObject;
4306              }
4307#ifdef FIXNOW
4308              assert(doneHotStart);
4309              solver->unmarkHotStart();
4310              model->resolve(NULL,11,saveSolution,saveLower,saveUpper);
4311              solver->markHotStart();
4312              // may be infeasible (if other way stopped on iterations)
4313              if (!solver->isProvenOptimal()) {
4314                // neither side feasible
4315                anyAction=-2;
4316                if (!choiceObject) {
4317                  delete choice.possibleBranch;
4318                  choice.possibleBranch=NULL;
4319                }
4320                //printf("Both infeasible for choice %d sequence %d\n",i,
4321                // model->object(choice.objectNumber)->columnNumber());
4322                delete ws;
4323                ws=NULL;
4324                break;
4325              }
4326#endif
4327            }
4328          }
4329        } else {
4330          if(choice.downMovement<1.0e100) {
4331            // down feasible, up infeasible
4332            anyAction=-1;
4333            worstFeasible = CoinMax(worstFeasible,choice.downMovement);
4334            model->messageHandler()->message(CBC_STRONG,*model->messagesPointer())
4335              << iObject << iColumn
4336              <<choice.downMovement<<choice.numIntInfeasDown
4337              <<choice.upMovement<<choice.numIntInfeasUp
4338              <<choice.possibleBranch->value()
4339              <<CoinMessageEol;
4340            //printf("Up infeasible for choice %d sequence %d\n",i,
4341            // model->object(choice.objectNumber)->columnNumber());
4342            if (!solveAll) {
4343              choice.possibleBranch->way(-1);
4344              choice.possibleBranch->branch();
4345              if (!choiceObject) {
4346                delete choice.possibleBranch;
4347                choice.possibleBranch=NULL;
4348              }
4349              delete ws;
4350              ws=NULL;
4351              break;
4352            } else {
4353              choice.fix=-1;
4354              fixObject[numberToFix++]=choice;
4355#ifdef FIXNOW
4356#if 0
4357              double value = floor(saveSolution[iColumn]);
4358              saveUpper[iColumn]=value;
4359              solver->setColUpper(iColumn,value);
4360#else
4361              choice.possibleBranch->fix(solver,saveLower,saveUpper,-1);
4362#endif
4363#endif
4364              if (!choiceObject) {
4365                choice.possibleBranch=NULL;
4366              } else {
4367                choiceObject = new CbcDynamicPseudoCostBranchingObject(*choiceObject);
4368                choice.possibleBranch=choiceObject;
4369              }
4370#ifdef FIXNOW
4371              assert(doneHotStart);
4372              solver->unmarkHotStart();
4373              model->resolve(NULL,11,saveSolution,saveLower,saveUpper);
4374              solver->markHotStart();
4375              // may be infeasible (if other way stopped on iterations)
4376              if (!solver->isProvenOptimal()) {
4377                // neither side feasible
4378                anyAction=-2;
4379                if (!choiceObject) {
4380                  delete choice.possibleBranch;
4381                  choice.possibleBranch=NULL;
4382                }
4383                //printf("Both infeasible for choice %d sequence %d\n",i,
4384                // model->object(choice.objectNumber)->columnNumber());
4385                delete ws;
4386                ws=NULL;
4387                break;
4388              }
4389#endif
4390            }
4391          } else {
4392            // neither side feasible
4393            anyAction=-2;
4394            if (!choiceObject) {
4395              delete choice.possibleBranch;
4396              choice.possibleBranch=NULL;
4397            }
4398            //printf("Both infeasible for choice %d sequence %d\n",i,
4399            // model->object(choice.objectNumber)->columnNumber());
4400            delete ws;
4401            ws=NULL;
4402            break;
4403          }
4404        }
4405        // Check max time
4406        hitMaxTime = ( CoinCpuTime()-model->getDblParam(CbcModel::CbcStartSeconds) > 
4407                       model->getDblParam(CbcModel::CbcMaximumSeconds));
4408        if (hitMaxTime) {
4409          // make sure rest are fast
4410          doQuickly=true;
4411          for ( int jDo=iDo+1;jDo<numberToDo;jDo++) {
4412            int iObject = whichObject[iDo];
4413            OsiObject * object = model->modifiableObject(iObject);
4414            CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
4415              dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
4416            if (dynamicObject) 
4417              dynamicObject->setNumberBeforeTrust(0);
4418          }
4419          numberTest=0;
4420          distanceToCutoff=-COIN_DBL_MAX;
4421        }
4422        if (!choiceObject) {
4423          delete choice.possibleBranch;
4424        }
4425      }
4426      double averageChange = model->sumChangeObjective()/
4427        static_cast<double> (model->getNodeCount());
4428      if (depth_<10||worstFeasible>0.2*averageChange) 
4429        solveAll=false;
4430      if (model->messageHandler()->logLevel()>3||false) { 
4431        if (anyAction==-2) {
4432          printf("infeasible\n");
4433        } else if(anyAction==-1) {
4434          if (!solveAll)
4435            printf("%d fixed\n",numberToFix);
4436          else
4437            printf("%d fixed AND choosing %d iDo %d iChosenWhen %d numberToDo %d\n",numberToFix,bestChoice,
4438                   iDo,whichChoice,numberToDo);
4439        } else {
4440          int iObject = whichObject[whichChoice];
4441          OsiObject * object = model->modifiableObject(iObject);
4442          CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
4443            dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
4444          if (dynamicObject) {
4445            int iColumn = dynamicObject->columnNumber();
4446            printf("choosing %d (column %d) iChosenWhen %d numberToDo %d\n",bestChoice,
4447                   iColumn,whichChoice,numberToDo);
4448          }
4449        }
4450      }
4451      if (doneHotStart) {
4452        // Delete the snapshot
4453        solver->unmarkHotStart();
4454        // back to normal
4455        solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
4456        // restore basis
4457        solver->setWarmStart(ws);
4458      }
4459      solver->setIntParam(OsiMaxNumIterationHotStart,saveLimit);
4460      // Unless infeasible we will carry on
4461      // But we could fix anyway
4462      if (numberToFix&&!hitMaxTime) {
4463        if (anyAction==-2) {
4464          // take off
4465          for (i = 0 ; i < numberToFix ; i++) {
4466            delete fixObject[i].possibleBranch;
4467          }
4468        } else {
4469          // apply and take off
4470          for (i = 0 ; i < numberToFix ; i++) {
4471#ifndef FIXNOW
4472            fixObject[i].possibleBranch->way(fixObject[i].fix) ;
4473            fixObject[i].possibleBranch->branch() ;
4474#endif
4475            delete fixObject[i].possibleBranch;
4476          }
4477          bool feasible=true;
4478#if ACTION <2
4479          if (solveAll) {
4480            // can do quick optimality check
4481            int easy=2;
4482            solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,&easy) ;
4483            model->resolve(NULL,11,saveSolution,saveLower,saveUpper) ;
4484            solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
4485            feasible = solver->isProvenOptimal();
4486            if (feasible) {
4487              anyAction=0;
4488              numberMini=0;
4489              // See if candidate still possible
4490              if (branch_) {
4491                const OsiObject * object = model->object(bestChoice);
4492                int preferredWay;
4493                double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
4494                if (!infeasibility) {
4495                  // take out
4496                  delete branch_;
4497                  branch_=NULL;
4498                } else {
4499                  CbcBranchingObject * branchObj =
4500                    dynamic_cast <CbcBranchingObject *>(branch_) ;
4501                  assert (branchObj);
4502                  branchObj->way(preferredWay);
4503                }
4504              }
4505            } else {
4506              anyAction=-2;
4507              finished=true;
4508            }
4509          }
4510#endif
4511          // If  fixed then round again
4512          if (!branch_&&anyAction!=-2) {
4513            finished=false;
4514          }
4515          // If these in then different action
4516#if ACTION == 1
4517          if (!anyAction)
4518            anyAction=-1;
4519          finished=true;
4520#endif
4521        }
4522      }
4523      delete ws;
4524    }
4525  }
4526#ifdef CBC_NODE7
4527  delete [] weightModifier;
4528#endif
4529  if (model->messageHandler()->logLevel()>2) 
4530    printf("%d strong, %d iters, %d pen, %d mark, %d fixed, action %d nnott %d nt %d, %d dq %s ns %d\n",
4531         numberStrongDone,numberStrongIterations,xPen,xMark,
4532           numberToFix,anyAction,numberNotTrusted,px[0],px[1],px[2]>0 ? "y" : "n",px[3]);
4533  // update number of strong iterations etc
4534  model->incrementStrongInfo(numberStrongDone,numberStrongIterations,
4535                             anyAction==-2 ? 0:numberToFix,anyAction==-2);
4536#if 0
4537  if (!numberNodes&&!model->parentModel()) {
4538    printf("DOZ %d strong, %d iterations, %d unfinished\n",
4539           numberStrongDone,numberStrongIterations,numberUnfinished);
4540    if (numberUnfinished>10&&4*numberUnfinished>numberStrongDone)
4541    /model->setNumberBeforeTrust(CoinMin(numberBeforeTrust,5));
4542  }
4543#endif
4544  if (!newWay) {
4545  if (((model->searchStrategy()+1)%1000)==0) {
4546#ifndef COIN_DEVELOP
4547    if (solver->messageHandler()->logLevel()>1)
4548#endif
4549      printf("%d strong, %d iters, %d inf, %d not finished, %d not trusted\n",
4550             numberStrongDone,numberStrongIterations,numberStrongInfeasible,numberUnfinished,
4551             numberNotTrusted);
4552    // decide what to do
4553    int strategy=1;
4554    if (((numberUnfinished*4>numberStrongDone&&
4555         numberStrongInfeasible*40<numberStrongDone)||
4556         numberStrongInfeasible<0)&&model->numberStrong()<10&&model->numberBeforeTrust()<=20&&model->numberObjects()>CoinMax(1000,solver->getNumRows())) {
4557      strategy=2;
4558#ifdef COIN_DEVELOP
4559      //if (model->logLevel()>1)
4560        printf("going to strategy 2\n");
4561#endif
4562#if NODE_NEW==1
4563      // Basically off
4564      model->setNumberStrong(0);
4565      model->setNumberBeforeTrust(-2);
4566#elif NODE_NEW==2
4567      // Weaken
4568      model->setNumberStrong(2);
4569      model->setNumberBeforeTrust(1);
4570#elif NODE_NEW==3
4571      // Off and ranging
4572      model->setNumberStrong(0);
4573      model->setNumberBeforeTrust(-1);
4574#elif NODE_NEW==4
4575      // Off and pseudo shadow prices
4576      model->setNumberStrong(0);
4577      model->setNumberBeforeTrust(-2);
4578#elif NODE_NEW==5
4579      // Just fewer iterations
4580#endif
4581      model->synchronizeNumberBeforeTrust();
4582    }
4583    if (numberNodes)
4584      strategy=1;  // should only happen after hot start
4585    if (model->searchStrategy()<999)
4586      model->setSearchStrategy(strategy);
4587  } else if (numberStrongDone) {
4588    //printf("%d strongB, %d iters, %d inf, %d not finished, %d not trusted\n",
4589    //   numberStrongDone,numberStrongIterations,numberStrongInfeasible,numberUnfinished,
4590    //   numberNotTrusted);
4591  }
4592  if (model->searchStrategy()==1&&numberNodes>500&&numberNodes<-510) {
4593#ifndef COIN_DEVELOP
4594    if (solver->messageHandler()->logLevel()>1)
4595#endif
4596      printf("after %d nodes - %d strong, %d iters, %d inf, %d not finished, %d not trusted\n",
4597             numberNodes,numberStrongDone,numberStrongIterations,numberStrongInfeasible,numberUnfinished,
4598             numberNotTrusted);
4599    // decide what to do
4600    if (numberUnfinished*10>numberStrongDone+1||
4601        !numberStrongInfeasible) {
4602      //if (model->logLevel()>1)
4603        printf("going to strategy 2\n");
4604#if NODE_NEW==1
4605      // Basically off
4606      model->setNumberStrong(0);
4607      model->setNumberBeforeTrust(-2);
4608#elif NODE_NEW==2
4609      // Weaken
4610      model->setNumberStrong(2);
4611      model->setNumberBeforeTrust(1);
4612#elif NODE_NEW==3
4613      // Off and ranging
4614      model->setNumberStrong(0);
4615      model->setNumberBeforeTrust(-1);
4616#elif NODE_NEW==4
4617      // Off and pseudo shadow prices
4618      model->setNumberStrong(0);
4619      model->setNumberBeforeTrust(-2);
4620#elif NODE_NEW==5
4621      // Just fewer iterations
4622#endif
4623      model->synchronizeNumberBeforeTrust();
4624      model->setSearchStrategy(2);
4625    }
4626  }
4627  }
4628  //if (numberToFix&&depth_<5)
4629  //printf("%d fixed by strong at depth %d\n",numberToFix,depth_);
4630  // Set guessed solution value
4631  guessedObjectiveValue_ = objectiveValue_+estimatedDegradation;
4632 
4633  // Get collection of branches if mini tree wanted
4634  if (anyAction==0&&numberMini&&numberMini>1) {
4635    // Sort
4636    CoinSort_2(sort,sort+numberMini,whichObject);
4637    delete branch_;
4638    branch_=NULL;
4639    numberMini = CoinMin(numberMini,model->sizeMiniTree());
4640    anyAction=numberMini;
4641    branches = new OsiSolverBranch[numberMini];
4642    for (int iDo=0;iDo<numberMini;iDo++) {
4643      int iObject = whichObject[iDo];
4644      OsiObject * object = model->modifiableObject(iObject);
4645      CbcSimpleInteger * obj =
4646        dynamic_cast <CbcSimpleInteger *>(object) ;
4647      OsiSolverBranch * oneBranch;
4648      if (obj) {
4649        oneBranch = obj->solverBranch(solver,&usefulInfo);
4650      } else {
4651        CbcObject * obj =
4652          dynamic_cast <CbcObject *>(object) ;
4653        assert (obj);
4654        oneBranch = obj->solverBranch();
4655      }
4656      branches[iDo]=*oneBranch;
4657      delete oneBranch;
4658    }
4659  }
4660/*
4661  Cleanup, then we're finished
4662*/
4663  if (!model->branchingMethod())
4664    delete decision;
4665
4666  delete choiceObject;
4667  delete [] fixObject;
4668  delete [] sort;
4669  delete [] whichObject;
4670  delete [] objectMark;
4671  delete [] saveLower;
4672  delete [] saveUpper;
4673  delete [] upEstimate;
4674  delete [] downEstimate;
4675# ifdef COIN_HAS_CLP
4676  if (osiclp) 
4677    osiclp->setSpecialOptions(saveClpOptions);
4678# endif
4679  // restore solution
4680  solver->setColSolution(saveSolution);
4681  model->reserveCurrentSolution(saveSolution);
4682  delete [] saveSolution;
4683  model->setStateOfSearch(saveStateOfSearch);
4684  model->setLogLevel(saveLogLevel);
4685  // delete extra regions
4686  if (usefulInfo.usefulRegion_) {
4687    delete [] usefulInfo.usefulRegion_;
4688    delete [] usefulInfo.indexRegion_;
4689    delete [] usefulInfo.pi_;
4690    usefulInfo.usefulRegion_ = NULL;
4691    usefulInfo.indexRegion_ = NULL;
4692    usefulInfo.pi_ = NULL;
4693  }
4694  return anyAction;
4695}
4696int CbcNode::analyze (CbcModel *model, double * results)
4697{
4698  int i;
4699  int numberIterationsAllowed = model->numberAnalyzeIterations();
4700  OsiSolverInterface * solver = model->solver();
4701  objectiveValue_ = solver->getObjSense()*solver->getObjValue();
4702  double cutoff =model->getCutoff();
4703  const double * lower = solver->getColLower();
4704  const double * upper = solver->getColUpper();
4705  const double * dj = solver->getReducedCost();
4706  int numberObjects = model->numberObjects();
4707  int numberColumns = model->getNumCols();
4708  // Initialize arrays
4709  int numberIntegers = model->numberIntegers();
4710  int * back = new int[numberColumns];
4711  const int * integerVariable = model->integerVariable();
4712  for (i=0;i<numberColumns;i++) 
4713    back[i]=-1;
4714  // What results is
4715  double * newLower = results;
4716  double * objLower = newLower+numberIntegers;
4717  double * newUpper = objLower+numberIntegers;
4718  double * objUpper = newUpper+numberIntegers;
4719  for (i=0;i<numberIntegers;i++) {
4720    int iColumn = integerVariable[i];
4721    back[iColumn]=i;
4722    newLower[i]=0.0;
4723    objLower[i]=-COIN_DBL_MAX;
4724    newUpper[i]=0.0;
4725    objUpper[i]=-COIN_DBL_MAX;
4726  }
4727  double * saveUpper = new double[numberColumns];
4728  double * saveLower = new double[numberColumns];
4729  int anyAction=0;
4730  // Save solution in case heuristics need good solution later
4731 
4732  double * saveSolution = new double[numberColumns];
4733  memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
4734  model->reserveCurrentSolution(saveSolution);
4735  for (i=0;i<numberColumns;i++) {
4736    saveLower[i] = lower[i];
4737    saveUpper[i] = upper[i];
4738  }
4739  // Get arrays to sort
4740  double * sort = new double[numberObjects];
4741  int * whichObject = new int[numberObjects];
4742  int numberToFix=0;
4743  int numberToDo=0;
4744  double integerTolerance = 
4745    model->getDblParam(CbcModel::CbcIntegerTolerance);
4746  // point to useful information
4747  OsiBranchingInformation usefulInfo = model->usefulInformation();
4748  // and modify
4749  usefulInfo.depth_=depth_;
4750     
4751  // compute current state
4752  int numberObjectInfeasibilities; // just odd ones
4753  int numberIntegerInfeasibilities;
4754  model->feasibleSolution(
4755                          numberIntegerInfeasibilities,
4756                          numberObjectInfeasibilities);
4757# ifdef COIN_HAS_CLP
4758  OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver);
4759  int saveClpOptions=0;
4760  bool fastIterations = (model->specialOptions()&8)!=0;
4761  if (osiclp&&fastIterations) {
4762    // for faster hot start
4763    saveClpOptions = osiclp->specialOptions();
4764    osiclp->setSpecialOptions(saveClpOptions|8192);
4765  }
4766# else
4767  bool fastIterations = false ;
4768# endif
4769  /*
4770    Scan for branching objects that indicate infeasibility. Choose candidates
4771    using priority as the first criteria, then integer infeasibility.
4772   
4773    The algorithm is to fill the array with a set of good candidates (by
4774    infeasibility) with priority bestPriority.  Finding a candidate with
4775    priority better (less) than bestPriority flushes the choice array. (This
4776    serves as initialization when the first candidate is found.)
4777   
4778  */
4779  numberToDo=0;
4780  for (i=0;i<numberObjects;i++) {
4781    OsiObject * object = model->modifiableObject(i);
4782    CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
4783      dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
4784    if(!dynamicObject)
4785      continue;
4786    int preferredWay;
4787    double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
4788    int iColumn = dynamicObject->columnNumber();
4789    if (saveUpper[iColumn]==saveLower[iColumn])
4790      continue;
4791    if (infeasibility)
4792      sort[numberToDo]=-1.0e10-infeasibility;
4793    else
4794      sort[numberToDo]=-fabs(dj[iColumn]);
4795    whichObject[numberToDo++]=i;
4796  }
4797  // Save basis
4798  CoinWarmStart * ws = solver->getWarmStart();
4799  int saveLimit;
4800  solver->getIntParam(OsiMaxNumIterationHotStart,saveLimit);
4801  int targetIterations = CoinMax(500,numberIterationsAllowed/numberObjects);
4802  if (saveLimit<targetIterations)
4803    solver->setIntParam(OsiMaxNumIterationHotStart,targetIterations); 
4804  // Mark hot start
4805  solver->markHotStart();
4806  // Sort
4807  CoinSort_2(sort,sort+numberToDo,whichObject);
4808  //double distanceToCutoff=model->getCutoff()-objectiveValue_;
4809  double * currentSolution = model->currentSolution();
4810  double objMin = 1.0e50;
4811  double objMax = -1.0e50;
4812  bool needResolve=false;
4813  int iDo;
4814  for (iDo=0;iDo<numberToDo;iDo++) {
4815    CbcStrongInfo choice;
4816    int iObject = whichObject[iDo];
4817    OsiObject * object = model->modifiableObject(iObject);
4818    CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
4819      static_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
4820    int iColumn = dynamicObject->columnNumber();
4821    int preferredWay;
4822    object->infeasibility(&usefulInfo,preferredWay);
4823    double value = currentSolution[iColumn];
4824    double nearest = floor(value+0.5);
4825    double lowerValue = floor(value);
4826    bool satisfied=false;
4827    if (fabs(value-nearest)<=integerTolerance||value<saveLower[iColumn]||value>saveUpper[iColumn]) {
4828      satisfied=true;
4829      double newValue;
4830      if (nearest<saveUpper[iColumn]) {
4831        newValue = nearest + 1.0001*integerTolerance;
4832        lowerValue = nearest;
4833      } else {
4834        newValue = nearest - 1.0001*integerTolerance;
4835        lowerValue = nearest-1;
4836      }
4837      currentSolution[iColumn]=newValue;
4838    }
4839    double upperValue = lowerValue+1.0;
4840    CbcSimpleInteger * obj =
4841      dynamic_cast <CbcSimpleInteger *>(object) ;
4842    if (obj) {
4843      choice.possibleBranch=obj->createBranch(solver,&usefulInfo,preferredWay);
4844    } else {
4845      CbcObject * obj =
4846        dynamic_cast <CbcObject *>(object) ;
4847      assert (obj);
4848      choice.possibleBranch=obj->createBranch(preferredWay);
4849    }
4850    currentSolution[iColumn]=value;
4851    // Save which object it was
4852    choice.objectNumber=iObject;
4853    choice.numIntInfeasUp = numberUnsatisfied_;
4854    choice.numIntInfeasDown = numberUnsatisfied_;
4855    choice.downMovement = 0.0;
4856    choice.upMovement = 0.0;
4857    choice.numItersDown = 0;
4858    choice.numItersUp = 0;
4859    choice.fix=0; // say not fixed
4860    double objectiveChange ;
4861    double newObjectiveValue=1.0e100;
4862    int j;
4863    // status is 0 finished, 1 infeasible and other
4864    int iStatus;
4865    /*
4866      Try the down direction first. (Specify the initial branching alternative as
4867      down with a call to way(-1). Each subsequent call to branch() performs the
4868      specified branch and advances the branch object state to the next branch
4869      alternative.)
4870    */
4871    choice.possibleBranch->way(-1) ;
4872    choice.possibleBranch->branch() ;
4873    if (fabs(value-lowerValue)>integerTolerance) {
4874      solver->solveFromHotStart() ;
4875      /*
4876        We now have an estimate of objective degradation that we can use for strong
4877        branching. If we're over the cutoff, the variable is monotone up.
4878        If we actually made it to optimality, check for a solution, and if we have
4879        a good one, call setBestSolution to process it. Note that this may reduce the
4880        cutoff, so we check again to see if we can declare this variable monotone.
4881      */
4882      if (solver->isProvenOptimal())
4883        iStatus=0; // optimal
4884      else if (solver->isIterationLimitReached()
4885               &&!solver->isDualObjectiveLimitReached())
4886        iStatus=2; // unknown
4887      else
4888        iStatus=1; // infeasible
4889      newObjectiveValue = solver->getObjSense()*solver->getObjValue();
4890      choice.numItersDown = solver->getIterationCount();
4891      numberIterationsAllowed -= choice.numItersDown;
4892      objectiveChange = newObjectiveValue  - objectiveValue_;
4893      if (!iStatus) {
4894        choice.finishedDown = true ;
4895        if (newObjectiveValue>=cutoff) {
4896          objectiveChange = 1.0e100; // say infeasible
4897        } else {
4898          // See if integer solution
4899          if (model->feasibleSolution(choice.numIntInfeasDown,
4900                                      choice.numObjInfeasDown)
4901              &&model->problemFeasibility()->feasible(model,-1)>=0) {
4902            model->setBestSolution(CBC_STRONGSOL,
4903                                   newObjectiveValue,
4904                                   solver->getColSolution()) ;
4905            model->setLastHeuristic(NULL);
4906            model->incrementUsed(solver->getColSolution());
4907            cutoff =model->getCutoff();
4908            if (newObjectiveValue >= cutoff)    //  *new* cutoff
4909              objectiveChange = 1.0e100 ;
4910          }
4911        }
4912      } else if (iStatus==1) {
4913        objectiveChange = 1.0e100 ;
4914      } else {
4915        // Can't say much as we did not finish
4916        choice.finishedDown = false ;
4917      }
4918      choice.downMovement = objectiveChange ;
4919    }
4920    // restore bounds
4921    for ( j=0;j<numberColumns;j++) {
4922      if (saveLower[j] != lower[j])
4923        solver->setColLower(j,saveLower[j]);
4924      if (saveUpper[j] != upper[j])
4925        solver->setColUpper(j,saveUpper[j]);
4926    }
4927    // repeat the whole exercise, forcing the variable up
4928    choice.possibleBranch->branch();
4929    if (fabs(value-upperValue)>integerTolerance) {
4930      solver->solveFromHotStart() ;
4931      /*
4932        We now have an estimate of objective degradation that we can use for strong
4933        branching. If we're over the cutoff, the variable is monotone up.
4934        If we actually made it to optimality, check for a solution, and if we have
4935        a good one, call setBestSolution to process it. Note that this may reduce the
4936        cutoff, so we check again to see if we can declare this variable monotone.
4937      */
4938      if (solver->isProvenOptimal())
4939        iStatus=0; // optimal
4940      else if (solver->isIterationLimitReached()
4941               &&!solver->isDualObjectiveLimitReached())
4942        iStatus=2; // unknown
4943      else
4944        iStatus=1; // infeasible
4945      newObjectiveValue = solver->getObjSense()*solver->getObjValue();
4946      choice.numItersUp = solver->getIterationCount();
4947      numberIterationsAllowed -= choice.numItersUp;
4948      objectiveChange = newObjectiveValue  - objectiveValue_;
4949      if (!iStatus) {
4950        choice.finishedUp = true ;
4951        if (newObjectiveValue>=cutoff) {
4952          objectiveChange = 1.0e100; // say infeasible
4953        } else {
4954          // See if integer solution
4955          if (model->feasibleSolution(choice.numIntInfeasUp,
4956                                      choice.numObjInfeasUp)
4957              &&model->problemFeasibility()->feasible(model,-1)>=0) {
4958            model->setBestSolution(CBC_STRONGSOL,
4959                                   newObjectiveValue,
4960                                   solver->getColSolution()) ;
4961            model->setLastHeuristic(NULL);
4962            model->incrementUsed(solver->getColSolution());
4963            cutoff =model->getCutoff();
4964            if (newObjectiveValue >= cutoff)    //  *new* cutoff
4965              objectiveChange = 1.0e100 ;
4966          }
4967        }
4968      } else if (iStatus==1) {
4969        objectiveChange = 1.0e100 ;
4970      } else {
4971        // Can't say much as we did not finish
4972        choice.finishedUp = false ;
4973      }
4974      choice.upMovement = objectiveChange ;
4975     
4976      // restore bounds
4977      for ( j=0;j<numberColumns;j++) {
4978        if (saveLower[j] != lower[j])
4979          solver->setColLower(j,saveLower[j]);
4980        if (saveUpper[j] != upper[j])
4981          solver->setColUpper(j,saveUpper[j]);
4982      }
4983    }
4984    // If objective goes above certain amount we can set bound
4985    int jInt = back[iColumn];
4986    newLower[jInt]=upperValue;
4987    if (choice.finishedDown)
4988      objLower[jInt]=choice.downMovement+objectiveValue_;
4989    else
4990      objLower[jInt]=objectiveValue_;
4991    newUpper[jInt]=lowerValue;
4992    if (choice.finishedUp)
4993      objUpper[jInt]=choice.upMovement+objectiveValue_;
4994    else
4995      objUpper[jInt]=objectiveValue_;
4996    objMin = CoinMin(CoinMin(objLower[jInt],objUpper[jInt]),objMin);
4997    /*
4998      End of evaluation for this candidate variable. Possibilities are:
4999      * Both sides below cutoff; this variable is a candidate for branching.
5000      * Both sides infeasible or above the objective cutoff: no further action
5001      here. Break from the evaluation loop and assume the node will be purged
5002      by the caller.
5003      * One side below cutoff: Install the branch (i.e., fix the variable). Break
5004      from the evaluation loop and assume the node will be reoptimised by the
5005      caller.
5006    */
5007    if (choice.upMovement<1.0e100) {
5008      if(choice.downMovement<1.0e100) {
5009        objMax = CoinMax(CoinMax(objLower[jInt],objUpper[jInt]),objMax);
5010        // In case solution coming in was odd
5011        choice.upMovement = CoinMax(0.0,choice.upMovement);
5012        choice.downMovement = CoinMax(0.0,choice.downMovement);
5013        // feasible -
5014        model->messageHandler()->message(CBC_STRONG,*model->messagesPointer())
5015          << iObject << iColumn
5016          <<choice.downMovement<<choice.numIntInfeasDown
5017          <<choice.upMovement<<choice.numIntInfeasUp
5018          <<value
5019          <<CoinMessageEol;
5020      } else {
5021        // up feasible, down infeasible
5022        anyAction=-1;
5023        if (!satisfied)
5024          needResolve=true;
5025        choice.fix=1;
5026        numberToFix++;
5027        saveLower[iColumn]=upperValue;
5028        solver->setColLower(iColumn,upperValue);
5029      }
5030    } else {
5031      if(choice.downMovement<1.0e100) {
5032        // down feasible, up infeasible
5033        anyAction=-1;
5034        if (!satisfied)
5035          needResolve=true;
5036        choice.fix=-1;
5037        numberToFix++;
5038        saveUpper[iColumn]=lowerValue;
5039        solver->setColUpper(iColumn,lowerValue);
5040      } else {
5041        // neither side feasible
5042        anyAction=-2;
5043        printf("Both infeasible for choice %d sequence %d\n",i,
5044               model->object(choice.objectNumber)->columnNumber());
5045        delete ws;
5046        ws=NULL;
5047        //solver->writeMps("bad");
5048        numberToFix=-1;
5049        delete choice.possibleBranch;
5050        choice.possibleBranch=NULL;
5051        break;
5052      }
5053    }
5054    delete choice.possibleBranch;
5055    if (numberIterationsAllowed<=0)
5056      break;
5057    //printf("obj %d, col %d, down %g up %g value %g\n",iObject,iColumn,
5058    //     choice.downMovement,choice.upMovement,value);
5059  }
5060  printf("Best possible solution %g, can fix more if solution of %g found - looked at %d variables in %d iterations\n",
5061         objMin,objMax,iDo,model->numberAnalyzeIterations()-numberIterationsAllowed);
5062  model->setNumberAnalyzeIterations(numberIterationsAllowed);
5063  // Delete the snapshot
5064  solver->unmarkHotStart();
5065  // back to normal
5066  solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
5067  solver->setIntParam(OsiMaxNumIterationHotStart,saveLimit);
5068  // restore basis
5069  solver->setWarmStart(ws);
5070  delete ws;
5071   
5072  delete [] sort;
5073  delete [] whichObject;
5074  delete [] saveLower;
5075  delete [] saveUpper;
5076  delete [] back;
5077  // restore solution
5078  solver->setColSolution(saveSolution);
5079# ifdef COIN_HAS_CLP
5080  if (osiclp) 
5081    osiclp->setSpecialOptions(saveClpOptions);
5082# endif
5083  model->reserveCurrentSolution(saveSolution);
5084  delete [] saveSolution;
5085  if (needResolve)
5086    solver->resolve();
5087  return numberToFix;
5088}
5089
5090
5091CbcNode::CbcNode(const CbcNode & rhs) 
5092{ 
5093#ifdef CHECK_NODE
5094  printf("CbcNode %x Constructor from rhs %x\n",this,&rhs);
5095#endif
5096  if (rhs.nodeInfo_)
5097    nodeInfo_ = rhs.nodeInfo_->clone();
5098  else
5099    nodeInfo_=NULL;
5100  objectiveValue_=rhs.objectiveValue_;
5101  guessedObjectiveValue_ = rhs.guessedObjectiveValue_;
5102  sumInfeasibilities_ = rhs.sumInfeasibilities_;
5103  if (rhs.branch_)
5104    branch_=rhs.branch_->clone();
5105  else
5106    branch_=NULL;
5107  depth_ = rhs.depth_;
5108  numberUnsatisfied_ = rhs.numberUnsatisfied_;
5109  nodeNumber_ = rhs.nodeNumber_;
5110  state_ = rhs.state_;
5111  if (nodeInfo_)
5112    assert ((state_&2)!=0);
5113  else
5114    assert ((state_&2)==0);
5115}
5116
5117CbcNode &
5118CbcNode::operator=(const CbcNode & rhs)
5119{
5120  if (this != &rhs) {
5121    delete nodeInfo_;
5122    if (rhs.nodeInfo_)
5123      nodeInfo_ = rhs.nodeInfo_->clone();
5124    else
5125      nodeInfo_ = NULL;
5126    objectiveValue_=rhs.objectiveValue_;
5127    guessedObjectiveValue_ = rhs.guessedObjectiveValue_;
5128    sumInfeasibilities_ = rhs.sumInfeasibilities_;
5129    if (rhs.branch_)
5130      branch_=rhs.branch_->clone();
5131    else
5132      branch_=NULL,
5133    depth_ = rhs.depth_;
5134    numberUnsatisfied_ = rhs.numberUnsatisfied_;
5135    nodeNumber_ = rhs.nodeNumber_;
5136    state_ = rhs.state_;
5137    if (nodeInfo_)
5138      assert ((state_&2)!=0);
5139    else
5140      assert ((state_&2)==0);
5141  }
5142  return *this;
5143}
5144CbcNode::~CbcNode ()
5145{
5146#ifdef CHECK_NODE
5147  if (nodeInfo_) {
5148    printf("CbcNode %x Destructor nodeInfo %x (%d)\n",
5149         this,nodeInfo_,nodeInfo_->numberPointingToThis());
5150    //assert(nodeInfo_->numberPointingToThis()>=0);
5151  } else {
5152    printf("CbcNode %x Destructor nodeInfo %x (?)\n",
5153         this,nodeInfo_);
5154  }
5155#endif
5156  if (nodeInfo_) {
5157    // was if (nodeInfo_&&(state_&2)!=0) {
5158    nodeInfo_->nullOwner();
5159    int numberToDelete=nodeInfo_->numberBranchesLeft();
5160    //    CbcNodeInfo * parent = nodeInfo_->parent();
5161    //assert (nodeInfo_->numberPointingToThis()>0);
5162    if (nodeInfo_->decrement(numberToDelete)==0||(state_&2)==0) {
5163      if ((state_&2)==0) 
5164        nodeInfo_->nullParent();
5165      delete nodeInfo_;
5166    } else {
5167      //printf("node %x nodeinfo %x parent %x\n",this,nodeInfo_,nodeInfo_->parent());
5168      // anyway decrement parent
5169      //if (parent)
5170      ///parent->decrement(1);
5171    }
5172  }
5173  delete branch_;
5174}
5175// Decrement  active cut counts
5176void 
5177CbcNode::decrementCuts(int change)
5178{
5179  if (nodeInfo_)
5180    assert ((state_&2)!=0);
5181  else
5182    assert ((state_&2)==0);
5183  if(nodeInfo_) {
5184    nodeInfo_->decrementCuts(change);
5185  }
5186}
5187void 
5188CbcNode::decrementParentCuts(CbcModel * model, int change)
5189{
5190  if (nodeInfo_)
5191    assert ((state_&2)!=0);
5192  else
5193    assert ((state_&2)==0);
5194  if(nodeInfo_) {
5195    nodeInfo_->decrementParentCuts(model, change);
5196  }
5197}
5198
5199/*
5200  Initialize reference counts (numberPointingToThis, numberBranchesLeft_)
5201  in the attached nodeInfo_.
5202*/
5203void
5204CbcNode::initializeInfo()
5205{
5206  assert(nodeInfo_ && branch_) ;
5207  nodeInfo_->initializeInfo(branch_->numberBranches());
5208  assert ((state_&2)!=0);
5209  assert (nodeInfo_->numberBranchesLeft()==
5210          branch_->numberBranchesLeft());
5211}
5212// Nulls out node info
5213void 
5214CbcNode::nullNodeInfo()
5215{
5216  nodeInfo_=NULL;
5217  // say not active
5218  state_ &= ~2;
5219}
5220
5221int
5222CbcNode::branch(OsiSolverInterface * solver)
5223{
5224  double changeInGuessed;
5225  assert (nodeInfo_->numberBranchesLeft()==
5226          branch_->numberBranchesLeft());
5227  if (!solver)
5228    changeInGuessed=branch_->branch();
5229  else
5230    changeInGuessed=branch_->branch(solver);
5231  guessedObjectiveValue_+= changeInGuessed;
5232  //#define PRINTIT
5233#ifdef PRINTIT
5234  int numberLeft = nodeInfo_->numberBranchesLeft();
5235  CbcNodeInfo * parent = nodeInfo_->parent();
5236  int parentNodeNumber = -1;
5237  CbcBranchingObject * object1 = 
5238    dynamic_cast<CbcBranchingObject *>(branch_) ;
5239  //OsiObject * object = object1->
5240  //int sequence = object->columnNumber);
5241  int id=-1;
5242  double value=0.0;
5243  if (object1) {
5244    id = object1->variable();
5245    value = object1->value();
5246  }
5247  printf("id %d value %g objvalue %g\n",id,value,objectiveValue_);
5248  if (parent)
5249    parentNodeNumber = parent->nodeNumber();
5250  printf("Node number %d, %s, way %d, depth %d, parent node number %d\n",
5251         nodeInfo_->nodeNumber(),(numberLeft==2) ? "leftBranch" : "rightBranch",
5252         way(),depth_,parentNodeNumber);
5253  assert (parentNodeNumber!=nodeInfo_->nodeNumber());
5254#endif
5255  return nodeInfo_->branchedOn();
5256}
5257/* Active arm of the attached OsiBranchingObject.
5258 
5259   In the simplest instance, coded -1 for the down arm of the branch, +1 for
5260   the up arm. But see OsiBranchingObject::way()
5261     Use nodeInfo--.numberBranchesLeft_ to see how active
5262*/
5263int 
5264CbcNode::way() const
5265{
5266  if (branch_) {
5267    CbcBranchingObject * obj =
5268      dynamic_cast <CbcBranchingObject *>(branch_) ;
5269    if (obj) {
5270      return obj->way();
5271    } else {
5272      OsiTwoWayBranchingObject * obj2 =
5273      dynamic_cast <OsiTwoWayBranchingObject *>(branch_) ;
5274      assert (obj2);
5275      return obj2->way();
5276    }
5277  } else {
5278    return 0;
5279  }
5280}
5281/* Create a branching object for the node
5282
5283    The routine scans the object list of the model and selects a set of
5284    unsatisfied objects as candidates for branching. The candidates are
5285    evaluated, and an appropriate branch object is installed.
5286
5287    The numberPassesLeft is decremented to stop fixing one variable each time
5288    and going on and on (e.g. for stock cutting, air crew scheduling)
5289
5290    If evaluation determines that an object is monotone or infeasible,
5291    the routine returns immediately. In the case of a monotone object,
5292    the branch object has already been called to modify the model.
5293
5294    Return value:
5295    <ul>
5296      <li>  0: A branching object has been installed
5297      <li> -1: A monotone object was discovered
5298      <li> -2: An infeasible object was discovered
5299    </ul>
5300    Branch state:
5301    <ul>
5302      <li> -1: start
5303      <li> -1: A monotone object was discovered
5304      <li> -2: An infeasible object was discovered
5305    </ul>
5306*/
5307int 
5308CbcNode::chooseOsiBranch (CbcModel * model,
5309                          CbcNode * lastNode,
5310                          OsiBranchingInformation * usefulInfo,
5311                          int branchState)
5312{
5313  int returnStatus=0;
5314  if (lastNode)
5315    depth_ = lastNode->depth_+1;
5316  else
5317    depth_ = 0;
5318  OsiSolverInterface * solver = model->solver();
5319  objectiveValue_ = solver->getObjValue()*solver->getObjSense();
5320  usefulInfo->objectiveValue_ = objectiveValue_;
5321  usefulInfo->depth_ = depth_;
5322  const double * saveInfoSol = usefulInfo->solution_;
5323  double * saveSolution = new double[solver->getNumCols()];
5324  memcpy(saveSolution,solver->getColSolution(),solver->getNumCols()*sizeof(double));
5325  usefulInfo->solution_ = saveSolution;
5326  OsiChooseVariable * choose = model->branchingMethod()->chooseMethod();
5327  int numberUnsatisfied=-1;
5328  if (branchState<0) {
5329    // initialize
5330    // initialize sum of "infeasibilities"
5331    sumInfeasibilities_ = 0.0;
5332    numberUnsatisfied = choose->setupList(usefulInfo,true);
5333    numberUnsatisfied_ = numberUnsatisfied;
5334    branchState=0;
5335    if (numberUnsatisfied_<0) {
5336      // infeasible
5337      delete [] saveSolution;
5338      return -2;
5339    }
5340  }
5341  // unset best
5342  int best=-1;
5343  choose->setBestObjectIndex(-1);
5344  if (numberUnsatisfied) {
5345    if (branchState>0||!choose->numberOnList()) {
5346      // we need to return at once - don't do strong branching or anything
5347      if (choose->numberOnList()||!choose->numberStrong()) {
5348        best = choose->candidates()[0];
5349        choose->setBestObjectIndex(best);
5350      } else {
5351        // nothing on list - need to try again - keep any solution
5352        numberUnsatisfied = choose->setupList(usefulInfo, false);
5353        numberUnsatisfied_ = numberUnsatisfied;
5354        if (numberUnsatisfied) {
5355          best = choose->candidates()[0];
5356          choose->setBestObjectIndex(best);
5357        }
5358      }
5359    } else {
5360      // carry on with strong branching or whatever
5361      int returnCode = choose->chooseVariable(solver, usefulInfo,true);
5362      // update number of strong iterations etc
5363      model->incrementStrongInfo(choose->numberStrongDone(),choose->numberStrongIterations(),
5364                                 returnCode==-1 ? 0:choose->numberStrongFixed(),returnCode==-1);
5365      if (returnCode>1) {
5366        // has fixed some
5367        returnStatus=-1;
5368      } else if (returnCode==-1) {
5369        // infeasible
5370        returnStatus=-2;
5371      } else if (returnCode==0) {
5372        // normal
5373        returnStatus=0;
5374        numberUnsatisfied=1;
5375      } else {
5376        // ones on list satisfied - double check
5377        numberUnsatisfied = choose->setupList(usefulInfo, false);
5378        numberUnsatisfied_ = numberUnsatisfied;
5379        if (numberUnsatisfied) {
5380          best = choose->candidates()[0];
5381          choose->setBestObjectIndex(best);
5382        }
5383      }
5384    }
5385  } 
5386  delete branch_;
5387  branch_ = NULL;
5388  guessedObjectiveValue_ = COIN_DBL_MAX;//objectiveValue_; // for now
5389  if (!returnStatus) {
5390    if (numberUnsatisfied) {
5391      // create branching object
5392      const OsiObject * obj = model->solver()->object(choose->bestObjectIndex());
5393      //const OsiSolverInterface * solver = usefulInfo->solver_;
5394      branch_ = obj->createBranch(model->solver(),usefulInfo,obj->whichWay());
5395    }
5396  }
5397  usefulInfo->solution_=saveInfoSol;
5398  delete [] saveSolution;
5399  // may have got solution
5400  if (choose->goodSolution()
5401      &&model->problemFeasibility()->feasible(model,-1)>=0) {
5402    // yes
5403    double objValue = choose->goodObjectiveValue();
5404    model->setBestSolution(CBC_STRONGSOL,
5405                                     objValue,
5406                                     choose->goodSolution()) ;
5407    model->setLastHeuristic(NULL);
5408    model->incrementUsed(choose->goodSolution());
5409    choose->clearGoodSolution();
5410  }
5411  return returnStatus;
5412}
5413int 
5414CbcNode::chooseClpBranch (CbcModel * model,
5415                       CbcNode * lastNode)
5416{ 
5417  assert(lastNode);
5418  depth_ = lastNode->depth_+1;
5419  delete branch_;
5420  branch_=NULL;
5421  OsiSolverInterface * solver = model->solver();
5422  //double saveObjectiveValue = solver->getObjValue();
5423  //double objectiveValue = CoinMax(solver->getObjSense()*saveObjectiveValue,objectiveValue_);
5424  const double * lower = solver->getColLower();
5425  const double * upper = solver->getColUpper();
5426  // point to useful information
5427  OsiBranchingInformation usefulInfo = model->usefulInformation();
5428  // and modify
5429  usefulInfo.depth_=depth_;
5430  int i;
5431  //bool beforeSolution = model->getSolutionCount()==0;
5432  int numberObjects = model->numberObjects();
5433  int numberColumns = model->getNumCols();
5434  double * saveUpper = new double[numberColumns];
5435  double * saveLower = new double[numberColumns];
5436
5437  // Save solution in case heuristics need good solution later
5438 
5439  double * saveSolution = new double[numberColumns];
5440  memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
5441  model->reserveCurrentSolution(saveSolution);
5442  for (i=0;i<numberColumns;i++) {
5443    saveLower[i] = lower[i];
5444    saveUpper[i] = upper[i];
5445  }
5446  // Save basis
5447  CoinWarmStart * ws = solver->getWarmStart();
5448  numberUnsatisfied_ = 0;
5449  // initialize sum of "infeasibilities"
5450  sumInfeasibilities_ = 0.0;
5451  // Note looks as if off end (hidden one)
5452  OsiObject * object = model->modifiableObject(numberObjects);
5453  CbcGeneralDepth * thisOne = dynamic_cast <CbcGeneralDepth *> (object);
5454  assert (thisOne);
5455  OsiClpSolverInterface * clpSolver
5456    = dynamic_cast<OsiClpSolverInterface *> (solver);
5457  assert (clpSolver);
5458  ClpSimplex * simplex = clpSolver->getModelPtr();
5459  int preferredWay;
5460  double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
5461  if (thisOne->whichSolution()>=0) {
5462    ClpNode * nodeInfo = thisOne->nodeInfo(thisOne->whichSolution());
5463    nodeInfo->applyNode(simplex,2);
5464    int saveLogLevel = simplex->logLevel();
5465    simplex->setLogLevel(0);
5466    simplex->dual();
5467    simplex->setLogLevel(saveLogLevel);
5468    double cutoff = model->getCutoff();
5469    bool goodSolution=true;
5470    if (simplex->status()) {
5471      simplex->writeMps("bad7.mps",2);
5472      if (nodeInfo->objectiveValue()>cutoff-1.0e-2)
5473        goodSolution=false;
5474      else
5475        assert (!simplex->status());
5476    }
5477    if (goodSolution) {
5478      double newObjectiveValue = solver->getObjSense()*solver->getObjValue();
5479      // See if integer solution
5480      int numInf;
5481      int numInf2;
5482      bool gotSol = model->feasibleSolution(numInf,numInf2);
5483      if (!gotSol) {
5484        printf("numinf %d\n",numInf);
5485        double * sol = simplex->primalColumnSolution();
5486        for (int i=0;i<numberColumns;i++) {
5487          if (simplex->isInteger(i)) {
5488            double value = floor(sol[i]+0.5);
5489            if (fabs(value-sol[i])>1.0e-7) {
5490              printf("%d value %g\n",i,sol[i]);
5491              if (fabs(value-sol[i])<1.0e-3) {
5492                sol[i]=value;
5493              }
5494            }
5495          }
5496        }
5497        simplex->writeMps("bad8.mps",2);
5498        bool gotSol = model->feasibleSolution(numInf,numInf2);
5499        if (!gotSol) 
5500          assert (gotSol);
5501      }
5502      model->setBestSolution(CBC_STRONGSOL,
5503                             newObjectiveValue,
5504                             solver->getColSolution()) ;
5505      model->setLastHeuristic(NULL);
5506      model->incrementUsed(solver->getColSolution());
5507    }
5508  }
5509  // restore bounds
5510  { for (int j=0;j<numberColumns;j++) {
5511      if (saveLower[j] != lower[j])
5512        solver->setColLower(j,saveLower[j]);
5513      if (saveUpper[j] != upper[j])
5514        solver->setColUpper(j,saveUpper[j]);
5515    }
5516  }
5517  // restore basis
5518  solver->setWarmStart(ws);
5519  delete ws;
5520  int anyAction;
5521  //#define CHECK_PATH
5522#ifdef CHECK_PATH
5523extern int gotGoodNode_Z;
5524 if (gotGoodNode_Z>=0)
5525   printf("good node %d %g\n",gotGoodNode_Z,infeasibility);
5526#endif
5527  if (infeasibility>0.0) {
5528    if (infeasibility==COIN_DBL_MAX) {
5529      anyAction=-2; // infeasible
5530    } else {
5531      branch_=thisOne->createBranch(preferredWay);
5532      // Set to firat one (and change when re-pushing)
5533      CbcGeneralBranchingObject * branch = 
5534        dynamic_cast <CbcGeneralBranchingObject *> (branch_);
5535      branch->state(objectiveValue_,sumInfeasibilities_,
5536                    numberUnsatisfied_,0);
5537      branch->setNode(this);
5538      anyAction=0;
5539    }
5540  } else {
5541    anyAction=-1;
5542  }
5543#ifdef CHECK_PATH
5544 gotGoodNode_Z=-1;
5545#endif
5546  // Set guessed solution value
5547  guessedObjectiveValue_ = objectiveValue_+1.0e-5;
5548  delete [] saveLower;
5549  delete [] saveUpper;
5550 
5551  // restore solution
5552  solver->setColSolution(saveSolution);
5553  delete [] saveSolution;
5554  return anyAction;
5555}
5556/* Double checks in case node can change its mind!
5557   Returns objective value
5558   Can change objective etc */
5559double
5560CbcNode::checkIsCutoff(double cutoff)
5561{
5562  branch_->checkIsCutoff(cutoff);
5563  return objectiveValue_;
5564}
Note: See TracBrowser for help on using the repository browser.