Ignore:
Timestamp:
Dec 4, 2009 2:41:17 PM (10 years ago)
Author:
coin
Message:

reformatted with 'astyle -A4 -p'

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/reengAnn/Cbc/src/CbcNode.cpp

    r1304 r1355  
    4545using namespace std;
    4646#include "CglCutGenerator.hpp"
    47 // Default Constructor 
     47// Default Constructor
    4848CbcNodeInfo::CbcNodeInfo ()
    49   :
    50   numberPointingToThis_(0),
    51   parent_(NULL),
    52   parentBranch_(NULL),
    53   owner_(NULL),
    54   numberCuts_(0),
    55   nodeNumber_(0),
    56   cuts_(NULL),
    57   numberRows_(0),
    58   numberBranchesLeft_(0),
    59   active_(7)
     49        :
     50        numberPointingToThis_(0),
     51        parent_(NULL),
     52        parentBranch_(NULL),
     53        owner_(NULL),
     54        numberCuts_(0),
     55        nodeNumber_(0),
     56        cuts_(NULL),
     57        numberRows_(0),
     58        numberBranchesLeft_(0),
     59        active_(7)
    6060{
    6161#ifdef CHECK_NODE
    62   printf("CbcNodeInfo %x Constructor\n",this);
     62    printf("CbcNodeInfo %x Constructor\n", this);
    6363#endif
    6464}
     
    6767CbcNodeInfo::setParentBasedData()
    6868{
    69   if (parent_) {
    70     numberRows_ = parent_->numberRows_+parent_->numberCuts_;
    71     //parent_->increment();
    72     if (parent_->owner()) {
    73       const OsiBranchingObject* br = parent_->owner()->branchingObject();
    74       assert(br);
    75       parentBranch_ = br->clone();
    76     }
    77   }
     69    if (parent_) {
     70        numberRows_ = parent_->numberRows_ + parent_->numberCuts_;
     71        //parent_->increment();
     72        if (parent_->owner()) {
     73            const OsiBranchingObject* br = parent_->owner()->branchingObject();
     74            assert(br);
     75            parentBranch_ = br->clone();
     76        }
     77    }
    7878}
    7979
     
    8181CbcNodeInfo::unsetParentBasedData()
    8282{
    83   if (parent_) {
    84     numberRows_ = 0;
    85     if (parent_->owner()) {
    86       delete parentBranch_;
    87       parentBranch_ = NULL;
    88     }
    89   }
     83    if (parent_) {
     84        numberRows_ = 0;
     85        if (parent_->owner()) {
     86            delete parentBranch_;
     87            parentBranch_ = NULL;
     88        }
     89    }
    9090}
    9191
     
    9393// Constructor given parent
    9494CbcNodeInfo::CbcNodeInfo (CbcNodeInfo * parent)
    95   :
    96   numberPointingToThis_(2),
    97   parent_(parent),
    98   parentBranch_(NULL),
    99   owner_(NULL),
    100   numberCuts_(0),
    101   nodeNumber_(0),
    102   cuts_(NULL),
    103   numberRows_(0),
    104   numberBranchesLeft_(2),
    105   active_(7)
     95        :
     96        numberPointingToThis_(2),
     97        parent_(parent),
     98        parentBranch_(NULL),
     99        owner_(NULL),
     100        numberCuts_(0),
     101        nodeNumber_(0),
     102        cuts_(NULL),
     103        numberRows_(0),
     104        numberBranchesLeft_(2),
     105        active_(7)
    106106{
    107107#ifdef CHECK_NODE
    108   printf("CbcNodeInfo %x Constructor from parent %x\n",this,parent_);
    109 #endif
    110   //setParentBasedData();
     108    printf("CbcNodeInfo %x Constructor from parent %x\n", this, parent_);
     109#endif
     110    //setParentBasedData();
    111111}
    112112#endif
    113113
    114 // Copy Constructor 
     114// Copy Constructor
    115115CbcNodeInfo::CbcNodeInfo (const CbcNodeInfo & rhs)
    116   :
    117   numberPointingToThis_(rhs.numberPointingToThis_),
    118   parent_(rhs.parent_),
    119   parentBranch_(NULL),
    120   owner_(rhs.owner_),
    121   numberCuts_(rhs.numberCuts_),
    122   nodeNumber_(rhs.nodeNumber_),
    123   cuts_(NULL),
    124   numberRows_(rhs.numberRows_),
    125   numberBranchesLeft_(rhs.numberBranchesLeft_),
    126   active_(rhs.active_)
     116        :
     117        numberPointingToThis_(rhs.numberPointingToThis_),
     118        parent_(rhs.parent_),
     119        parentBranch_(NULL),
     120        owner_(rhs.owner_),
     121        numberCuts_(rhs.numberCuts_),
     122        nodeNumber_(rhs.nodeNumber_),
     123        cuts_(NULL),
     124        numberRows_(rhs.numberRows_),
     125        numberBranchesLeft_(rhs.numberBranchesLeft_),
     126        active_(rhs.active_)
    127127{
    128128#ifdef CHECK_NODE
    129   printf("CbcNodeInfo %x Copy constructor\n",this);
    130 #endif
    131   if (numberCuts_) {
    132     cuts_ = new CbcCountRowCut * [numberCuts_];
    133     int n=0;
    134     for (int i=0;i<numberCuts_;i++) {
    135       CbcCountRowCut * thisCut = rhs.cuts_[i];
    136       if (thisCut) {
    137         // I think this is correct - new one should take priority
    138         thisCut->setInfo(this,n);
    139         thisCut->increment(numberBranchesLeft_);
    140         cuts_[n++] = thisCut;
    141       }
    142     }
    143     numberCuts_=n;
    144   }
    145   if (rhs.parentBranch_) {
    146     parentBranch_ = rhs.parentBranch_->clone();
    147   }
     129    printf("CbcNodeInfo %x Copy constructor\n", this);
     130#endif
     131    if (numberCuts_) {
     132        cuts_ = new CbcCountRowCut * [numberCuts_];
     133        int n = 0;
     134        for (int i = 0; i < numberCuts_; i++) {
     135            CbcCountRowCut * thisCut = rhs.cuts_[i];
     136            if (thisCut) {
     137                // I think this is correct - new one should take priority
     138                thisCut->setInfo(this, n);
     139                thisCut->increment(numberBranchesLeft_);
     140                cuts_[n++] = thisCut;
     141            }
     142        }
     143        numberCuts_ = n;
     144    }
     145    if (rhs.parentBranch_) {
     146        parentBranch_ = rhs.parentBranch_->clone();
     147    }
    148148}
    149149// Constructor given parent and owner
    150150CbcNodeInfo::CbcNodeInfo (CbcNodeInfo * parent, CbcNode * owner)
    151   :
    152   numberPointingToThis_(2),
    153   parent_(parent),
    154   parentBranch_(NULL),
    155   owner_(owner),
    156   numberCuts_(0),
    157   nodeNumber_(0),
    158   cuts_(NULL),
    159   numberRows_(0),
    160   numberBranchesLeft_(2),
    161   active_(7)
     151        :
     152        numberPointingToThis_(2),
     153        parent_(parent),
     154        parentBranch_(NULL),
     155        owner_(owner),
     156        numberCuts_(0),
     157        nodeNumber_(0),
     158        cuts_(NULL),
     159        numberRows_(0),
     160        numberBranchesLeft_(2),
     161        active_(7)
    162162{
    163163#ifdef CHECK_NODE
    164   printf("CbcNodeInfo %x Constructor from parent %x\n",this,parent_);
    165 #endif
    166   //setParentBasedData();
     164    printf("CbcNodeInfo %x Constructor from parent %x\n", this, parent_);
     165#endif
     166    //setParentBasedData();
    167167}
    168168
     
    175175{
    176176#ifdef CHECK_NODE
    177   printf("CbcNodeInfo %x Destructor parent %x\n",this,parent_);
    178 #endif
    179  
    180   assert(!numberPointingToThis_);
    181   // But there may be some left (max nodes?)
    182   for (int i=0;i<numberCuts_;i++) {
    183     if (cuts_[i]) {
     177    printf("CbcNodeInfo %x Destructor parent %x\n", this, parent_);
     178#endif
     179
     180    assert(!numberPointingToThis_);
     181    // But there may be some left (max nodes?)
     182    for (int i = 0; i < numberCuts_; i++) {
     183        if (cuts_[i]) {
    184184#ifndef GLOBAL_CUTS_JUST_POINTERS
    185       delete cuts_[i];
     185            delete cuts_[i];
    186186#else
    187       if (cuts_[i]->globallyValidAsInteger()!=2)
    188         delete cuts_[i];
    189 #endif
    190     }
    191   }
    192   delete [] cuts_;
    193   if (owner_)
    194     owner_->nullNodeInfo();
    195   if (parent_) {
    196     int numberLinks = parent_->decrement();
    197     if (!numberLinks) delete parent_;
    198   }
    199   delete parentBranch_;
     187            if (cuts_[i]->globallyValidAsInteger() != 2)
     188                delete cuts_[i];
     189#endif
     190        }
     191    }
     192    delete [] cuts_;
     193    if (owner_)
     194        owner_->nullNodeInfo();
     195    if (parent_) {
     196        int numberLinks = parent_->decrement();
     197        if (!numberLinks) delete parent_;
     198    }
     199    delete parentBranch_;
    200200}
    201201
     
    205205CbcNodeInfo::decrementCuts(int change)
    206206{
    207   int i;
    208   // get rid of all remaining if negative
    209   int changeThis;
    210   if (change<0)
    211     changeThis = numberBranchesLeft_;
    212   else
    213     changeThis = change;
    214   // decrement cut counts
    215   for (i=0;i<numberCuts_;i++) {
    216     if (cuts_[i]) {
    217       int number = cuts_[i]->decrement(changeThis);
    218       if (!number) {
    219         //printf("info %x del cut %d %x\n",this,i,cuts_[i]);
     207    int i;
     208    // get rid of all remaining if negative
     209    int changeThis;
     210    if (change < 0)
     211        changeThis = numberBranchesLeft_;
     212    else
     213        changeThis = change;
     214    // decrement cut counts
     215    for (i = 0; i < numberCuts_; i++) {
     216        if (cuts_[i]) {
     217            int number = cuts_[i]->decrement(changeThis);
     218            if (!number) {
     219                //printf("info %x del cut %d %x\n",this,i,cuts_[i]);
    220220#ifndef GLOBAL_CUTS_JUST_POINTERS
    221         delete cuts_[i];
     221                delete cuts_[i];
    222222#else
    223         if (cuts_[i]->globallyValidAsInteger()!=2)
    224           delete cuts_[i];
    225 #endif
    226         cuts_[i]=NULL;
    227       }
    228     }
    229   }
     223                if (cuts_[i]->globallyValidAsInteger() != 2)
     224                    delete cuts_[i];
     225#endif
     226                cuts_[i] = NULL;
     227            }
     228        }
     229    }
    230230}
    231231void
    232232CbcNodeInfo::incrementCuts(int change)
    233233{
    234   int i;
    235   assert (change>0);
    236   // increment cut counts
    237   for (i=0;i<numberCuts_;i++) {
    238     if (cuts_[i])
    239       cuts_[i]->increment(change);
    240   }
     234    int i;
     235    assert (change > 0);
     236    // increment cut counts
     237    for (i = 0; i < numberCuts_; i++) {
     238        if (cuts_[i])
     239            cuts_[i]->increment(change);
     240    }
    241241}
    242242void
    243 CbcNodeInfo::decrementParentCuts(CbcModel * model,int change)
     243CbcNodeInfo::decrementParentCuts(CbcModel * model, int change)
    244244{
    245   if (parent_) {
    246     // get rid of all remaining if negative
    247     int changeThis;
    248     if (change<0)
    249       changeThis = numberBranchesLeft_;
    250     else
    251       changeThis = change;
    252     int i;
    253     // Get over-estimate of space needed for basis
    254     CoinWarmStartBasis & dummy = model->workingBasis();
    255     dummy.setSize(0,numberRows_+numberCuts_);
    256     buildRowBasis(dummy);
    257     /* everything is zero (i.e. free) so we can use to see
    258        if latest basis */
    259     CbcNodeInfo * thisInfo = parent_;
    260     while (thisInfo)
    261       thisInfo = thisInfo->buildRowBasis(dummy);
    262     // decrement cut counts
    263     thisInfo = parent_;
    264     int numberRows=numberRows_;
    265     while (thisInfo) {
    266       for (i=thisInfo->numberCuts_-1;i>=0;i--) {
    267         CoinWarmStartBasis::Status status = dummy.getArtifStatus(--numberRows);
     245    if (parent_) {
     246        // get rid of all remaining if negative
     247        int changeThis;
     248        if (change < 0)
     249            changeThis = numberBranchesLeft_;
     250        else
     251            changeThis = change;
     252        int i;
     253        // Get over-estimate of space needed for basis
     254        CoinWarmStartBasis & dummy = model->workingBasis();
     255        dummy.setSize(0, numberRows_ + numberCuts_);
     256        buildRowBasis(dummy);
     257        /* everything is zero (i.e. free) so we can use to see
     258           if latest basis */
     259        CbcNodeInfo * thisInfo = parent_;
     260        while (thisInfo)
     261            thisInfo = thisInfo->buildRowBasis(dummy);
     262        // decrement cut counts
     263        thisInfo = parent_;
     264        int numberRows = numberRows_;
     265        while (thisInfo) {
     266            for (i = thisInfo->numberCuts_ - 1; i >= 0; i--) {
     267                CoinWarmStartBasis::Status status = dummy.getArtifStatus(--numberRows);
    268268#ifdef ALLCUTS
    269         status = CoinWarmStartBasis::isFree;
    270 #endif
    271         if (thisInfo->cuts_[i]) {
    272           int number=1;
    273           if (status!=CoinWarmStartBasis::basic) {
    274             // tight - drop 1 or 2
    275             if (change<0)
    276               number = thisInfo->cuts_[i]->decrement(changeThis);
    277             else
    278               number = thisInfo->cuts_[i]->decrement(change);
    279           }
    280           if (!number) {
     269                status = CoinWarmStartBasis::isFree;
     270#endif
     271                if (thisInfo->cuts_[i]) {
     272                    int number = 1;
     273                    if (status != CoinWarmStartBasis::basic) {
     274                        // tight - drop 1 or 2
     275                        if (change < 0)
     276                            number = thisInfo->cuts_[i]->decrement(changeThis);
     277                        else
     278                            number = thisInfo->cuts_[i]->decrement(change);
     279                    }
     280                    if (!number) {
    281281#ifndef GLOBAL_CUTS_JUST_POINTERS
    282             delete thisInfo->cuts_[i];
     282                        delete thisInfo->cuts_[i];
    283283#else
    284             if (thisInfo->cuts_[i]->globallyValidAsInteger()!=2)
    285               delete thisInfo->cuts_[i];
    286 #endif
    287             thisInfo->cuts_[i]=NULL;
    288           }
    289         }
    290       }
    291       thisInfo = thisInfo->parent_;
    292     }
    293   }
     284                        if (thisInfo->cuts_[i]->globallyValidAsInteger() != 2)
     285                            delete thisInfo->cuts_[i];
     286#endif
     287                        thisInfo->cuts_[i] = NULL;
     288                    }
     289                }
     290            }
     291            thisInfo = thisInfo->parent_;
     292        }
     293    }
    294294}
    295295#if 0
     
    297297CbcNodeInfo::incrementParentCuts(CbcModel * model, int change)
    298298{
    299   if (parent_) {
    300     int i;
    301     // Get over-estimate of space needed for basis
    302     CoinWarmStartBasis & dummy = model->workingBasis();
    303     dummy.setSize(0,numberRows_+numberCuts_);
    304     /* everything is zero (i.e. free) so we can use to see
    305        if latest basis */
    306     buildRowBasis(dummy);
    307     CbcNodeInfo * thisInfo = parent_;
    308     while (thisInfo)
    309       thisInfo = thisInfo->buildRowBasis(dummy);
    310     // increment cut counts
    311     thisInfo = parent_;
    312     int numberRows=numberRows_;
    313     while (thisInfo) {
    314       for (i=thisInfo->numberCuts_-1;i>=0;i--) {
    315         CoinWarmStartBasis::Status status = dummy.getArtifStatus(--numberRows);
     299    if (parent_) {
     300        int i;
     301        // Get over-estimate of space needed for basis
     302        CoinWarmStartBasis & dummy = model->workingBasis();
     303        dummy.setSize(0, numberRows_ + numberCuts_);
     304        /* everything is zero (i.e. free) so we can use to see
     305           if latest basis */
     306        buildRowBasis(dummy);
     307        CbcNodeInfo * thisInfo = parent_;
     308        while (thisInfo)
     309            thisInfo = thisInfo->buildRowBasis(dummy);
     310        // increment cut counts
     311        thisInfo = parent_;
     312        int numberRows = numberRows_;
     313        while (thisInfo) {
     314            for (i = thisInfo->numberCuts_ - 1; i >= 0; i--) {
     315                CoinWarmStartBasis::Status status = dummy.getArtifStatus(--numberRows);
    316316#ifdef ALLCUTS
    317         status = CoinWarmStartBasis::isFree;
    318 #endif
    319         if (thisInfo->cuts_[i]&&status!=CoinWarmStartBasis::basic) {
    320           thisInfo->cuts_[i]->increment(change);
    321         }
    322       }
    323       thisInfo = thisInfo->parent_;
    324     }
    325   }
     317                status = CoinWarmStartBasis::isFree;
     318#endif
     319                if (thisInfo->cuts_[i] && status != CoinWarmStartBasis::basic) {
     320                    thisInfo->cuts_[i]->increment(change);
     321                }
     322            }
     323            thisInfo = thisInfo->parent_;
     324        }
     325    }
    326326}
    327327#endif
     
    334334void
    335335CbcNodeInfo::addCuts (OsiCuts & cuts, int numberToBranchOn,
    336                       /*int * whichGenerator,*/int numberPointingToThis)
     336                      /*int * whichGenerator,*/int numberPointingToThis)
    337337{
    338   int numberCuts = cuts.sizeRowCuts();
    339   if (numberCuts) {
    340     int i;
    341     if (!numberCuts_) {
    342       cuts_ = new CbcCountRowCut * [numberCuts];
    343     } else {
    344       CbcCountRowCut ** temp = new CbcCountRowCut * [numberCuts+numberCuts_];
    345       memcpy(temp,cuts_,numberCuts_*sizeof(CbcCountRowCut *));
    346       delete [] cuts_;
    347       cuts_ = temp;
    348     }
    349     for (i=0;i<numberCuts;i++) {
    350       CbcCountRowCut * thisCut = new CbcCountRowCut(*cuts.rowCutPtr(i),
    351                                                     this,numberCuts_,
    352                                                     -1,numberPointingToThis);
    353       thisCut->increment(numberToBranchOn);
    354       cuts_[numberCuts_++] = thisCut;
     338    int numberCuts = cuts.sizeRowCuts();
     339    if (numberCuts) {
     340        int i;
     341        if (!numberCuts_) {
     342            cuts_ = new CbcCountRowCut * [numberCuts];
     343        } else {
     344            CbcCountRowCut ** temp = new CbcCountRowCut * [numberCuts+numberCuts_];
     345            memcpy(temp, cuts_, numberCuts_*sizeof(CbcCountRowCut *));
     346            delete [] cuts_;
     347            cuts_ = temp;
     348        }
     349        for (i = 0; i < numberCuts; i++) {
     350            CbcCountRowCut * thisCut = new CbcCountRowCut(*cuts.rowCutPtr(i),
     351                    this, numberCuts_,
     352                    -1, numberPointingToThis);
     353            thisCut->increment(numberToBranchOn);
     354            cuts_[numberCuts_++] = thisCut;
    355355#ifdef CBC_DEBUG
    356356#if CBC_DEBUG>1
    357       int n=thisCut->row().getNumElements();
    358       printf("Cut %d has %d entries, rhs %g %g =>",i,n,thisCut->lb(),
    359              thisCut->ub());
    360       int j;
    361       const int * index = thisCut->row().getIndices();
    362       const double * element = thisCut->row().getElements();
    363       for (j=0;j<n;j++) {
    364         printf(" (%d,%g)",index[j],element[j]);
    365         assert(fabs(element[j])>1.00e-12);
    366       }
    367       printf("\n");
     357            int n = thisCut->row().getNumElements();
     358            printf("Cut %d has %d entries, rhs %g %g =>", i, n, thisCut->lb(),
     359                   thisCut->ub());
     360            int j;
     361            const int * index = thisCut->row().getIndices();
     362            const double * element = thisCut->row().getElements();
     363            for (j = 0; j < n; j++) {
     364                printf(" (%d,%g)", index[j], element[j]);
     365                assert(fabs(element[j]) > 1.00e-12);
     366            }
     367            printf("\n");
    368368#else
    369       int n=thisCut->row().getNumElements();
    370       int j;
    371       const double * element = thisCut->row().getElements();
    372       for (j=0;j<n;j++) {
    373         assert(fabs(element[j])>1.00e-12);
    374       }
    375 #endif
    376 #endif
    377     }
    378   }
     369            int n = thisCut->row().getNumElements();
     370            int j;
     371            const double * element = thisCut->row().getElements();
     372            for (j = 0; j < n; j++) {
     373                assert(fabs(element[j]) > 1.00e-12);
     374            }
     375#endif
     376#endif
     377        }
     378    }
    379379}
    380380
    381381void
    382 CbcNodeInfo::addCuts(int numberCuts, CbcCountRowCut ** cut, 
    383                      int numberToBranchOn)
     382CbcNodeInfo::addCuts(int numberCuts, CbcCountRowCut ** cut,
     383                     int numberToBranchOn)
    384384{
    385   if (numberCuts) {
    386     int i;
    387     if (!numberCuts_) {
    388       cuts_ = new CbcCountRowCut * [numberCuts];
    389     } else {
    390       CbcCountRowCut ** temp = new CbcCountRowCut * [numberCuts+numberCuts_];
    391       memcpy(temp,cuts_,numberCuts_*sizeof(CbcCountRowCut *));
    392       delete [] cuts_;
    393       cuts_ = temp;
    394     }
    395     for (i=0;i<numberCuts;i++) {
    396       CbcCountRowCut * thisCut = cut[i];
    397       thisCut->setInfo(this,numberCuts_);
    398       //printf("info %x cut %d %x\n",this,i,thisCut);
    399       thisCut->increment(numberToBranchOn);
    400       cuts_[numberCuts_++] = thisCut;
     385    if (numberCuts) {
     386        int i;
     387        if (!numberCuts_) {
     388            cuts_ = new CbcCountRowCut * [numberCuts];
     389        } else {
     390            CbcCountRowCut ** temp = new CbcCountRowCut * [numberCuts+numberCuts_];
     391            memcpy(temp, cuts_, numberCuts_*sizeof(CbcCountRowCut *));
     392            delete [] cuts_;
     393            cuts_ = temp;
     394        }
     395        for (i = 0; i < numberCuts; i++) {
     396            CbcCountRowCut * thisCut = cut[i];
     397            thisCut->setInfo(this, numberCuts_);
     398            //printf("info %x cut %d %x\n",this,i,thisCut);
     399            thisCut->increment(numberToBranchOn);
     400            cuts_[numberCuts_++] = thisCut;
    401401#ifdef CBC_DEBUG
    402       int n=thisCut->row().getNumElements();
     402            int n = thisCut->row().getNumElements();
    403403#if CBC_DEBUG>1
    404       printf("Cut %d has %d entries, rhs %g %g =>",i,n,thisCut->lb(),
    405              thisCut->ub());
    406 #endif
    407       int j;
     404            printf("Cut %d has %d entries, rhs %g %g =>", i, n, thisCut->lb(),
     405                   thisCut->ub());
     406#endif
     407            int j;
    408408#if CBC_DEBUG>1
    409       const int * index = thisCut->row().getIndices();
    410 #endif
    411       const double * element = thisCut->row().getElements();
    412       for (j=0;j<n;j++) {
     409            const int * index = thisCut->row().getIndices();
     410#endif
     411            const double * element = thisCut->row().getElements();
     412            for (j = 0; j < n; j++) {
    413413#if CBC_DEBUG>1
    414         printf(" (%d,%g)",index[j],element[j]);
    415 #endif
    416         assert(fabs(element[j])>1.00e-12);
    417       }
    418       printf("\n");
    419 #endif
    420     }
    421   }
     414                printf(" (%d,%g)", index[j], element[j]);
     415#endif
     416                assert(fabs(element[j]) > 1.00e-12);
     417            }
     418            printf("\n");
     419#endif
     420        }
     421    }
    422422}
    423423
     
    426426CbcNodeInfo::deleteCuts(int numberToDelete, CbcCountRowCut ** cuts)
    427427{
    428   int i;
    429   int j;
    430   int last=-1;
    431   for (i=0;i<numberToDelete;i++) {
    432     CbcCountRowCut * next = cuts[i];
    433     for (j=last+1;j<numberCuts_;j++) {
    434       if (next==cuts_[j])
    435         break;
    436     }
    437     if (j==numberCuts_) {
    438       // start from beginning
    439       for (j=0;j<last;j++) {
    440         if (next==cuts_[j])
    441           break;
    442       }
    443       assert(j<last);
    444     }
    445     last=j;
    446     int number = cuts_[j]->decrement();
    447     if (!number) {
     428    int i;
     429    int j;
     430    int last = -1;
     431    for (i = 0; i < numberToDelete; i++) {
     432        CbcCountRowCut * next = cuts[i];
     433        for (j = last + 1; j < numberCuts_; j++) {
     434            if (next == cuts_[j])
     435                break;
     436        }
     437        if (j == numberCuts_) {
     438            // start from beginning
     439            for (j = 0; j < last; j++) {
     440                if (next == cuts_[j])
     441                    break;
     442            }
     443            assert(j < last);
     444        }
     445        last = j;
     446        int number = cuts_[j]->decrement();
     447        if (!number) {
    448448#ifndef GLOBAL_CUTS_JUST_POINTERS
    449       delete cuts_[j];
     449            delete cuts_[j];
    450450#else
    451       if (cuts_[j]->globallyValidAsInteger()!=2)
    452         delete cuts_[j];
    453 #endif
    454     }
    455     cuts_[j]=NULL;
    456   }
    457   j=0;
    458   for (i=0;i<numberCuts_;i++) {
    459     if (cuts_[i])
    460       cuts_[j++]=cuts_[i];
    461   }
    462   numberCuts_ = j;
     451            if (cuts_[j]->globallyValidAsInteger() != 2)
     452                delete cuts_[j];
     453#endif
     454        }
     455        cuts_[j] = NULL;
     456    }
     457    j = 0;
     458    for (i = 0; i < numberCuts_; i++) {
     459        if (cuts_[i])
     460            cuts_[j++] = cuts_[i];
     461    }
     462    numberCuts_ = j;
    463463}
    464464
     
    467467CbcNodeInfo::deleteCuts(int numberToDelete, int * which)
    468468{
    469   int i;
    470   for (i=0;i<numberToDelete;i++) {
    471     int iCut=which[i];
    472     int number = cuts_[iCut]->decrement();
    473     if (!number) {
     469    int i;
     470    for (i = 0; i < numberToDelete; i++) {
     471        int iCut = which[i];
     472        int number = cuts_[iCut]->decrement();
     473        if (!number) {
    474474#ifndef GLOBAL_CUTS_JUST_POINTERS
    475       delete cuts_[iCut];
     475            delete cuts_[iCut];
    476476#else
    477       if (cuts_[iCut]->globallyValidAsInteger()!=2)
    478         delete cuts_[iCut];
    479 #endif
    480     }
    481     cuts_[iCut]=NULL;
    482   }
    483   int j=0;
    484   for (i=0;i<numberCuts_;i++) {
    485     if (cuts_[i])
    486       cuts_[j++]=cuts_[i];
    487   }
    488   numberCuts_ = j;
     477            if (cuts_[iCut]->globallyValidAsInteger() != 2)
     478                delete cuts_[iCut];
     479#endif
     480        }
     481        cuts_[iCut] = NULL;
     482    }
     483    int j = 0;
     484    for (i = 0; i < numberCuts_; i++) {
     485        if (cuts_[i])
     486            cuts_[j++] = cuts_[i];
     487    }
     488    numberCuts_ = j;
    489489}
    490490
    491491// Really delete a cut
    492 void 
     492void
    493493CbcNodeInfo::deleteCut(int whichOne)
    494494{
    495   assert(whichOne<numberCuts_);
    496   cuts_[whichOne]=NULL;
     495    assert(whichOne < numberCuts_);
     496    cuts_[whichOne] = NULL;
    497497}
    498498/* Deactivate node information.
     
    501501   4 - basis!
    502502*/
    503 void 
     503void
    504504CbcNodeInfo::deactivate(int mode)
    505505{
    506   active_ &= (~mode);
     506    active_ &= (~mode);
    507507}
    508508
    509509CbcFullNodeInfo::CbcFullNodeInfo() :
    510   CbcNodeInfo(),
    511   basis_(),
    512   numberIntegers_(0),
    513   lower_(NULL),
    514   upper_(NULL)
     510        CbcNodeInfo(),
     511        basis_(),
     512        numberIntegers_(0),
     513        lower_(NULL),
     514        upper_(NULL)
    515515{
    516516}
    517517CbcFullNodeInfo::CbcFullNodeInfo(CbcModel * model,
    518                                 int numberRowsAtContinuous) :
    519   CbcNodeInfo(NULL, model->currentNode())
     518                                int numberRowsAtContinuous) :
     519        CbcNodeInfo(NULL, model->currentNode())
    520520{
    521   OsiSolverInterface * solver = model->solver();
    522   numberRows_ = numberRowsAtContinuous;
    523   numberIntegers_ = model->numberIntegers();
    524   int numberColumns = model->getNumCols();
    525   lower_ = new double [numberColumns];
    526   upper_ = new double [numberColumns];
    527   const double * lower = solver->getColLower();
    528   const double * upper = solver->getColUpper();
    529   int i;
    530  
    531   for (i=0;i<numberColumns;i++) {
    532     lower_[i]=lower[i];
    533     upper_[i]=upper[i];
    534   }
    535  
    536   basis_ =  dynamic_cast<CoinWarmStartBasis*>(solver->getWarmStart());
    537 }
    538 
    539 CbcFullNodeInfo::CbcFullNodeInfo(const CbcFullNodeInfo & rhs) :
    540   CbcNodeInfo(rhs)
    541 
    542   basis_= dynamic_cast<CoinWarmStartBasis *>(rhs.basis_->clone()) ;
    543   numberIntegers_=rhs.numberIntegers_;
    544   lower_=NULL;
    545   upper_=NULL;
    546   if (rhs.lower_!=NULL) {
    547     int numberColumns = basis_->getNumStructural();
     521    OsiSolverInterface * solver = model->solver();
     522    numberRows_ = numberRowsAtContinuous;
     523    numberIntegers_ = model->numberIntegers();
     524    int numberColumns = model->getNumCols();
    548525    lower_ = new double [numberColumns];
    549526    upper_ = new double [numberColumns];
    550     assert (upper_!=NULL);
    551     memcpy(lower_,rhs.lower_,numberColumns*sizeof(double));
    552     memcpy(upper_,rhs.upper_,numberColumns*sizeof(double));
    553   }
     527    const double * lower = solver->getColLower();
     528    const double * upper = solver->getColUpper();
     529    int i;
     530
     531    for (i = 0; i < numberColumns; i++) {
     532        lower_[i] = lower[i];
     533        upper_[i] = upper[i];
     534    }
     535
     536    basis_ =  dynamic_cast<CoinWarmStartBasis*>(solver->getWarmStart());
    554537}
    555538
    556 CbcNodeInfo *
     539CbcFullNodeInfo::CbcFullNodeInfo(const CbcFullNodeInfo & rhs) :
     540        CbcNodeInfo(rhs)
     541{
     542    basis_ = dynamic_cast<CoinWarmStartBasis *>(rhs.basis_->clone()) ;
     543    numberIntegers_ = rhs.numberIntegers_;
     544    lower_ = NULL;
     545    upper_ = NULL;
     546    if (rhs.lower_ != NULL) {
     547        int numberColumns = basis_->getNumStructural();
     548        lower_ = new double [numberColumns];
     549        upper_ = new double [numberColumns];
     550        assert (upper_ != NULL);
     551        memcpy(lower_, rhs.lower_, numberColumns*sizeof(double));
     552        memcpy(upper_, rhs.upper_, numberColumns*sizeof(double));
     553    }
     554}
     555
     556CbcNodeInfo *
    557557CbcFullNodeInfo::clone() const
    558 { 
    559   return (new CbcFullNodeInfo(*this));
     558{
     559    return (new CbcFullNodeInfo(*this));
    560560}
    561561
    562562CbcFullNodeInfo::~CbcFullNodeInfo ()
    563563{
    564   delete basis_ ;
    565   delete [] lower_;
    566   delete [] upper_;
     564    delete basis_ ;
     565    delete [] lower_;
     566    delete [] upper_;
    567567}
    568568
     
    573573  node are added to the list in addCuts, but not actually added to the
    574574  constraint system in the model.
    575  
     575
    576576  Why pass in a basis at all? The short answer is ``We need the parameter to
    577577  pass out a basis, so might as well use it to pass in the size.''
    578  
     578
    579579  A longer answer is that in practice we take a memory allocation hit up in
    580580  addCuts1 (the only place applyToModel is called) when we setSize() the
     
    585585
    586586void CbcFullNodeInfo::applyToModel (CbcModel *model,
    587                                     CoinWarmStartBasis *&basis,
    588                                     CbcCountRowCut **addCuts,
    589                                     int &currentNumberCuts) const
    590  
    591 { OsiSolverInterface *solver = model->solver() ;
    592  
    593   // branch - do bounds
    594   assert (active_==7||active_==15);
    595   int i;
    596   solver->setColLower(lower_);
    597   solver->setColUpper(upper_);
    598   int numberColumns = model->getNumCols();
    599   // move basis - but make sure size stays
    600   // for bon-min - should not be needed int numberRows = model->getNumRows();
    601   int numberRows=basis->getNumArtificial();
    602   delete basis ;
    603   if (basis_) {
    604     basis = dynamic_cast<CoinWarmStartBasis *>(basis_->clone()) ;
    605     basis->resize(numberRows,numberColumns);
     587                                    CoinWarmStartBasis *&basis,
     588                                    CbcCountRowCut **addCuts,
     589                                    int &currentNumberCuts) const
     590
     591{
     592    OsiSolverInterface *solver = model->solver() ;
     593
     594    // branch - do bounds
     595    assert (active_ == 7 || active_ == 15);
     596    int i;
     597    solver->setColLower(lower_);
     598    solver->setColUpper(upper_);
     599    int numberColumns = model->getNumCols();
     600    // move basis - but make sure size stays
     601    // for bon-min - should not be needed int numberRows = model->getNumRows();
     602    int numberRows = basis->getNumArtificial();
     603    delete basis ;
     604    if (basis_) {
     605        basis = dynamic_cast<CoinWarmStartBasis *>(basis_->clone()) ;
     606        basis->resize(numberRows, numberColumns);
    606607#ifdef CBC_CHECK_BASIS
    607     std::cout << "Basis (after applying root " <<this<<") "<< std::endl ;
    608     basis->print() ;
    609 #endif   
    610   } else {
    611     // We have a solver without a basis
    612     basis=NULL;
    613   }
    614   for (i=0;i<numberCuts_;i++)
    615     addCuts[currentNumberCuts+i]= cuts_[i];
    616   currentNumberCuts += numberCuts_;
    617   assert(!parent_);
    618   return ;
     608        std::cout << "Basis (after applying root " << this << ") " << std::endl ;
     609        basis->print() ;
     610#endif
     611    } else {
     612        // We have a solver without a basis
     613        basis = NULL;
     614    }
     615    for (i = 0; i < numberCuts_; i++)
     616        addCuts[currentNumberCuts+i] = cuts_[i];
     617    currentNumberCuts += numberCuts_;
     618    assert(!parent_);
     619    return ;
    619620}
    620621// Just apply bounds to one variable (1=>infeasible)
    621 int 
    622 CbcFullNodeInfo::applyBounds(int iColumn, double & lower, double & upper,int force)
     622int
     623CbcFullNodeInfo::applyBounds(int iColumn, double & lower, double & upper, int force)
    623624{
    624   if ((force&&1)==0) {
    625     if (lower>lower_[iColumn])
    626       printf("%d odd lower going from %g to %g\n",iColumn,lower,lower_[iColumn]);
    627     lower = lower_[iColumn];
    628   } else {
    629     lower_[iColumn]=lower;
    630   }
    631   if ((force&&2)==0) {
    632     if (upper<upper_[iColumn])
    633       printf("%d odd upper going from %g to %g\n",iColumn,upper,upper_[iColumn]);
    634     upper = upper_[iColumn];
    635   } else {
    636     upper_[iColumn]=upper;
    637   }
    638   return (upper_[iColumn]>=lower_[iColumn]) ? 0 : 1;
     625    if ((force && 1) == 0) {
     626        if (lower > lower_[iColumn])
     627            printf("%d odd lower going from %g to %g\n", iColumn, lower, lower_[iColumn]);
     628        lower = lower_[iColumn];
     629    } else {
     630        lower_[iColumn] = lower;
     631    }
     632    if ((force && 2) == 0) {
     633        if (upper < upper_[iColumn])
     634            printf("%d odd upper going from %g to %g\n", iColumn, upper, upper_[iColumn]);
     635        upper = upper_[iColumn];
     636    } else {
     637        upper_[iColumn] = upper;
     638    }
     639    return (upper_[iColumn] >= lower_[iColumn]) ? 0 : 1;
    639640}
    640641
     
    643644   Depends on Free being 0 and impossible for cuts
    644645*/
    645 CbcNodeInfo * 
    646 CbcFullNodeInfo::buildRowBasis(CoinWarmStartBasis & basis ) const 
     646CbcNodeInfo *
     647CbcFullNodeInfo::buildRowBasis(CoinWarmStartBasis & basis ) const
    647648{
    648   const unsigned int * saved =
    649     reinterpret_cast<const unsigned int *> (basis_->getArtificialStatus());
    650   unsigned int * now =
    651     reinterpret_cast<unsigned int *> (basis.getArtificialStatus());
    652   int number=basis_->getNumArtificial()>>4;;
    653   int i;
    654   for (i=0;i<number;i++) {
    655     if (!now[i])
    656       now[i] = saved[i];
    657   }
    658   return NULL;
     649    const unsigned int * saved =
     650        reinterpret_cast<const unsigned int *> (basis_->getArtificialStatus());
     651    unsigned int * now =
     652        reinterpret_cast<unsigned int *> (basis.getArtificialStatus());
     653    int number = basis_->getNumArtificial() >> 4;;
     654    int i;
     655    for (i = 0; i < number; i++) {
     656        if (!now[i])
     657            now[i] = saved[i];
     658    }
     659    return NULL;
    659660}
    660661
     
    662663// Default constructor
    663664CbcPartialNodeInfo::CbcPartialNodeInfo()
    664  
    665   : CbcNodeInfo(),
    666     basisDiff_(NULL),
    667     variables_(NULL),
    668     newBounds_(NULL),
    669     numberChangedBounds_(0)
    670    
     665
     666        : CbcNodeInfo(),
     667        basisDiff_(NULL),
     668        variables_(NULL),
     669        newBounds_(NULL),
     670        numberChangedBounds_(0)
     671
    671672{ /* this space intentionally left blank */ }
    672673
    673 // Constructor from current state 
     674// Constructor from current state
    674675CbcPartialNodeInfo::CbcPartialNodeInfo (CbcNodeInfo *parent, CbcNode *owner,
    675                                         int numberChangedBounds,
    676                                         const int *variables,
    677                                         const double *boundChanges,
    678                                         const CoinWarmStartDiff *basisDiff)
    679   : CbcNodeInfo(parent,owner)
     676                                        int numberChangedBounds,
     677                                        const int *variables,
     678                                        const double *boundChanges,
     679                                        const CoinWarmStartDiff *basisDiff)
     680        : CbcNodeInfo(parent, owner)
    680681{
    681   basisDiff_ = basisDiff->clone() ;
     682    basisDiff_ = basisDiff->clone() ;
    682683#ifdef CBC_CHECK_BASIS
    683   std::cout << "Constructor (" <<this<<") "<< std::endl ;
    684 #endif   
    685  
    686   numberChangedBounds_ = numberChangedBounds;
    687   int size = numberChangedBounds_*(sizeof(double)+sizeof(int));
    688   char * temp = new char [size];
    689   newBounds_ = reinterpret_cast<double *> (temp);
    690   variables_ = reinterpret_cast<int *> (newBounds_+numberChangedBounds_);
    691  
    692   int i ;
    693   for (i=0;i<numberChangedBounds_;i++) {
    694     variables_[i]=variables[i];
    695     newBounds_[i]=boundChanges[i];
    696   }
     684    std::cout << "Constructor (" << this << ") " << std::endl ;
     685#endif
     686
     687    numberChangedBounds_ = numberChangedBounds;
     688    int size = numberChangedBounds_ * (sizeof(double) + sizeof(int));
     689    char * temp = new char [size];
     690    newBounds_ = reinterpret_cast<double *> (temp);
     691    variables_ = reinterpret_cast<int *> (newBounds_ + numberChangedBounds_);
     692
     693    int i ;
     694    for (i = 0; i < numberChangedBounds_; i++) {
     695        variables_[i] = variables[i];
     696        newBounds_[i] = boundChanges[i];
     697    }
    697698}
    698699
    699700CbcPartialNodeInfo::CbcPartialNodeInfo (const CbcPartialNodeInfo & rhs)
    700  
    701   : CbcNodeInfo(rhs)
    702    
    703 { basisDiff_ = rhs.basisDiff_->clone() ;
    704  
     701
     702        : CbcNodeInfo(rhs)
     703
     704{
     705    basisDiff_ = rhs.basisDiff_->clone() ;
     706
    705707#ifdef CBC_CHECK_BASIS
    706   std::cout << "Copy constructor (" <<this<<") from "<<this<< std::endl ;
    707 #endif   
    708   numberChangedBounds_ = rhs.numberChangedBounds_;
    709   int size = numberChangedBounds_*(sizeof(double)+sizeof(int));
    710   char * temp = new char [size];
    711   newBounds_ = reinterpret_cast<double *> (temp);
    712   variables_ = reinterpret_cast<int *> (newBounds_+numberChangedBounds_);
    713  
    714   int i ;
    715   for (i=0;i<numberChangedBounds_;i++) {
    716     variables_[i]=rhs.variables_[i];
    717     newBounds_[i]=rhs.newBounds_[i];
    718   }
     708    std::cout << "Copy constructor (" << this << ") from " << this << std::endl ;
     709#endif
     710    numberChangedBounds_ = rhs.numberChangedBounds_;
     711    int size = numberChangedBounds_ * (sizeof(double) + sizeof(int));
     712    char * temp = new char [size];
     713    newBounds_ = reinterpret_cast<double *> (temp);
     714    variables_ = reinterpret_cast<int *> (newBounds_ + numberChangedBounds_);
     715
     716    int i ;
     717    for (i = 0; i < numberChangedBounds_; i++) {
     718        variables_[i] = rhs.variables_[i];
     719        newBounds_[i] = rhs.newBounds_[i];
     720    }
    719721}
    720722
    721 CbcNodeInfo * 
     723CbcNodeInfo *
    722724CbcPartialNodeInfo::clone() const
    723 { 
    724   return (new CbcPartialNodeInfo(*this));
     725{
     726    return (new CbcPartialNodeInfo(*this));
    725727}
    726728
     
    728730CbcPartialNodeInfo::~CbcPartialNodeInfo ()
    729731{
    730   delete basisDiff_ ;
    731   delete [] newBounds_;
     732    delete basisDiff_ ;
     733    delete [] newBounds_;
    732734}
    733735
     
    740742
    741743void CbcPartialNodeInfo::applyToModel (CbcModel *model,
    742                                        CoinWarmStartBasis *&basis,
    743                                        CbcCountRowCut **addCuts,
    744                                        int &currentNumberCuts) const
    745  
    746 { OsiSolverInterface *solver = model->solver();
    747   if ((active_&4)!=0) {
    748     basis->applyDiff(basisDiff_) ;
     744                                       CoinWarmStartBasis *&basis,
     745                                       CbcCountRowCut **addCuts,
     746                                       int &currentNumberCuts) const
     747
     748{
     749    OsiSolverInterface *solver = model->solver();
     750    if ((active_&4) != 0) {
     751        basis->applyDiff(basisDiff_) ;
    749752#ifdef CBC_CHECK_BASIS
    750     std::cout << "Basis (after applying " <<this<<") "<< std::endl ;
    751     basis->print() ;
    752 #endif   
    753   }
    754  
    755   // branch - do bounds
    756   int i;
    757   if ((active_&1)!=0) {
    758     for (i=0;i<numberChangedBounds_;i++) {
    759       int variable = variables_[i];
    760       int k = variable&0x3fffffff;
    761       if ((variable&0x80000000)==0) {
    762         // lower bound changing
    763         //#define CBC_PRINT2
     753        std::cout << "Basis (after applying " << this << ") " << std::endl ;
     754        basis->print() ;
     755#endif
     756    }
     757
     758    // branch - do bounds
     759    int i;
     760    if ((active_&1) != 0) {
     761        for (i = 0; i < numberChangedBounds_; i++) {
     762            int variable = variables_[i];
     763            int k = variable & 0x3fffffff;
     764            if ((variable&0x80000000) == 0) {
     765                // lower bound changing
     766                //#define CBC_PRINT2
    764767#ifdef CBC_PRINT2
    765         if(solver->getColLower()[k]!=newBounds_[i])
    766           printf("lower change for column %d - from %g to %g\n",k,solver->getColLower()[k],newBounds_[i]);
     768                if (solver->getColLower()[k] != newBounds_[i])
     769                    printf("lower change for column %d - from %g to %g\n", k, solver->getColLower()[k], newBounds_[i]);
    767770#endif
    768771#ifndef NDEBUG
    769         if ((variable&0x40000000)==0&&false) {
    770           double oldValue = solver->getColLower()[k];
    771           assert (newBounds_[i]>oldValue-1.0e-8);
    772           if (newBounds_[i]<oldValue+1.0e-8)
    773             printf("bad null lower change for column %d - bound %g\n",k,oldValue);
    774         }
    775 #endif
    776         solver->setColLower(k,newBounds_[i]);
    777       } else {
    778         // upper bound changing
     772                if ((variable&0x40000000) == 0 && false) {
     773                    double oldValue = solver->getColLower()[k];
     774                    assert (newBounds_[i] > oldValue - 1.0e-8);
     775                    if (newBounds_[i] < oldValue + 1.0e-8)
     776                        printf("bad null lower change for column %d - bound %g\n", k, oldValue);
     777                }
     778#endif
     779                solver->setColLower(k, newBounds_[i]);
     780            } else {
     781                // upper bound changing
    779782#ifdef CBC_PRINT2
    780         if(solver->getColUpper()[k]!=newBounds_[i])
    781           printf("upper change for column %d - from %g to %g\n",k,solver->getColUpper()[k],newBounds_[i]);
     783                if (solver->getColUpper()[k] != newBounds_[i])
     784                    printf("upper change for column %d - from %g to %g\n", k, solver->getColUpper()[k], newBounds_[i]);
    782785#endif
    783786#ifndef NDEBUG
    784         if ((variable&0x40000000)==0&&false) {
    785           double oldValue = solver->getColUpper()[k];
    786           assert (newBounds_[i]<oldValue+1.0e-8);
    787           if (newBounds_[i]>oldValue-1.0e-8)
    788             printf("bad null upper change for column %d - bound %g\n",k,oldValue);
    789         }
    790 #endif
    791         solver->setColUpper(k,newBounds_[i]);
    792       }
    793     }
    794   }
    795   if ((active_&2)!=0) {
    796     for (i=0;i<numberCuts_;i++) {
    797       addCuts[currentNumberCuts+i]= cuts_[i];
    798       if (cuts_[i]&&model->messageHandler()->logLevel()>4) {
    799         cuts_[i]->print();
    800       }
    801     }
    802    
    803     currentNumberCuts += numberCuts_;
    804   }
    805   return ;
     787                if ((variable&0x40000000) == 0 && false) {
     788                    double oldValue = solver->getColUpper()[k];
     789                    assert (newBounds_[i] < oldValue + 1.0e-8);
     790                    if (newBounds_[i] > oldValue - 1.0e-8)
     791                        printf("bad null upper change for column %d - bound %g\n", k, oldValue);
     792                }
     793#endif
     794                solver->setColUpper(k, newBounds_[i]);
     795            }
     796        }
     797    }
     798    if ((active_&2) != 0) {
     799        for (i = 0; i < numberCuts_; i++) {
     800            addCuts[currentNumberCuts+i] = cuts_[i];
     801            if (cuts_[i] && model->messageHandler()->logLevel() > 4) {
     802                cuts_[i]->print();
     803            }
     804        }
     805
     806        currentNumberCuts += numberCuts_;
     807    }
     808    return ;
    806809}
    807810// Just apply bounds to one variable (1=>infeasible)
    808811int
    809 CbcPartialNodeInfo::applyBounds(int iColumn, double & lower, double & upper,int force)
     812CbcPartialNodeInfo::applyBounds(int iColumn, double & lower, double & upper, int force)
    810813{
    811   // branch - do bounds
    812   int i;
    813   int found=0;
    814   double newLower = -COIN_DBL_MAX;
    815   double newUpper = COIN_DBL_MAX;
    816   for (i=0;i<numberChangedBounds_;i++) {
    817     int variable = variables_[i];
    818     int k = variable&0x3fffffff;
    819     if (k==iColumn) {
    820       if ((variable&0x80000000)==0) {
    821         // lower bound changing
    822         found |= 1;
    823         newLower = CoinMax(newLower,newBounds_[i]);
    824         if ((force&1)==0) {
    825           if (lower>newBounds_[i])
    826             printf("%d odd lower going from %g to %g\n",iColumn,lower,newBounds_[i]);
    827           lower = newBounds_[i];
    828         } else {
    829           newBounds_[i]=lower;
    830           variables_[i] |= 0x40000000; // say can go odd way
    831         }
    832       } else {
    833         // upper bound changing
    834         found |= 2;
    835         newUpper = CoinMin(newUpper,newBounds_[i]);
    836         if ((force&2)==0) {
    837           if (upper<newBounds_[i])
    838             printf("%d odd upper going from %g to %g\n",iColumn,upper,newBounds_[i]);
    839           upper = newBounds_[i];
    840         } else {
    841           newBounds_[i]=upper;
    842           variables_[i] |= 0x40000000; // say can go odd way
    843         }
    844       }
    845     }
    846   }
    847   newLower = CoinMax(newLower,lower);
    848   newUpper = CoinMin(newUpper,upper);
    849   int nAdd=0;
    850   if ((force&2)!=0&&(found&2)==0) {
    851     // need to add new upper
    852     nAdd++;
    853   }
    854   if ((force&1)!=0&&(found&1)==0) {
    855     // need to add new lower
    856     nAdd++;
    857   }
    858   if (nAdd) {
    859     int size = (numberChangedBounds_+nAdd)*(sizeof(double)+sizeof(int));
    860     char * temp = new char [size];
    861     double * newBounds = reinterpret_cast<double *> (temp);
    862     int * variables = reinterpret_cast<int *> (newBounds+numberChangedBounds_+nAdd);
    863    
    864     int i ;
    865     for (i=0;i<numberChangedBounds_;i++) {
    866       variables[i]=variables_[i];
    867       newBounds[i]=newBounds_[i];
    868     }
    869     delete [] newBounds_;
    870     newBounds_ = newBounds;
    871     variables_ = variables;
    872     if ((force&2)!=0&&(found&2)==0) {
    873       // need to add new upper
    874       int variable = iColumn | 0x80000000;
    875       variables_[numberChangedBounds_]=variable;
    876       newBounds_[numberChangedBounds_++]=newUpper;
    877     }
    878     if ((force&1)!=0&&(found&1)==0) {
    879       // need to add new lower
    880       int variable = iColumn;
    881       variables_[numberChangedBounds_]=variable;
    882       newBounds_[numberChangedBounds_++]=newLower;
    883     }
    884   }
    885  
    886   return (newUpper>=newLower) ? 0 : 1;
     814    // branch - do bounds
     815    int i;
     816    int found = 0;
     817    double newLower = -COIN_DBL_MAX;
     818    double newUpper = COIN_DBL_MAX;
     819    for (i = 0; i < numberChangedBounds_; i++) {
     820        int variable = variables_[i];
     821        int k = variable & 0x3fffffff;
     822        if (k == iColumn) {
     823            if ((variable&0x80000000) == 0) {
     824                // lower bound changing
     825                found |= 1;
     826                newLower = CoinMax(newLower, newBounds_[i]);
     827                if ((force&1) == 0) {
     828                    if (lower > newBounds_[i])
     829                        printf("%d odd lower going from %g to %g\n", iColumn, lower, newBounds_[i]);
     830                    lower = newBounds_[i];
     831                } else {
     832                    newBounds_[i] = lower;
     833                    variables_[i] |= 0x40000000; // say can go odd way
     834                }
     835            } else {
     836                // upper bound changing
     837                found |= 2;
     838                newUpper = CoinMin(newUpper, newBounds_[i]);
     839                if ((force&2) == 0) {
     840                    if (upper < newBounds_[i])
     841                        printf("%d odd upper going from %g to %g\n", iColumn, upper, newBounds_[i]);
     842                    upper = newBounds_[i];
     843                } else {
     844                    newBounds_[i] = upper;
     845                    variables_[i] |= 0x40000000; // say can go odd way
     846                }
     847            }
     848        }
     849    }
     850    newLower = CoinMax(newLower, lower);
     851    newUpper = CoinMin(newUpper, upper);
     852    int nAdd = 0;
     853    if ((force&2) != 0 && (found&2) == 0) {
     854        // need to add new upper
     855        nAdd++;
     856    }
     857    if ((force&1) != 0 && (found&1) == 0) {
     858        // need to add new lower
     859        nAdd++;
     860    }
     861    if (nAdd) {
     862        int size = (numberChangedBounds_ + nAdd) * (sizeof(double) + sizeof(int));
     863        char * temp = new char [size];
     864        double * newBounds = reinterpret_cast<double *> (temp);
     865        int * variables = reinterpret_cast<int *> (newBounds + numberChangedBounds_ + nAdd);
     866
     867        int i ;
     868        for (i = 0; i < numberChangedBounds_; i++) {
     869            variables[i] = variables_[i];
     870            newBounds[i] = newBounds_[i];
     871        }
     872        delete [] newBounds_;
     873        newBounds_ = newBounds;
     874        variables_ = variables;
     875        if ((force&2) != 0 && (found&2) == 0) {
     876            // need to add new upper
     877            int variable = iColumn | 0x80000000;
     878            variables_[numberChangedBounds_] = variable;
     879            newBounds_[numberChangedBounds_++] = newUpper;
     880        }
     881        if ((force&1) != 0 && (found&1) == 0) {
     882            // need to add new lower
     883            int variable = iColumn;
     884            variables_[numberChangedBounds_] = variable;
     885            newBounds_[numberChangedBounds_++] = newLower;
     886        }
     887    }
     888
     889    return (newUpper >= newLower) ? 0 : 1;
    887890}
    888891
     
    892895*/
    893896
    894 CbcNodeInfo *
    895 CbcPartialNodeInfo::buildRowBasis(CoinWarmStartBasis & basis ) const
    896  
    897 { basis.applyDiff(basisDiff_) ;
    898  
    899   return parent_ ; }
     897CbcNodeInfo *
     898CbcPartialNodeInfo::buildRowBasis(CoinWarmStartBasis & basis ) const
     899
     900{
     901    basis.applyDiff(basisDiff_) ;
     902
     903    return parent_ ;
     904}
    900905CbcNode::CbcNode() :
    901   nodeInfo_(NULL),
    902   objectiveValue_(1.0e100),
    903   guessedObjectiveValue_(1.0e100),
    904   sumInfeasibilities_(0.0),
    905   branch_(NULL),
    906   depth_(-1),
    907   numberUnsatisfied_(0),
    908   nodeNumber_(-1),
    909   state_(0)
     906        nodeInfo_(NULL),
     907        objectiveValue_(1.0e100),
     908        guessedObjectiveValue_(1.0e100),
     909        sumInfeasibilities_(0.0),
     910        branch_(NULL),
     911        depth_(-1),
     912        numberUnsatisfied_(0),
     913        nodeNumber_(-1),
     914        state_(0)
    910915{
    911916#ifdef CHECK_NODE
    912   printf("CbcNode %x Constructor\n",this);
     917    printf("CbcNode %x Constructor\n", this);
    913918#endif
    914919}
    915920// Print
    916 void 
     921void
    917922CbcNode::print() const
    918923{
    919   printf("number %d obj %g depth %d sumun %g nunsat %d state %d\n",
    920          nodeNumber_,objectiveValue_,depth_,sumInfeasibilities_,numberUnsatisfied_,state_);
     924    printf("number %d obj %g depth %d sumun %g nunsat %d state %d\n",
     925           nodeNumber_, objectiveValue_, depth_, sumInfeasibilities_, numberUnsatisfied_, state_);
    921926}
    922927CbcNode::CbcNode(CbcModel * model,
    923                 CbcNode * lastNode) :
    924   nodeInfo_(NULL),
    925   objectiveValue_(1.0e100),
    926   guessedObjectiveValue_(1.0e100),
    927   sumInfeasibilities_(0.0),
    928   branch_(NULL),
    929   depth_(-1),
    930   numberUnsatisfied_(0),
    931   nodeNumber_(-1),
    932   state_(0)
     928                CbcNode * lastNode) :
     929        nodeInfo_(NULL),
     930        objectiveValue_(1.0e100),
     931        guessedObjectiveValue_(1.0e100),
     932        sumInfeasibilities_(0.0),
     933        branch_(NULL),
     934        depth_(-1),
     935        numberUnsatisfied_(0),
     936        nodeNumber_(-1),
     937        state_(0)
    933938{
    934939#ifdef CHECK_NODE
    935   printf("CbcNode %x Constructor from model\n",this);
    936 #endif
    937   model->setObjectiveValue(this,lastNode);
    938  
    939   if (lastNode) {
    940     if (lastNode->nodeInfo_) {
    941       lastNode->nodeInfo_->increment();
    942     }
    943   }
    944   nodeNumber_= model->getNodeCount();
     940    printf("CbcNode %x Constructor from model\n", this);
     941#endif
     942    model->setObjectiveValue(this, lastNode);
     943
     944    if (lastNode) {
     945        if (lastNode->nodeInfo_) {
     946            lastNode->nodeInfo_->increment();
     947        }
     948    }
     949    nodeNumber_ = model->getNodeCount();
    945950}
    946951
     
    957962void
    958963CbcNode::createInfo (CbcModel *model,
    959                      CbcNode *lastNode,
    960                      const CoinWarmStartBasis *lastws,
    961                      const double *lastLower, const double *lastUpper,
    962                      int numberOldActiveCuts, int numberNewCuts)
    963  
    964 { OsiSolverInterface *solver = model->solver();
    965   CbcStrategy *strategy = model->strategy();
    966   /*
    967     The root --- no parent. Create full basis and bounds information.
    968   */
    969   if (!lastNode)
    970     {
    971       if (!strategy)
    972         nodeInfo_=new CbcFullNodeInfo(model,solver->getNumRows());
    973       else
    974         nodeInfo_ = strategy->fullNodeInfo(model,solver->getNumRows());
     964                     CbcNode *lastNode,
     965                     const CoinWarmStartBasis *lastws,
     966                     const double *lastLower, const double *lastUpper,
     967                     int numberOldActiveCuts, int numberNewCuts)
     968
     969{
     970    OsiSolverInterface *solver = model->solver();
     971    CbcStrategy *strategy = model->strategy();
     972    /*
     973      The root --- no parent. Create full basis and bounds information.
     974    */
     975    if (!lastNode) {
     976        if (!strategy)
     977            nodeInfo_ = new CbcFullNodeInfo(model, solver->getNumRows());
     978        else
     979            nodeInfo_ = strategy->fullNodeInfo(model, solver->getNumRows());
    975980    } else {
    976     /*
    977       Not the root. Create an edit from the parent's basis & bound information.
    978       This is not quite as straightforward as it seems. We need to reintroduce
    979       cuts we may have dropped out of the basis, in the correct position, because
    980       this whole process is strictly positional. Start by grabbing the current
    981       basis.
    982     */
    983     bool mustDeleteBasis;
    984     const CoinWarmStartBasis *ws =
    985       dynamic_cast<const CoinWarmStartBasis*>(solver->getPointerToWarmStart(mustDeleteBasis));
    986     assert(ws!=NULL); // make sure not volume
    987     //int numberArtificials = lastws->getNumArtificial();
    988     int numberColumns = solver->getNumCols();
    989     int numberRowsAtContinuous = model->numberRowsAtContinuous();
    990     int currentNumberCuts = model->currentNumberCuts();
     981        /*
     982          Not the root. Create an edit from the parent's basis & bound information.
     983          This is not quite as straightforward as it seems. We need to reintroduce
     984          cuts we may have dropped out of the basis, in the correct position, because
     985          this whole process is strictly positional. Start by grabbing the current
     986          basis.
     987        */
     988        bool mustDeleteBasis;
     989        const CoinWarmStartBasis *ws =
     990            dynamic_cast<const CoinWarmStartBasis*>(solver->getPointerToWarmStart(mustDeleteBasis));
     991        assert(ws != NULL); // make sure not volume
     992        //int numberArtificials = lastws->getNumArtificial();
     993        int numberColumns = solver->getNumCols();
     994        int numberRowsAtContinuous = model->numberRowsAtContinuous();
     995        int currentNumberCuts = model->currentNumberCuts();
    991996#   ifdef CBC_CHECK_BASIS
    992     std::cout
    993       << "Before expansion: orig " << numberRowsAtContinuous
    994       << ", old " << numberOldActiveCuts
    995       << ", new " << numberNewCuts
    996       << ", current " << currentNumberCuts << "." << std::endl ;
    997     ws->print();
     997        std::cout
     998            << "Before expansion: orig " << numberRowsAtContinuous
     999            << ", old " << numberOldActiveCuts
     1000            << ", new " << numberNewCuts
     1001            << ", current " << currentNumberCuts << "." << std::endl ;
     1002        ws->print();
    9981003#   endif
    999     /*
    1000       Clone the basis and resize it to hold the structural constraints, plus
    1001       all the cuts: old cuts, both active and inactive (currentNumberCuts),
    1002       and new cuts (numberNewCuts). This will become the expanded basis.
    1003     */
    1004     CoinWarmStartBasis *expanded =
    1005       dynamic_cast<CoinWarmStartBasis *>(ws->clone()) ;
    1006     int iCompact = numberRowsAtContinuous+numberOldActiveCuts+numberNewCuts ;
    1007     // int nPartial = numberRowsAtContinuous+currentNumberCuts;
    1008     int iFull = numberRowsAtContinuous+currentNumberCuts+numberNewCuts;
    1009     // int maxBasisLength = ((iFull+15)>>4)+((numberColumns+15)>>4);
    1010     // printf("l %d full %d\n",maxBasisLength,iFull);
    1011     expanded->resize(iFull,numberColumns);
     1004        /*
     1005          Clone the basis and resize it to hold the structural constraints, plus
     1006          all the cuts: old cuts, both active and inactive (currentNumberCuts),
     1007          and new cuts (numberNewCuts). This will become the expanded basis.
     1008        */
     1009        CoinWarmStartBasis *expanded =
     1010            dynamic_cast<CoinWarmStartBasis *>(ws->clone()) ;
     1011        int iCompact = numberRowsAtContinuous + numberOldActiveCuts + numberNewCuts ;
     1012        // int nPartial = numberRowsAtContinuous+currentNumberCuts;
     1013        int iFull = numberRowsAtContinuous + currentNumberCuts + numberNewCuts;
     1014        // int maxBasisLength = ((iFull+15)>>4)+((numberColumns+15)>>4);
     1015        // printf("l %d full %d\n",maxBasisLength,iFull);
     1016        expanded->resize(iFull, numberColumns);
    10121017#   ifdef CBC_CHECK_BASIS
    1013     std::cout
    1014       << "\tFull basis " << iFull << " rows, "
    1015       << numberColumns << " columns; compact "
    1016       << iCompact << " rows." << std::endl ;
     1018        std::cout
     1019            << "\tFull basis " << iFull << " rows, "
     1020            << numberColumns << " columns; compact "
     1021            << iCompact << " rows." << std::endl ;
    10171022#   endif
    1018     /*
    1019       Now flesh out the expanded basis. The clone already has the
    1020       correct status information for the variables and for the structural
    1021       (numberRowsAtContinuous) constraints. Any indices beyond nPartial must be
    1022       cuts created while processing this node --- they can be copied en bloc
    1023       into the correct position in the expanded basis. The space reserved for
    1024       xferRows is a gross overestimate.
    1025     */
    1026     CoinWarmStartBasis::XferVec xferRows ;
    1027     xferRows.reserve(iFull-numberRowsAtContinuous+1) ;
    1028     if (numberNewCuts) {
    1029       xferRows.push_back(
    1030                          CoinWarmStartBasis::XferEntry(iCompact-numberNewCuts,
    1031                                                        iFull-numberNewCuts,numberNewCuts)) ;
    1032     }
    1033     /*
    1034       From nPartial down, record the entries we want to copy from the current
    1035       basis (the entries for the active cuts; non-zero in the list returned
    1036       by addedCuts). Fill the expanded basis with entries showing a status of
    1037       basic for the deactivated (loose) cuts.
    1038     */
    1039     CbcCountRowCut **cut = model->addedCuts();
    1040     iFull -= (numberNewCuts+1) ;
    1041     iCompact -= (numberNewCuts+1) ;
    1042     int runLen = 0 ;
    1043     CoinWarmStartBasis::XferEntry entry(-1,-1,-1) ;
    1044     while (iFull >= numberRowsAtContinuous) {
    1045       for ( ; iFull >= numberRowsAtContinuous &&
    1046               cut[iFull-numberRowsAtContinuous] ; iFull--)
    1047         runLen++ ;
    1048       if (runLen) {
    1049         iCompact -= runLen ;
    1050         entry.first = iCompact+1 ;
    1051         entry.second = iFull+1 ;
    1052         entry.third = runLen ;
    1053         runLen = 0 ;
    1054         xferRows.push_back(entry) ;
    1055       }
    1056       for ( ; iFull >= numberRowsAtContinuous &&
    1057               !cut[iFull-numberRowsAtContinuous] ; iFull--)
    1058         expanded->setArtifStatus(iFull,CoinWarmStartBasis::basic);
    1059     }
    1060 /*
    1061   Finally, call mergeBasis to copy over entries from the current basis to
    1062   the expanded basis. Since we cloned the expanded basis from the active basis
    1063   and havn't changed the number of variables, only row status entries need
    1064   to be copied.
    1065 */
    1066     expanded->mergeBasis(ws,&xferRows,0) ;
    1067    
     1023        /*
     1024          Now flesh out the expanded basis. The clone already has the
     1025          correct status information for the variables and for the structural
     1026          (numberRowsAtContinuous) constraints. Any indices beyond nPartial must be
     1027          cuts created while processing this node --- they can be copied en bloc
     1028          into the correct position in the expanded basis. The space reserved for
     1029          xferRows is a gross overestimate.
     1030        */
     1031        CoinWarmStartBasis::XferVec xferRows ;
     1032        xferRows.reserve(iFull - numberRowsAtContinuous + 1) ;
     1033        if (numberNewCuts) {
     1034            xferRows.push_back(
     1035                CoinWarmStartBasis::XferEntry(iCompact - numberNewCuts,
     1036                                              iFull - numberNewCuts, numberNewCuts)) ;
     1037        }
     1038        /*
     1039          From nPartial down, record the entries we want to copy from the current
     1040          basis (the entries for the active cuts; non-zero in the list returned
     1041          by addedCuts). Fill the expanded basis with entries showing a status of
     1042          basic for the deactivated (loose) cuts.
     1043        */
     1044        CbcCountRowCut **cut = model->addedCuts();
     1045        iFull -= (numberNewCuts + 1) ;
     1046        iCompact -= (numberNewCuts + 1) ;
     1047        int runLen = 0 ;
     1048        CoinWarmStartBasis::XferEntry entry(-1, -1, -1) ;
     1049        while (iFull >= numberRowsAtContinuous) {
     1050            for ( ; iFull >= numberRowsAtContinuous &&
     1051                    cut[iFull-numberRowsAtContinuous] ; iFull--)
     1052                runLen++ ;
     1053            if (runLen) {
     1054                iCompact -= runLen ;
     1055                entry.first = iCompact + 1 ;
     1056                entry.second = iFull + 1 ;
     1057                entry.third = runLen ;
     1058                runLen = 0 ;
     1059                xferRows.push_back(entry) ;
     1060            }
     1061            for ( ; iFull >= numberRowsAtContinuous &&
     1062                    !cut[iFull-numberRowsAtContinuous] ; iFull--)
     1063                expanded->setArtifStatus(iFull, CoinWarmStartBasis::basic);
     1064        }
     1065        /*
     1066          Finally, call mergeBasis to copy over entries from the current basis to
     1067          the expanded basis. Since we cloned the expanded basis from the active basis
     1068          and havn't changed the number of variables, only row status entries need
     1069          to be copied.
     1070        */
     1071        expanded->mergeBasis(ws, &xferRows, 0) ;
     1072
    10681073#ifdef CBC_CHECK_BASIS
    1069     std::cout << "Expanded basis:" << std::endl ;
    1070     expanded->print() ;
    1071     std::cout << "Diffing against:" << std::endl ;
    1072     lastws->print() ;
    1073 #endif   
    1074     assert (expanded->getNumArtificial()>=lastws->getNumArtificial());
     1074        std::cout << "Expanded basis:" << std::endl ;
     1075        expanded->print() ;
     1076        std::cout << "Diffing against:" << std::endl ;
     1077        lastws->print() ;
     1078#endif
     1079        assert (expanded->getNumArtificial() >= lastws->getNumArtificial());
    10751080#ifdef CLP_INVESTIGATE
    1076     if (!expanded->fullBasis()) {
    1077       int iFull = numberRowsAtContinuous+currentNumberCuts+numberNewCuts;
    1078       printf("cont %d old %d new %d current %d full inc %d full %d\n",
    1079              numberRowsAtContinuous,numberOldActiveCuts,numberNewCuts,
    1080              currentNumberCuts,iFull,iFull-numberNewCuts);
    1081     }
    1082 #endif
    1083    
    1084     /*
    1085       Now that we have two bases in proper positional correspondence, creating
    1086       the actual diff is dead easy.
    1087      
    1088       Note that we're going to compare the expanded basis here to the stripped
    1089       basis (lastws) produced by addCuts. It doesn't affect the correctness (the
    1090       diff process has no knowledge of the meaning of an entry) but it does
    1091       mean that we'll always generate a whack of diff entries because the expanded
    1092       basis is considerably larger than the stripped basis.
    1093     */
    1094     CoinWarmStartDiff *basisDiff = expanded->generateDiff(lastws) ;
    1095    
    1096     /*
    1097       Diff the bound vectors. It's assumed the number of structural variables
    1098       is not changing. For branching objects that change bounds on integer
    1099       variables, we should see at least one bound change as a consequence
    1100       of applying the branch that generated this subproblem from its parent.
    1101       This need not hold for other types of branching objects (hyperplane
    1102       branches, for example).
    1103     */
    1104     const double * lower = solver->getColLower();
    1105     const double * upper = solver->getColUpper();
    1106    
    1107     double *boundChanges = new double [2*numberColumns] ;
    1108     int *variables = new int [2*numberColumns] ;
    1109     int numberChangedBounds=0;
    1110    
    1111     int i;
    1112     for (i=0;i<numberColumns;i++) {
    1113       if (lower[i]!=lastLower[i]) {
    1114         variables[numberChangedBounds]=i;
    1115         boundChanges[numberChangedBounds++]=lower[i];
    1116       }
    1117       if (upper[i]!=lastUpper[i]) {
    1118         variables[numberChangedBounds]=i|0x80000000;
    1119         boundChanges[numberChangedBounds++]=upper[i];
    1120       }
     1081        if (!expanded->fullBasis()) {
     1082            int iFull = numberRowsAtContinuous + currentNumberCuts + numberNewCuts;
     1083            printf("cont %d old %d new %d current %d full inc %d full %d\n",
     1084                   numberRowsAtContinuous, numberOldActiveCuts, numberNewCuts,
     1085                   currentNumberCuts, iFull, iFull - numberNewCuts);
     1086        }
     1087#endif
     1088
     1089        /*
     1090          Now that we have two bases in proper positional correspondence, creating
     1091          the actual diff is dead easy.
     1092
     1093          Note that we're going to compare the expanded basis here to the stripped
     1094          basis (lastws) produced by addCuts. It doesn't affect the correctness (the
     1095          diff process has no knowledge of the meaning of an entry) but it does
     1096          mean that we'll always generate a whack of diff entries because the expanded
     1097          basis is considerably larger than the stripped basis.
     1098        */
     1099        CoinWarmStartDiff *basisDiff = expanded->generateDiff(lastws) ;
     1100
     1101        /*
     1102          Diff the bound vectors. It's assumed the number of structural variables
     1103          is not changing. For branching objects that change bounds on integer
     1104          variables, we should see at least one bound change as a consequence
     1105          of applying the branch that generated this subproblem from its parent.
     1106          This need not hold for other types of branching objects (hyperplane
     1107          branches, for example).
     1108        */
     1109        const double * lower = solver->getColLower();
     1110        const double * upper = solver->getColUpper();
     1111
     1112        double *boundChanges = new double [2*numberColumns] ;
     1113        int *variables = new int [2*numberColumns] ;
     1114        int numberChangedBounds = 0;
     1115
     1116        int i;
     1117        for (i = 0; i < numberColumns; i++) {
     1118            if (lower[i] != lastLower[i]) {
     1119                variables[numberChangedBounds] = i;
     1120                boundChanges[numberChangedBounds++] = lower[i];
     1121            }
     1122            if (upper[i] != lastUpper[i]) {
     1123                variables[numberChangedBounds] = i | 0x80000000;
     1124                boundChanges[numberChangedBounds++] = upper[i];
     1125            }
    11211126#ifdef CBC_DEBUG
    1122       if (lower[i] != lastLower[i]) {
    1123         std::cout
    1124           << "lower on " << i << " changed from "
    1125           << lastLower[i] << " to " << lower[i] << std::endl ;
    1126       }
    1127       if (upper[i] != lastUpper[i]) {
    1128         std::cout
    1129           << "upper on " << i << " changed from "
    1130           << lastUpper[i] << " to " << upper[i] << std::endl ;
    1131       }
    1132 #endif
    1133     }
     1127            if (lower[i] != lastLower[i]) {
     1128                std::cout
     1129                    << "lower on " << i << " changed from "
     1130                    << lastLower[i] << " to " << lower[i] << std::endl ;
     1131            }
     1132            if (upper[i] != lastUpper[i]) {
     1133                std::cout
     1134                    << "upper on " << i << " changed from "
     1135                    << lastUpper[i] << " to " << upper[i] << std::endl ;
     1136            }
     1137#endif
     1138        }
    11341139#ifdef CBC_DEBUG
    1135     std::cout << numberChangedBounds << " changed bounds." << std::endl ;
    1136 #endif
    1137     //if (lastNode->branchingObject()->boundBranch())
    1138     //assert (numberChangedBounds);
    1139     /*
    1140       Hand the lot over to the CbcPartialNodeInfo constructor, then clean up and
    1141       return.
    1142     */
    1143     if (!strategy)
    1144       nodeInfo_ =
    1145         new CbcPartialNodeInfo(lastNode->nodeInfo_,this,numberChangedBounds,
    1146                                variables,boundChanges,basisDiff) ;
    1147     else
    1148       nodeInfo_ =
    1149         strategy->partialNodeInfo(model,lastNode->nodeInfo_,this,
    1150                                   numberChangedBounds,variables,boundChanges,
    1151                                   basisDiff) ;
    1152     delete basisDiff ;
    1153     delete [] boundChanges;
    1154     delete [] variables;
    1155     delete expanded ;
    1156     if  (mustDeleteBasis)
    1157       delete ws;
    1158   }
    1159   // Set node number
    1160   nodeInfo_->setNodeNumber(model->getNodeCount2());
    1161   state_ |= 2; // say active
     1140        std::cout << numberChangedBounds << " changed bounds." << std::endl ;
     1141#endif
     1142        //if (lastNode->branchingObject()->boundBranch())
     1143        //assert (numberChangedBounds);
     1144        /*
     1145          Hand the lot over to the CbcPartialNodeInfo constructor, then clean up and
     1146          return.
     1147        */
     1148        if (!strategy)
     1149            nodeInfo_ =
     1150                new CbcPartialNodeInfo(lastNode->nodeInfo_, this, numberChangedBounds,
     1151                                       variables, boundChanges, basisDiff) ;
     1152        else
     1153            nodeInfo_ =
     1154                strategy->partialNodeInfo(model, lastNode->nodeInfo_, this,
     1155                                          numberChangedBounds, variables, boundChanges,
     1156                                          basisDiff) ;
     1157        delete basisDiff ;
     1158        delete [] boundChanges;
     1159        delete [] variables;
     1160        delete expanded ;
     1161        if  (mustDeleteBasis)
     1162            delete ws;
     1163    }
     1164    // Set node number
     1165    nodeInfo_->setNodeNumber(model->getNodeCount2());
     1166    state_ |= 2; // say active
    11621167}
    11631168
     
    11671172  and selects the one with the least objective degradation.  A corresponding
    11681173  branching object is left attached to lastNode.
    1169  
     1174
    11701175  If strong branching is disabled, a candidate object is chosen essentially
    11711176  at random (whatever object ends up in pos'n 0 of the candidate array).
    1172  
     1177
    11731178  If a branching candidate is found to be monotone, bounds are set to fix the
    11741179  variable and the routine immediately returns (the caller is expected to
    11751180  reoptimize).
    1176  
     1181
    11771182  If a branching candidate is found to result in infeasibility in both
    11781183  directions, the routine immediately returns an indication of infeasibility.
    1179  
     1184
    11801185  Returns:  0   both branch directions are feasible
    11811186  -1    branching variable is monotone
    11821187  -2    infeasible
    1183  
     1188
    11841189  Original comments:
    11851190  Here could go cuts etc etc
     
    11871192*/
    11881193
    1189 int CbcNode::chooseBranch (CbcModel *model, CbcNode *lastNode,int numberPassesLeft)
    1190  
    1191 { if (lastNode)
    1192     depth_ = lastNode->depth_+1;
    1193   else
    1194     depth_ = 0;
    1195   delete branch_;
    1196   branch_=NULL;
    1197   OsiSolverInterface * solver = model->solver();
     1194int CbcNode::chooseBranch (CbcModel *model, CbcNode *lastNode, int numberPassesLeft)
     1195
     1196{
     1197    if (lastNode)
     1198        depth_ = lastNode->depth_ + 1;
     1199    else
     1200        depth_ = 0;
     1201    delete branch_;
     1202    branch_ = NULL;
     1203    OsiSolverInterface * solver = model->solver();
    11981204# ifdef COIN_HAS_CLP
    1199   OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver);
    1200   int saveClpOptions=0;
    1201   if (osiclp) {
    1202     // for faster hot start
    1203     saveClpOptions = osiclp->specialOptions();
    1204     osiclp->setSpecialOptions(saveClpOptions|8192);
    1205   }
     1205    OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver);
     1206    int saveClpOptions = 0;
     1207    if (osiclp) {
     1208        // for faster hot start
     1209        saveClpOptions = osiclp->specialOptions();
     1210        osiclp->setSpecialOptions(saveClpOptions | 8192);
     1211    }
    12061212# else
    1207   OsiSolverInterface *osiclp = NULL ;
     1213    OsiSolverInterface *osiclp = NULL ;
    12081214# endif
    1209   double saveObjectiveValue = solver->getObjValue();
    1210   double objectiveValue = CoinMax(solver->getObjSense()*saveObjectiveValue,objectiveValue_);
    1211   const double * lower = solver->getColLower();
    1212   const double * upper = solver->getColUpper();
    1213   // See what user thinks
    1214   int anyAction=model->problemFeasibility()->feasible(model,0);
    1215   if (anyAction) {
    1216     // will return -2 if infeasible , 0 if treat as integer
    1217     return anyAction-1;
    1218   }
    1219   double integerTolerance =
    1220     model->getDblParam(CbcModel::CbcIntegerTolerance);
    1221   // point to useful information
    1222   OsiBranchingInformation usefulInfo = model->usefulInformation();
    1223   // and modify
    1224   usefulInfo.depth_=depth_;
    1225   int i;
    1226   bool beforeSolution = model->getSolutionCount()==0;
    1227   int numberStrong=model->numberStrong();
    1228   // switch off strong if hotstart
    1229   const double * hotstartSolution = model->hotstartSolution();
    1230   const int * hotstartPriorities = model->hotstartPriorities();
    1231   int numberObjects = model->numberObjects();
    1232   int numberColumns = model->getNumCols();
    1233   double * saveUpper = new double[numberColumns];
    1234   double * saveLower = new double[numberColumns];
    1235   for (i=0;i<numberColumns;i++) {
    1236     saveLower[i] = lower[i];
    1237     saveUpper[i] = upper[i];
    1238   }
    1239  
    1240   // Save solution in case heuristics need good solution later
    1241  
    1242   double * saveSolution = new double[numberColumns];
    1243   memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
    1244   model->reserveCurrentSolution(saveSolution);
    1245   if (hotstartSolution) {
    1246     numberStrong=0;
    1247     if((model->moreSpecialOptions()&1024)!=0) {
    1248       int nBad=0;
    1249       int nUnsat=0;
    1250       int nDiff=0;
    1251       for (int i=0;i<numberObjects;i++) {
    1252         OsiObject * object = model->modifiableObject(i);
    1253         const CbcSimpleInteger * thisOne = dynamic_cast <const CbcSimpleInteger *> (object);
    1254         if (thisOne) {
    1255           int iColumn = thisOne->columnNumber();
    1256           double targetValue = hotstartSolution[iColumn];
    1257           double value = saveSolution[iColumn];
    1258           if (fabs(value-floor(value+0.5))>1.0e-6) {
    1259             nUnsat++;
    1260 #ifdef CLP_INVESTIGATE
    1261             printf("H %d is %g target %g\n",iColumn,value,targetValue);
    1262 #endif
    1263           } else if (fabs(targetValue-value)>1.0e-6) {
    1264             nDiff++;
    1265           }
    1266           if (targetValue<saveLower[iColumn]||
    1267               targetValue>saveUpper[iColumn]) {
    1268 #ifdef CLP_INVESTIGATE
    1269             printf("%d has target %g and current bounds %g and %g\n",
    1270                    iColumn,targetValue,saveLower[iColumn],saveUpper[iColumn]);
    1271 #endif
    1272             nBad++;
    1273           }
    1274         }
    1275       }
    1276 #ifdef CLP_INVESTIGATE
    1277       printf("Hot %d unsatisfied, %d outside limits, %d different\n",
    1278              nUnsat,nBad,nDiff);
    1279 #endif
    1280       if (nBad) {
    1281         // switch off as not possible
    1282           hotstartSolution=NULL;
    1283           model->setHotstartSolution(NULL,NULL);
    1284           usefulInfo.hotstartSolution_=NULL;
    1285       }
    1286     }
    1287   }
    1288   int numberStrongDone=0;
    1289   int numberUnfinished=0;
    1290   int numberStrongInfeasible=0;
    1291   int numberStrongIterations=0;
    1292   int saveNumberStrong=numberStrong;
    1293   bool checkFeasibility = numberObjects>model->numberIntegers();
    1294   int maximumStrong = CoinMax(CoinMin(numberStrong,numberObjects),1);
    1295   /*
    1296     Get a branching decision object. Use the default decision criteria unless
    1297     the user has loaded a decision method into the model.
    1298   */
    1299   CbcBranchDecision *decision = model->branchingMethod();
    1300   CbcDynamicPseudoCostBranchingObject * dynamicBranchingObject =
    1301     dynamic_cast<CbcDynamicPseudoCostBranchingObject *>(decision);
    1302   if (!decision||dynamicBranchingObject)
    1303     decision = new CbcBranchDefaultDecision();
    1304   decision->initialize(model);
    1305   CbcStrongInfo * choice = new CbcStrongInfo[maximumStrong];
    1306   // May go round twice if strong branching fixes all local candidates
    1307   bool finished=false;
    1308   double estimatedDegradation=0.0;
    1309   while(!finished) {
    1310     finished=true;
    1311     // Some objects may compute an estimate of best solution from here
    1312     estimatedDegradation=0.0;
    1313     //int numberIntegerInfeasibilities=0; // without odd ones
    1314     numberStrongDone=0;
    1315     numberUnfinished=0;
    1316     numberStrongInfeasible=0;
    1317     numberStrongIterations=0;
    1318    
    1319     // We may go round this loop twice (only if we think we have solution)
    1320     for (int iPass=0;iPass<2;iPass++) {
    1321      
    1322       // compute current state
    1323       //int numberObjectInfeasibilities; // just odd ones
    1324       //model->feasibleSolution(
    1325       //                      numberIntegerInfeasibilities,
    1326       //                      numberObjectInfeasibilities);
    1327       // Some objects may compute an estimate of best solution from here
    1328       estimatedDegradation=0.0;
    1329       numberUnsatisfied_ = 0;
    1330       // initialize sum of "infeasibilities"
    1331       sumInfeasibilities_ = 0.0;
    1332       int bestPriority=COIN_INT_MAX;
    1333       /*
    1334         Scan for branching objects that indicate infeasibility. Choose the best
    1335         maximumStrong candidates, using priority as the first criteria, then
    1336         integer infeasibility.
    1337        
    1338         The algorithm is to fill the choice array with a set of good candidates (by
    1339         infeasibility) with priority bestPriority.  Finding a candidate with
    1340         priority better (less) than bestPriority flushes the choice array. (This
    1341         serves as initialization when the first candidate is found.)
    1342        
    1343         A new candidate is added to choices only if its infeasibility exceeds the
    1344         current max infeasibility (mostAway). When a candidate is added, it
    1345         replaces the candidate with the smallest infeasibility (tracked by
    1346         iSmallest).
    1347       */
    1348       int iSmallest = 0;
    1349       double mostAway = 1.0e-100;
    1350       for (i = 0 ; i < maximumStrong ; i++)
    1351         choice[i].possibleBranch = NULL ;
    1352       numberStrong=0;
    1353       bool canDoOneHot=false;
    1354       for (i=0;i<numberObjects;i++) {
    1355         OsiObject * object = model->modifiableObject(i);
    1356         int preferredWay;
    1357         double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
    1358         int priorityLevel = object->priority();
    1359         if (hotstartSolution) {
    1360           // we are doing hot start
    1361           const CbcSimpleInteger * thisOne = dynamic_cast <const CbcSimpleInteger *> (object);
    1362           if (thisOne) {
    1363             int iColumn = thisOne->columnNumber();
    1364             bool canDoThisHot=true;
    1365             double targetValue = hotstartSolution[iColumn];
    1366             if (saveUpper[iColumn]>saveLower[iColumn]) {
    1367               double value = saveSolution[iColumn];
    1368               if (hotstartPriorities)
    1369                 priorityLevel=hotstartPriorities[iColumn];
    1370               //double originalLower = thisOne->originalLower();
    1371               //double originalUpper = thisOne->originalUpper();
    1372               // switch off if not possible
    1373               if (targetValue>=saveLower[iColumn]&&targetValue<=saveUpper[iColumn]) {
    1374                 /* priority outranks rest always if negative
    1375                    otherwise can be downgraded if at correct level.
    1376                    Infeasibility may be increased to choose 1.0 values first.
    1377                    choose one near wanted value
    1378                 */
    1379                 if (fabs(value-targetValue)>integerTolerance) {
    1380                   //if (infeasibility>0.01)
    1381                   //infeasibility = fabs(1.0e6-fabs(value-targetValue));
    1382                   //else
    1383                   infeasibility = fabs(value-targetValue);
    1384                   //if (targetValue==1.0)
    1385                   //infeasibility += 1.0;
    1386                   if (value>targetValue) {
    1387                     preferredWay=-1;
    1388                   } else {
    1389                     preferredWay=1;
    1390                   }
    1391                   priorityLevel = CoinAbs(priorityLevel);
    1392                 } else if (priorityLevel<0) {
    1393                   priorityLevel = CoinAbs(priorityLevel);
    1394                   if (targetValue==saveLower[iColumn]) {
    1395                     infeasibility = integerTolerance+1.0e-12;
    1396                     preferredWay=-1;
    1397                   } else if (targetValue==saveUpper[iColumn]) {
    1398                     infeasibility = integerTolerance+1.0e-12;
    1399                     preferredWay=1;
    1400                   } else {
    1401                     // can't
    1402                     priorityLevel += 10000000;
    1403                     canDoThisHot=false;
    1404                   }
     1215    double saveObjectiveValue = solver->getObjValue();
     1216    double objectiveValue = CoinMax(solver->getObjSense() * saveObjectiveValue, objectiveValue_);
     1217    const double * lower = solver->getColLower();
     1218    const double * upper = solver->getColUpper();
     1219    // See what user thinks
     1220    int anyAction = model->problemFeasibility()->feasible(model, 0);
     1221    if (anyAction) {
     1222        // will return -2 if infeasible , 0 if treat as integer
     1223        return anyAction - 1;
     1224    }
     1225    double integerTolerance =
     1226        model->getDblParam(CbcModel::CbcIntegerTolerance);
     1227    // point to useful information
     1228    OsiBranchingInformation usefulInfo = model->usefulInformation();
     1229    // and modify
     1230    usefulInfo.depth_ = depth_;
     1231    int i;
     1232    bool beforeSolution = model->getSolutionCount() == 0;
     1233    int numberStrong = model->numberStrong();
     1234    // switch off strong if hotstart
     1235    const double * hotstartSolution = model->hotstartSolution();
     1236    const int * hotstartPriorities = model->hotstartPriorities();
     1237    int numberObjects = model->numberObjects();
     1238    int numberColumns = model->getNumCols();
     1239    double * saveUpper = new double[numberColumns];
     1240    double * saveLower = new double[numberColumns];
     1241    for (i = 0; i < numberColumns; i++) {
     1242        saveLower[i] = lower[i];
     1243        saveUpper[i] = upper[i];
     1244    }
     1245
     1246    // Save solution in case heuristics need good solution later
     1247
     1248    double * saveSolution = new double[numberColumns];
     1249    memcpy(saveSolution, solver->getColSolution(), numberColumns*sizeof(double));
     1250    model->reserveCurrentSolution(saveSolution);
     1251    if (hotstartSolution) {
     1252        numberStrong = 0;
     1253        if ((model->moreSpecialOptions()&1024) != 0) {
     1254            int nBad = 0;
     1255            int nUnsat = 0;
     1256            int nDiff = 0;
     1257            for (int i = 0; i < numberObjects; i++) {
     1258                OsiObject * object = model->modifiableObject(i);
     1259                const CbcSimpleInteger * thisOne = dynamic_cast <const CbcSimpleInteger *> (object);
     1260                if (thisOne) {
     1261                    int iColumn = thisOne->columnNumber();
     1262                    double targetValue = hotstartSolution[iColumn];
     1263                    double value = saveSolution[iColumn];
     1264                    if (fabs(value - floor(value + 0.5)) > 1.0e-6) {
     1265                        nUnsat++;
     1266#ifdef CLP_INVESTIGATE
     1267                        printf("H %d is %g target %g\n", iColumn, value, targetValue);
     1268#endif
     1269                    } else if (fabs(targetValue - value) > 1.0e-6) {
     1270                        nDiff++;
     1271                    }
     1272                    if (targetValue < saveLower[iColumn] ||
     1273                            targetValue > saveUpper[iColumn]) {
     1274#ifdef CLP_INVESTIGATE
     1275                        printf("%d has target %g and current bounds %g and %g\n",
     1276                               iColumn, targetValue, saveLower[iColumn], saveUpper[iColumn]);
     1277#endif
     1278                        nBad++;
     1279                    }
     1280                }
     1281            }
     1282#ifdef CLP_INVESTIGATE
     1283            printf("Hot %d unsatisfied, %d outside limits, %d different\n",
     1284                   nUnsat, nBad, nDiff);
     1285#endif
     1286            if (nBad) {
     1287                // switch off as not possible
     1288                hotstartSolution = NULL;
     1289                model->setHotstartSolution(NULL, NULL);
     1290                usefulInfo.hotstartSolution_ = NULL;
     1291            }
     1292        }
     1293    }
     1294    int numberStrongDone = 0;
     1295    int numberUnfinished = 0;
     1296    int numberStrongInfeasible = 0;
     1297    int numberStrongIterations = 0;
     1298    int saveNumberStrong = numberStrong;
     1299    bool checkFeasibility = numberObjects > model->numberIntegers();
     1300    int maximumStrong = CoinMax(CoinMin(numberStrong, numberObjects), 1);
     1301    /*
     1302      Get a branching decision object. Use the default decision criteria unless
     1303      the user has loaded a decision method into the model.
     1304    */
     1305    CbcBranchDecision *decision = model->branchingMethod();
     1306    CbcDynamicPseudoCostBranchingObject * dynamicBranchingObject =
     1307        dynamic_cast<CbcDynamicPseudoCostBranchingObject *>(decision);
     1308    if (!decision || dynamicBranchingObject)
     1309        decision = new CbcBranchDefaultDecision();
     1310    decision->initialize(model);
     1311    CbcStrongInfo * choice = new CbcStrongInfo[maximumStrong];
     1312    // May go round twice if strong branching fixes all local candidates
     1313    bool finished = false;
     1314    double estimatedDegradation = 0.0;
     1315    while (!finished) {
     1316        finished = true;
     1317        // Some objects may compute an estimate of best solution from here
     1318        estimatedDegradation = 0.0;
     1319        //int numberIntegerInfeasibilities=0; // without odd ones
     1320        numberStrongDone = 0;
     1321        numberUnfinished = 0;
     1322        numberStrongInfeasible = 0;
     1323        numberStrongIterations = 0;
     1324
     1325        // We may go round this loop twice (only if we think we have solution)
     1326        for (int iPass = 0; iPass < 2; iPass++) {
     1327
     1328            // compute current state
     1329            //int numberObjectInfeasibilities; // just odd ones
     1330            //model->feasibleSolution(
     1331            //                      numberIntegerInfeasibilities,
     1332            //                      numberObjectInfeasibilities);
     1333            // Some objects may compute an estimate of best solution from here
     1334            estimatedDegradation = 0.0;
     1335            numberUnsatisfied_ = 0;
     1336            // initialize sum of "infeasibilities"
     1337            sumInfeasibilities_ = 0.0;
     1338            int bestPriority = COIN_INT_MAX;
     1339            /*
     1340              Scan for branching objects that indicate infeasibility. Choose the best
     1341              maximumStrong candidates, using priority as the first criteria, then
     1342              integer infeasibility.
     1343
     1344              The algorithm is to fill the choice array with a set of good candidates (by
     1345              infeasibility) with priority bestPriority.  Finding a candidate with
     1346              priority better (less) than bestPriority flushes the choice array. (This
     1347              serves as initialization when the first candidate is found.)
     1348
     1349              A new candidate is added to choices only if its infeasibility exceeds the
     1350              current max infeasibility (mostAway). When a candidate is added, it
     1351              replaces the candidate with the smallest infeasibility (tracked by
     1352              iSmallest).
     1353            */
     1354            int iSmallest = 0;
     1355            double mostAway = 1.0e-100;
     1356            for (i = 0 ; i < maximumStrong ; i++)
     1357                choice[i].possibleBranch = NULL ;
     1358            numberStrong = 0;
     1359            bool canDoOneHot = false;
     1360            for (i = 0; i < numberObjects; i++) {
     1361                OsiObject * object = model->modifiableObject(i);
     1362                int preferredWay;
     1363                double infeasibility = object->infeasibility(&usefulInfo, preferredWay);
     1364                int priorityLevel = object->priority();
     1365                if (hotstartSolution) {
     1366                    // we are doing hot start
     1367                    const CbcSimpleInteger * thisOne = dynamic_cast <const CbcSimpleInteger *> (object);
     1368                    if (thisOne) {
     1369                        int iColumn = thisOne->columnNumber();
     1370                        bool canDoThisHot = true;
     1371                        double targetValue = hotstartSolution[iColumn];
     1372                        if (saveUpper[iColumn] > saveLower[iColumn]) {
     1373                            double value = saveSolution[iColumn];
     1374                            if (hotstartPriorities)
     1375                                priorityLevel = hotstartPriorities[iColumn];
     1376                            //double originalLower = thisOne->originalLower();
     1377                            //double originalUpper = thisOne->originalUpper();
     1378                            // switch off if not possible
     1379                            if (targetValue >= saveLower[iColumn] && targetValue <= saveUpper[iColumn]) {
     1380                                /* priority outranks rest always if negative
     1381                                   otherwise can be downgraded if at correct level.
     1382                                   Infeasibility may be increased to choose 1.0 values first.
     1383                                   choose one near wanted value
     1384                                */
     1385                                if (fabs(value - targetValue) > integerTolerance) {
     1386                                    //if (infeasibility>0.01)
     1387                                    //infeasibility = fabs(1.0e6-fabs(value-targetValue));
     1388                                    //else
     1389                                    infeasibility = fabs(value - targetValue);
     1390                                    //if (targetValue==1.0)
     1391                                    //infeasibility += 1.0;
     1392                                    if (value > targetValue) {
     1393                                        preferredWay = -1;
     1394                                    } else {
     1395                                        preferredWay = 1;
     1396                                    }
     1397                                    priorityLevel = CoinAbs(priorityLevel);
     1398                                } else if (priorityLevel < 0) {
     1399                                    priorityLevel = CoinAbs(priorityLevel);
     1400                                    if (targetValue == saveLower[iColumn]) {
     1401                                        infeasibility = integerTolerance + 1.0e-12;
     1402                                        preferredWay = -1;
     1403                                    } else if (targetValue == saveUpper[iColumn]) {
     1404                                        infeasibility = integerTolerance + 1.0e-12;
     1405                                        preferredWay = 1;
     1406                                    } else {
     1407                                        // can't
     1408                                        priorityLevel += 10000000;
     1409                                        canDoThisHot = false;
     1410                                    }
     1411                                } else {
     1412                                    priorityLevel += 10000000;
     1413                                    canDoThisHot = false;
     1414                                }
     1415                            } else {
     1416                                // switch off if not possible
     1417                                canDoThisHot = false;
     1418                            }
     1419                            if (canDoThisHot)
     1420                                canDoOneHot = true;
     1421                        } else if (targetValue < saveLower[iColumn] || targetValue > saveUpper[iColumn]) {
     1422                        }
     1423                    } else {
     1424                        priorityLevel += 10000000;
     1425                    }
     1426                }
     1427                if (infeasibility) {
     1428                    // Increase estimated degradation to solution
     1429                    estimatedDegradation += CoinMin(object->upEstimate(), object->downEstimate());
     1430                    numberUnsatisfied_++;
     1431                    sumInfeasibilities_ += infeasibility;
     1432                    // Better priority? Flush choices.
     1433                    if (priorityLevel < bestPriority) {
     1434                        int j;
     1435                        iSmallest = 0;
     1436                        for (j = 0; j < maximumStrong; j++) {
     1437                            choice[j].upMovement = 0.0;
     1438                            delete choice[j].possibleBranch;
     1439                            choice[j].possibleBranch = NULL;
     1440                        }
     1441                        bestPriority = priorityLevel;
     1442                        mostAway = 1.0e-100;
     1443                        numberStrong = 0;
     1444                    } else if (priorityLevel > bestPriority) {
     1445                        continue;
     1446                    }
     1447                    // Check for suitability based on infeasibility.
     1448                    if (infeasibility > mostAway) {
     1449                        //add to list
     1450                        choice[iSmallest].upMovement = infeasibility;
     1451                        delete choice[iSmallest].possibleBranch;
     1452                        CbcObject * obj =
     1453                            dynamic_cast <CbcObject *>(object) ;
     1454                        assert (obj);
     1455                        choice[iSmallest].possibleBranch = obj->createCbcBranch(solver, &usefulInfo, preferredWay);
     1456                        numberStrong = CoinMax(numberStrong, iSmallest + 1);
     1457                        // Save which object it was
     1458                        choice[iSmallest].objectNumber = i;
     1459                        int j;
     1460                        iSmallest = -1;
     1461                        mostAway = 1.0e50;
     1462                        for (j = 0; j < maximumStrong; j++) {
     1463                            if (choice[j].upMovement < mostAway) {
     1464                                mostAway = choice[j].upMovement;
     1465                                iSmallest = j;
     1466                            }
     1467                        }
     1468                    }
     1469                }
     1470            }
     1471            if (!canDoOneHot && hotstartSolution) {
     1472                // switch off as not possible
     1473                hotstartSolution = NULL;
     1474                model->setHotstartSolution(NULL, NULL);
     1475                usefulInfo.hotstartSolution_ = NULL;
     1476            }
     1477            if (numberUnsatisfied_) {
     1478                // some infeasibilities - go to next steps
     1479#ifdef CLP_INVESTIGATE
     1480                if (hotstartSolution) {
     1481                    int k = choice[0].objectNumber;
     1482                    OsiObject * object = model->modifiableObject(k);
     1483                    const CbcSimpleInteger * thisOne = dynamic_cast <const CbcSimpleInteger *> (object);
     1484                    assert (thisOne);
     1485                    int iColumn = thisOne->columnNumber();
     1486                    double targetValue = hotstartSolution[iColumn];
     1487                    double value = saveSolution[iColumn];
     1488                    printf("Branch on %d has target %g (value %g) and current bounds %g and %g\n",
     1489                           iColumn, targetValue, value, saveLower[iColumn], saveUpper[iColumn]);
     1490                }
     1491#endif
     1492                break;
     1493            } else if (!iPass) {
     1494                // looks like a solution - get paranoid
     1495                bool roundAgain = false;
     1496                // get basis
     1497                CoinWarmStartBasis * ws = dynamic_cast<CoinWarmStartBasis*>(solver->getWarmStart());
     1498                if (!ws)
     1499                    break;
     1500                for (i = 0; i < numberColumns; i++) {
     1501                    double value = saveSolution[i];
     1502                    if (value < lower[i]) {
     1503                        saveSolution[i] = lower[i];
     1504                        roundAgain = true;
     1505                        ws->setStructStatus(i, CoinWarmStartBasis::atLowerBound);
     1506                    } else if (value > upper[i]) {
     1507                        saveSolution[i] = upper[i];
     1508                        roundAgain = true;
     1509                        ws->setStructStatus(i, CoinWarmStartBasis::atUpperBound);
     1510                    }
     1511                }
     1512                if (roundAgain && saveNumberStrong) {
     1513                    // restore basis
     1514                    solver->setWarmStart(ws);
     1515                    delete ws;
     1516                    solver->resolve();
     1517                    memcpy(saveSolution, solver->getColSolution(), numberColumns*sizeof(double));
     1518                    model->reserveCurrentSolution(saveSolution);
     1519                    if (!solver->isProvenOptimal()) {
     1520                        // infeasible
     1521                        anyAction = -2;
     1522                        break;
     1523                    }
    14051524                } else {
    1406                   priorityLevel += 10000000;
    1407                   canDoThisHot=false;
    1408                 }
    1409               } else {
    1410                 // switch off if not possible
    1411                 canDoThisHot=false;
    1412               }
    1413               if (canDoThisHot)
    1414                 canDoOneHot=true;
    1415             } else if (targetValue<saveLower[iColumn]||targetValue>saveUpper[iColumn]) {
    1416             }
    1417           } else {
    1418             priorityLevel += 10000000;
    1419           }
    1420         }
    1421         if (infeasibility) {
    1422           // Increase estimated degradation to solution
    1423           estimatedDegradation += CoinMin(object->upEstimate(),object->downEstimate());
    1424           numberUnsatisfied_++;
    1425           sumInfeasibilities_ += infeasibility;
    1426           // Better priority? Flush choices.
    1427           if (priorityLevel<bestPriority) {
    1428             int j;
    1429             iSmallest=0;
    1430             for (j=0;j<maximumStrong;j++) {
    1431               choice[j].upMovement=0.0;
    1432               delete choice[j].possibleBranch;
    1433               choice[j].possibleBranch=NULL;
    1434             }
    1435             bestPriority = priorityLevel;
    1436             mostAway=1.0e-100;
    1437             numberStrong=0;
    1438           } else if (priorityLevel>bestPriority) {
    1439             continue;
    1440           }
    1441           // Check for suitability based on infeasibility.
    1442           if (infeasibility>mostAway) {
    1443             //add to list
    1444             choice[iSmallest].upMovement=infeasibility;
    1445             delete choice[iSmallest].possibleBranch;
    1446             CbcObject * obj =
    1447               dynamic_cast <CbcObject *>(object) ;
    1448             assert (obj);
    1449             choice[iSmallest].possibleBranch=obj->createCbcBranch(solver,&usefulInfo,preferredWay);
    1450             numberStrong = CoinMax(numberStrong,iSmallest+1);
    1451             // Save which object it was
    1452             choice[iSmallest].objectNumber=i;
    1453             int j;
    1454             iSmallest=-1;
    1455             mostAway = 1.0e50;
    1456             for (j=0;j<maximumStrong;j++) {
    1457               if (choice[j].upMovement<mostAway) {
    1458                 mostAway=choice[j].upMovement;
    1459                 iSmallest=j;
    1460               }
    1461             }
    1462           }
    1463         }
    1464       }
    1465       if (!canDoOneHot&&hotstartSolution) {
    1466         // switch off as not possible
    1467         hotstartSolution=NULL;
    1468         model->setHotstartSolution(NULL,NULL);
    1469         usefulInfo.hotstartSolution_=NULL;
    1470       }
    1471       if (numberUnsatisfied_) {
    1472         // some infeasibilities - go to next steps
    1473 #ifdef CLP_INVESTIGATE
    1474         if (hotstartSolution) {
    1475           int k=choice[0].objectNumber;
    1476           OsiObject * object = model->modifiableObject(k);
    1477           const CbcSimpleInteger * thisOne = dynamic_cast <const CbcSimpleInteger *> (object);
    1478           assert (thisOne);
    1479           int iColumn = thisOne->columnNumber();
    1480           double targetValue = hotstartSolution[iColumn];
    1481           double value = saveSolution[iColumn];
    1482           printf("Branch on %d has target %g (value %g) and current bounds %g and %g\n",
    1483                  iColumn,targetValue,value,saveLower[iColumn],saveUpper[iColumn]);
    1484         }
    1485 #endif
    1486         break;
    1487       } else if (!iPass) {
    1488         // looks like a solution - get paranoid
    1489         bool roundAgain=false;
    1490         // get basis
    1491         CoinWarmStartBasis * ws = dynamic_cast<CoinWarmStartBasis*>(solver->getWarmStart());
    1492         if (!ws)
    1493           break;
    1494         for (i=0;i<numberColumns;i++) {
    1495           double value = saveSolution[i];
    1496           if (value<lower[i]) {
    1497             saveSolution[i]=lower[i];
    1498             roundAgain=true;
    1499             ws->setStructStatus(i,CoinWarmStartBasis::atLowerBound);
    1500           } else if (value>upper[i]) {
    1501             saveSolution[i]=upper[i];
    1502             roundAgain=true;
    1503             ws->setStructStatus(i,CoinWarmStartBasis::atUpperBound);
    1504           }
    1505         }
    1506         if (roundAgain&&saveNumberStrong) {
    1507           // restore basis
    1508           solver->setWarmStart(ws);
    1509           delete ws;
    1510           solver->resolve();
    1511           memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
    1512           model->reserveCurrentSolution(saveSolution);
    1513           if (!solver->isProvenOptimal()) {
    1514             // infeasible
    1515             anyAction=-2;
    1516             break;
    1517           }
    1518         } else {
    1519           delete ws;
    1520           break;
    1521         }
    1522       }
    1523     }
    1524     /* Some solvers can do the strong branching calculations faster if
    1525        they do them all at once.  At present only Clp does for ordinary
    1526        integers but I think this coding would be easy to modify
    1527     */
    1528     bool allNormal=true; // to say if we can do fast strong branching
    1529     // Say which one will be best
    1530     int bestChoice=0;
    1531     double worstInfeasibility=0.0;
    1532     for (i=0;i<numberStrong;i++) {
    1533       choice[i].numIntInfeasUp = numberUnsatisfied_;
    1534       choice[i].numIntInfeasDown = numberUnsatisfied_;
    1535       choice[i].fix=0; // say not fixed
    1536       if (!dynamic_cast <const CbcSimpleInteger *> (model->object(choice[i].objectNumber)))
    1537         allNormal=false; // Something odd so lets skip clever fast branching
    1538       if ( !model->object(choice[i].objectNumber)->boundBranch())
    1539         numberStrong=0; // switch off
    1540       if ( choice[i].possibleBranch->numberBranches()>2)
    1541         numberStrong=0; // switch off
    1542       // Do best choice in case switched off
    1543       if (choice[i].upMovement>worstInfeasibility) {
    1544         worstInfeasibility=choice[i].upMovement;
    1545         bestChoice=i;
    1546       }
    1547     }
    1548     // If we have hit max time don't do strong branching
    1549     bool hitMaxTime = ( CoinCpuTime()-model->getDblParam(CbcModel::CbcStartSeconds) >
    1550                         model->getDblParam(CbcModel::CbcMaximumSeconds));
    1551     // also give up if we are looping round too much
    1552     if (hitMaxTime||numberPassesLeft<=0)
    1553       numberStrong=0;
    1554     /*
    1555       Is strong branching enabled? If so, set up and do it. Otherwise, we'll
    1556       fall through to simple branching.
    1557      
    1558       Setup for strong branching involves saving the current basis (for restoration
    1559       afterwards) and setting up for hot starts.
    1560     */
    1561     if (numberStrong&&saveNumberStrong) {
    1562      
    1563       bool solveAll=false; // set true to say look at all even if some fixed (experiment)
    1564       solveAll=true;
    1565       // worth trying if too many times
    1566       // Save basis
    1567       CoinWarmStart * ws = solver->getWarmStart();
    1568       // save limit
    1569       int saveLimit;
    1570       solver->getIntParam(OsiMaxNumIterationHotStart,saveLimit);
    1571       if (beforeSolution&&saveLimit<100)
    1572         solver->setIntParam(OsiMaxNumIterationHotStart,100); // go to end
    1573 #     ifdef COIN_HAS_CLP     
    1574       /* If we are doing all strong branching in one go then we create new arrays
    1575          to store information.  If clp NULL then doing old way.
    1576          Going down -
    1577          outputSolution[2*i] is final solution.
    1578          outputStuff[2*i] is status (0 - finished, 1 infeas, other unknown
    1579          outputStuff[2*i+numberStrong] is number iterations
    1580          On entry newUpper[i] is new upper bound, on exit obj change
    1581          Going up -
    1582          outputSolution[2*i+1] is final solution.
    1583          outputStuff[2*i+1] is status (0 - finished, 1 infeas, other unknown
    1584          outputStuff[2*i+1+numberStrong] is number iterations
    1585          On entry newLower[i] is new lower bound, on exit obj change
    1586       */
    1587       ClpSimplex * clp=NULL;
    1588       double * newLower = NULL;
    1589       double * newUpper = NULL;
    1590       double ** outputSolution=NULL;
    1591       int * outputStuff=NULL;
    1592       // Go back to normal way if user wants it
    1593       if (osiclp&&(osiclp->specialOptions()&16)!=0&&osiclp->specialOptions()>0)
    1594         allNormal=false;
    1595       if (osiclp&&!allNormal) {
    1596         // say do fast
    1597         int easy=1;
    1598         osiclp->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,&easy) ;
    1599       }
    1600       if (osiclp&& allNormal) {
    1601         clp = osiclp->getModelPtr();
    1602         // Clp - do a different way
    1603         newLower = new double[numberStrong];
    1604         newUpper = new double[numberStrong];
    1605         outputSolution = new double * [2*numberStrong];
    1606         outputStuff = new int [4*numberStrong];
    1607         int * which = new int[numberStrong];
    1608         int startFinishOptions;
    1609         int specialOptions = osiclp->specialOptions();
    1610         int clpOptions = clp->specialOptions();
    1611         int returnCode=0;
     1525                    delete ws;
     1526                    break;
     1527                }
     1528            }
     1529        }
     1530        /* Some solvers can do the strong branching calculations faster if
     1531           they do them all at once.  At present only Clp does for ordinary
     1532           integers but I think this coding would be easy to modify
     1533        */
     1534        bool allNormal = true; // to say if we can do fast strong branching
     1535        // Say which one will be best
     1536        int bestChoice = 0;
     1537        double worstInfeasibility = 0.0;
     1538        for (i = 0; i < numberStrong; i++) {
     1539            choice[i].numIntInfeasUp = numberUnsatisfied_;
     1540            choice[i].numIntInfeasDown = numberUnsatisfied_;
     1541            choice[i].fix = 0; // say not fixed
     1542            if (!dynamic_cast <const CbcSimpleInteger *> (model->object(choice[i].objectNumber)))
     1543                allNormal = false; // Something odd so lets skip clever fast branching
     1544            if ( !model->object(choice[i].objectNumber)->boundBranch())
     1545                numberStrong = 0; // switch off
     1546            if ( choice[i].possibleBranch->numberBranches() > 2)
     1547                numberStrong = 0; // switch off
     1548            // Do best choice in case switched off
     1549            if (choice[i].upMovement > worstInfeasibility) {
     1550                worstInfeasibility = choice[i].upMovement;
     1551                bestChoice = i;
     1552            }
     1553        }
     1554        // If we have hit max time don't do strong branching
     1555        bool hitMaxTime = ( CoinCpuTime() - model->getDblParam(CbcModel::CbcStartSeconds) >
     1556                            model->getDblParam(CbcModel::CbcMaximumSeconds));
     1557        // also give up if we are looping round too much
     1558        if (hitMaxTime || numberPassesLeft <= 0)
     1559            numberStrong = 0;
     1560        /*
     1561          Is strong branching enabled? If so, set up and do it. Otherwise, we'll
     1562          fall through to simple branching.
     1563
     1564          Setup for strong branching involves saving the current basis (for restoration
     1565          afterwards) and setting up for hot starts.
     1566        */
     1567        if (numberStrong && saveNumberStrong) {
     1568
     1569            bool solveAll = false; // set true to say look at all even if some fixed (experiment)
     1570            solveAll = true;
     1571            // worth trying if too many times
     1572            // Save basis
     1573            CoinWarmStart * ws = solver->getWarmStart();
     1574            // save limit
     1575            int saveLimit;
     1576            solver->getIntParam(OsiMaxNumIterationHotStart, saveLimit);
     1577            if (beforeSolution && saveLimit < 100)
     1578                solver->setIntParam(OsiMaxNumIterationHotStart, 100); // go to end
     1579#     ifdef COIN_HAS_CLP
     1580            /* If we are doing all strong branching in one go then we create new arrays
     1581               to store information.  If clp NULL then doing old way.
     1582               Going down -
     1583               outputSolution[2*i] is final solution.
     1584               outputStuff[2*i] is status (0 - finished, 1 infeas, other unknown
     1585               outputStuff[2*i+numberStrong] is number iterations
     1586               On entry newUpper[i] is new upper bound, on exit obj change
     1587               Going up -
     1588               outputSolution[2*i+1] is final solution.
     1589               outputStuff[2*i+1] is status (0 - finished, 1 infeas, other unknown
     1590               outputStuff[2*i+1+numberStrong] is number iterations
     1591            On entry newLower[i] is new lower bound, on exit obj change
     1592            */
     1593            ClpSimplex * clp = NULL;
     1594            double * newLower = NULL;
     1595            double * newUpper = NULL;
     1596            double ** outputSolution = NULL;
     1597            int * outputStuff = NULL;
     1598            // Go back to normal way if user wants it
     1599            if (osiclp && (osiclp->specialOptions()&16) != 0 && osiclp->specialOptions() > 0)
     1600                allNormal = false;
     1601            if (osiclp && !allNormal) {
     1602                // say do fast
     1603                int easy = 1;
     1604                osiclp->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo, &easy) ;
     1605            }
     1606            if (osiclp && allNormal) {
     1607                clp = osiclp->getModelPtr();
     1608                // Clp - do a different way
     1609                newLower = new double[numberStrong];
     1610                newUpper = new double[numberStrong];
     1611                outputSolution = new double * [2*numberStrong];
     1612                outputStuff = new int [4*numberStrong];
     1613                int * which = new int[numberStrong];
     1614                int startFinishOptions;
     1615                int specialOptions = osiclp->specialOptions();
     1616                int clpOptions = clp->specialOptions();
     1617                int returnCode = 0;
    16121618#define CRUNCH
    16131619#ifdef CRUNCH
    1614         // Crunch down problem
    1615         int numberRows = clp->numberRows();
    1616         // Use dual region
    1617         double * rhs = clp->dualRowSolution();
    1618         int * whichRow = new int[3*numberRows];
    1619         int * whichColumn = new int[2*numberColumns];
    1620         int nBound;
    1621         ClpSimplex * small = static_cast<ClpSimplexOther *> (clp)->crunch(rhs,whichRow,whichColumn,nBound,true);
    1622         if (!small) {
    1623           anyAction=-2;
    1624           //printf("XXXX Inf by inspection\n");
    1625           delete [] whichColumn;
    1626           whichColumn=NULL;
    1627           delete [] whichRow;
    1628           whichRow=NULL;
    1629           break;
    1630         } else {
    1631           clp = small;
    1632         }
     1620                // Crunch down problem
     1621                int numberRows = clp->numberRows();
     1622                // Use dual region
     1623                double * rhs = clp->dualRowSolution();
     1624                int * whichRow = new int[3*numberRows];
     1625                int * whichColumn = new int[2*numberColumns];
     1626                int nBound;
     1627                ClpSimplex * small = static_cast<ClpSimplexOther *> (clp)->crunch(rhs, whichRow, whichColumn, nBound, true);
     1628                if (!small) {
     1629                    anyAction = -2;
     1630                    //printf("XXXX Inf by inspection\n");
     1631                    delete [] whichColumn;
     1632                    whichColumn = NULL;
     1633                    delete [] whichRow;
     1634                    whichRow = NULL;
     1635                    break;
     1636                } else {
     1637                    clp = small;
     1638                }
    16331639#else
    1634         int saveLogLevel = clp->logLevel();
    1635         int saveMaxIts = clp->maximumIterations();
    1636 #endif
    1637         clp->setLogLevel(0);
    1638         if((specialOptions&1)==0) {
    1639           startFinishOptions=0;
    1640           clp->setSpecialOptions(clpOptions|(64|1024));
    1641         } else {
    1642           startFinishOptions=1+2+4;
    1643           //startFinishOptions=1+4; // for moment re-factorize
    1644           if((specialOptions&4)==0)
    1645             clp->setSpecialOptions(clpOptions|(64|128|512|1024|4096));
    1646           else
    1647             clp->setSpecialOptions(clpOptions|(64|128|512|1024|2048|4096));
    1648         }
    1649         // User may want to clean up before strong branching
    1650         if ((clp->specialOptions()&32)!=0) {
    1651           clp->primal(1);
    1652           if (clp->numberIterations())
    1653             model->messageHandler()->message(CBC_ITERATE_STRONG,*model->messagesPointer())
    1654               << clp->numberIterations()
    1655               <<CoinMessageEol;
    1656         }
    1657         clp->setMaximumIterations(saveLimit);
     1640                int saveLogLevel = clp->logLevel();
     1641                int saveMaxIts = clp->maximumIterations();
     1642#endif
     1643                clp->setLogLevel(0);
     1644                if ((specialOptions&1) == 0) {
     1645                    startFinishOptions = 0;
     1646                    clp->setSpecialOptions(clpOptions | (64 | 1024));
     1647                } else {
     1648                    startFinishOptions = 1 + 2 + 4;
     1649                    //startFinishOptions=1+4; // for moment re-factorize
     1650                    if ((specialOptions&4) == 0)
     1651                        clp->setSpecialOptions(clpOptions | (64 | 128 | 512 | 1024 | 4096));
     1652                    else
     1653                        clp->setSpecialOptions(clpOptions | (64 | 128 | 512 | 1024 | 2048 | 4096));
     1654                }
     1655                // User may want to clean up before strong branching
     1656                if ((clp->specialOptions()&32) != 0) {
     1657                    clp->primal(1);
     1658                    if (clp->numberIterations())
     1659                        model->messageHandler()->message(CBC_ITERATE_STRONG, *model->messagesPointer())
     1660                        << clp->numberIterations()
     1661                        << CoinMessageEol;
     1662                }
     1663                clp->setMaximumIterations(saveLimit);
    16581664#ifdef CRUNCH
    1659         int * backColumn = whichColumn+numberColumns;
    1660 #endif
    1661         for (i=0;i<numberStrong;i++) {
    1662           int iObject = choice[i].objectNumber;
    1663           const OsiObject * object = model->object(iObject);
    1664           const CbcSimpleInteger * simple = static_cast <const CbcSimpleInteger *> (object);
    1665           int iSequence = simple->columnNumber();
    1666           newLower[i]= ceil(saveSolution[iSequence]);
    1667           newUpper[i]= floor(saveSolution[iSequence]);
     1665                int * backColumn = whichColumn + numberColumns;
     1666#endif
     1667                for (i = 0; i < numberStrong; i++) {
     1668                    int iObject = choice[i].objectNumber;
     1669                    const OsiObject * object = model->object(iObject);
     1670                    const CbcSimpleInteger * simple = static_cast <const CbcSimpleInteger *> (object);
     1671                    int iSequence = simple->columnNumber();
     1672                    newLower[i] = ceil(saveSolution[iSequence]);
     1673                    newUpper[i] = floor(saveSolution[iSequence]);
    16681674#ifdef CRUNCH
    1669           iSequence = backColumn[iSequence];
    1670           assert (iSequence>=0);
    1671 #endif
    1672           which[i]=iSequence;
    1673           outputSolution[2*i]= new double [numberColumns];
    1674           outputSolution[2*i+1]= new double [numberColumns];
    1675         }
    1676         //clp->writeMps("bad");
    1677         returnCode=clp->strongBranching(numberStrong,which,
    1678                                         newLower, newUpper,outputSolution,
    1679                                         outputStuff,outputStuff+2*numberStrong,!solveAll,false,
    1680                                         startFinishOptions);
     1675                    iSequence = backColumn[iSequence];
     1676                    assert (iSequence >= 0);
     1677#endif
     1678                    which[i] = iSequence;
     1679                    outputSolution[2*i] = new double [numberColumns];
     1680                    outputSolution[2*i+1] = new double [numberColumns];
     1681                }
     1682                //clp->writeMps("bad");
     1683                returnCode = clp->strongBranching(numberStrong, which,
     1684                                                  newLower, newUpper, outputSolution,
     1685                                                  outputStuff, outputStuff + 2 * numberStrong, !solveAll, false,
     1686                                                  startFinishOptions);
    16811687#ifndef CRUNCH
    1682         clp->setSpecialOptions(clpOptions); // restore
    1683         clp->setMaximumIterations(saveMaxIts);
    1684         clp->setLogLevel(saveLogLevel);
    1685 #endif
    1686         if (returnCode==-2) {
    1687           // bad factorization!!!
    1688           // Doing normal way
    1689           // Mark hot start
    1690           solver->markHotStart();
    1691           clp = NULL;
    1692         } else {
     1688                clp->setSpecialOptions(clpOptions); // restore
     1689                clp->setMaximumIterations(saveMaxIts);
     1690                clp->setLogLevel(saveLogLevel);
     1691#endif
     1692                if (returnCode == -2) {
     1693                    // bad factorization!!!
     1694                    // Doing normal way
     1695                    // Mark hot start
     1696                    solver->markHotStart();
     1697                    clp = NULL;
     1698                } else {
    16931699#ifdef CRUNCH
    1694           // extract solution
    1695           //bool checkSol=true;
    1696           for (i=0;i<numberStrong;i++) {
    1697             int iObject = choice[i].objectNumber;
    1698             const OsiObject * object = model->object(iObject);
    1699             const CbcSimpleInteger * simple = static_cast <const CbcSimpleInteger *> (object);
    1700             int iSequence = simple->columnNumber();
    1701             which[i]=iSequence;
    1702             double * sol = outputSolution[2*i];
    1703             double * sol2 = outputSolution[2*i+1];
    1704             //bool x=true;
    1705             //bool x2=true;
    1706             for (int iColumn=numberColumns-1;iColumn>=0;iColumn--) {
    1707               int jColumn = backColumn[iColumn];
    1708               if (jColumn>=0) {
    1709                 sol[iColumn]=sol[jColumn];
    1710                 sol2[iColumn]=sol2[jColumn];
    1711               } else {
    1712                 sol[iColumn]=saveSolution[iColumn];
    1713                 sol2[iColumn]=saveSolution[iColumn];
    1714               }
    1715             }
    1716           }
    1717 #endif
    1718         }
     1700                    // extract solution
     1701                    //bool checkSol=true;
     1702                    for (i = 0; i < numberStrong; i++) {
     1703                        int iObject = choice[i].objectNumber;
     1704                        const OsiObject * object = model->object(iObject);
     1705                        const CbcSimpleInteger * simple = static_cast <const CbcSimpleInteger *> (object);
     1706                        int iSequence = simple->columnNumber();
     1707                        which[i] = iSequence;
     1708                        double * sol = outputSolution[2*i];
     1709                        double * sol2 = outputSolution[2*i+1];
     1710                        //bool x=true;
     1711                        //bool x2=true;
     1712                        for (int iColumn = numberColumns - 1; iColumn >= 0; iColumn--) {
     1713                            int jColumn = backColumn[iColumn];
     1714                            if (jColumn >= 0) {
     1715                                sol[iColumn] = sol[jColumn];
     1716                                sol2[iColumn] = sol2[jColumn];
     1717                            } else {
     1718                                sol[iColumn] = saveSolution[iColumn];
     1719                                sol2[iColumn] = saveSolution[iColumn];
     1720                            }
     1721                        }
     1722                    }
     1723#endif
     1724                }
    17191725#ifdef CRUNCH
    1720         delete [] whichColumn;
    1721         delete [] whichRow;
    1722         delete small;
    1723 #endif
    1724         delete [] which;
    1725       } else {
    1726         // Doing normal way
    1727         // Mark hot start
    1728         solver->markHotStart();
    1729       }
     1726                delete [] whichColumn;
     1727                delete [] whichRow;
     1728                delete small;
     1729#endif
     1730                delete [] which;
     1731            } else {
     1732                // Doing normal way
     1733                // Mark hot start
     1734                solver->markHotStart();
     1735            }
    17301736#     else      /* COIN_HAS_CLP */
    1731      
    1732       OsiSolverInterface *clp = NULL ;
    1733       double **outputSolution = NULL ;
    1734       int *outputStuff = NULL ;
    1735       double * newLower = NULL ;
    1736       double * newUpper = NULL ;
    1737      
    1738       solver->markHotStart();
    1739      
     1737
     1738            OsiSolverInterface *clp = NULL ;
     1739            double **outputSolution = NULL ;
     1740            int *outputStuff = NULL ;
     1741            double * newLower = NULL ;
     1742            double * newUpper = NULL ;
     1743
     1744            solver->markHotStart();
     1745
    17401746#     endif     /* COIN_HAS_CLP */
    1741       /*
    1742         Open a loop to do the strong branching LPs. For each candidate variable,
    1743         solve an LP with the variable forced down, then up. If a direction turns
    1744         out to be infeasible or monotonic (i.e., over the dual objective cutoff),
    1745         force the objective change to be big (1.0e100). If we determine the problem
    1746         is infeasible, or find a monotone variable, escape the loop.
    1747        
    1748         TODO: The `restore bounds' part might be better encapsulated as an
    1749         unbranch() method. Branching objects more exotic than simple integers
    1750         or cliques might not restrict themselves to variable bounds.
    1751        
    1752         TODO: Virtuous solvers invalidate the current solution (or give bogus
    1753         results :-) when the bounds are changed out from under them. So we
    1754         need to do all the work associated with finding a new solution before
    1755         restoring the bounds.
    1756       */
    1757       for (i = 0 ; i < numberStrong ; i++)
    1758         { double objectiveChange ;
    1759           double newObjectiveValue=1.0e100;
    1760           // status is 0 finished, 1 infeasible and other
    1761           int iStatus;
    1762           /*
    1763             Try the down direction first. (Specify the initial branching alternative as
    1764             down with a call to way(-1). Each subsequent call to branch() performs the
    1765             specified branch and advances the branch object state to the next branch
    1766             alternative.)
    1767           */
    1768           if (!clp) {
    1769             choice[i].possibleBranch->way(-1) ;
    1770             choice[i].possibleBranch->branch() ;
    1771             bool feasible=true;
    1772             if (checkFeasibility) {
    1773               // check branching did not make infeasible
    1774               int iColumn;
    1775               int numberColumns = solver->getNumCols();
    1776               const double * columnLower = solver->getColLower();
    1777               const double * columnUpper = solver->getColUpper();
    1778               for (iColumn= 0;iColumn<numberColumns;iColumn++) {
    1779                 if (columnLower[iColumn]>columnUpper[iColumn]+1.0e-5)
    1780                   feasible=false;
    1781               }
    1782             }
    1783             if (feasible) {
    1784               solver->solveFromHotStart() ;
    1785               numberStrongDone++;
    1786               numberStrongIterations += solver->getIterationCount();
    1787               /*
    1788                 We now have an estimate of objective degradation that we can use for strong
    1789                 branching. If we're over the cutoff, the variable is monotone up.
    1790                 If we actually made it to optimality, check for a solution, and if we have
    1791                 a good one, call setBestSolution to process it. Note that this may reduce the
    1792                 cutoff, so we check again to see if we can declare this variable monotone.
    1793               */
    1794               if (solver->isProvenOptimal())
    1795                 iStatus=0; // optimal
    1796               else if (solver->isIterationLimitReached()
    1797                        &&!solver->isDualObjectiveLimitReached())
    1798                 iStatus=2; // unknown
    1799               else
    1800                 iStatus=1; // infeasible
    1801               newObjectiveValue = solver->getObjSense()*solver->getObjValue();
    1802               choice[i].numItersDown = solver->getIterationCount();
    1803             } else {
    1804               iStatus=1; // infeasible
    1805               newObjectiveValue = 1.0e100;
    1806               choice[i].numItersDown = 0;
    1807             }
    1808           } else {
    1809             iStatus = outputStuff[2*i];
    1810             choice[i].numItersDown = outputStuff[2*numberStrong+2*i];
    1811             numberStrongDone++;
    1812             numberStrongIterations += choice[i].numItersDown;
    1813             newObjectiveValue = objectiveValue+newUpper[i];
    1814             solver->setColSolution(outputSolution[2*i]);
    1815           }
    1816           objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
    1817           if (!iStatus) {
    1818             choice[i].finishedDown = true ;
    1819             if (newObjectiveValue>=model->getCutoff()) {
    1820               objectiveChange = 1.0e100; // say infeasible
    1821               numberStrongInfeasible++;
    1822             } else {
    1823               // See if integer solution
    1824               if (model->feasibleSolution(choice[i].numIntInfeasDown,
    1825                                           choice[i].numObjInfeasDown)
    1826                   &&model->problemFeasibility()->feasible(model,-1)>=0) {
    1827                 model->setBestSolution(CBC_STRONGSOL,
    1828                                        newObjectiveValue,
    1829                                        solver->getColSolution()) ;
    1830                 // only needed for odd solvers
    1831                 newObjectiveValue = solver->getObjSense()*solver->getObjValue();
    1832                 objectiveChange = CoinMax(newObjectiveValue-objectiveValue_,0.0) ;
    1833                 model->setLastHeuristic(NULL);
    1834                 model->incrementUsed(solver->getColSolution());
    1835                 if (newObjectiveValue >= model->getCutoff()) {  //  *new* cutoff
    1836                   objectiveChange = 1.0e100 ;
    1837                   numberStrongInfeasible++;
    1838                 }
    1839               }
    1840             }
    1841           } else if (iStatus==1) {
    1842             objectiveChange = 1.0e100 ;
    1843             numberStrongInfeasible++;
    1844           } else {
    1845             // Can't say much as we did not finish
    1846             choice[i].finishedDown = false ;
    1847             numberUnfinished++;
    1848           }
    1849           choice[i].downMovement = objectiveChange ;
    1850          
    1851           // restore bounds
    1852           if (!clp)
    1853             { for (int j=0;j<numberColumns;j++) {
    1854                 if (saveLower[j] != lower[j])
    1855                   solver->setColLower(j,saveLower[j]);
    1856                 if (saveUpper[j] != upper[j])
    1857                   solver->setColUpper(j,saveUpper[j]);
    1858               }
    1859             }
    1860           //printf("Down on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
    1861           //     choice[i].objectNumber,iStatus,newObjectiveValue,choice[i].numItersDown,
    1862           //     choice[i].downMovement,choice[i].finishedDown,choice[i].numIntInfeasDown,
    1863           //     choice[i].numObjInfeasDown);
    1864          
    1865           // repeat the whole exercise, forcing the variable up
    1866           if (!clp) {
    1867             bool feasible=true;
    1868             // If odd branching then maybe just one possibility
    1869             if(choice[i].possibleBranch->numberBranchesLeft()>0) {
    1870               choice[i].possibleBranch->branch();
    1871               if (checkFeasibility) {
    1872                 // check branching did not make infeasible
    1873                 int iColumn;
    1874                 int numberColumns = solver->getNumCols();
    1875                 const double * columnLower = solver->getColLower();
    1876                 const double * columnUpper = solver->getColUpper();
    1877                 for (iColumn= 0;iColumn<numberColumns;iColumn++) {
    1878                   if (columnLower[iColumn]>columnUpper[iColumn]+1.0e-5)
    1879                     feasible=false;
    1880                 }
    1881               }
    1882             } else {
    1883               // second branch infeasible
    1884               feasible=false;
    1885             }
    1886             if (feasible) {
    1887               solver->solveFromHotStart() ;
    1888               numberStrongDone++;
    1889               numberStrongIterations += solver->getIterationCount();
    1890               /*
    1891                 We now have an estimate of objective degradation that we can use for strong
    1892                 branching. If we're over the cutoff, the variable is monotone up.
    1893                 If we actually made it to optimality, check for a solution, and if we have
    1894                 a good one, call setBestSolution to process it. Note that this may reduce the
    1895                 cutoff, so we check again to see if we can declare this variable monotone.
    1896               */
    1897               if (solver->isProvenOptimal())
    1898                 iStatus=0; // optimal
    1899               else if (solver->isIterationLimitReached()
    1900                        &&!solver->isDualObjectiveLimitReached())
    1901                 iStatus=2; // unknown
    1902               else
    1903                 iStatus=1; // infeasible
    1904               newObjectiveValue = solver->getObjSense()*solver->getObjValue();
    1905               choice[i].numItersUp = solver->getIterationCount();
    1906             } else {
    1907               iStatus=1; // infeasible
    1908               newObjectiveValue = 1.0e100;
    1909               choice[i].numItersDown = 0;
    1910             }
    1911           } else {
    1912             iStatus = outputStuff[2*i+1];
    1913             choice[i].numItersUp = outputStuff[2*numberStrong+2*i+1];
    1914             numberStrongDone++;
    1915             numberStrongIterations += choice[i].numItersUp;
    1916             newObjectiveValue = objectiveValue+newLower[i];
    1917             solver->setColSolution(outputSolution[2*i+1]);
    1918           }
    1919           objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_,0.0);
    1920           if (!iStatus) {
    1921             choice[i].finishedUp = true ;
    1922             if (newObjectiveValue>=model->getCutoff()) {
    1923               objectiveChange = 1.0e100; // say infeasible
    1924               numberStrongInfeasible++;
    1925             } else {
    1926               // See if integer solution
    1927               if (model->feasibleSolution(choice[i].numIntInfeasUp,
    1928                                           choice[i].numObjInfeasUp)
    1929                   &&model->problemFeasibility()->feasible(model,-1)>=0) {
    1930                 model->setBestSolution(CBC_STRONGSOL,
    1931                                        newObjectiveValue,
    1932                                        solver->getColSolution()) ;
    1933                 // only needed for odd solvers
    1934                 newObjectiveValue = solver->getObjSense()*solver->getObjValue();
    1935                 objectiveChange = CoinMax(newObjectiveValue-objectiveValue_,0.0) ;
    1936                 model->setLastHeuristic(NULL);
    1937                 model->incrementUsed(solver->getColSolution());
    1938                 if (newObjectiveValue >= model->getCutoff()) {  //  *new* cutoff
    1939                   objectiveChange = 1.0e100 ;
    1940                   numberStrongInfeasible++;
    1941                 }
    1942               }
    1943             }
    1944           } else if (iStatus==1) {
    1945             objectiveChange = 1.0e100 ;
    1946             numberStrongInfeasible++;
    1947           } else {
    1948             // Can't say much as we did not finish
    1949             choice[i].finishedUp = false ;
    1950             numberUnfinished++;
    1951           }
    1952           choice[i].upMovement = objectiveChange ;
    1953          
    1954           // restore bounds
    1955           if (!clp)
    1956             { for (int j=0;j<numberColumns;j++) {
    1957                 if (saveLower[j] != lower[j])
    1958                   solver->setColLower(j,saveLower[j]);
    1959                 if (saveUpper[j] != upper[j])
    1960                   solver->setColUpper(j,saveUpper[j]);
    1961               }
    1962             }
    1963          
    1964           //printf("Up on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
    1965           //     choice[i].objectNumber,iStatus,newObjectiveValue,choice[i].numItersUp,
    1966           //     choice[i].upMovement,choice[i].finishedUp,choice[i].numIntInfeasUp,
    1967           //     choice[i].numObjInfeasUp);
    1968          
    1969           /*
    1970             End of evaluation for this candidate variable. Possibilities are:
    1971             * Both sides below cutoff; this variable is a candidate for branching.
    1972             * Both sides infeasible or above the objective cutoff: no further action
    1973             here. Break from the evaluation loop and assume the node will be purged
    1974             by the caller.
    1975             * One side below cutoff: Install the branch (i.e., fix the variable). Break
    1976             from the evaluation loop and assume the node will be reoptimised by the
    1977             caller.
    1978           */
    1979           // reset
    1980           choice[i].possibleBranch->resetNumberBranchesLeft();
    1981           if (choice[i].upMovement<1.0e100) {
    1982             if(choice[i].downMovement<1.0e100) {
    1983               // feasible - no action
    1984             } else {
    1985               // up feasible, down infeasible
    1986               anyAction=-1;
    1987               //printf("Down infeasible for choice %d sequence %d\n",i,
    1988               // model->object(choice[i].objectNumber)->columnNumber());
    1989               if (!solveAll) {
    1990                 choice[i].possibleBranch->way(1);
    1991                 choice[i].possibleBranch->branch();
    1992                 break;
    1993               } else {
    1994                 choice[i].fix=1;
    1995               }
    1996             }
    1997           } else {
    1998             if(choice[i].downMovement<1.0e100) {
    1999               // down feasible, up infeasible
    2000               anyAction=-1;
    2001               //printf("Up infeasible for choice %d sequence %d\n",i,
    2002               // model->object(choice[i].objectNumber)->columnNumber());
    2003               if (!solveAll) {
    2004                 choice[i].possibleBranch->way(-1);
    2005                 choice[i].possibleBranch->branch();
    2006                 break;
    2007               } else {
    2008                 choice[i].fix=-1;
    2009               }
    2010             } else {
    2011               // neither side feasible
    2012               anyAction=-2;
    2013               //printf("Both infeasible for choice %d sequence %d\n",i,
    2014               // model->object(choice[i].objectNumber)->columnNumber());
    2015               break;
    2016             }
    2017           }
    2018           bool hitMaxTime = ( CoinCpuTime()-model->getDblParam(CbcModel::CbcStartSeconds) >
    2019                               model->getDblParam(CbcModel::CbcMaximumSeconds));
    2020           if (hitMaxTime) {
    2021             numberStrong=i+1;
    2022             break;
    2023           }
    2024         }
    2025       if (!clp) {
    2026         // Delete the snapshot
    2027         solver->unmarkHotStart();
    2028       } else {
    2029         delete [] newLower;
    2030         delete [] newUpper;
    2031         delete [] outputStuff;
    2032         int i;
    2033         for (i=0;i<2*numberStrong;i++)
    2034           delete [] outputSolution[i];
    2035         delete [] outputSolution;
    2036       }
    2037       solver->setIntParam(OsiMaxNumIterationHotStart,saveLimit);
    2038       // restore basis
    2039       solver->setWarmStart(ws);
    2040       // Unless infeasible we will carry on
    2041       // But we could fix anyway
    2042       if (anyAction==-1&&solveAll) {
    2043         // apply and take off
    2044         for (i = 0 ; i < numberStrong ; i++) {
    2045           if (choice[i].fix) {
    2046             choice[i].possibleBranch->way(choice[i].fix) ;
    2047             choice[i].possibleBranch->branch() ;
    2048           }
    2049         }
    2050         bool feasible=true;
    2051         if (checkFeasibility) {
    2052           // check branching did not make infeasible
    2053           int iColumn;
    2054           int numberColumns = solver->getNumCols();
    2055           const double * columnLower = solver->getColLower();
    2056           const double * columnUpper = solver->getColUpper();
    2057           for (iColumn= 0;iColumn<numberColumns;iColumn++) {
    2058             if (columnLower[iColumn]>columnUpper[iColumn]+1.0e-5)
    2059               feasible=false;
    2060           }
    2061         }
    2062         if (feasible) {
    2063           // can do quick optimality check
    2064           int easy=2;
    2065           solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,&easy) ;
    2066           solver->resolve() ;
    2067           solver->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
    2068           feasible = solver->isProvenOptimal();
    2069         }
    2070         if (feasible) {
    2071           memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
    2072           model->reserveCurrentSolution(saveSolution);
    2073           memcpy(saveLower,solver->getColLower(),numberColumns*sizeof(double));
    2074           memcpy(saveUpper,solver->getColUpper(),numberColumns*sizeof(double));
    2075           // Clean up all candidates whih are fixed
    2076           int numberLeft=0;
    2077           for (i = 0 ; i < numberStrong ; i++) {
    2078             CbcStrongInfo thisChoice = choice[i];
    2079             choice[i].possibleBranch=NULL;
    2080             const OsiObject * object = model->object(thisChoice.objectNumber);
    2081             int preferredWay;
    2082             double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
    2083             if (!infeasibility) {
    2084               // take out
    2085               delete thisChoice.possibleBranch;
     1747            /*
     1748              Open a loop to do the strong branching LPs. For each candidate variable,
     1749              solve an LP with the variable forced down, then up. If a direction turns
     1750              out to be infeasible or monotonic (i.e., over the dual objective cutoff),
     1751              force the objective change to be big (1.0e100). If we determine the problem
     1752              is infeasible, or find a monotone variable, escape the loop.
     1753
     1754              TODO: The `restore bounds' part might be better encapsulated as an
     1755            unbranch() method. Branching objects more exotic than simple integers
     1756            or cliques might not restrict themselves to variable bounds.
     1757
     1758              TODO: Virtuous solvers invalidate the current solution (or give bogus
     1759            results :-) when the bounds are changed out from under them. So we
     1760            need to do all the work associated with finding a new solution before
     1761            restoring the bounds.
     1762            */
     1763            for (i = 0 ; i < numberStrong ; i++) {
     1764                double objectiveChange ;
     1765                double newObjectiveValue = 1.0e100;
     1766                // status is 0 finished, 1 infeasible and other
     1767                int iStatus;
     1768                /*
     1769                  Try the down direction first. (Specify the initial branching alternative as
     1770                  down with a call to way(-1). Each subsequent call to branch() performs the
     1771                  specified branch and advances the branch object state to the next branch
     1772                  alternative.)
     1773                */
     1774                if (!clp) {
     1775                    choice[i].possibleBranch->way(-1) ;
     1776                    choice[i].possibleBranch->branch() ;
     1777                    bool feasible = true;
     1778                    if (checkFeasibility) {
     1779                        // check branching did not make infeasible
     1780                        int iColumn;
     1781                        int numberColumns = solver->getNumCols();
     1782                        const double * columnLower = solver->getColLower();
     1783                        const double * columnUpper = solver->getColUpper();
     1784                        for (iColumn = 0; iColumn < numberColumns; iColumn++) {
     1785                            if (columnLower[iColumn] > columnUpper[iColumn] + 1.0e-5)
     1786                                feasible = false;
     1787                        }
     1788                    }
     1789                    if (feasible) {
     1790                        solver->solveFromHotStart() ;
     1791                        numberStrongDone++;
     1792                        numberStrongIterations += solver->getIterationCount();
     1793                        /*
     1794                        We now have an estimate of objective degradation that we can use for strong
     1795                        branching. If we're over the cutoff, the variable is monotone up.
     1796                        If we actually made it to optimality, check for a solution, and if we have
     1797                        a good one, call setBestSolution to process it. Note that this may reduce the
     1798                        cutoff, so we check again to see if we can declare this variable monotone.
     1799                        */
     1800                        if (solver->isProvenOptimal())
     1801                            iStatus = 0; // optimal
     1802                        else if (solver->isIterationLimitReached()
     1803                                 && !solver->isDualObjectiveLimitReached())
     1804                            iStatus = 2; // unknown
     1805                        else
     1806                            iStatus = 1; // infeasible
     1807                        newObjectiveValue = solver->getObjSense() * solver->getObjValue();
     1808                        choice[i].numItersDown = solver->getIterationCount();
     1809                    } else {
     1810                        iStatus = 1; // infeasible
     1811                        newObjectiveValue = 1.0e100;
     1812                        choice[i].numItersDown = 0;
     1813                    }
     1814                } else {
     1815                    iStatus = outputStuff[2*i];
     1816                    choice[i].numItersDown = outputStuff[2*numberStrong+2*i];
     1817                    numberStrongDone++;
     1818                    numberStrongIterations += choice[i].numItersDown;
     1819                    newObjectiveValue = objectiveValue + newUpper[i];
     1820                    solver->setColSolution(outputSolution[2*i]);
     1821                }
     1822                objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_, 0.0);
     1823                if (!iStatus) {
     1824                    choice[i].finishedDown = true ;
     1825                    if (newObjectiveValue >= model->getCutoff()) {
     1826                        objectiveChange = 1.0e100; // say infeasible
     1827                        numberStrongInfeasible++;
     1828                    } else {
     1829                        // See if integer solution
     1830                        if (model->feasibleSolution(choice[i].numIntInfeasDown,
     1831                                                    choice[i].numObjInfeasDown)
     1832                                && model->problemFeasibility()->feasible(model, -1) >= 0) {
     1833                            model->setBestSolution(CBC_STRONGSOL,
     1834                                                   newObjectiveValue,
     1835                                                   solver->getColSolution()) ;
     1836                            // only needed for odd solvers
     1837                            newObjectiveValue = solver->getObjSense() * solver->getObjValue();
     1838                            objectiveChange = CoinMax(newObjectiveValue - objectiveValue_, 0.0) ;
     1839                            model->setLastHeuristic(NULL);
     1840                            model->incrementUsed(solver->getColSolution());
     1841                            if (newObjectiveValue >= model->getCutoff()) {      //  *new* cutoff
     1842                                objectiveChange = 1.0e100 ;
     1843                                numberStrongInfeasible++;
     1844                            }
     1845                        }
     1846                    }
     1847                } else if (iStatus == 1) {
     1848                    objectiveChange = 1.0e100 ;
     1849                    numberStrongInfeasible++;
     1850                } else {
     1851                    // Can't say much as we did not finish
     1852                    choice[i].finishedDown = false ;
     1853                    numberUnfinished++;
     1854                }
     1855                choice[i].downMovement = objectiveChange ;
     1856
     1857                // restore bounds
     1858                if (!clp) {
     1859                    for (int j = 0; j < numberColumns; j++) {
     1860                        if (saveLower[j] != lower[j])
     1861                            solver->setColLower(j, saveLower[j]);
     1862                        if (saveUpper[j] != upper[j])
     1863                            solver->setColUpper(j, saveUpper[j]);
     1864                    }
     1865                }
     1866                //printf("Down on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
     1867                //     choice[i].objectNumber,iStatus,newObjectiveValue,choice[i].numItersDown,
     1868                //     choice[i].downMovement,choice[i].finishedDown,choice[i].numIntInfeasDown,
     1869                //     choice[i].numObjInfeasDown);
     1870
     1871                // repeat the whole exercise, forcing the variable up
     1872                if (!clp) {
     1873                    bool feasible = true;
     1874                    // If odd branching then maybe just one possibility
     1875                    if (choice[i].possibleBranch->numberBranchesLeft() > 0) {
     1876                        choice[i].possibleBranch->branch();
     1877                        if (checkFeasibility) {
     1878                            // check branching did not make infeasible
     1879                            int iColumn;
     1880                            int numberColumns = solver->getNumCols();
     1881                            const double * columnLower = solver->getColLower();
     1882                            const double * columnUpper = solver->getColUpper();
     1883                            for (iColumn = 0; iColumn < numberColumns; iColumn++) {
     1884                                if (columnLower[iColumn] > columnUpper[iColumn] + 1.0e-5)
     1885                                    feasible = false;
     1886                            }
     1887                        }
     1888                    } else {
     1889                        // second branch infeasible
     1890                        feasible = false;
     1891                    }
     1892                    if (feasible) {
     1893                        solver->solveFromHotStart() ;
     1894                        numberStrongDone++;
     1895                        numberStrongIterations += solver->getIterationCount();
     1896                        /*
     1897                        We now have an estimate of objective degradation that we can use for strong
     1898                        branching. If we're over the cutoff, the variable is monotone up.
     1899                        If we actually made it to optimality, check for a solution, and if we have
     1900                        a good one, call setBestSolution to process it. Note that this may reduce the
     1901                        cutoff, so we check again to see if we can declare this variable monotone.
     1902                        */
     1903                        if (solver->isProvenOptimal())
     1904                            iStatus = 0; // optimal
     1905                        else if (solver->isIterationLimitReached()
     1906                                 && !solver->isDualObjectiveLimitReached())
     1907                            iStatus = 2; // unknown
     1908                        else
     1909                            iStatus = 1; // infeasible
     1910                        newObjectiveValue = solver->getObjSense() * solver->getObjValue();
     1911                        choice[i].numItersUp = solver->getIterationCount();
     1912                    } else {
     1913                        iStatus = 1; // infeasible
     1914                        newObjectiveValue = 1.0e100;
     1915                        choice[i].numItersDown = 0;
     1916                    }
     1917                } else {
     1918                    iStatus = outputStuff[2*i+1];
     1919                    choice[i].numItersUp = outputStuff[2*numberStrong+2*i+1];
     1920                    numberStrongDone++;
     1921                    numberStrongIterations += choice[i].numItersUp;
     1922                    newObjectiveValue = objectiveValue + newLower[i];
     1923                    solver->setColSolution(outputSolution[2*i+1]);
     1924                }
     1925                objectiveChange = CoinMax(newObjectiveValue  - objectiveValue_, 0.0);
     1926                if (!iStatus) {
     1927                    choice[i].finishedUp = true ;
     1928                    if (newObjectiveValue >= model->getCutoff()) {
     1929                        objectiveChange = 1.0e100; // say infeasible
     1930                        numberStrongInfeasible++;
     1931                    } else {
     1932                        // See if integer solution
     1933                        if (model->feasibleSolution(choice[i].numIntInfeasUp,
     1934                                                    choice[i].numObjInfeasUp)
     1935                                && model->problemFeasibility()->feasible(model, -1) >= 0) {
     1936                            model->setBestSolution(CBC_STRONGSOL,
     1937                                                   newObjectiveValue,
     1938                                                   solver->getColSolution()) ;
     1939                            // only needed for odd solvers
     1940                            newObjectiveValue = solver->getObjSense() * solver->getObjValue();
     1941                            objectiveChange = CoinMax(newObjectiveValue - objectiveValue_, 0.0) ;
     1942                            model->setLastHeuristic(NULL);
     1943                            model->incrementUsed(solver->getColSolution());
     1944                            if (newObjectiveValue >= model->getCutoff()) {      //  *new* cutoff
     1945                                objectiveChange = 1.0e100 ;
     1946                                numberStrongInfeasible++;
     1947                            }
     1948                        }
     1949                    }
     1950                } else if (iStatus == 1) {
     1951                    objectiveChange = 1.0e100 ;
     1952                    numberStrongInfeasible++;
     1953                } else {
     1954                    // Can't say much as we did not finish
     1955                    choice[i].finishedUp = false ;
     1956                    numberUnfinished++;
     1957                }
     1958                choice[i].upMovement = objectiveChange ;
     1959
     1960                // restore bounds
     1961                if (!clp) {
     1962                    for (int j = 0; j < numberColumns; j++) {
     1963                        if (saveLower[j] != lower[j])
     1964                            solver->setColLower(j, saveLower[j]);
     1965                        if (saveUpper[j] != upper[j])
     1966                            solver->setColUpper(j, saveUpper[j]);
     1967                    }
     1968                }
     1969
     1970                //printf("Up on %d, status is %d, obj %g its %d cost %g finished %d inf %d infobj %d\n",
     1971                //     choice[i].objectNumber,iStatus,newObjectiveValue,choice[i].numItersUp,
     1972                //     choice[i].upMovement,choice[i].finishedUp,choice[i].numIntInfeasUp,
     1973                //     choice[i].numObjInfeasUp);
     1974
     1975                /*
     1976                  End of evaluation for this candidate variable. Possibilities are:
     1977                  * Both sides below cutoff; this variable is a candidate for branching.
     1978                  * Both sides infeasible or above the objective cutoff: no further action
     1979                  here. Break from the evaluation loop and assume the node will be purged
     1980                  by the caller.
     1981                  * One side below cutoff: Install the branch (i.e., fix the variable). Break
     1982                  from the evaluation loop and assume the node will be reoptimised by the
     1983                  caller.
     1984                */
     1985                // reset
     1986                choice[i].possibleBranch->resetNumberBranchesLeft();
     1987                if (choice[i].upMovement < 1.0e100) {
     1988                    if (choice[i].downMovement < 1.0e100) {
     1989                        // feasible - no action
     1990                    } else {
     1991                        // up feasible, down infeasible
     1992                        anyAction = -1;
     1993                        //printf("Down infeasible for choice %d sequence %d\n",i,
     1994                        // model->object(choice[i].objectNumber)->columnNumber());
     1995                        if (!solveAll) {
     1996                            choice[i].possibleBranch->way(1);
     1997                            choice[i].possibleBranch->branch();
     1998                            break;
     1999                        } else {
     2000                            choice[i].fix = 1;
     2001                        }
     2002                    }
     2003                } else {
     2004                    if (choice[i].downMovement < 1.0e100) {
     2005                        // down feasible, up infeasible
     2006                        anyAction = -1;
     2007                        //printf("Up infeasible for choice %d sequence %d\n",i,
     2008                        // model->object(choice[i].objectNumber)->columnNumber());
     2009                        if (!solveAll) {
     2010                            choice[i].possibleBranch->way(-1);
     2011                            choice[i].possibleBranch->branch();
     2012                            break;
     2013                        } else {
     2014                            choice[i].fix = -1;
     2015                        }
     2016                    } else {
     2017                        // neither side feasible
     2018                        anyAction = -2;
     2019                        //printf("Both infeasible for choice %d sequence %d\n",i,
     2020                        // model->object(choice[i].objectNumber)->columnNumber());
     2021                        break;
     2022                    }
     2023                }
     2024                bool hitMaxTime = ( CoinCpuTime() - model->getDblParam(CbcModel::CbcStartSeconds) >
     2025                                    model->getDblParam(CbcModel::CbcMaximumSeconds));
     2026                if (hitMaxTime) {
     2027                    numberStrong = i + 1;
     2028                    break;
     2029                }
     2030            }
     2031            if (!clp) {
     2032                // Delete the snapshot
     2033                solver->unmarkHotStart();
    20862034            } else {
    2087               choice[numberLeft++]=thisChoice;
    2088             }
    2089           }
    2090           numberStrong=numberLeft;
    2091           for (;i<maximumStrong;i++) {
    2092             delete choice[i].possibleBranch;
    2093             choice[i].possibleBranch=NULL;
    2094           }
    2095           // If all fixed then round again
    2096           if (!numberLeft) {
    2097             finished=false;
    2098             numberStrong=0;
    2099             saveNumberStrong=0;
    2100             maximumStrong=1;
    2101           } else {
    2102             anyAction=0;
    2103           }
    2104           // If these two uncommented then different action
    2105           anyAction=-1;
    2106           finished=true;
    2107           //printf("some fixed but continuing %d left\n",numberLeft);
    2108         } else {
    2109           anyAction=-2; // say infeasible
    2110         }
    2111       }
    2112       delete ws;
    2113       int numberNodes = model->getNodeCount();
    2114       // update number of strong iterations etc
    2115       model->incrementStrongInfo(numberStrongDone,numberStrongIterations,
    2116                                  anyAction==-2 ? 0:numberStrongInfeasible,anyAction==-2);
    2117      
    2118       /*
    2119         anyAction >= 0 indicates that strong branching didn't produce any monotone
    2120         variables. Sift through the candidates for the best one.
    2121        
    2122         QUERY: Setting numberNodes looks to be a distributed noop. numberNodes is
    2123         local to this code block. Perhaps should be numberNodes_ from model?
    2124         Unclear what this calculation is doing.
    2125       */
    2126       if (anyAction>=0) {
    2127        
    2128         // get average cost per iteration and assume stopped ones
    2129         // would stop after 50% more iterations at average cost??? !!! ???
    2130         double averageCostPerIteration=0.0;
    2131         double totalNumberIterations=1.0;
    2132         int smallestNumberInfeasibilities=COIN_INT_MAX;
    2133         for (i=0;i<numberStrong;i++) {
    2134           totalNumberIterations += choice[i].numItersDown +
    2135             choice[i].numItersUp ;
    2136           averageCostPerIteration += choice[i].downMovement +
    2137             choice[i].upMovement;
    2138           smallestNumberInfeasibilities=
    2139             CoinMin(CoinMin(choice[i].numIntInfeasDown ,
    2140                             choice[i].numIntInfeasUp ),
    2141                     smallestNumberInfeasibilities);
    2142         }
    2143         //if (smallestNumberInfeasibilities>=numberIntegerInfeasibilities)
    2144         //numberNodes=1000000; // switch off search for better solution
    2145         numberNodes=1000000; // switch off anyway
    2146         averageCostPerIteration /= totalNumberIterations;
    2147         // all feasible - choose best bet
    2148        
    2149         // New method does all at once so it can be more sophisticated
    2150         // in deciding how to balance actions.
    2151         // But it does need arrays
    2152         double * changeUp = new double [numberStrong];
    2153         int * numberInfeasibilitiesUp = new int [numberStrong];
    2154         double * changeDown = new double [numberStrong];
    2155         int * numberInfeasibilitiesDown = new int [numberStrong];
    2156         CbcBranchingObject ** objects = new CbcBranchingObject * [ numberStrong];
    2157         for (i = 0 ; i < numberStrong ; i++) {
    2158           int iColumn = choice[i].possibleBranch->variable() ;
    2159           model->messageHandler()->message(CBC_STRONG,*model->messagesPointer())
    2160             << i << iColumn
    2161             <<choice[i].downMovement<<choice[i].numIntInfeasDown
    2162             <<choice[i].upMovement<<choice[i].numIntInfeasUp
    2163             <<choice[i].possibleBranch->value()
    2164             <<CoinMessageEol;
    2165           changeUp[i]=choice[i].upMovement;
    2166           numberInfeasibilitiesUp[i] = choice[i].numIntInfeasUp;
    2167           changeDown[i]=choice[i].downMovement;
    2168           numberInfeasibilitiesDown[i] = choice[i].numIntInfeasDown;
    2169           objects[i] = choice[i].possibleBranch;
    2170         }
    2171         int whichObject = decision->bestBranch(objects,numberStrong,numberUnsatisfied_,
    2172                                                changeUp,numberInfeasibilitiesUp,
    2173                                                changeDown,numberInfeasibilitiesDown,
    2174                                                objectiveValue_);
    2175         // move branching object and make sure it will not be deleted
    2176         if (whichObject>=0) {
    2177           branch_ = objects[whichObject];
    2178           if (model->messageHandler()->logLevel()>3)
    2179             printf("Choosing column %d\n",choice[whichObject].possibleBranch->variable()) ;
    2180           choice[whichObject].possibleBranch=NULL;
    2181         }
    2182         delete [] changeUp;
    2183         delete [] numberInfeasibilitiesUp;
    2184         delete [] changeDown;
    2185         delete [] numberInfeasibilitiesDown;
    2186         delete [] objects;
    2187       }
     2035                delete [] newLower;
     2036                delete [] newUpper;
     2037                delete [] outputStuff;
     2038                int i;
     2039                for (i = 0; i < 2*numberStrong; i++)
     2040                    delete [] outputSolution[i];
     2041                delete [] outputSolution;
     2042            }
     2043            solver->setIntParam(OsiMaxNumIterationHotStart, saveLimit);
     2044            // restore basis
     2045            solver->setWarmStart(ws);
     2046            // Unless infeasible we will carry on
     2047            // But we could fix anyway
     2048            if (anyAction == -1 && solveAll) {
     2049                // apply and take off
     2050                for (i = 0 ; i < numberStrong ; i++) {
     2051                    if (choice[i].fix) {
     2052                        choice[i].possibleBranch->way(choice[i].fix) ;
     2053                        choice[i].possibleBranch->branch() ;
     2054                    }
     2055                }
     2056                bool feasible = true;
     2057                if (checkFeasibility) {
     2058                    // check branching did not make infeasible
     2059                    int iColumn;
     2060                    int numberColumns = solver->getNumCols();
     2061                    const double * columnLower = solver->getColLower();
     2062                    const double * columnUpper = solver->getColUpper();
     2063                    for (iColumn = 0; iColumn < numberColumns; iColumn++) {
     2064                        if (columnLower[iColumn] > columnUpper[iColumn] + 1.0e-5)
     2065                            feasible = false;
     2066                    }
     2067                }
     2068                if (feasible) {
     2069                    // can do quick optimality check
     2070                    int easy = 2;
     2071                    solver->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo, &easy) ;
     2072                    solver->resolve() ;
     2073                    solver->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo, NULL) ;
     2074                    feasible = solver->isProvenOptimal();
     2075                }
     2076                if (feasible) {
     2077                    memcpy(saveSolution, solver->getColSolution(), numberColumns*sizeof(double));
     2078                    model->reserveCurrentSolution(saveSolution);
     2079                    memcpy(saveLower, solver->getColLower(), numberColumns*sizeof(double));
     2080                    memcpy(saveUpper, solver->getColUpper(), numberColumns*sizeof(double));
     2081                    // Clean up all candidates whih are fixed
     2082                    int numberLeft = 0;
     2083                    for (i = 0 ; i < numberStrong ; i++) {
     2084                        CbcStrongInfo thisChoice = choice[i];
     2085                        choice[i].possibleBranch = NULL;
     2086                        const OsiObject * object = model->object(thisChoice.objectNumber);
     2087                        int preferredWay;
     2088                        double infeasibility = object->infeasibility(&usefulInfo, preferredWay);
     2089                        if (!infeasibility) {
     2090                            // take out
     2091                            delete thisChoice.possibleBranch;
     2092                        } else {
     2093                            choice[numberLeft++] = thisChoice;
     2094                        }
     2095                    }
     2096                    numberStrong = numberLeft;
     2097                    for (; i < maximumStrong; i++) {
     2098                        delete choice[i].possibleBranch;
     2099                        choice[i].possibleBranch = NULL;
     2100                    }
     2101                    // If all fixed then round again
     2102                    if (!numberLeft) {
     2103                        finished = false;
     2104                        numberStrong = 0;
     2105                        saveNumberStrong = 0;
     2106                        maximumStrong = 1;
     2107                    } else {
     2108                        anyAction = 0;
     2109                    }
     2110                    // If these two uncommented then different action
     2111                    anyAction = -1;
     2112                    finished = true;
     2113                    //printf("some fixed but continuing %d left\n",numberLeft);
     2114                } else {
     2115                    anyAction = -2; // say infeasible
     2116                }
     2117            }
     2118            delete ws;
     2119            int numberNodes = model->getNodeCount();
     2120            // update number of strong iterations etc
     2121            model->incrementStrongInfo(numberStrongDone, numberStrongIterations,
     2122                                       anyAction == -2 ? 0 : numberStrongInfeasible, anyAction == -2);
     2123
     2124            /*
     2125              anyAction >= 0 indicates that strong branching didn't produce any monotone
     2126              variables. Sift through the candidates for the best one.
     2127
     2128              QUERY: Setting numberNodes looks to be a distributed noop. numberNodes is
     2129              local to this code block. Perhaps should be numberNodes_ from model?
     2130              Unclear what this calculation is doing.
     2131            */
     2132            if (anyAction >= 0) {
     2133
     2134                // get average cost per iteration and assume stopped ones
     2135                // would stop after 50% more iterations at average cost??? !!! ???
     2136                double averageCostPerIteration = 0.0;
     2137                double totalNumberIterations = 1.0;
     2138                int smallestNumberInfeasibilities = COIN_INT_MAX;
     2139                for (i = 0; i < numberStrong; i++) {
     2140                    totalNumberIterations += choice[i].numItersDown +
     2141                                             choice[i].numItersUp ;
     2142                    averageCostPerIteration += choice[i].downMovement +
     2143                                               choice[i].upMovement;
     2144                    smallestNumberInfeasibilities =
     2145                        CoinMin(CoinMin(choice[i].numIntInfeasDown ,
     2146                                        choice[i].numIntInfeasUp ),
     2147                                smallestNumberInfeasibilities);
     2148                }
     2149                //if (smallestNumberInfeasibilities>=numberIntegerInfeasibilities)
     2150                //numberNodes=1000000; // switch off search for better solution
     2151                numberNodes = 1000000; // switch off anyway
     2152                averageCostPerIteration /= totalNumberIterations;
     2153                // all feasible - choose best bet
     2154
     2155                // New method does all at once so it can be more sophisticated
     2156                // in deciding how to balance actions.
     2157                // But it does need arrays
     2158                double * changeUp = new double [numberStrong];
     2159                int * numberInfeasibilitiesUp = new int [numberStrong];
     2160                double * changeDown = new double [numberStrong];
     2161                int * numberInfeasibilitiesDown = new int [numberStrong];
     2162                CbcBranchingObject ** objects = new CbcBranchingObject * [ numberStrong];
     2163                for (i = 0 ; i < numberStrong ; i++) {
     2164                    int iColumn = choice[i].possibleBranch->variable() ;
     2165                    model->messageHandler()->message(CBC_STRONG, *model->messagesPointer())
     2166                    << i << iColumn
     2167                    << choice[i].downMovement << choice[i].numIntInfeasDown
     2168                    << choice[i].upMovement << choice[i].numIntInfeasUp
     2169                    << choice[i].possibleBranch->value()
     2170                    << CoinMessageEol;
     2171                    changeUp[i] = choice[i].upMovement;
     2172                    numberInfeasibilitiesUp[i] = choice[i].numIntInfeasUp;
     2173                    changeDown[i] = choice[i].downMovement;
     2174                    numberInfeasibilitiesDown[i] = choice[i].numIntInfeasDown;
     2175                    objects[i] = choice[i].possibleBranch;
     2176                }
     2177                int whichObject = decision->bestBranch(objects, numberStrong, numberUnsatisfied_,
     2178                                                       changeUp, numberInfeasibilitiesUp,
     2179                                                       changeDown, numberInfeasibilitiesDown,
     2180                                                       objectiveValue_);
     2181                // move branching object and make sure it will not be deleted
     2182                if (whichObject >= 0) {
     2183                    branch_ = objects[whichObject];
     2184                    if (model->messageHandler()->logLevel() > 3)
     2185                        printf("Choosing column %d\n", choice[whichObject].possibleBranch->variable()) ;
     2186                    choice[whichObject].possibleBranch = NULL;
     2187                }
     2188                delete [] changeUp;
     2189                delete [] numberInfeasibilitiesUp;
     2190                delete [] changeDown;
     2191                delete [] numberInfeasibilitiesDown;
     2192                delete [] objects;
     2193            }
    21882194#     ifdef COIN_HAS_CLP
    2189       if (osiclp&&!allNormal) {
    2190         // back to normal
    2191         osiclp->setHintParam(OsiDoInBranchAndCut,true,OsiHintDo,NULL) ;
    2192       }
     2195            if (osiclp && !allNormal) {
     2196                // back to normal
     2197                osiclp->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo, NULL) ;
     2198            }
    21932199#     endif
    2194     }
     2200        }
     2201        /*
     2202          Simple branching. Probably just one, but we may have got here
     2203          because of an odd branch e.g. a cut
     2204        */
     2205        else {
     2206            // not strong
     2207            // C) create branching object
     2208            branch_ = choice[bestChoice].possibleBranch;
     2209            choice[bestChoice].possibleBranch = NULL;
     2210        }
     2211    }
     2212    // Set guessed solution value
     2213    guessedObjectiveValue_ = objectiveValue_ + estimatedDegradation;
    21952214    /*
    2196       Simple branching. Probably just one, but we may have got here
    2197       because of an odd branch e.g. a cut
     2215      Cleanup, then we're outta here.
    21982216    */
    2199     else {
    2200       // not strong
    2201       // C) create branching object
    2202       branch_ = choice[bestChoice].possibleBranch;
    2203       choice[bestChoice].possibleBranch=NULL;
    2204     }
    2205   }
    2206   // Set guessed solution value
    2207   guessedObjectiveValue_ = objectiveValue_+estimatedDegradation;
    2208   /*
    2209     Cleanup, then we're outta here.
    2210   */
    2211   if (!model->branchingMethod()||dynamicBranchingObject)
    2212     delete decision;
    2213  
    2214   for (i=0;i<maximumStrong;i++)
    2215     delete choice[i].possibleBranch;
    2216   delete [] choice;
    2217   delete [] saveLower;
    2218   delete [] saveUpper;
    2219  
    2220   // restore solution
    2221   solver->setColSolution(saveSolution);
    2222   delete [] saveSolution;
     2217    if (!model->branchingMethod() || dynamicBranchingObject)
     2218        delete decision;
     2219
     2220    for (i = 0; i < maximumStrong; i++)
     2221        delete choice[i].possibleBranch;
     2222    delete [] choice;
     2223    delete [] saveLower;
     2224    delete [] saveUpper;
     2225
     2226    // restore solution
     2227    solver->setColSolution(saveSolution);
     2228    delete [] saveSolution;
    22232229# ifdef COIN_HAS_CLP
    2224   if (osiclp)
    2225     osiclp->setSpecialOptions(saveClpOptions);
     2230    if (osiclp)
     2231        osiclp->setSpecialOptions(saveClpOptions);
    22262232# endif
    2227   return anyAction;
     2233    return anyAction;
    22282234}
    22292235
    22302236/*
    22312237  Version for dynamic pseudo costs.
    2232  
     2238
    22332239  **** For now just return if anything odd
    22342240  later allow even if odd
    2235  
     2241
    22362242  The routine scans through the object list of the model looking for objects
    22372243  that indicate infeasibility. It tests each object using strong branching
     
    22422248  to say give up if last few tries have not changed incumbent.
    22432249  See Achterberg, Koch and Martin.
    2244  
     2250
    22452251  If strong branching is disabled, a candidate object is chosen essentially
    22462252  at random (whatever object ends up in pos'n 0 of the candidate array).
    2247  
     2253
    22482254  If a branching candidate is found to be monotone, bounds are set to fix the
    22492255  variable and the routine immediately returns (the caller is expected to
    22502256  reoptimize).
    2251  
     2257
    22522258  If a branching candidate is found to result in infeasibility in both
    22532259  directions, the routine immediately returns an indication of infeasibility.
    2254  
     2260
    22552261  Returns:  0   both branch directions are feasible
    22562262  -1    branching variable is monotone
    22572263  -2    infeasible
    22582264  -3   Use another method
    2259  
     2265
    22602266  For now just fix on objective from strong branching.
    22612267*/
     
    22632269int CbcNode::chooseDynamicBranch (CbcModel *model, CbcNode *lastNode,
    22642270                                  OsiSolverBranch * & /*branches*/,
    2265                                   int numberPassesLeft)
    2266  
    2267 { if (lastNode)
    2268     depth_ = lastNode->depth_+1;
    2269   else
    2270     depth_ = 0;
    2271   // Go to other choose if hot start
    2272   if (model->hotstartSolution()&&
    2273       (((model->moreSpecialOptions()&1024)==0)||false))
    2274     return -3;
    2275   delete branch_;
    2276   branch_=NULL;
    2277   OsiSolverInterface * solver = model->solver();
    2278   // get information on solver type
    2279   const OsiAuxInfo * auxInfo = solver->getAuxiliaryInfo();
    2280   const OsiBabSolver * auxiliaryInfo = dynamic_cast<const OsiBabSolver *> (auxInfo);
    2281   if (!auxiliaryInfo) {
    2282     // use one from CbcModel
    2283     auxiliaryInfo = model->solverCharacteristics();
    2284   }
    2285   int numberObjects = model->numberObjects();
    2286   // If very odd set of objects then use older chooseBranch
    2287   bool useOldWay = false;
    2288   // point to useful information
    2289   OsiBranchingInformation usefulInfo = model->usefulInformation();
    2290   if (numberObjects>model->numberIntegers()) {
    2291     for (int i=model->numberIntegers();i<numberObjects;i++) {
    2292       OsiObject * object = model->modifiableObject(i);
    2293       CbcObject * obj = dynamic_cast <CbcObject *>(object) ;
    2294       if (!obj || !obj->optionalObject()) {
    2295         int preferredWay;
    2296         double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
    2297         if (infeasibility) {
    2298           useOldWay=true;
    2299           break;
    2300         }
    2301       }
    2302     }
    2303   }
    2304   if ((model->specialOptions()&128)!=0)
    2305     useOldWay=false; // allow
    2306   // For now return if not simple
    2307   if (useOldWay)
    2308     return -3;
    2309   // Modify useful info
    2310   usefulInfo.depth_=depth_;
    2311   if ((model->specialOptions()&128)!=0) {
    2312     // SOS - shadow prices
    2313     int numberRows = solver->getNumRows();
    2314     const double * pi = usefulInfo.pi_;
    2315     double sumPi=0.0;
    2316     for (int i=0;i<numberRows;i++)
    2317       sumPi += fabs(pi[i]);
    2318     sumPi /= static_cast<double> (numberRows);
    2319     // and scale back
    2320     sumPi *= 0.01;
    2321     usefulInfo.defaultDual_ = sumPi; // switch on
    2322     int numberColumns = solver->getNumCols();
    2323     int size = CoinMax(numberColumns,2*numberRows);
    2324     usefulInfo.usefulRegion_ = new double [size];
    2325     CoinZeroN(usefulInfo.usefulRegion_,size);
    2326     usefulInfo.indexRegion_ = new int [size];
    2327     // pi may change
    2328     usefulInfo.pi_=CoinCopyOfArray(usefulInfo.pi_,numberRows);
    2329   }
    2330   assert (auxiliaryInfo);
    2331   double cutoff =model->getCutoff();
    2332   const double * lower = solver->getColLower();
    2333   const double * upper = solver->getColUpper();
    2334   // See if user thinks infeasible
    2335   int anyAction=model->problemFeasibility()->feasible(model,0);
    2336   if (anyAction) {
    2337     // will return -2 if infeasible , 0 if treat as integer
    2338     return anyAction-1;
    2339   }
    2340   int i;
    2341   int saveStateOfSearch = model->stateOfSearch()%10;
    2342   int numberStrong=model->numberStrong();
    2343   /* Ranging is switched off.
    2344      The idea is that you can find out the effect of one iteration
    2345      on each unsatisfied variable cheaply.  Then use this
    2346      if you have not got much else to go on.
    2347   */
    2348   //#define RANGING
     2271                                  int numberPassesLeft)
     2272
     2273{
     2274    if (lastNode)
     2275        depth_ = lastNode->depth_ + 1;
     2276    else
     2277        depth_ = 0;
     2278    // Go to other choose if hot start
     2279    if (model->hotstartSolution() &&
     2280            (((model->moreSpecialOptions()&1024) == 0) || false))
     2281        return -3;
     2282    delete branch_;
     2283    branch_ = NULL;
     2284    OsiSolverInterface * solver = model->solver();
     2285    // get information on solver type
     2286    const OsiAuxInfo * auxInfo = solver->getAuxiliaryInfo();
     2287    const OsiBabSolver * auxiliaryInfo = dynamic_cast<const OsiBabSolver *> (auxInfo);
     2288    if (!auxiliaryInfo) {
     2289        // use one from CbcModel
     2290        auxiliaryInfo = model->solverCharacteristics();
     2291    }
     2292    int numberObjects = model->numberObjects();
     2293    // If very odd set of objects then use older chooseBranch
     2294    bool useOldWay = false;
     2295    // point to useful information
     2296    OsiBranchingInformation usefulInfo = model->usefulInformation();
     2297    if (numberObjects > model->numberIntegers()) {
     2298        for (int i = model->numberIntegers(); i < numberObjects; i++) {
     2299            OsiObject * object = model->modifiableObject(i);
     2300            CbcObject * obj =   dynamic_cast <CbcObject *>(object) ;
     2301            if (!obj || !obj->optionalObject()) {
     2302                int preferredWay;
     2303                double infeasibility = object->infeasibility(&usefulInfo, preferredWay);
     2304                if (infeasibility) {
     2305                    useOldWay = true;
     2306                    break;
     2307                }
     2308            }
     2309        }
     2310    }
     2311    if ((model->specialOptions()&128) != 0)
     2312        useOldWay = false; // allow
     2313    // For now return if not simple
     2314    if (useOldWay)
     2315        return -3;
     2316    // Modify useful info
     2317    usefulInfo.depth_ = depth_;
     2318    if ((model->specialOptions()&128) != 0) {
     2319        // SOS - shadow prices
     2320        int numberRows = solver->getNumRows();
     2321        const double * pi = usefulInfo.pi_;
     2322        double sumPi = 0.0;
     2323        for (int i = 0; i < numberRows; i++)
     2324            sumPi += fabs(pi[i]);
     2325        sumPi /= static_cast<double> (numberRows);
     2326        // and scale back
     2327        sumPi *= 0.01;
     2328        usefulInfo.defaultDual_ = sumPi; // switch on
     2329        int numberColumns = solver->getNumCols();
     2330        int size = CoinMax(numberColumns, 2 * numberRows);
     2331        usefulInfo.usefulRegion_ = new double [size];
     2332        CoinZeroN(usefulInfo.usefulRegion_, size);
     2333        usefulInfo.indexRegion_ = new int [size];
     2334        // pi may change
     2335        usefulInfo.pi_ = CoinCopyOfArray(usefulInfo.pi_, numberRows);
     2336    }
     2337    assert (auxiliaryInfo);
     2338    double cutoff = model->getCutoff();
     2339    const double * lower = solver->getColLower();
     2340    const double * upper = solver->getColUpper();
     2341    // See if user thinks infeasible
     2342    int anyAction = model->problemFeasibility()->feasible(model, 0);
     2343    if (anyAction) {
     2344        // will return -2 if infeasible , 0 if treat as integer
     2345        return anyAction - 1;
     2346    }
     2347    int i;
     2348    int saveStateOfSearch = model->stateOfSearch() % 10;
     2349    int numberStrong = model->numberStrong();
     2350    /* Ranging is switched off.
     2351       The idea is that you can find out the effect of one iteration
     2352       on each unsatisfied variable cheaply.  Then use this
     2353       if you have not got much else to go on.
     2354    */
     2355    //#define RANGING
    23492356#ifdef RANGING
    2350   // must have clp
     2357    // must have clp
    23512358#ifndef COIN_HAS_CLP
    23522359#  warning("Ranging switched off as not Clp");
    23532360#undef RANGING
    23542361#endif
    2355   // Pass number
    2356   int kPass=0;
    2357   int numberRows = solver->getNumRows();
    2358 #endif
    2359   int numberColumns = model->getNumCols();
    2360   double * saveUpper = new double[numberColumns];
    2361   double * saveLower = new double[numberColumns];
    2362   for (i=0;i<numberColumns;i++) {
    2363     saveLower[i] = lower[i];
    2364     saveUpper[i] = upper[i];
    2365   }
    2366  
    2367   // Save solution in case heuristics need good solution later
    2368  
    2369   double * saveSolution = new double[numberColumns];
    2370   memcpy(saveSolution,solver->getColSolution(),numberColumns*sizeof(double));
    2371   model->reserveCurrentSolution(saveSolution);
    2372   const double * hotstartSolution = model->hotstartSolution();
    2373   const int * hotstartPriorities = model->hotstartPriorities();
    2374   double integerTolerance =
    2375     model->getDblParam(CbcModel::CbcIntegerTolerance);
    2376   if (hotstartSolution) {
    2377     if((model->moreSpecialOptions()&1024)!=0) {
    2378       int nBad=0;
    2379       int nUnsat=0;
    2380       int nDiff=0;
    2381       for (int i=0;i<numberObjects;i++) {
    2382         OsiObject * object = model->modifiableObject(i);
    2383         const CbcSimpleInteger * thisOne = dynamic_cast <const CbcSimpleInteger *> (object);
    2384         if (thisOne) {
    2385           int iColumn = thisOne->columnNumber();
    2386           double targetValue = hotstartSolution[iColumn];
    2387           double value = saveSolution[iColumn];
    2388           if (fabs(value-floor(value+0.5))>1.0e-6) {
    2389             nUnsat++;
    2390 #ifdef CLP_INVESTIGATE 
    2391             printf("H %d is %g target %g\n",iColumn,value,targetValue);
    2392 #endif
    2393           } else if (fabs(targetValue-value)>1.0e-6) {
    2394             nDiff++;
    2395           }
    2396           if (targetValue<saveLower[iColumn]||
    2397               targetValue>saveUpper[iColumn]) {
    2398 #ifdef CLP_INVESTIGATE 
    2399             printf("%d has target %g and current bounds %g and %g\n",
    2400                    iColumn,targetValue,saveLower[iColumn],saveUpper[iColumn]);
    2401 #endif
    2402             nBad++;
    2403           }
    2404         }
    2405       }
    2406 #ifdef CLP_INVESTIGATE 
    2407       printf("Hot %d unsatisfied, %d outside limits, %d different\n",
    2408              nUnsat,nBad,nDiff);
    2409 #endif
    2410       if (nBad) {
    2411         // switch off as not possible
    2412           hotstartSolution=NULL;
    2413           model->setHotstartSolution(NULL,NULL);
    2414           usefulInfo.hotstartSolution_=NULL;
    2415       }
    2416     }
    2417   }
    2418   /*
    2419     Get a branching decision object. Use the default dynamic decision criteria unless
    2420     the user has loaded a decision method into the model.
    2421   */
    2422   CbcBranchDecision *decision = model->branchingMethod();
    2423   if (!decision)
    2424     decision = new CbcBranchDynamicDecision();
    2425   int xMark=0;
    2426   // Get arrays to sort
    2427   double * sort = new double[numberObjects];
    2428   int * whichObject = new int[numberObjects];
     2362    // Pass number
     2363    int kPass = 0;
     2364    int numberRows = solver->getNumRows();
     2365#endif
     2366    int numberColumns = model->getNumCols();
     2367    double * saveUpper = new double[numberColumns];
     2368    double * saveLower = new double[numberColumns];
     2369    for (i = 0; i < numberColumns; i++) {
     2370        saveLower[i] = lower[i];
     2371        saveUpper[i] = upper[i];
     2372    }
     2373
     2374    // Save solution in case heuristics need good solution later
     2375
     2376    double * saveSolution = new double[numberColumns];
     2377    memcpy(saveSolution, solver->getColSolution(), numberColumns*sizeof(double));
     2378    model->reserveCurrentSolution(saveSolution);
     2379    const double * hotstartSolution = model->hotstartSolution();
     2380    const int * hotstartPriorities = model->hotstartPriorities();
     2381    double integerTolerance =
     2382        model->getDblParam(CbcModel::CbcIntegerTolerance);
     2383    if (hotstartSolution) {
     2384        if ((model->moreSpecialOptions()&1024) != 0) {
     2385            int nBad = 0;
     2386            int nUnsat = 0;
     2387            int nDiff = 0;
     2388            for (int i = 0; i < numberObjects; i++) {
     2389                OsiObject * object = model->modifiableObject(i);
     2390                const CbcSimpleInteger * thisOne = dynamic_cast <const CbcSimpleInteger *> (object);
     2391                if (thisOne) {
     2392                    int iColumn = thisOne->columnNumber();
     2393                    double targetValue = hotstartSolution[iColumn];
     2394                    double value = saveSolution[iColumn];
     2395                    if (fabs(value - floor(value + 0.5)) > 1.0e-6) {
     2396                        nUnsat++;
     2397#ifdef CLP_INVESTIGATE
     2398                        printf("H %d is %g target %g\n", iColumn, value, targetValue);
     2399#endif
     2400                    } else if (fabs(targetValue - value) > 1.0e-6) {
     2401                        nDiff++;
     2402                    }
     2403                    if (targetValue < saveLower[iColumn] ||
     2404                            targetValue > saveUpper[iColumn]) {
     2405#ifdef CLP_INVESTIGATE
     2406                        printf("%d has target %g and current bounds %g and %g\n",
     2407                               iColumn, targetValue, saveLower[iColumn], saveUpper[iColumn]);
     2408#endif
     2409                        nBad++;
     2410                    }
     2411                }
     2412            }
     2413#ifdef CLP_INVESTIGATE
     2414            printf("Hot %d unsatisfied, %d outside limits, %d different\n",
     2415                   nUnsat, nBad, nDiff);
     2416#endif
     2417            if (nBad) {
     2418                // switch off as not possible
     2419                hotstartSolution = NULL;
     2420                model->setHotstartSolution(NULL, NULL);
     2421                usefulInfo.hotstartSolution_ = NULL;
     2422            }
     2423        }
     2424    }
     2425    /*
     2426      Get a branching decision object. Use the default dynamic decision criteria unless
     2427      the user has loaded a decision method into the model.
     2428    */
     2429    CbcBranchDecision *decision = model->branchingMethod();
     2430    if (!decision)
     2431        decision = new CbcBranchDynamicDecision();
     2432    int xMark = 0;
     2433    // Get arrays to sort
     2434    double * sort = new double[numberObjects];
     2435    int * whichObject = new int[numberObjects];
    24292436#ifdef RANGING
    2430   int xPen=0;
    2431   int * objectMark = new int[2*numberObjects+1];
    2432 #endif
    2433   // Arrays with movements
    2434   double * upEstimate = new double[numberObjects];
    2435   double * downEstimate = new double[numberObjects];
    2436   double estimatedDegradation=0.0;
    2437   int numberNodes=model->getNodeCount();
    2438   int saveLogLevel = model->logLevel();
     2437    int xPen = 0;
     2438    int * objectMark = new int[2*numberObjects+1];
     2439#endif
     2440    // Arrays with movements
     2441    double * upEstimate = new double[numberObjects];
     2442    double * downEstimate = new double[numberObjects];
     2443    double estimatedDegradation = 0.0;
     2444    int numberNodes = model->getNodeCount();
     2445    int saveLogLevel = model->logLevel();
    24392446#if 0
    2440   if ((numberNodes%500)==0) {
    2441     model->setLogLevel(6);
     2447    if ((numberNodes % 500) == 0) {
     2448        model->setLogLevel(6);
     2449        // Get average up and down costs
     2450        double averageUp = 0.0;
     2451        double averageDown = 0.0;
     2452        int numberUp = 0;
     2453        int numberDown = 0;
     2454        int i;
     2455        for ( i = 0; i < numberObjects; i++) {
     2456            OsiObject * object = model->modifiableObject(i);
     2457            CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
     2458                dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     2459            assert(dynamicObject);
     2460            int  numberUp2 = 0;
     2461            int numberDown2 = 0;
     2462            double up = 0.0;
     2463            double down = 0.0;
     2464            if (dynamicObject->numberTimesUp()) {
     2465                numberUp++;
     2466                averageUp += dynamicObject->upDynamicPseudoCost();
     2467                numberUp2 += dynamicObject->numberTimesUp();
     2468                up = dynamicObject->upDynamicPseudoCost();
     2469            }
     2470            if (dynamicObject->numberTimesDown()) {
     2471                numberDown++;
     2472                averageDown += dynamicObject->downDynamicPseudoCost();
     2473                numberDown2 += dynamicObject->numberTimesDown();
     2474                down = dynamicObject->downDynamicPseudoCost();
     2475            }
     2476            if (numberUp2 || numberDown2)
     2477                printf("col %d - up %d times cost %g, - down %d times cost %g\n",
     2478                       dynamicObject->columnNumber(), numberUp2, up, numberDown2, down);
     2479        }
     2480        if (numberUp)
     2481            averageUp /= static_cast<double> (numberUp);
     2482        else
     2483            averageUp = 1.0;
     2484        if (numberDown)
     2485            averageDown /= static_cast<double> (numberDown);
     2486        else
     2487            averageDown = 1.0;
     2488        printf("total - up %d vars average %g, - down %d vars average %g\n",
     2489               numberUp, averageUp, numberDown, averageDown);
     2490    }
     2491#endif
     2492    int numberBeforeTrust = model->numberBeforeTrust();
     2493    // May go round twice if strong branching fixes all local candidates
     2494    bool finished = false;
     2495    int numberToFix = 0;
     2496# ifdef COIN_HAS_CLP
     2497    OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver);
     2498    int saveClpOptions = 0;
     2499    if (osiclp) {
     2500        // for faster hot start
     2501        saveClpOptions = osiclp->specialOptions();
     2502        osiclp->setSpecialOptions(saveClpOptions | 8192);
     2503    }
     2504# else
     2505    OsiSolverInterface *osiclp = NULL ;
     2506# endif
     2507    //const CglTreeProbingInfo * probingInfo = NULL; //model->probingInfo();
     2508    // Old code left in with DEPRECATED_STRATEGY
     2509    assert (model->searchStrategy() == -1 ||
     2510            model->searchStrategy() == 1 ||
     2511            model->searchStrategy() == 2);
     2512#ifdef DEPRECATED_STRATEGY
     2513    int saveSearchStrategy2 = model->searchStrategy();
     2514#endif
    24422515    // Get average up and down costs
    2443     double averageUp=0.0;
    2444     double averageDown=0.0;
    2445     int numberUp=0;
    2446     int numberDown=0;
    2447     int i;
    2448     for ( i=0;i<numberObjects;i++) {
    2449       OsiObject * object = model->modifiableObject(i);
    2450       CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    2451         dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    2452       assert(dynamicObject);
    2453       int  numberUp2=0;
    2454       int numberDown2=0;
    2455       double up=0.0;
    2456       double down=0.0;
    2457       if (dynamicObject->numberTimesUp()) {
    2458         numberUp++;
    2459         averageUp += dynamicObject->upDynamicPseudoCost();
    2460         numberUp2 += dynamicObject->numberTimesUp();
    2461         up = dynamicObject->upDynamicPseudoCost();
    2462       }
    2463       if (dynamicObject->numberTimesDown()) {
    2464         numberDown++;
    2465         averageDown += dynamicObject->downDynamicPseudoCost();
    2466         numberDown2 += dynamicObject->numberTimesDown();
    2467         down = dynamicObject->downDynamicPseudoCost();
    2468       }
    2469       if (numberUp2||numberDown2)
    2470         printf("col %d - up %d times cost %g, - down %d times cost %g\n",
    2471                dynamicObject->columnNumber(),numberUp2,up,numberDown2,down);
    2472     }
    2473     if (numberUp)
    2474       averageUp /= static_cast<double> (numberUp);
    2475     else
    2476       averageUp=1.0;
    2477     if (numberDown)
    2478       averageDown /= static_cast<double> (numberDown);
    2479     else
    2480       averageDown=1.0;
    2481     printf("total - up %d vars average %g, - down %d vars average %g\n",
    2482            numberUp,averageUp,numberDown,averageDown);
    2483   }
    2484 #endif
    2485   int numberBeforeTrust = model->numberBeforeTrust();
    2486   // May go round twice if strong branching fixes all local candidates
    2487   bool finished=false;
    2488   int numberToFix=0;
    2489 # ifdef COIN_HAS_CLP
    2490   OsiClpSolverInterface * osiclp = dynamic_cast< OsiClpSolverInterface*> (solver);
    2491   int saveClpOptions=0;
    2492   if (osiclp) {
    2493     // for faster hot start
    2494     saveClpOptions = osiclp->specialOptions();
    2495     osiclp->setSpecialOptions(saveClpOptions|8192);
    2496   }
    2497 # else
    2498   OsiSolverInterface *osiclp = NULL ;
    2499 # endif
    2500   //const CglTreeProbingInfo * probingInfo = NULL; //model->probingInfo();
    2501   // Old code left in with DEPRECATED_STRATEGY
    2502   assert (model->searchStrategy()==-1||
    2503           model->searchStrategy()==1||
    2504           model->searchStrategy()==2);
     2516    {
     2517        double averageUp = 0.0;
     2518        double averageDown = 0.0;
     2519        int numberUp = 0;
     2520        int numberDown = 0;
     2521        int i;
     2522        for ( i = 0; i < numberObjects; i++) {
     2523            OsiObject * object = model->modifiableObject(i);
     2524            CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
     2525                dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     2526            if (dynamicObject) {
     2527                if (dynamicObject->numberTimesUp()) {
     2528                    numberUp++;
     2529                    averageUp += dynamicObject->upDynamicPseudoCost();
     2530                }
     2531                if (dynamicObject->numberTimesDown()) {
     2532                    numberDown++;
     2533                    averageDown += dynamicObject->downDynamicPseudoCost();
     2534                }
     2535            }
     2536        }
     2537        if (numberUp)
     2538            averageUp /= static_cast<double> (numberUp);
     2539        else
     2540            averageUp = 1.0;
     2541        if (numberDown)
     2542            averageDown /= static_cast<double> (numberDown);
     2543        else
     2544            averageDown = 1.0;
     2545        for ( i = 0; i < numberObjects; i++) {
     2546            OsiObject * object = model->modifiableObject(i);
     2547            CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
     2548                dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     2549            if (dynamicObject) {
     2550                if (!dynamicObject->numberTimesUp())
     2551                    dynamicObject->setUpDynamicPseudoCost(averageUp);
     2552                if (!dynamicObject->numberTimesDown())
     2553                    dynamicObject->setDownDynamicPseudoCost(averageDown);
     2554            }
     2555        }
     2556    }
     2557    /*
     2558      1 strong
     2559      2 no strong
     2560      3 strong just before solution
     2561      4 no strong just before solution
     2562      5 strong first time or before solution
     2563      6 strong first time
     2564    */
     2565    int useShadow = model->moreSpecialOptions() & 7;
     2566    if (useShadow > 2) {
     2567        if (model->getSolutionCount()) {
     2568            if (numberNodes || useShadow < 5) {
     2569                useShadow = 0;
     2570                // zap pseudo shadow prices
     2571                model->pseudoShadow(-1);
     2572                // and switch off
     2573                model->setMoreSpecialOptions(model->moreSpecialOptions()&(~1023));
     2574            } else {
     2575                useShadow = 1;
     2576            }
     2577        } else if (useShadow < 5) {
     2578            useShadow -= 2;
     2579        } else {
     2580            useShadow = 1;
     2581        }
     2582    }
     2583    if (useShadow) {
     2584        // pseudo shadow prices
     2585        model->pseudoShadow((model->moreSpecialOptions() >> 3)&63);
     2586    }
    25052587#ifdef DEPRECATED_STRATEGY
    2506   int saveSearchStrategy2 = model->searchStrategy();
    2507 #endif
    2508   // Get average up and down costs
    2509   {
    2510     double averageUp=0.0;
    2511     double averageDown=0.0;
    2512     int numberUp=0;
    2513     int numberDown=0;
    2514     int i;
    2515     for ( i=0;i<numberObjects;i++) {
    2516       OsiObject * object = model->modifiableObject(i);
    2517       CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    2518         dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    2519       if (dynamicObject) {
    2520         if (dynamicObject->numberTimesUp()) {
    2521           numberUp++;
    2522           averageUp += dynamicObject->upDynamicPseudoCost();
    2523         }
    2524         if (dynamicObject->numberTimesDown()) {
    2525           numberDown++;
    2526           averageDown += dynamicObject->downDynamicPseudoCost();
    2527         }
    2528       }
    2529     }
    2530     if (numberUp)
    2531       averageUp /= static_cast<double> (numberUp);
    2532     else
    2533       averageUp=1.0;
    2534     if (numberDown)
    2535       averageDown /= static_cast<double> (numberDown);
    2536     else
    2537       averageDown=1.0;
    2538     for ( i=0;i<numberObjects;i++) {
    2539       OsiObject * object = model->modifiableObject(i);
    2540       CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    2541         dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    2542       if (dynamicObject) {
    2543         if (!dynamicObject->numberTimesUp())
    2544           dynamicObject->setUpDynamicPseudoCost(averageUp);
    2545         if (!dynamicObject->numberTimesDown())
    2546           dynamicObject->setDownDynamicPseudoCost(averageDown);
    2547       }
    2548     }
    2549   }
    2550   /*
    2551     1 strong
    2552     2 no strong
    2553     3 strong just before solution
    2554     4 no strong just before solution
    2555     5 strong first time or before solution
    2556     6 strong first time
    2557   */
    2558   int useShadow = model->moreSpecialOptions()&7;
    2559   if (useShadow>2) {
    2560     if (model->getSolutionCount()) {
    2561       if (numberNodes||useShadow<5) {
    2562         useShadow=0;
    2563         // zap pseudo shadow prices
    2564         model->pseudoShadow(-1);
    2565         // and switch off
    2566         model->setMoreSpecialOptions(model->moreSpecialOptions()&(~1023));
    2567       } else {
    2568         useShadow=1;
    2569       }
    2570     } else if (useShadow<5) {
    2571       useShadow -= 2;
     2588    { // in for tabbing
     2589    } else if (saveSearchStrategy2 < 1999) {
     2590        // pseudo shadow prices
     2591        model->pseudoShadow(NULL, NULL);
     2592    } else if (saveSearchStrategy2 < 2999) {
     2593        // leave old ones
     2594    } else if (saveSearchStrategy2 < 3999) {
     2595        // pseudo shadow prices at root
     2596        if (!numberNodes)
     2597            model->pseudoShadow(NULL, NULL);
    25722598    } else {
    2573       useShadow=1;
    2574     }
    2575   }
    2576   if (useShadow) {
    2577     // pseudo shadow prices
    2578     model->pseudoShadow((model->moreSpecialOptions()>>3)&63);
    2579   }
    2580 #ifdef DEPRECATED_STRATEGY
    2581   { // in for tabbing
    2582   } else if (saveSearchStrategy2<1999) {
    2583     // pseudo shadow prices
    2584     model->pseudoShadow(NULL,NULL);
    2585   } else if (saveSearchStrategy2<2999) {
    2586     // leave old ones
    2587   } else if (saveSearchStrategy2<3999) {
    2588     // pseudo shadow prices at root
    2589     if (!numberNodes)
    2590       model->pseudoShadow(NULL,NULL);
    2591   } else {
    2592     abort();
    2593   }
    2594   if (saveSearchStrategy2>=0)
    2595     saveSearchStrategy2 = saveSearchStrategy2 % 1000;
    2596   if (saveSearchStrategy2==999)
    2597     saveSearchStrategy2=-1;
    2598   int saveSearchStrategy = saveSearchStrategy2<99 ? saveSearchStrategy2 : saveSearchStrategy2-100;
     2599        abort();
     2600    }
     2601    if (saveSearchStrategy2 >= 0)
     2602        saveSearchStrategy2 = saveSearchStrategy2 % 1000;
     2603    if (saveSearchStrategy2 == 999)
     2604        saveSearchStrategy2 = -1;
     2605    int saveSearchStrategy = saveSearchStrategy2 < 99 ? saveSearchStrategy2 : saveSearchStrategy2 - 100;
    25992606#endif //DEPRECATED_STRATEGY
    2600   int numberNotTrusted=0;
    2601   int numberStrongDone=0;
    2602   int numberUnfinished=0;
    2603   int numberStrongInfeasible=0;
    2604   int numberStrongIterations=0;
    2605   // so we can save lots of stuff
    2606   CbcStrongInfo choice;
    2607   CbcDynamicPseudoCostBranchingObject * choiceObject = NULL;
    2608   if (model->allDynamic()) {
    2609     CbcSimpleIntegerDynamicPseudoCost * object = NULL;
    2610     choiceObject=new CbcDynamicPseudoCostBranchingObject(model,0,-1,0.5,object);
    2611   }
    2612   choice.possibleBranch=choiceObject;
    2613   numberPassesLeft = CoinMax(numberPassesLeft,2);
    2614   while(!finished) {
    2615     numberPassesLeft--;
    2616     finished=true;
    2617     decision->initialize(model);
    2618     // Some objects may compute an estimate of best solution from here
    2619     estimatedDegradation=0.0;
    2620     numberToFix=0;
    2621     int numberToDo=0;
    2622     int iBestNot=-1;
    2623     int iBestGot=-1;
    2624     double best=0.0;
    2625     numberNotTrusted=0;
    2626     numberStrongDone=0;
    2627     numberUnfinished=0;
    2628     numberStrongInfeasible=0;
    2629     numberStrongIterations=0;
     2607    int numberNotTrusted = 0;
     2608    int numberStrongDone = 0;
     2609    int numberUnfinished = 0;
     2610    int numberStrongInfeasible = 0;
     2611    int numberStrongIterations = 0;
     2612    // so we can save lots of stuff
     2613    CbcStrongInfo choice;
     2614    CbcDynamicPseudoCostBranchingObject * choiceObject = NULL;
     2615    if (model->allDynamic()) {
     2616        CbcSimpleIntegerDynamicPseudoCost * object = NULL;
     2617        choiceObject = new CbcDynamicPseudoCostBranchingObject(model, 0, -1, 0.5, object);
     2618    }
     2619    choice.possibleBranch = choiceObject;
     2620    numberPassesLeft = CoinMax(numberPassesLeft, 2);
     2621    while (!finished) {
     2622        numberPassesLeft--;
     2623        finished = true;
     2624        decision->initialize(model);
     2625        // Some objects may compute an estimate of best solution from here
     2626        estimatedDegradation = 0.0;
     2627        numberToFix = 0;
     2628        int numberToDo = 0;
     2629        int iBestNot = -1;
     2630        int iBestGot = -1;
     2631        double best = 0.0;
     2632        numberNotTrusted = 0;
     2633        numberStrongDone = 0;
     2634        numberUnfinished = 0;
     2635        numberStrongInfeasible = 0;
     2636        numberStrongIterations = 0;
    26302637#ifdef RANGING
    2631     int * which = objectMark+numberObjects+1;
    2632     int neededPenalties;
    2633     int optionalPenalties;
    2634 #endif
    2635     // We may go round this loop three times (only if we think we have solution)
    2636     for (int iPass=0;iPass<3;iPass++) {
    2637      
    2638       // Some objects may compute an estimate of best solution from here
    2639       estimatedDegradation=0.0;
    2640       numberUnsatisfied_ = 0;
    2641       // initialize sum of "infeasibilities"
    2642       sumInfeasibilities_ = 0.0;
    2643       int bestPriority=COIN_INT_MAX;
     2638        int * which = objectMark + numberObjects + 1;
     2639        int neededPenalties;
     2640        int optionalPenalties;
     2641#endif
     2642        // We may go round this loop three times (only if we think we have solution)
     2643        for (int iPass = 0; iPass < 3; iPass++) {
     2644
     2645            // Some objects may compute an estimate of best solution from here
     2646            estimatedDegradation = 0.0;
     2647            numberUnsatisfied_ = 0;
     2648            // initialize sum of "infeasibilities"
     2649            sumInfeasibilities_ = 0.0;
     2650            int bestPriority = COIN_INT_MAX;
    26442651#if 0
    2645       int number01 = 0;
    2646       const cliqueEntry * entry = NULL;
    2647       const int * toZero = NULL;
    2648       const int * toOne = NULL;
    2649       const int * backward = NULL;
    2650       int numberUnsatisProbed=0;
    2651       int numberUnsatisNotProbed=0; // 0-1
    2652       if (probingInfo) {
    2653         number01 = probingInfo->numberIntegers();
    2654         entry = probingInfo->fixEntries();
    2655         toZero = probingInfo->toZero();
    2656         toOne = probingInfo->toOne();
    2657         backward = probingInfo->backward();
    2658         if (!toZero[number01]||number01<numberObjects||true) {
    2659           // no info
    2660           probingInfo=NULL;
    2661         }
    2662       }
    2663 #endif
    2664       /*
    2665         Scan for branching objects that indicate infeasibility. Choose candidates
    2666         using priority as the first criteria, then integer infeasibility.
    2667        
    2668         The algorithm is to fill the array with a set of good candidates (by
    2669         infeasibility) with priority bestPriority.  Finding a candidate with
    2670         priority better (less) than bestPriority flushes the choice array. (This
    2671         serves as initialization when the first candidate is found.)
    2672        
    2673       */
    2674       numberToDo=0;
     2652            int number01 = 0;
     2653            const cliqueEntry * entry = NULL;
     2654            const int * toZero = NULL;
     2655            const int * toOne = NULL;
     2656            const int * backward = NULL;
     2657            int numberUnsatisProbed = 0;
     2658            int numberUnsatisNotProbed = 0; // 0-1
     2659            if (probingInfo) {
     2660                number01 = probingInfo->numberIntegers();
     2661                entry = probingInfo->fixEntries();
     2662                toZero = probingInfo->toZero();
     2663                toOne = probingInfo->toOne();
     2664                backward = probingInfo->backward();
     2665                if (!toZero[number01] || number01 < numberObjects || true) {
     2666                    // no info
     2667                    probingInfo = NULL;
     2668                }
     2669            }
     2670#endif
     2671            /*
     2672              Scan for branching objects that indicate infeasibility. Choose candidates
     2673              using priority as the first criteria, then integer infeasibility.
     2674
     2675              The algorithm is to fill the array with a set of good candidates (by
     2676              infeasibility) with priority bestPriority.  Finding a candidate with
     2677              priority better (less) than bestPriority flushes the choice array. (This
     2678              serves as initialization when the first candidate is found.)
     2679
     2680            */
     2681            numberToDo = 0;
    26752682#ifdef RANGING
    2676       neededPenalties=0;
    2677       optionalPenalties=numberObjects;
    2678 #endif
    2679       iBestNot=-1;
    2680       double bestNot=0.0;
    2681       iBestGot=-1;
    2682       best=0.0;
    2683       /* Problem type as set by user or found by analysis.  This will be extended
    2684         0 - not known
    2685         1 - Set partitioning <=
    2686         2 - Set partitioning ==
    2687         3 - Set covering
    2688         4 - all +- 1 or all +1 and odd
    2689       */
    2690       int problemType = model->problemType();
    2691       bool canDoOneHot=false;
    2692       for (i=0;i<numberObjects;i++) {
    2693         OsiObject * object = model->modifiableObject(i);
    2694         CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
    2695           dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
    2696         int preferredWay;
    2697         double infeasibility = object->infeasibility(&usefulInfo,preferredWay);
    2698         int priorityLevel = object->priority();
    2699         if (hotstartSolution) {
    2700           // we are doing hot start
    2701           const CbcSimpleInteger * thisOne = dynamic_cast <const CbcSimpleInteger *> (object);
    2702           if (thisOne) {
    2703             int iColumn = thisOne->columnNumber();
    2704             bool canDoThisHot=true;
    2705             double targetValue = hotstartSolution[iColumn];
    2706             if (saveUpper[iColumn]>saveLower[iColumn]) {
    2707               double value = saveSolution[iColumn];
    2708               if (hotstartPriorities)
    2709                 priorityLevel=hotstartPriorities[iColumn];
    2710               //double originalLower = thisOne->originalLower();
    2711               //double originalUpper = thisOne->originalUpper();
    2712               // switch off if not possible
    2713               if (targetValue>=saveLower[iColumn]&&targetValue<=saveUpper[iColumn]) {
    2714                 /* priority outranks rest always if negative
    2715                    otherwise can be downgraded if at correct level.
    2716                    Infeasibility may be increased to choose 1.0 values first.
    2717                    choose one near wanted value
    2718                 */
    2719                 if (fabs(value-targetValue)>integerTolerance) {
    2720                   //if (infeasibility>0.01)
    2721                   //infeasibility = fabs(1.0e6-fabs(value-targetValue));
    2722                   //else
    2723                   infeasibility = fabs(value-targetValue);
    2724                   //if (targetValue==1.0)
    2725                   //infeasibility += 1.0;
    2726                   if (value>targetValue) {
    2727                     preferredWay=-1;
    2728                   } else {
    2729                     preferredWay=1;
    2730                   }
    2731                   priorityLevel = CoinAbs(priorityLevel);
    2732                 } else if (priorityLevel<0) {
    2733                   priorityLevel = CoinAbs(priorityLevel);
    2734                   if (targetValue==saveLower[iColumn]) {
    2735                     infeasibility = integerTolerance+1.0e-12;
    2736                     preferredWay=-1;
    2737                   } else if (targetValue==saveUpper[iColumn]) {
    2738                     infeasibility = integerTolerance+1.0e-12;
    2739                     preferredWay=1;
    2740                   } else {
    2741                     // can't
    2742                     priorityLevel += 10000000;
    2743                     canDoThisHot=false;
    2744                   }
    2745                 } else {
    2746                   priorityLevel += 10000000;
    2747                   canDoThisHot=false;
    2748                 }
    2749               } else {
    2750                 // switch off if not possible
    2751                 canDoThisHot=false;
    2752               }
    2753               if (canDoThisHot)
    2754                 canDoOneHot=true;
    2755             } else if (targetValue<saveLower[iColumn]||targetValue>saveUpper[iColumn]) {
    2756             }
    2757           } else {
    2758             priorityLevel += 10000000;
    2759           }
    2760         }
     2683            neededPenalties = 0;
     2684            optionalPenalties = numberObjects;
     2685#endif
     2686            iBestNot = -1;
     2687            double bestNot = 0.0;
     2688            iBestGot = -1;
     2689            best = 0.0;
     2690            /* Problem type as set by user or found by analysis.  This will be extended
     2691            0 - not known
     2692            1 - Set partitioning <=
     2693            2 - Set partitioning ==
     2694            3 - Set covering
     2695            4 - all +- 1 or all +1 and odd
     2696            */
     2697            int problemType = model->problemType();
     2698            bool canDoOneHot = false;
     2699            for (i = 0; i < numberObjects; i++) {
     2700                OsiObject * object = model->modifiableObject(i);
     2701                CbcSimpleIntegerDynamicPseudoCost * dynamicObject =
     2702                    dynamic_cast <CbcSimpleIntegerDynamicPseudoCost *>(object) ;
     2703                int preferredWay;
     2704                double infeasibility = object->infeasibility(&usefulInfo, preferredWay);
     2705                int priorityLevel = object->priority();
     2706                if (hotstartSolution) {
     2707                    // we are doing hot start
     2708                    const CbcSimpleInteger * thisOne = dynamic_cast <const CbcSimpleInteger *> (object);
     2709                    if (thisOne) {
     2710                        int iColumn = thisOne->columnNumber();
     2711                        bool canDoThisHot = true;
     2712                        double targetValue = hotstartSolution[iColumn];
     2713                        if (saveUpper[iColumn] > saveLower[iColumn]) {
     2714                            double value = saveSolution[iColumn];
     2715                            if (hotstartPriorities)
     2716                                priorityLevel = hotstartPriorities[iColumn];
     2717                            //double originalLower = thisOne->originalLower();
     2718                            //double originalUpper = thisOne->originalUpper();
     2719                            // switch off if not possible
     2720                            if (targetValue >= saveLower[iColumn] && targetValue <= saveUpper[iColumn]) {
     2721                                /* priority outranks rest always if negative
     2722                                   otherwise can be downgraded if at correct level.
     2723                                   Infeasibility may be increased to choose 1.0 values first.
     2724                                   choose one near wanted value
     2725                                */
     2726                                if (fabs(value - targetValue) > integerTolerance) {
     2727                                    //if (infeasibility>0.01)
     2728                                    //infeasibility = fabs(1.0e6-fabs(value-targetValue));
     2729                                    //else
     2730                                    infeasibility = fabs(value - targetValue);
     2731                                    //if (targetValue==1.0)
     2732                                    //infeasibility += 1.0;
     2733                                    if (value > targetValue) {
     2734                                        preferredWay = -1;
     2735                                    } else {
     2736                                        preferredWay = 1;
     2737                                    }
     2738                                    priorityLevel = CoinAbs(priorityLevel);
     2739                                } else if (priorityLevel < 0) {
     2740                                    priorityLevel = CoinAbs(priorityLevel);
     2741                                    if (targetValue == saveLower[iColumn]) {
     2742                                        infeasibility = integerTolerance + 1.0e-12;
     2743                                        preferredWay = -1;
     2744                                    } else if (targetValue == saveUpper[iColumn]) {
     2745                                        infeasibility = integerTolerance + 1.0e-12;
     2746                                        preferredWay = 1;
     2747                                    } else {
     2748                                        // can't
     2749                                        priorityLevel += 10000000;
     2750                                        canDoThisHot = false;
     2751                                    }
     2752                                } else {
     2753                                    priorityLevel += 10000000;
     2754                                    canDoThisHot = false;
     2755                                }
     2756                            } else {
     2757                                // switch off if not possible
     2758                                canDoThisHot = false;
     2759                            }
     2760                            if (canDoThisHot)
     2761                                canDoOneHot = true;
     2762                        } else if (targetValue < saveLower[iColumn] || targetValue > saveUpper[iColumn]) {
     2763                        }
     2764                    } else {
     2765                        priorityLevel += 10000000;
     2766                    }
     2767                }
    27612768#define ZERO_ONE 0
    27622769#define ZERO_FAKE 1.0e20;
    27632770#if ZERO_ONE==1
    2764         // branch on 0-1 first (temp)
    2765         if (fabs(saveSolution[dynamicObject->columnNumber()])<1.0)
    2766           priorityLevel--;
     2771                // branch on 0-1 first (temp)
     2772                if (fabs(saveSolution[dynamicObject->columnNumber()]) < 1.0)
     2773                    priorityLevel--;
    27672774#endif
    27682775#if ZERO_ONE==2
    2769         if (fabs(saveSolution[dynamicObject->columnNumber()])<1.0)
    2770           infeasibility *= ZERO_FAKE;
    2771 #endif
    2772         if (infeasibility) {
    2773           int iColumn = numberColumns+i;
    2774           bool gotDown=false;
    2775           int numberThisDown = 0;
    2776           bool gotUp=false;
    2777           int numberThisUp = 0;
    2778           double downGuess=object->downEstimate();
    2779           double upGuess=object->upEstimate();
    2780           if (dynamicObject) {
    2781             // Use this object's numberBeforeTrust
    2782             int numberBeforeTrust = dynamicObject->numberBeforeTrust();
    2783             iColumn = dynamicObject->columnNumber();
    2784             gotDown=false;
    2785             numberThisDown = dynamicObject->numberTimesDown();
    2786             if (numberThisDown>=numberBeforeTrust)
    2787               gotDown=true;
    2788             gotUp=false;
    2789             numberThisUp = dynamicObject->numberTimesUp();
    2790             if (numberThisUp>=numberBeforeTrust)
    2791               gotUp=true;
    2792             if (!depth_&&false) {
    2793               // try closest to 0.5
    2794               double part =saveSolution[iColumn]-floor(saveSolution[iColumn]);
    2795               infeasibility = fabs(0.5-part);
    2796             }
    2797             if (problemType>0&&problemType<4&&false) {
    2798               // try closest to 0.5
    2799               double part =saveSolution[iColumn]-floor(saveSolution[iColumn]);
    2800               infeasibility = 0.5-fabs(0.5-part);
    2801             }
     2776                if (fabs(saveSolution[dynamicObject->columnNumber()]) < 1.0)
     2777                    infeasibility *= ZERO_FAKE;
     2778#endif
     2779                if (infeasibility) {
     2780                    int iColumn = numberColumns + i;
     2781                    bool gotDown = false;
     2782                    int numberThisDown = 0;
     2783                    bool gotUp = false;
     2784                    int numberThisUp = 0;
     2785                    double downGuess = object->downEstimate();
     2786                    double upGuess = object->upEstimate();
     2787                    if (dynamicObject) {
     2788                        // Use this object's numberBeforeTrust
     2789                        int numberBeforeTrust = dynamicObject->numberBeforeTrust();
     2790                        iColumn = dynamicObject->columnNumber();
     2791                        gotDown = false;
     2792                        numberThisDown = dynamicObject->numberTimesDown();
     2793                        if (numberThisDown >= numberBeforeTrust)
     2794                            gotDown = true;
     2795                        gotUp = false;
     2796                        numberThisUp = dynamicObject->numberTimesUp();
     2797                        if (numberThisUp >= numberBeforeTrust)
     2798                            gotUp = true;
     2799                        if (!depth_ && false) {
     2800                            // try closest to 0.5
     2801                            double part = saveSolution[iColumn] - floor(saveSolution[iColumn]);
     2802                            infeasibility = fabs(0.5 - part);
     2803                        }
     2804                        if (problemType > 0 && problemType < 4 && false) {
     2805                            // try closest to 0.5
     2806                            double part = saveSolution[iColumn] - floor(saveSolution[iColumn]);
     2807                            infeasibility = 0.5 - fabs(0.5 - part);
     2808                        }
    28022809#if 0
    2803             if (probingInfo) {
    2804               int iSeq = backward[iColumn];
    2805               assert (iSeq>=0);
    2806               infeasibility = 1.0 + (toZero[iSeq+1]-toZero[iSeq])+
    2807                 5.0*CoinMin(toOne[iSeq]-toZero[iSeq],toZero[iSeq+1]-toOne[iSeq]);
    2808               if (toZero[iSeq+1]>toZero[iSeq]) {
    2809                 numberUnsatisProbed++;
    2810               } else {
    2811                 numberUnsatisNotProbed++;
    2812               }
    2813             }
    2814 #endif
    2815           } else {
    2816             // see if SOS
    2817             CbcSOS * sosObject =
    2818               dynamic_cast <CbcSOS *>(object) ;
    2819             if (sosObject) {
    2820               gotDown=false;
    2821               numberThisDown = sosObject->numberTimesDown();
    2822               if (numberThisDown>=numberBeforeTrust)
    2823                 gotDown=true;
    2824               gotUp=false;
    2825               numberThisUp = sosObject->numberTimesUp();
    2826               if (numberThisUp>=numberBeforeTrust)
    2827                 gotUp=true;
    2828             } else {
    2829               gotDown=true;
    2830               numberThisDown=999999;
    2831               downGuess=1.0e20;
    2832               gotUp=true;
    2833               numberThisUp=999999;
    2834               upGuess=1.0e20;
    2835               numberPassesLeft=0;
    2836             }
    2837           }
    2838           // Increase estimated degradation to solution
    2839           estimatedDegradation += CoinMin(downGuess,upGuess);
    2840           downEstimate[i]=downGuess;
    2841           upEstimate[i]=upGuess;
    2842           numberUnsatisfied_++;
    2843           sumInfeasibilities_ += infeasibility;
    2844           // Better priority? Flush choices.
    2845           if (priorityLevel<bestPriority) {
    2846             numberToDo=0;
    2847             bestPriority = priorityLevel;
    2848             iBestGot=-1;
    2849             best=0.0;
    2850             numberNotTrusted=0;
     2810                        if (probingInfo) {
     2811                            int iSeq = backward[iColumn];
     2812                            assert (iSeq >= 0);
     2813                            infeasibility = 1.0 + (toZero[iSeq+1] - toZero[iSeq]) +
     2814                                            5.0 * CoinMin(toOne[iSeq] - toZero[iSeq], toZero[iSeq+1] - toOne[iSeq]);
     2815                            if (toZero[iSeq+1] > toZero[iSeq]) {
     2816                                numberUnsatisProbed++;
     2817                            } else {
     2818                                numberUnsatisNotProbed++;
     2819                            }
     2820                        }
     2821#endif
     2822                    } else {
     2823                        // see if SOS
     2824                        CbcSOS * sosObject =
     2825                            dynamic_cast <CbcSOS *>(object) ;
     2826                        if (sosObject) {
     2827                            gotDown = false;
     2828                            numberThisDown = sosObject->numberTimesDown();
     2829                            if (numberThisDown >= numberBeforeTrust)
     2830                                gotDown = true;
     2831                            gotUp = false;
     2832                            numberThisUp = sosObject->numberTimesUp();
     2833                            if (numberThisUp >= numberBeforeTrust)
     2834                                gotUp = true;
     2835                        } else {
     2836                            gotDown = true;
     2837                            numberThisDown = 999999;
     2838                            downGuess = 1.0e20;
     2839                            gotUp = true;
     2840                            numberThisUp = 999999;
     2841                            upGuess = 1.0e20;
     2842                            numberPassesLeft = 0;
     2843                        }
     2844                    }
     2845                    // Increase estimated degradation to solution
     2846                    estimatedDegradation += CoinMin(downGuess, upGuess);
     2847                    downEstimate[i] = downGuess;
     2848                    upEstimate[i] = upGuess;
     2849                    numberUnsatisfied_++;
     2850                    sumInfeasibilities_ += infeasibility;
     2851                    // Better priority? Flush choices.
     2852                    if (priorityLevel < bestPriority) {
     2853                        numberToDo = 0;
     2854                        bestPriority = priorityLevel;
     2855                        iBestGot = -1;
     2856                        best = 0.0;
     2857                        numberNotTrusted = 0;
    28512858#ifdef RANGING
    2852             neededPenalties=0;
    2853             optionalPenalties=numberObjects;
    2854 #endif
    2855           } else if (priorityLevel>bestPriority) {
     2859                        neededPenalties = 0;
     2860                        optionalPenalties = numberObjects;
     2861#endif
     2862                    } else if (priorityLevel > bestPriority) {
     2863                        continue;
     2864                    }
     2865                    if (!gotUp || !gotDown)
     2866                        numberNotTrusted++;
     2867                    // Check for suitability based on infeasibility.
     2868                    if ((gotDown && gotUp) && numberStrong > 0) {
     2869                        sort[numberToDo] = -infeasibility;
     2870                        if (infeasibility > best) {
     2871                            best = infeasibility;
     2872                            iBestGot = numberToDo;
     2873                        }
     2874#ifdef RANGING
     2875                        if (dynamicObject) {
     2876                            objectMark[--optionalPenalties] = numberToDo;
     2877                            which[optionalPenalties] = iColumn;
     2878                        }
     2879#endif
     2880                    } else {
     2881#ifdef RANGING
     2882                        if (dynamicObject) {
     2883                            objectMark[neededPenalties] = numberToDo;
     2884                            which[neededPenalties++] = iColumn;
     2885                        }
     2886#endif
     2887                        sort[numberToDo] = -10.0 * infeasibility;
     2888                        if (!(numberThisUp + numberThisDown))
     2889                            sort[numberToDo] *= 100.0; // make even more likely
     2890                        if (iColumn < numberColumns) {
     2891                            double part = saveSolution[iColumn] - floor(saveSolution[iColumn]);
     2892                            if (1.0 - fabs(part - 0.5) > bestNot) {
     2893                                iBestNot = numberToDo;
     2894                                bestNot = 1.0 - fabs(part - 0.5);
     2895                            }
     2896                        } else {
     2897                            // SOS
     2898                            if (-sort[numberToDo] > bestNot) {
     2899                                iBestNot = numberToDo;
     2900                                bestNot = -sort[numberToDo];
     2901                            }
     2902                        }
     2903                    }
     2904                    if (model->messageHandler()->logLevel() > 3) {
     2905                        printf("%d (%d) down %d %g up %d %g - infeas %g - sort %g solution %g\n",
     2906                               i, iColumn, numberThisDown, object->downEstimate(), numberThisUp, object->upEstimate(),
     2907                               infeasibility, sort[numberToDo], saveSolution[iColumn]);
     2908                    }
     2909                    whichObject[numberToDo++] = i;
     2910                } else {
     2911                    // for debug
     2912                    downEstimate[i] = -1.0;
     2913                    upEstimate[i] = -1.0;
     2914                }
     2915            }
     2916            if (numberUnsatisfied_) {
     2917                //if (probingInfo&&false)
     2918                //printf("nunsat %d, %d probed, %d other 0-1\n",numberUnsatisfied_,
     2919                // numberUnsatisProbed,numberUnsatisNotProbed);
     2920                // some infeasibilities - go to next steps
     2921                if (!canDoOneHot && hotstartSolution) {
     2922                    // switch off as not possible
     2923                    hotstartSolution = NULL;
     2924                    model->setHotstartSolution(NULL, NULL);
     2925                    usefulInfo.hotstartSolution_ = NULL;
     2926                }
     2927                break;
     2928            } else if (!iPass) {
     2929                // may just need resolve
     2930                model->resolve(NULL, 11, saveSolution, saveLower, saveUpper);
     2931                //double newObjValue = solver->getObjSense()*solver->getObjValue();
     2932                //objectiveValue_ = CoinMax(objectiveValue_,newObjValue);
     2933                if (!solver->isProvenOptimal()) {
     2934                    // infeasible
     2935                    anyAction = -2;
     2936                    break;
     2937                }
     2938            } else if (iPass == 1) {
     2939                // looks like a solution - get paranoid
     2940                bool roundAgain = false;
     2941                // get basis
     2942                CoinWarmStartBasis * ws = dynamic_cast<CoinWarmStartBasis*>(solver->getWarmStart());
     2943                if (!ws)
     2944                    break;
     2945                double tolerance;
     2946                solver->getDblParam(OsiPrimalTolerance, tolerance);
     2947                for (i = 0; i < numberColumns; i++) {
     2948                    double value = saveSolution[i];
     2949                    if (value < lower[i] - tolerance) {
     2950                        saveSolution[i] = lower[i];
     2951                        roundAgain = true;
     2952                        ws->setStructStatus(i, CoinWarmStartBasis::atLowerBound);
     2953                    } else if (value > upper[i] + tolerance) {
     2954                        saveSolution[i] = upper[i];
     2955                        roundAgain = true;
     2956                        ws->setStructStatus(i, CoinWarmStartBasis::atUpperBound);
     2957                    }
     2958                }
     2959                if (roundAgain) {
     2960                    // restore basis
     2961                    solver->setWarmStart(ws);
     2962                    solver->setColSolution(saveSolution);
     2963                    delete ws;
     2964                    bool takeHint;
     2965                    OsiHintStrength strength;
     2966                    solver->getHintParam(OsiDoDualInResolve, takeHint, strength);
     2967                    solver->setHintParam(OsiDoDualInResolve, false, OsiHintDo) ;
     2968                    model->resolve(NULL, 11, saveSolution, saveLower, saveUpper);
     2969                    //double newObjValue = solver->getObjSense()*solver->getObjValue();
     2970                    //objectiveValue_ = CoinMax(objectiveValue_,newObjValue);
     2971                    solver->setHintParam(OsiDoDualInResolve, takeHint, strength) ;
     2972                    if (!solver->isProvenOptimal()) {
     2973                        // infeasible
     2974                        anyAction = -2;
     2975                        break;
     2976                    }
     2977                } else {
     2978                    delete ws;
     2979                    break;
     2980                }
     2981            }
     2982        }
     2983        if (anyAction == -2) {
     2984            break;
     2985        }
     2986        // skip if solution
     2987        if (!numberUnsatisfied_)
     2988            break;
     2989        int skipAll = (numberNotTrusted == 0 || numberToDo == 1) ? 1 : 0;
     2990        bool doneHotStart = false;
     2991        //DEPRECATED_STRATEGYint searchStrategy = saveSearchStrategy>=0 ? (saveSearchStrategy%10) : -1;
     2992        int searchStrategy = model->searchStrategy();
     2993        // But adjust depending on ratio of iterations
     2994        if (searchStrategy > 0) {
     2995            if (numberBeforeTrust >= 5 && numberBeforeTrust <= 10) {
     2996                if (searchStrategy != 2) {
     2997                    assert (searchStrategy == 1);
     2998                    if (depth_ > 5) {
     2999                        int numberIterations = model->getIterationCount();
     3000                        int numberStrongIterations = model->numberStrongIterations();
     3001                        if (numberStrongIterations > numberIterations + 10000) {
     3002                            searchStrategy = 2;
     3003                            skipAll = 1;
     3004                        } else if (numberStrongIterations*4 + 1000 < numberIterations) {
     3005                            searchStrategy = 3;
     3006                            skipAll = 0;
     3007                        }
     3008                    } else {
     3009                        searchStrategy = 3;
     3010                        skipAll = 0;
     3011                    }
     3012                }
     3013            }
     3014        }
     3015        // worth trying if too many times
     3016        // Save basis
     3017        CoinWarmStart * ws = NULL;
     3018#   if CBC_DEBUG > 0
     3019        std::cout << "chDyBr: declaring null warm start." << std::endl ;
     3020#   endif
     3021        // save limit
     3022        int saveLimit = 0;
     3023        solver->getIntParam(OsiMaxNumIterationHotStart, saveLimit);
     3024        if (!numberPassesLeft)
     3025            skipAll = 1;
     3026        if (!skipAll) {
     3027            ws = solver->getWarmStart();
     3028#     if CBC_DEBUG > 0
     3029            std::cout
     3030                << "chDyBr: Acquired real warm start "
     3031                << std::hex << ws << std::dec << "." << std::endl ;
     3032#     endif
     3033            int limit = 100;
     3034            if (!saveStateOfSearch && saveLimit < limit && saveLimit == 100)
     3035                solver->setIntParam(OsiMaxNumIterationHotStart, limit);
     3036        }
     3037        // Say which one will be best
     3038        int whichChoice = 0;
     3039        int bestChoice;
     3040        if (iBestGot >= 0)
     3041            bestChoice = iBestGot;
     3042        else
     3043            bestChoice = iBestNot;
     3044        assert (bestChoice >= 0);
     3045        // If we have hit max time don't do strong branching
     3046        bool hitMaxTime = ( CoinCpuTime() - model->getDblParam(CbcModel::CbcStartSeconds) >
     3047                            model->getDblParam(CbcModel::CbcMaximumSeconds));
     3048        // also give up if we are looping round too much
     3049        if (hitMaxTime || numberPassesLeft <= 0 || useShadow == 2) {
     3050            int iObject = whichObject[bestChoice];
     3051            OsiObject * object = model->modifiableObject(iObject);
     3052            int preferredWay;
     3053            object->infeasibility(&usefulInfo, preferredWay);
     3054            CbcObject * obj =
     3055                dynamic_cast <CbcObject *>(object) ;
     3056            assert (obj);
     3057            branch_ = obj->createCbcBranch(solver, &usefulInfo, preferredWay);
     3058            {
     3059                CbcBranchingObject * branchObj =
     3060                    dynamic_cast <CbcBranchingObject *>(branch_) ;
     3061                assert (branchObj);
     3062                branchObj->way(preferredWay);
     3063            }
     3064            delete ws;
     3065#     if CBC_DEBUG > 0
     3066            std::cout
     3067                << "chDyBr(1): deleting warm start "
     3068                << std::hex << ws << std::dec << "." << std::endl ;
     3069#     endif
     3070            ws = NULL;
     3071            break;
     3072        } else {
     3073            // say do fast
     3074            int easy = 1;
     3075            if (!skipAll)
     3076                solver->setHintParam(OsiDoInBranchAndCut, true, OsiHintDo, &easy) ;
     3077            int iDo;
     3078#ifdef RANGING
     3079            bool useRanging = model->allDynamic() && !skipAll;
     3080            if (useRanging) {
     3081                double currentObjective = solver->getObjValue() * solver->getObjSense();
     3082                double gap = cutoff - currentObjective;
     3083                // relax a bit
     3084                gap *= 1.0000001;
     3085                gap = CoinMax(1.0e-5, gap);
     3086                // off penalties if too much
     3087                double needed = neededPenalties;
     3088                needed *= numberRows;
     3089                if (numberNodes) {
     3090                    if (needed > 1.0e6) {
     3091                        neededPenalties = 0;
     3092                    } else if (gap < 1.0e5) {
     3093                        // maybe allow some not needed
     3094                        int extra = static_cast<int> ((1.0e6 - needed) / numberRows);
     3095                        int nStored = numberObjects - optionalPenalties;
     3096                        extra = CoinMin(extra, nStored);
     3097                        for (int i = 0; i < extra; i++) {
     3098                            objectMark[neededPenalties] = objectMark[optionalPenalties+i];
     3099                            which[neededPenalties++] = which[optionalPenalties+i];;
     3100                        }
     3101                    }
     3102                }
     3103                if (osiclp && neededPenalties) {
     3104                    assert (!doneHotStart);
     3105                    xPen += neededPenalties;
     3106                    which--;
     3107                    which[0] = neededPenalties;
     3108                    osiclp->passInRanges(which);
     3109                    // Mark hot start and get ranges
     3110                    if (kPass) {
     3111                        // until can work out why solution can go funny
     3112                        int save = osiclp->specialOptions();
     3113                        osiclp->setSpecialOptions(save | 256);