Ignore:
Timestamp:
Nov 9, 2009 6:33:07 PM (10 years ago)
Author:
EdwinStraver
Message:

Changed formatting using AStyle -A4 -p

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/sandbox/Cbc/src/CbcBranchCut.cpp

    r1271 r1286  
    2424*/
    2525CbcBranchCut::CbcBranchCut ()
    26   : CbcObject()
     26        : CbcObject()
    2727{
    2828}
    2929
    3030/* Constructor so model can be passed up
    31 */ 
     31*/
    3232CbcBranchCut::CbcBranchCut (CbcModel * model)
    33   : CbcObject(model)
    34 {
    35 }
    36 // Copy constructor 
     33        : CbcObject(model)
     34{
     35}
     36// Copy constructor
    3737CbcBranchCut::CbcBranchCut ( const CbcBranchCut & rhs)
    38   :CbcObject(rhs)
     38        : CbcObject(rhs)
    3939
    4040{
     
    4545CbcBranchCut::clone() const
    4646{
    47   return new CbcBranchCut(*this);
    48 }
    49 
    50 // Assignment operator 
    51 CbcBranchCut & 
     47    return new CbcBranchCut(*this);
     48}
     49
     50// Assignment operator
     51CbcBranchCut &
    5252CbcBranchCut::operator=( const CbcBranchCut& /*rhs*/)
    5353{
    54   return *this;
    55 }
    56 
    57 // Destructor 
     54    return *this;
     55}
     56
     57// Destructor
    5858CbcBranchCut::~CbcBranchCut ()
    5959{
    6060}
    61 double 
     61double
    6262CbcBranchCut::infeasibility(const OsiBranchingInformation * /*info*/,
    63                                int &preferredWay) const
    64 {
    65   throw CoinError("Use of base class","infeasibility","CbcBranchCut");
    66   preferredWay=-1;
    67   return 0.0;
     63                            int &preferredWay) const
     64{
     65    throw CoinError("Use of base class", "infeasibility", "CbcBranchCut");
     66    preferredWay = -1;
     67    return 0.0;
    6868}
    6969
     
    7373    nearest integer value.
    7474*/
    75 void 
     75void
    7676CbcBranchCut::feasibleRegion()
    7777{
     
    7979/* Return true if branch created by object should fix variables
    8080 */
    81 bool
    82 CbcBranchCut::boundBranch() const
    83 {return false;}
    84 CbcBranchingObject *
    85 CbcBranchCut::createCbcBranch(OsiSolverInterface * /*solver*/,const OsiBranchingInformation * /*info*/, int /*way*/)
    86 {
    87   throw CoinError("Use of base class","createCbcBranch","CbcBranchCut");
    88   return new CbcCutBranchingObject();
     81bool
     82CbcBranchCut::boundBranch() const
     83{
     84    return false;
     85}
     86CbcBranchingObject *
     87CbcBranchCut::createCbcBranch(OsiSolverInterface * /*solver*/, const OsiBranchingInformation * /*info*/, int /*way*/)
     88{
     89    throw CoinError("Use of base class", "createCbcBranch", "CbcBranchCut");
     90    return new CbcCutBranchingObject();
    8991}
    9092
     
    9597   If no feasible point returns null
    9698*/
    97 CbcBranchingObject * 
     99CbcBranchingObject *
    98100CbcBranchCut::preferredNewFeasible() const
    99101{
    100   throw CoinError("Use of base class","preferredNewFeasible","CbcBranchCut");
    101   return new CbcCutBranchingObject();
    102 }
    103  
     102    throw CoinError("Use of base class", "preferredNewFeasible", "CbcBranchCut");
     103    return new CbcCutBranchingObject();
     104}
     105
    104106/* Given valid solution (i.e. satisfied) and reduced costs etc
    105107   returns a branching object which would give a new feasible
     
    107109   If no feasible point returns null
    108110*/
    109 CbcBranchingObject * 
    110 CbcBranchCut::notPreferredNewFeasible() const 
    111 {
    112   throw CoinError("Use of base class","notPreferredNewFeasible","CbcBranchCut");
    113   return new CbcCutBranchingObject();
    114 }
    115  
     111CbcBranchingObject *
     112CbcBranchCut::notPreferredNewFeasible() const
     113{
     114    throw CoinError("Use of base class", "notPreferredNewFeasible", "CbcBranchCut");
     115    return new CbcCutBranchingObject();
     116}
     117
    116118/*
    117119  Bounds may be tightened, so it may be good to be able to refresh the local
    118120  copy of the original bounds.
    119121 */
    120 void 
     122void
    121123CbcBranchCut::resetBounds()
    122124{
     
    124126
    125127
    126 // Default Constructor 
     128// Default Constructor
    127129CbcCutBranchingObject::CbcCutBranchingObject()
    128   :CbcBranchingObject()
    129 {
    130   down_=OsiRowCut();
    131   up_=OsiRowCut();
    132   canFix_=false;
     130        : CbcBranchingObject()
     131{
     132    down_ = OsiRowCut();
     133    up_ = OsiRowCut();
     134    canFix_ = false;
    133135}
    134136
    135137// Useful constructor
    136 CbcCutBranchingObject::CbcCutBranchingObject (CbcModel * model,
    137                                               OsiRowCut & down,
    138                                               OsiRowCut &up,
    139                                               bool canFix)
    140   :CbcBranchingObject(model,0,-1,0.0)
    141 {
    142   down_ = down;
    143   up_ = up;
    144   canFix_ = canFix;
    145 }
    146 
    147 // Copy constructor
    148 CbcCutBranchingObject::CbcCutBranchingObject ( const CbcCutBranchingObject & rhs) :CbcBranchingObject(rhs)
    149 {
    150   down_ = rhs.down_;
    151   up_ = rhs.up_;
    152   canFix_ = rhs.canFix_;
    153 }
    154 
    155 // Assignment operator
    156 CbcCutBranchingObject &
    157 CbcCutBranchingObject::operator=( const CbcCutBranchingObject& rhs)
    158 {
    159   if (this != &rhs) {
    160     CbcBranchingObject::operator=(rhs);
     138CbcCutBranchingObject::CbcCutBranchingObject (CbcModel * model,
     139        OsiRowCut & down,
     140        OsiRowCut &up,
     141        bool canFix)
     142        : CbcBranchingObject(model, 0, -1, 0.0)
     143{
     144    down_ = down;
     145    up_ = up;
     146    canFix_ = canFix;
     147}
     148
     149// Copy constructor
     150CbcCutBranchingObject::CbcCutBranchingObject ( const CbcCutBranchingObject & rhs) : CbcBranchingObject(rhs)
     151{
    161152    down_ = rhs.down_;
    162153    up_ = rhs.up_;
    163154    canFix_ = rhs.canFix_;
    164   }
    165   return *this;
    166 }
    167 CbcBranchingObject *
     155}
     156
     157// Assignment operator
     158CbcCutBranchingObject &
     159CbcCutBranchingObject::operator=( const CbcCutBranchingObject & rhs)
     160{
     161    if (this != &rhs) {
     162        CbcBranchingObject::operator=(rhs);
     163        down_ = rhs.down_;
     164        up_ = rhs.up_;
     165        canFix_ = rhs.canFix_;
     166    }
     167    return *this;
     168}
     169CbcBranchingObject *
    168170CbcCutBranchingObject::clone() const
    169 { 
    170   return (new CbcCutBranchingObject(*this));
    171 }
    172 
    173 
    174 // Destructor 
     171{
     172    return (new CbcCutBranchingObject(*this));
     173}
     174
     175
     176// Destructor
    175177CbcCutBranchingObject::~CbcCutBranchingObject ()
    176178{
     
    187189CbcCutBranchingObject::branch()
    188190{
    189   decrementNumberBranchesLeft();
    190   OsiRowCut * cut;
    191   if (way_<0) {
    192     cut = &down_;
    193     way_=1;
    194   } else {
    195     cut = &up_;
    196     way_=-1;      // Swap direction
    197   }
    198   printf("CUT %s ",(way_==-1) ? "up" : "down");
    199   cut->print();
    200   // See if cut just fixes variables
    201   double lb = cut->lb();
    202   double ub = cut->ub();
    203   int n=cut->row().getNumElements();
    204   const int * column = cut->row().getIndices();
    205   const double * element = cut->row().getElements();
    206   OsiSolverInterface * solver = model_->solver();
    207   const double * upper = solver->getColUpper();
    208   const double * lower = solver->getColLower();
    209   double low = 0.0;
    210   double high=0.0;
    211   for (int i=0;i<n;i++) {
    212     int iColumn = column[i];
    213     double value = element[i];
    214     if (value>0.0) {
    215       high += upper[iColumn]*value;
    216       low += lower[iColumn]*value;
     191    decrementNumberBranchesLeft();
     192    OsiRowCut * cut;
     193    if (way_ < 0) {
     194        cut = &down_;
     195        way_ = 1;
    217196    } else {
    218       high += lower[iColumn]*value;
    219       low += upper[iColumn]*value;
    220     }
    221   }
    222   // leave as cut
    223   //model_->setNextRowCut(*cut);
    224   //return 0.0;
    225   // assume cut was cunningly constructed so we need not worry too much about tolerances
    226   if (low+1.0e-8>=ub&&canFix_) {
    227     // fix
    228     for (int i=0;i<n;i++) {
    229       int iColumn = column[i];
    230       double value = element[i];
    231       if (value>0.0) {
    232         solver->setColUpper(iColumn,lower[iColumn]);
    233       } else {
    234         solver->setColLower(iColumn,upper[iColumn]);
    235       }
    236     }
    237   } else if (high-1.0e-8<=lb&&canFix_) {
    238     // fix
    239     for (int i=0;i<n;i++) {
    240       int iColumn = column[i];
    241       double value = element[i];
    242       if (value>0.0) {
    243         solver->setColLower(iColumn,upper[iColumn]);
    244       } else {
    245         solver->setColUpper(iColumn,lower[iColumn]);
    246       }
    247     }
    248   } else {
     197        cut = &up_;
     198        way_ = -1;        // Swap direction
     199    }
     200    printf("CUT %s ", (way_ == -1) ? "up" : "down");
     201    cut->print();
     202    // See if cut just fixes variables
     203    double lb = cut->lb();
     204    double ub = cut->ub();
     205    int n = cut->row().getNumElements();
     206    const int * column = cut->row().getIndices();
     207    const double * element = cut->row().getElements();
     208    OsiSolverInterface * solver = model_->solver();
     209    const double * upper = solver->getColUpper();
     210    const double * lower = solver->getColLower();
     211    double low = 0.0;
     212    double high = 0.0;
     213    for (int i = 0; i < n; i++) {
     214        int iColumn = column[i];
     215        double value = element[i];
     216        if (value > 0.0) {
     217            high += upper[iColumn] * value;
     218            low += lower[iColumn] * value;
     219        } else {
     220            high += lower[iColumn] * value;
     221            low += upper[iColumn] * value;
     222        }
     223    }
    249224    // leave as cut
    250     model_->setNextRowCut(*cut);
    251   }
    252   return 0.0;
    253 }
    254 // Print what would happen 
     225    //model_->setNextRowCut(*cut);
     226    //return 0.0;
     227    // assume cut was cunningly constructed so we need not worry too much about tolerances
     228    if (low + 1.0e-8 >= ub && canFix_) {
     229        // fix
     230        for (int i = 0; i < n; i++) {
     231            int iColumn = column[i];
     232            double value = element[i];
     233            if (value > 0.0) {
     234                solver->setColUpper(iColumn, lower[iColumn]);
     235            } else {
     236                solver->setColLower(iColumn, upper[iColumn]);
     237            }
     238        }
     239    } else if (high - 1.0e-8 <= lb && canFix_) {
     240        // fix
     241        for (int i = 0; i < n; i++) {
     242            int iColumn = column[i];
     243            double value = element[i];
     244            if (value > 0.0) {
     245                solver->setColLower(iColumn, upper[iColumn]);
     246            } else {
     247                solver->setColUpper(iColumn, lower[iColumn]);
     248            }
     249        }
     250    } else {
     251        // leave as cut
     252        model_->setNextRowCut(*cut);
     253    }
     254    return 0.0;
     255}
     256// Print what would happen
    255257void
    256258CbcCutBranchingObject::print()
    257259{
    258   OsiRowCut * cut;
    259   if (way_<0) {
    260     cut = &down_;
    261     printf("CbcCut would branch down");
    262   } else {
    263     cut = &up_;
    264     printf("CbcCut would branch up");
    265   }
    266   double lb = cut->lb();
    267   double ub = cut->ub();
    268   int n=cut->row().getNumElements();
    269   const int * column = cut->row().getIndices();
    270   const double * element = cut->row().getElements();
    271   if (n>5) {
    272     printf(" - %d elements, lo=%g, up=%g\n",n,lb,ub);
    273   } else {
    274     printf(" - %g <=",lb);
    275     for (int i=0;i<n;i++) {
    276       int iColumn = column[i];
    277       double value = element[i];
    278       printf(" (%d,%g)",iColumn,value);
    279     }
    280     printf(" <= %g\n",ub);
    281   }
     260    OsiRowCut * cut;
     261    if (way_ < 0) {
     262        cut = &down_;
     263        printf("CbcCut would branch down");
     264    } else {
     265        cut = &up_;
     266        printf("CbcCut would branch up");
     267    }
     268    double lb = cut->lb();
     269    double ub = cut->ub();
     270    int n = cut->row().getNumElements();
     271    const int * column = cut->row().getIndices();
     272    const double * element = cut->row().getElements();
     273    if (n > 5) {
     274        printf(" - %d elements, lo=%g, up=%g\n", n, lb, ub);
     275    } else {
     276        printf(" - %g <=", lb);
     277        for (int i = 0; i < n; i++) {
     278            int iColumn = column[i];
     279            double value = element[i];
     280            printf(" (%d,%g)", iColumn, value);
     281        }
     282        printf(" <= %g\n", ub);
     283    }
    282284}
    283285
    284286// Return true if branch should fix variables
    285 bool 
     287bool
    286288CbcCutBranchingObject::boundBranch() const
    287289{
    288   return false;
     290    return false;
    289291}
    290292
     
    292294    brObj. Assumes that there is an ordering of the original objects.
    293295    This method should be invoked only if \c this and brObj are of the same
    294     type. 
     296    type.
    295297    Return negative/0/positive depending on whether \c this is
    296298    smaller/same/larger than the argument.
     
    300302(const CbcBranchingObject* brObj) const
    301303{
    302   const CbcCutBranchingObject* br =
    303     dynamic_cast<const CbcCutBranchingObject*>(brObj);
    304   assert(br);
    305   const OsiRowCut& r0 = way_ == -1 ? down_ : up_;
    306   const OsiRowCut& r1 = br->way_ == -1 ? br->down_ : br->up_;
    307   return r0.row().compare(r1.row());
     304    const CbcCutBranchingObject* br =
     305        dynamic_cast<const CbcCutBranchingObject*>(brObj);
     306    assert(br);
     307    const OsiRowCut& r0 = way_ == -1 ? down_ : up_;
     308    const OsiRowCut& r1 = br->way_ == -1 ? br->down_ : br->up_;
     309    return r0.row().compare(r1.row());
    308310}
    309311
     
    321323(const CbcBranchingObject* brObj, const bool replaceIfOverlap)
    322324{
    323   const CbcCutBranchingObject* br =
    324     dynamic_cast<const CbcCutBranchingObject*>(brObj);
    325   assert(br);
    326   OsiRowCut& r0 = way_ == -1 ? down_ : up_;
    327   const OsiRowCut& r1 = br->way_ == -1 ? br->down_ : br->up_;
    328   double thisBd[2];
    329   thisBd[0] = r0.lb();
    330   thisBd[1] = r0.ub();
    331   double otherBd[2];
    332   otherBd[0] = r1.lb();
    333   otherBd[1] = r1.ub();
    334   CbcRangeCompare comp = CbcCompareRanges(thisBd, otherBd, replaceIfOverlap);
    335   if (comp != CbcRangeOverlap || (comp==CbcRangeOverlap && !replaceIfOverlap)) {
     325    const CbcCutBranchingObject* br =
     326        dynamic_cast<const CbcCutBranchingObject*>(brObj);
     327    assert(br);
     328    OsiRowCut& r0 = way_ == -1 ? down_ : up_;
     329    const OsiRowCut& r1 = br->way_ == -1 ? br->down_ : br->up_;
     330    double thisBd[2];
     331    thisBd[0] = r0.lb();
     332    thisBd[1] = r0.ub();
     333    double otherBd[2];
     334    otherBd[0] = r1.lb();
     335    otherBd[1] = r1.ub();
     336    CbcRangeCompare comp = CbcCompareRanges(thisBd, otherBd, replaceIfOverlap);
     337    if (comp != CbcRangeOverlap || (comp == CbcRangeOverlap && !replaceIfOverlap)) {
     338        return comp;
     339    }
     340    r0.setLb(thisBd[0]);
     341    r0.setUb(thisBd[1]);
    336342    return comp;
    337   }
    338   r0.setLb(thisBd[0]);
    339   r0.setUb(thisBd[1]);
    340   return comp;
    341343}
    342344
     
    348350*/
    349351CbcBranchToFixLots::CbcBranchToFixLots ()
    350   : CbcBranchCut(),
    351     djTolerance_(COIN_DBL_MAX),
    352     fractionFixed_(1.0),
    353     mark_(NULL),
    354     depth_(-1),
    355     numberClean_(0),
    356     alwaysCreate_(false)
     352        : CbcBranchCut(),
     353        djTolerance_(COIN_DBL_MAX),
     354        fractionFixed_(1.0),
     355        mark_(NULL),
     356        depth_(-1),
     357        numberClean_(0),
     358        alwaysCreate_(false)
    357359{
    358360}
     
    363365   Always does if all 1 rows cleaned up and number>0 or if fraction columns reached
    364366   Also whether to create branch if can't reach fraction.
    365 */ 
     367*/
    366368CbcBranchToFixLots::CbcBranchToFixLots (CbcModel * model, double djTolerance,
    367                                         double fractionFixed, int depth,
    368                                         int numberClean,
    369                                         const char * mark, bool alwaysCreate)
    370   : CbcBranchCut(model)
    371 {
    372   djTolerance_ = djTolerance;
    373   fractionFixed_ = fractionFixed;
    374   if (mark) {
    375     int numberColumns = model->getNumCols();
    376     mark_ = new char[numberColumns];
    377     memcpy(mark_,mark,numberColumns);
    378   } else {
    379     mark_ = NULL;
    380   }
    381   depth_ = depth;
    382   assert (model);
    383   OsiSolverInterface * solver = model_->solver();
    384   matrixByRow_ = *solver->getMatrixByRow();
    385   numberClean_ = numberClean;
    386   alwaysCreate_ = alwaysCreate;
    387 }
    388 // Copy constructor 
     369                                        double fractionFixed, int depth,
     370                                        int numberClean,
     371                                        const char * mark, bool alwaysCreate)
     372        : CbcBranchCut(model)
     373{
     374    djTolerance_ = djTolerance;
     375    fractionFixed_ = fractionFixed;
     376    if (mark) {
     377        int numberColumns = model->getNumCols();
     378        mark_ = new char[numberColumns];
     379        memcpy(mark_, mark, numberColumns);
     380    } else {
     381        mark_ = NULL;
     382    }
     383    depth_ = depth;
     384    assert (model);
     385    OsiSolverInterface * solver = model_->solver();
     386    matrixByRow_ = *solver->getMatrixByRow();
     387    numberClean_ = numberClean;
     388    alwaysCreate_ = alwaysCreate;
     389}
     390// Copy constructor
    389391CbcBranchToFixLots::CbcBranchToFixLots ( const CbcBranchToFixLots & rhs)
    390   :CbcBranchCut(rhs)
    391 {
    392   djTolerance_ = rhs.djTolerance_;
    393   fractionFixed_ = rhs.fractionFixed_;
    394   int numberColumns = model_->getNumCols();
    395   mark_ = CoinCopyOfArray(rhs.mark_,numberColumns);
    396   matrixByRow_=rhs.matrixByRow_;
    397   depth_ = rhs.depth_;
    398   numberClean_ = rhs.numberClean_;
    399   alwaysCreate_ = rhs.alwaysCreate_;
     392        : CbcBranchCut(rhs)
     393{
     394    djTolerance_ = rhs.djTolerance_;
     395    fractionFixed_ = rhs.fractionFixed_;
     396    int numberColumns = model_->getNumCols();
     397    mark_ = CoinCopyOfArray(rhs.mark_, numberColumns);
     398    matrixByRow_ = rhs.matrixByRow_;
     399    depth_ = rhs.depth_;
     400    numberClean_ = rhs.numberClean_;
     401    alwaysCreate_ = rhs.alwaysCreate_;
    400402}
    401403
     
    404406CbcBranchToFixLots::clone() const
    405407{
    406   return new CbcBranchToFixLots(*this);
    407 }
    408 
    409 // Assignment operator
    410 CbcBranchToFixLots &
    411 CbcBranchToFixLots::operator=( const CbcBranchToFixLots& rhs)
    412 {
    413   if (this!=&rhs) {
    414     CbcBranchCut::operator=(rhs);
    415     djTolerance_ = rhs.djTolerance_;
    416     fractionFixed_ = rhs.fractionFixed_;
    417     int numberColumns = model_->getNumCols();
     408    return new CbcBranchToFixLots(*this);
     409}
     410
     411// Assignment operator
     412CbcBranchToFixLots &
     413CbcBranchToFixLots::operator=( const CbcBranchToFixLots & rhs)
     414{
     415    if (this != &rhs) {
     416        CbcBranchCut::operator=(rhs);
     417        djTolerance_ = rhs.djTolerance_;
     418        fractionFixed_ = rhs.fractionFixed_;
     419        int numberColumns = model_->getNumCols();
     420        delete [] mark_;
     421        mark_ = CoinCopyOfArray(rhs.mark_, numberColumns);
     422        matrixByRow_ = rhs.matrixByRow_;
     423        depth_ = rhs.depth_;
     424        numberClean_ = rhs.numberClean_;
     425        alwaysCreate_ = rhs.alwaysCreate_;
     426    }
     427    return *this;
     428}
     429
     430// Destructor
     431CbcBranchToFixLots::~CbcBranchToFixLots ()
     432{
    418433    delete [] mark_;
    419     mark_ = CoinCopyOfArray(rhs.mark_,numberColumns);
    420     matrixByRow_=rhs.matrixByRow_;
    421     depth_ = rhs.depth_;
    422     numberClean_ = rhs.numberClean_;
    423     alwaysCreate_ = rhs.alwaysCreate_;
    424   }
    425   return *this;
    426 }
    427 
    428 // Destructor
    429 CbcBranchToFixLots::~CbcBranchToFixLots ()
    430 {
    431   delete [] mark_;
    432 }
    433 CbcBranchingObject *
    434 CbcBranchToFixLots::createCbcBranch(OsiSolverInterface * solver,const OsiBranchingInformation * /*info*/, int /*way*/)
    435 {
    436   // by default way must be -1
    437   //assert (way==-1);
    438   //OsiSolverInterface * solver = model_->solver();
    439   const double * solution = model_->testSolution();
    440   const double * lower = solver->getColLower();
    441   const double * upper = solver->getColUpper();
    442   const double * dj = solver->getReducedCost();
    443   int i;
    444   int numberIntegers = model_->numberIntegers();
    445   const int * integerVariable = model_->integerVariable();
    446   double integerTolerance =
    447     model_->getDblParam(CbcModel::CbcIntegerTolerance);
    448   // make smaller ?
    449   double tolerance = CoinMin(1.0e-8,integerTolerance);
    450   // How many fixed are we aiming at
    451   int wantedFixed = static_cast<int> (static_cast<double>(numberIntegers)*fractionFixed_);
    452   int nSort=0;
    453   int numberFixed=0;
    454   int numberColumns = solver->getNumCols();
    455   int * sort = new int[numberColumns];
    456   double * dsort = new double[numberColumns];
    457   if (djTolerance_!=-1.234567) {
    458     int type = shallWe();
    459     assert (type);
    460     // Take clean first
    461     if (type==1) {
    462       for (i=0;i<numberIntegers;i++) {
    463         int iColumn = integerVariable[i];
    464         if (upper[iColumn]>lower[iColumn]) {
    465           if (!mark_||!mark_[iColumn]) {
    466             if(solution[iColumn]<lower[iColumn]+tolerance) {
    467               if (dj[iColumn]>djTolerance_) {
    468                 dsort[nSort]=-dj[iColumn];
    469                 sort[nSort++]=iColumn;
    470               }
    471             } else if (solution[iColumn]>upper[iColumn]-tolerance) {
    472               if (dj[iColumn]<-djTolerance_) {
    473                 dsort[nSort]=dj[iColumn];
    474                 sort[nSort++]=iColumn;
    475               }
    476             }
    477           }
    478         } else {
    479           numberFixed++;
    480         }
    481       }
    482       // sort
    483       CoinSort_2(dsort,dsort+nSort,sort);
    484       nSort= CoinMin(nSort,wantedFixed-numberFixed);
    485     } else if (type<10) {
    486       int i;
    487       //const double * rowLower = solver->getRowLower();
    488       const double * rowUpper = solver->getRowUpper();
    489       // Row copy
    490       const double * elementByRow = matrixByRow_.getElements();
    491       const int * column = matrixByRow_.getIndices();
    492       const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
    493       const int * rowLength = matrixByRow_.getVectorLengths();
    494       const double * columnLower = solver->getColLower();
    495       const double * columnUpper = solver->getColUpper();
    496       const double * solution = solver->getColSolution();
    497       int numberColumns = solver->getNumCols();
    498       int numberRows = solver->getNumRows();
    499       for (i=0;i<numberColumns;i++) {
    500         sort[i]=i;
    501         if (columnLower[i]!=columnUpper[i]){
    502           dsort[i]=1.0e100;
    503         } else {
    504           dsort[i]=1.0e50;
    505           numberFixed++;
    506         }
    507       }
    508       for (i=0;i<numberRows;i++) {
    509         double rhsValue = rowUpper[i];
    510         bool oneRow=true;
    511         // check elements
    512         int numberUnsatisfied=0;
    513         for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
    514           int iColumn = column[j];
    515           double value = elementByRow[j];
    516           double solValue = solution[iColumn];
    517           if (columnLower[iColumn]!=columnUpper[iColumn]) {
    518             if (solValue<1.0-integerTolerance&&solValue>integerTolerance)
    519               numberUnsatisfied++;
    520             if (value!=1.0) {
    521               oneRow=false;
    522               break;
    523             }
    524           } else {
    525             rhsValue -= value*floor(solValue+0.5);
    526           }
    527         }
    528         if (oneRow&&rhsValue<=1.0+tolerance) {
    529           if (!numberUnsatisfied) {
    530             for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
    531               int iColumn = column[j];
    532               if (dsort[iColumn]>1.0e50){
    533                 dsort[iColumn]=0;
    534                 nSort++;
    535               }
    536             }
    537           }
    538         }
    539       }
    540       // sort
    541       CoinSort_2(dsort,dsort+numberColumns,sort);
     434}
     435CbcBranchingObject *
     436CbcBranchToFixLots::createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * /*info*/, int /*way*/)
     437{
     438    // by default way must be -1
     439    //assert (way==-1);
     440    //OsiSolverInterface * solver = model_->solver();
     441    const double * solution = model_->testSolution();
     442    const double * lower = solver->getColLower();
     443    const double * upper = solver->getColUpper();
     444    const double * dj = solver->getReducedCost();
     445    int i;
     446    int numberIntegers = model_->numberIntegers();
     447    const int * integerVariable = model_->integerVariable();
     448    double integerTolerance =
     449        model_->getDblParam(CbcModel::CbcIntegerTolerance);
     450    // make smaller ?
     451    double tolerance = CoinMin(1.0e-8, integerTolerance);
     452    // How many fixed are we aiming at
     453    int wantedFixed = static_cast<int> (static_cast<double>(numberIntegers) * fractionFixed_);
     454    int nSort = 0;
     455    int numberFixed = 0;
     456    int numberColumns = solver->getNumCols();
     457    int * sort = new int[numberColumns];
     458    double * dsort = new double[numberColumns];
     459    if (djTolerance_ != -1.234567) {
     460        int type = shallWe();
     461        assert (type);
     462        // Take clean first
     463        if (type == 1) {
     464            for (i = 0; i < numberIntegers; i++) {
     465                int iColumn = integerVariable[i];
     466                if (upper[iColumn] > lower[iColumn]) {
     467                    if (!mark_ || !mark_[iColumn]) {
     468                        if (solution[iColumn] < lower[iColumn] + tolerance) {
     469                            if (dj[iColumn] > djTolerance_) {
     470                                dsort[nSort] = -dj[iColumn];
     471                                sort[nSort++] = iColumn;
     472                            }
     473                        } else if (solution[iColumn] > upper[iColumn] - tolerance) {
     474                            if (dj[iColumn] < -djTolerance_) {
     475                                dsort[nSort] = dj[iColumn];
     476                                sort[nSort++] = iColumn;
     477                            }
     478                        }
     479                    }
     480                } else {
     481                    numberFixed++;
     482                }
     483            }
     484            // sort
     485            CoinSort_2(dsort, dsort + nSort, sort);
     486            nSort = CoinMin(nSort, wantedFixed - numberFixed);
     487        } else if (type < 10) {
     488            int i;
     489            //const double * rowLower = solver->getRowLower();
     490            const double * rowUpper = solver->getRowUpper();
     491            // Row copy
     492            const double * elementByRow = matrixByRow_.getElements();
     493            const int * column = matrixByRow_.getIndices();
     494            const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
     495            const int * rowLength = matrixByRow_.getVectorLengths();
     496            const double * columnLower = solver->getColLower();
     497            const double * columnUpper = solver->getColUpper();
     498            const double * solution = solver->getColSolution();
     499            int numberColumns = solver->getNumCols();
     500            int numberRows = solver->getNumRows();
     501            for (i = 0; i < numberColumns; i++) {
     502                sort[i] = i;
     503                if (columnLower[i] != columnUpper[i]) {
     504                    dsort[i] = 1.0e100;
     505                } else {
     506                    dsort[i] = 1.0e50;
     507                    numberFixed++;
     508                }
     509            }
     510            for (i = 0; i < numberRows; i++) {
     511                double rhsValue = rowUpper[i];
     512                bool oneRow = true;
     513                // check elements
     514                int numberUnsatisfied = 0;
     515                for (int j = rowStart[i]; j < rowStart[i] + rowLength[i]; j++) {
     516                    int iColumn = column[j];
     517                    double value = elementByRow[j];
     518                    double solValue = solution[iColumn];
     519                    if (columnLower[iColumn] != columnUpper[iColumn]) {
     520                        if (solValue < 1.0 - integerTolerance && solValue > integerTolerance)
     521                            numberUnsatisfied++;
     522                        if (value != 1.0) {
     523                            oneRow = false;
     524                            break;
     525                        }
     526                    } else {
     527                        rhsValue -= value * floor(solValue + 0.5);
     528                    }
     529                }
     530                if (oneRow && rhsValue <= 1.0 + tolerance) {
     531                    if (!numberUnsatisfied) {
     532                        for (int j = rowStart[i]; j < rowStart[i] + rowLength[i]; j++) {
     533                            int iColumn = column[j];
     534                            if (dsort[iColumn] > 1.0e50) {
     535                                dsort[iColumn] = 0;
     536                                nSort++;
     537                            }
     538                        }
     539                    }
     540                }
     541            }
     542            // sort
     543            CoinSort_2(dsort, dsort + numberColumns, sort);
     544        } else {
     545            // new way
     546            for (i = 0; i < numberIntegers; i++) {
     547                int iColumn = integerVariable[i];
     548                if (upper[iColumn] > lower[iColumn]) {
     549                    if (!mark_ || !mark_[iColumn]) {
     550                        double distanceDown = solution[iColumn] - lower[iColumn];
     551                        double distanceUp = upper[iColumn] - solution[iColumn];
     552                        double distance = CoinMin(distanceDown, distanceUp);
     553                        if (distance > 0.001 && distance < 0.5) {
     554                            dsort[nSort] = distance;
     555                            sort[nSort++] = iColumn;
     556                        }
     557                    }
     558                }
     559            }
     560            // sort
     561            CoinSort_2(dsort, dsort + nSort, sort);
     562            int n = 0;
     563            double sum = 0.0;
     564            for (int k = 0; k < nSort; k++) {
     565                sum += dsort[k];
     566                if (sum <= djTolerance_)
     567                    n = k;
     568                else
     569                    break;
     570            }
     571            nSort = CoinMin(n, numberClean_ / 1000000);
     572        }
    542573    } else {
    543       // new way
    544       for (i=0;i<numberIntegers;i++) {
    545         int iColumn = integerVariable[i];
    546         if (upper[iColumn]>lower[iColumn]) {
    547           if (!mark_||!mark_[iColumn]) {
    548             double distanceDown=solution[iColumn]-lower[iColumn];
    549             double distanceUp=upper[iColumn]-solution[iColumn];
    550             double distance = CoinMin(distanceDown,distanceUp);
    551             if (distance>0.001&&distance<0.5) {
    552               dsort[nSort]=distance;
    553               sort[nSort++]=iColumn;
    554             }
    555           }
    556         }
    557       }
    558       // sort
    559       CoinSort_2(dsort,dsort+nSort,sort);
    560       int n=0;
    561       double sum=0.0;
    562       for (int k=0;k<nSort;k++) {
    563         sum += dsort[k];
    564         if (sum<=djTolerance_)
    565           n=k;
    566         else
    567           break;
    568       }
    569       nSort = CoinMin(n,numberClean_/1000000);
    570     }
    571   } else {
    572574#define FIX_IF_LESS -0.1
    573     // 3 in same row and sum <FIX_IF_LESS?
    574     int numberRows = matrixByRow_.getNumRows();
    575     const double * solution = model_->testSolution();
    576     const int * column = matrixByRow_.getIndices();
    577     const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
    578     const int * rowLength = matrixByRow_.getVectorLengths();
    579     double bestSum=1.0;
    580     int nBest=-1;
    581     int kRow=-1;
    582     OsiSolverInterface * solver = model_->solver();
    583     for (int i=0;i<numberRows;i++) {
    584       int numberUnsatisfied=0;
    585       double sum=0.0;
    586       for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
    587         int iColumn = column[j];
    588         if (solver->isInteger(iColumn)) {
    589           double solValue = solution[iColumn];
    590           if (solValue>1.0e-5&&solValue<FIX_IF_LESS) {
    591             numberUnsatisfied++;
    592             sum += solValue;
    593           }
    594         }
    595       }
    596       if (numberUnsatisfied>=3&&sum<FIX_IF_LESS) {
    597         // possible
    598         if (numberUnsatisfied>nBest||
    599             (numberUnsatisfied==nBest&&sum<bestSum)) {
    600           nBest=numberUnsatisfied;
    601           bestSum=sum;
    602           kRow=i;
    603         }
    604       }
    605     }
    606     assert (nBest>0);
    607     for (int j=rowStart[kRow];j<rowStart[kRow]+rowLength[kRow];j++) {
    608       int iColumn = column[j];
    609       if (solver->isInteger(iColumn)) {
    610         double solValue = solution[iColumn];
    611         if (solValue>1.0e-5&&solValue<FIX_IF_LESS) {
    612           sort[nSort++]=iColumn;
    613         }
    614       }
    615     }
    616   }
    617   OsiRowCut down;
    618   down.setLb(-COIN_DBL_MAX);
    619   double rhs=0.0;
    620   for (i=0;i<nSort;i++) {
    621     int iColumn = sort[i];
    622     double distanceDown=solution[iColumn]-lower[iColumn];
    623     double distanceUp=upper[iColumn]-solution[iColumn];
    624     if(distanceDown<distanceUp) {
    625       rhs += lower[iColumn];
    626       dsort[i]=1.0;
    627     } else {
    628       rhs -= upper[iColumn];
    629       dsort[i]=-1.0;
    630     }
    631   }
    632   down.setUb(rhs);
    633   down.setRow(nSort,sort,dsort);
    634   down.setEffectiveness(COIN_DBL_MAX); // so will persist
    635   delete [] sort;
    636   delete [] dsort;
    637   // up is same - just with rhs changed
    638   OsiRowCut up = down;
    639   up.setLb(rhs +1.0);
    640   up.setUb(COIN_DBL_MAX);
    641   // Say can fix one way
    642   CbcCutBranchingObject * newObject =
    643     new CbcCutBranchingObject(model_,down,up,true);
    644   if (model_->messageHandler()->logLevel()>1)
    645     printf("creating cut in CbcBranchCut\n");
    646   return newObject;
     575        // 3 in same row and sum <FIX_IF_LESS?
     576        int numberRows = matrixByRow_.getNumRows();
     577        const double * solution = model_->testSolution();
     578        const int * column = matrixByRow_.getIndices();
     579        const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
     580        const int * rowLength = matrixByRow_.getVectorLengths();
     581        double bestSum = 1.0;
     582        int nBest = -1;
     583        int kRow = -1;
     584        OsiSolverInterface * solver = model_->solver();
     585        for (int i = 0; i < numberRows; i++) {
     586            int numberUnsatisfied = 0;
     587            double sum = 0.0;
     588            for (int j = rowStart[i]; j < rowStart[i] + rowLength[i]; j++) {
     589                int iColumn = column[j];
     590                if (solver->isInteger(iColumn)) {
     591                    double solValue = solution[iColumn];
     592                    if (solValue > 1.0e-5 && solValue < FIX_IF_LESS) {
     593                        numberUnsatisfied++;
     594                        sum += solValue;
     595                    }
     596                }
     597            }
     598            if (numberUnsatisfied >= 3 && sum < FIX_IF_LESS) {
     599                // possible
     600                if (numberUnsatisfied > nBest ||
     601                        (numberUnsatisfied == nBest && sum < bestSum)) {
     602                    nBest = numberUnsatisfied;
     603                    bestSum = sum;
     604                    kRow = i;
     605                }
     606            }
     607        }
     608        assert (nBest > 0);
     609        for (int j = rowStart[kRow]; j < rowStart[kRow] + rowLength[kRow]; j++) {
     610            int iColumn = column[j];
     611            if (solver->isInteger(iColumn)) {
     612                double solValue = solution[iColumn];
     613                if (solValue > 1.0e-5 && solValue < FIX_IF_LESS) {
     614                    sort[nSort++] = iColumn;
     615                }
     616            }
     617        }
     618    }
     619    OsiRowCut down;
     620    down.setLb(-COIN_DBL_MAX);
     621    double rhs = 0.0;
     622    for (i = 0; i < nSort; i++) {
     623        int iColumn = sort[i];
     624        double distanceDown = solution[iColumn] - lower[iColumn];
     625        double distanceUp = upper[iColumn] - solution[iColumn];
     626        if (distanceDown < distanceUp) {
     627            rhs += lower[iColumn];
     628            dsort[i] = 1.0;
     629        } else {
     630            rhs -= upper[iColumn];
     631            dsort[i] = -1.0;
     632        }
     633    }
     634    down.setUb(rhs);
     635    down.setRow(nSort, sort, dsort);
     636    down.setEffectiveness(COIN_DBL_MAX); // so will persist
     637    delete [] sort;
     638    delete [] dsort;
     639    // up is same - just with rhs changed
     640    OsiRowCut up = down;
     641    up.setLb(rhs + 1.0);
     642    up.setUb(COIN_DBL_MAX);
     643    // Say can fix one way
     644    CbcCutBranchingObject * newObject =
     645        new CbcCutBranchingObject(model_, down, up, true);
     646    if (model_->messageHandler()->logLevel() > 1)
     647        printf("creating cut in CbcBranchCut\n");
     648    return newObject;
    647649}
    648650/* Does a lot of the work,
     
    650652   10 if branching on ones away from bound
    651653*/
    652 int 
     654int
    653655CbcBranchToFixLots::shallWe() const
    654656{
    655   int returnCode=0;
    656   OsiSolverInterface * solver = model_->solver();
    657   int numberRows = matrixByRow_.getNumRows();
    658   //if (numberRows!=solver->getNumRows())
    659   //return 0;
    660   const double * solution = model_->testSolution();
    661   const double * lower = solver->getColLower();
    662   const double * upper = solver->getColUpper();
    663   const double * dj = solver->getReducedCost();
    664   int i;
    665   int numberIntegers = model_->numberIntegers();
    666   const int * integerVariable = model_->integerVariable();
    667   if (numberClean_>1000000) {
    668     int wanted = numberClean_%1000000;
    669     int * sort = new int[numberIntegers];
    670     double * dsort = new double[numberIntegers];
    671     int nSort=0;
    672     for (i=0;i<numberIntegers;i++) {
    673       int iColumn = integerVariable[i];
    674       if (upper[iColumn]>lower[iColumn]) {
    675         if (!mark_||!mark_[iColumn]) {
    676           double distanceDown=solution[iColumn]-lower[iColumn];
    677           double distanceUp=upper[iColumn]-solution[iColumn];
    678           double distance = CoinMin(distanceDown,distanceUp);
    679           if (distance>0.001&&distance<0.5) {
    680             dsort[nSort]=distance;
    681             sort[nSort++]=iColumn;
    682           }
    683         }
    684       }
    685     }
    686     // sort
    687     CoinSort_2(dsort,dsort+nSort,sort);
    688     int n=0;
    689     double sum=0.0;
    690     for (int k=0;k<nSort;k++) {
    691       sum += dsort[k];
    692       if (sum<=djTolerance_)
    693         n=k;
    694       else
    695         break;
    696     }
    697     delete [] sort;
    698     delete [] dsort;
    699     return (n>=wanted) ? 10 : 0;
    700   }
    701   double integerTolerance =
    702     model_->getDblParam(CbcModel::CbcIntegerTolerance);
    703   // make smaller ?
    704   double tolerance = CoinMin(1.0e-8,integerTolerance);
    705   // How many fixed are we aiming at
    706   int wantedFixed = static_cast<int> (static_cast<double>(numberIntegers)*fractionFixed_);
    707   if (djTolerance_<1.0e10) {
    708     int nSort=0;
    709     int numberFixed=0;
    710     for (i=0;i<numberIntegers;i++) {
    711       int iColumn = integerVariable[i];
    712       if (upper[iColumn]>lower[iColumn]) {
    713         if (!mark_||!mark_[iColumn]) {
    714           if(solution[iColumn]<lower[iColumn]+tolerance) {
    715             if (dj[iColumn]>djTolerance_) {
    716               nSort++;
    717             }
    718           } else if (solution[iColumn]>upper[iColumn]-tolerance) {
    719             if (dj[iColumn]<-djTolerance_) {
    720               nSort++;
    721             }
    722           }
    723         }
    724       } else {
    725         numberFixed++;
    726       }
    727     }
    728     if (numberFixed+nSort<wantedFixed&&!alwaysCreate_) {
    729       returnCode = 0;
    730     } else if (numberFixed<wantedFixed) {
    731       returnCode = 1;
     657    int returnCode = 0;
     658    OsiSolverInterface * solver = model_->solver();
     659    int numberRows = matrixByRow_.getNumRows();
     660    //if (numberRows!=solver->getNumRows())
     661    //return 0;
     662    const double * solution = model_->testSolution();
     663    const double * lower = solver->getColLower();
     664    const double * upper = solver->getColUpper();
     665    const double * dj = solver->getReducedCost();
     666    int i;
     667    int numberIntegers = model_->numberIntegers();
     668    const int * integerVariable = model_->integerVariable();
     669    if (numberClean_ > 1000000) {
     670        int wanted = numberClean_ % 1000000;
     671        int * sort = new int[numberIntegers];
     672        double * dsort = new double[numberIntegers];
     673        int nSort = 0;
     674        for (i = 0; i < numberIntegers; i++) {
     675            int iColumn = integerVariable[i];
     676            if (upper[iColumn] > lower[iColumn]) {
     677                if (!mark_ || !mark_[iColumn]) {
     678                    double distanceDown = solution[iColumn] - lower[iColumn];
     679                    double distanceUp = upper[iColumn] - solution[iColumn];
     680                    double distance = CoinMin(distanceDown, distanceUp);
     681                    if (distance > 0.001 && distance < 0.5) {
     682                        dsort[nSort] = distance;
     683                        sort[nSort++] = iColumn;
     684                    }
     685                }
     686            }
     687        }
     688        // sort
     689        CoinSort_2(dsort, dsort + nSort, sort);
     690        int n = 0;
     691        double sum = 0.0;
     692        for (int k = 0; k < nSort; k++) {
     693            sum += dsort[k];
     694            if (sum <= djTolerance_)
     695                n = k;
     696            else
     697                break;
     698        }
     699        delete [] sort;
     700        delete [] dsort;
     701        return (n >= wanted) ? 10 : 0;
     702    }
     703    double integerTolerance =
     704        model_->getDblParam(CbcModel::CbcIntegerTolerance);
     705    // make smaller ?
     706    double tolerance = CoinMin(1.0e-8, integerTolerance);
     707    // How many fixed are we aiming at
     708    int wantedFixed = static_cast<int> (static_cast<double>(numberIntegers) * fractionFixed_);
     709    if (djTolerance_ < 1.0e10) {
     710        int nSort = 0;
     711        int numberFixed = 0;
     712        for (i = 0; i < numberIntegers; i++) {
     713            int iColumn = integerVariable[i];
     714            if (upper[iColumn] > lower[iColumn]) {
     715                if (!mark_ || !mark_[iColumn]) {
     716                    if (solution[iColumn] < lower[iColumn] + tolerance) {
     717                        if (dj[iColumn] > djTolerance_) {
     718                            nSort++;
     719                        }
     720                    } else if (solution[iColumn] > upper[iColumn] - tolerance) {
     721                        if (dj[iColumn] < -djTolerance_) {
     722                            nSort++;
     723                        }
     724                    }
     725                }
     726            } else {
     727                numberFixed++;
     728            }
     729        }
     730        if (numberFixed + nSort < wantedFixed && !alwaysCreate_) {
     731            returnCode = 0;
     732        } else if (numberFixed < wantedFixed) {
     733            returnCode = 1;
     734        } else {
     735            returnCode = 0;
     736        }
     737    }
     738    if (numberClean_) {
     739        // see how many rows clean
     740        int i;
     741        //const double * rowLower = solver->getRowLower();
     742        const double * rowUpper = solver->getRowUpper();
     743        // Row copy
     744        const double * elementByRow = matrixByRow_.getElements();
     745        const int * column = matrixByRow_.getIndices();
     746        const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
     747        const int * rowLength = matrixByRow_.getVectorLengths();
     748        const double * columnLower = solver->getColLower();
     749        const double * columnUpper = solver->getColUpper();
     750        const double * solution = solver->getColSolution();
     751        int numberClean = 0;
     752        bool someToDoYet = false;
     753        int numberColumns = solver->getNumCols();
     754        char * mark = new char[numberColumns];
     755        int numberFixed = 0;
     756        for (i = 0; i < numberColumns; i++) {
     757            if (columnLower[i] != columnUpper[i]) {
     758                mark[i] = 0;
     759            } else {
     760                mark[i] = 1;
     761                numberFixed++;
     762            }
     763        }
     764        int numberNewFixed = 0;
     765        for (i = 0; i < numberRows; i++) {
     766            double rhsValue = rowUpper[i];
     767            bool oneRow = true;
     768            // check elements
     769            int numberUnsatisfied = 0;
     770            for (int j = rowStart[i]; j < rowStart[i] + rowLength[i]; j++) {
     771                int iColumn = column[j];
     772                double value = elementByRow[j];
     773                double solValue = solution[iColumn];
     774                if (columnLower[iColumn] != columnUpper[iColumn]) {
     775                    if (solValue < 1.0 - integerTolerance && solValue > integerTolerance)
     776                        numberUnsatisfied++;
     777                    if (value != 1.0) {
     778                        oneRow = false;
     779                        break;
     780                    }
     781                } else {
     782                    rhsValue -= value * floor(solValue + 0.5);
     783                }
     784            }
     785            if (oneRow && rhsValue <= 1.0 + tolerance) {
     786                if (numberUnsatisfied) {
     787                    someToDoYet = true;
     788                } else {
     789                    numberClean++;
     790                    for (int j = rowStart[i]; j < rowStart[i] + rowLength[i]; j++) {
     791                        int iColumn = column[j];
     792                        if (columnLower[iColumn] != columnUpper[iColumn] && !mark[iColumn]) {
     793                            mark[iColumn] = 1;
     794                            numberNewFixed++;
     795                        }
     796                    }
     797                }
     798            }
     799        }
     800        delete [] mark;
     801        //printf("%d clean, %d old fixed, %d new fixed\n",
     802        //   numberClean,numberFixed,numberNewFixed);
     803        if (someToDoYet && numberClean < numberClean_
     804                && numberNewFixed + numberFixed < wantedFixed) {
     805        } else if (numberFixed < wantedFixed) {
     806            returnCode |= 2;
     807        } else {
     808        }
     809    }
     810    return returnCode;
     811}
     812double
     813CbcBranchToFixLots::infeasibility(const OsiBranchingInformation * /*info*/,
     814                                  int &preferredWay) const
     815{
     816    preferredWay = -1;
     817    CbcNode * node = model_->currentNode();
     818    int depth;
     819    if (node)
     820        depth = CoinMax(node->depth(), 0);
     821    else
     822        return 0.0;
     823    if (depth_ < 0) {
     824        return 0.0;
     825    } else if (depth_ > 0) {
     826        if ((depth % depth_) != 0)
     827            return 0.0;
     828    }
     829    if (djTolerance_ != -1.234567) {
     830        if (!shallWe())
     831            return 0.0;
     832        else
     833            return 1.0e20;
    732834    } else {
    733       returnCode = 0;
    734     }
    735   }
    736   if (numberClean_) {
    737     // see how many rows clean
    738     int i;
    739     //const double * rowLower = solver->getRowLower();
    740     const double * rowUpper = solver->getRowUpper();
    741     // Row copy
    742     const double * elementByRow = matrixByRow_.getElements();
    743     const int * column = matrixByRow_.getIndices();
    744     const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
    745     const int * rowLength = matrixByRow_.getVectorLengths();
    746     const double * columnLower = solver->getColLower();
    747     const double * columnUpper = solver->getColUpper();
    748     const double * solution = solver->getColSolution();
    749     int numberClean=0;
    750     bool someToDoYet=false;
    751     int numberColumns = solver->getNumCols();
    752     char * mark = new char[numberColumns];
    753     int numberFixed=0;
    754     for (i=0;i<numberColumns;i++) {
    755       if (columnLower[i]!=columnUpper[i]){
    756         mark[i]=0;
    757       } else {
    758         mark[i]=1;
    759         numberFixed++;
    760       }
    761     }
    762     int numberNewFixed=0;
    763     for (i=0;i<numberRows;i++) {
    764       double rhsValue = rowUpper[i];
    765       bool oneRow=true;
    766       // check elements
    767       int numberUnsatisfied=0;
    768       for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
    769         int iColumn = column[j];
    770         double value = elementByRow[j];
    771         double solValue = solution[iColumn];
    772         if (columnLower[iColumn]!=columnUpper[iColumn]) {
    773           if (solValue<1.0-integerTolerance&&solValue>integerTolerance)
    774             numberUnsatisfied++;
    775           if (value!=1.0) {
    776             oneRow=false;
    777             break;
    778           }
    779         } else {
    780           rhsValue -= value*floor(solValue+0.5);
    781         }
    782       }
    783       if (oneRow&&rhsValue<=1.0+tolerance) {
    784         if (numberUnsatisfied) {
    785           someToDoYet=true;
    786         } else {
    787           numberClean++;
    788           for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
    789             int iColumn = column[j];
    790             if (columnLower[iColumn]!=columnUpper[iColumn]&&!mark[iColumn]){
    791               mark[iColumn]=1;
    792               numberNewFixed++;
    793             }
    794           }
    795         }
    796       }
    797     }
    798     delete [] mark;
    799     //printf("%d clean, %d old fixed, %d new fixed\n",
    800     //   numberClean,numberFixed,numberNewFixed);
    801     if (someToDoYet&&numberClean<numberClean_
    802         &&numberNewFixed+numberFixed<wantedFixed) {
    803     } else if (numberFixed<wantedFixed) {
    804       returnCode |= 2;
    805     } else {
    806     }
    807   }
    808   return returnCode;
    809 }
    810 double
    811 CbcBranchToFixLots::infeasibility(const OsiBranchingInformation * /*info*/,
    812                                int &preferredWay) const
    813 {
    814   preferredWay=-1;
    815   CbcNode * node = model_->currentNode();
    816   int depth;
    817   if (node)
    818     depth=CoinMax(node->depth(),0);
    819   else
    820     return 0.0;
    821   if (depth_<0) {
    822     return 0.0;
    823   } else if (depth_>0) {
    824     if ((depth%depth_)!=0)
    825       return 0.0;
    826   }
    827   if (djTolerance_!=-1.234567) {
    828     if (!shallWe())
    829       return 0.0;
    830     else
    831       return 1.0e20;
    832   } else {
    833     // See if 3 in same row and sum <FIX_IF_LESS?
    834     int numberRows = matrixByRow_.getNumRows();
    835     const double * solution = model_->testSolution();
    836     const int * column = matrixByRow_.getIndices();
    837     const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
    838     const int * rowLength = matrixByRow_.getVectorLengths();
    839     double bestSum=1.0;
    840     int nBest=-1;
     835        // See if 3 in same row and sum <FIX_IF_LESS?
     836        int numberRows = matrixByRow_.getNumRows();
     837        const double * solution = model_->testSolution();
     838        const int * column = matrixByRow_.getIndices();
     839        const CoinBigIndex * rowStart = matrixByRow_.getVectorStarts();
     840        const int * rowLength = matrixByRow_.getVectorLengths();
     841        double bestSum = 1.0;
     842        int nBest = -1;
     843        OsiSolverInterface * solver = model_->solver();
     844        for (int i = 0; i < numberRows; i++) {
     845            int numberUnsatisfied = 0;
     846            double sum = 0.0;
     847            for (int j = rowStart[i]; j < rowStart[i] + rowLength[i]; j++) {
     848                int iColumn = column[j];
     849                if (solver->isInteger(iColumn)) {
     850                    double solValue = solution[iColumn];
     851                    if (solValue > 1.0e-5 && solValue < FIX_IF_LESS) {
     852                        numberUnsatisfied++;
     853                        sum += solValue;
     854                    }
     855                }
     856            }
     857            if (numberUnsatisfied >= 3 && sum < FIX_IF_LESS) {
     858                // possible
     859                if (numberUnsatisfied > nBest ||
     860                        (numberUnsatisfied == nBest && sum < bestSum)) {
     861                    nBest = numberUnsatisfied;
     862                    bestSum = sum;
     863                }
     864            }
     865        }
     866        if (nBest > 0)
     867            return 1.0e20;
     868        else
     869            return 0.0;
     870    }
     871}
     872// Redoes data when sequence numbers change
     873void
     874CbcBranchToFixLots::redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns)
     875{
     876    model_ = model;
     877    if (mark_) {
     878        OsiSolverInterface * solver = model_->solver();
     879        int numberColumnsNow = solver->getNumCols();
     880        char * temp = new char[numberColumnsNow];
     881        memset(temp, 0, numberColumnsNow);
     882        for (int i = 0; i < numberColumns; i++) {
     883            int j = originalColumns[i];
     884            temp[i] = mark_[j];
     885        }
     886        delete [] mark_;
     887        mark_ = temp;
     888    }
    841889    OsiSolverInterface * solver = model_->solver();
    842     for (int i=0;i<numberRows;i++) {
    843       int numberUnsatisfied=0;
    844       double sum=0.0;
    845       for (int j=rowStart[i];j<rowStart[i]+rowLength[i];j++) {
    846         int iColumn = column[j];
    847         if (solver->isInteger(iColumn)) {
    848           double solValue = solution[iColumn];
    849           if (solValue>1.0e-5&&solValue<FIX_IF_LESS) {
    850             numberUnsatisfied++;
    851             sum += solValue;
    852           }
    853         }
    854       }
    855       if (numberUnsatisfied>=3&&sum<FIX_IF_LESS) {
    856         // possible
    857         if (numberUnsatisfied>nBest||
    858             (numberUnsatisfied==nBest&&sum<bestSum)) {
    859           nBest=numberUnsatisfied;
    860           bestSum=sum;
    861         }
    862       }
    863     }
    864     if (nBest>0)
    865       return 1.0e20;
    866     else
    867       return 0.0;
    868   }
    869 }
    870 // Redoes data when sequence numbers change
    871 void
    872 CbcBranchToFixLots::redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns)
    873 {
    874   model_=model;
    875   if (mark_) {
    876     OsiSolverInterface * solver = model_->solver();
    877     int numberColumnsNow = solver->getNumCols();
    878     char * temp = new char[numberColumnsNow];
    879     memset(temp,0,numberColumnsNow);
    880     for (int i=0;i<numberColumns;i++) {
    881       int j = originalColumns[i];
    882       temp[i]=mark_[j];
    883     }
    884     delete [] mark_;
    885     mark_=temp;
    886   }
    887   OsiSolverInterface * solver = model_->solver();
    888   matrixByRow_ = *solver->getMatrixByRow();
     890    matrixByRow_ = *solver->getMatrixByRow();
    889891}
    890892
     
    892894*/
    893895CbcBranchAllDifferent::CbcBranchAllDifferent ()
    894   : CbcBranchCut(),
    895     numberInSet_(0),
    896     which_(NULL)
     896        : CbcBranchCut(),
     897        numberInSet_(0),
     898        which_(NULL)
    897899{
    898900}
    899901
    900902/* Useful constructor - passed set of variables
    901 */ 
     903*/
    902904CbcBranchAllDifferent::CbcBranchAllDifferent (CbcModel * model, int numberInSet,
    903                                               const int * members)
    904   : CbcBranchCut(model)
    905 {
    906   numberInSet_=numberInSet;
    907   which_ = CoinCopyOfArray(members,numberInSet_);
    908 }
    909 // Copy constructor 
     905        const int * members)
     906        : CbcBranchCut(model)
     907{
     908    numberInSet_ = numberInSet;
     909    which_ = CoinCopyOfArray(members, numberInSet_);
     910}
     911// Copy constructor
    910912CbcBranchAllDifferent::CbcBranchAllDifferent ( const CbcBranchAllDifferent & rhs)
    911   :CbcBranchCut(rhs)
    912 {
    913   numberInSet_=rhs.numberInSet_;
    914   which_ = CoinCopyOfArray(rhs.which_,numberInSet_);
     913        : CbcBranchCut(rhs)
     914{
     915    numberInSet_ = rhs.numberInSet_;
     916    which_ = CoinCopyOfArray(rhs.which_, numberInSet_);
    915917}
    916918
     
    919921CbcBranchAllDifferent::clone() const
    920922{
    921   return new CbcBranchAllDifferent(*this);
    922 }
    923 
    924 // Assignment operator
    925 CbcBranchAllDifferent &
    926 CbcBranchAllDifferent::operator=( const CbcBranchAllDifferent& rhs)
    927 {
    928   if (this!=&rhs) {
    929     CbcBranchCut::operator=(rhs);
     923    return new CbcBranchAllDifferent(*this);
     924}
     925
     926// Assignment operator
     927CbcBranchAllDifferent &
     928CbcBranchAllDifferent::operator=( const CbcBranchAllDifferent & rhs)
     929{
     930    if (this != &rhs) {
     931        CbcBranchCut::operator=(rhs);
     932        delete [] which_;
     933        numberInSet_ = rhs.numberInSet_;
     934        which_ = CoinCopyOfArray(rhs.which_, numberInSet_);
     935    }
     936    return *this;
     937}
     938
     939// Destructor
     940CbcBranchAllDifferent::~CbcBranchAllDifferent ()
     941{
    930942    delete [] which_;
    931     numberInSet_=rhs.numberInSet_;
    932     which_ = CoinCopyOfArray(rhs.which_,numberInSet_);
    933   }
    934   return *this;
    935 }
    936 
    937 // Destructor
    938 CbcBranchAllDifferent::~CbcBranchAllDifferent ()
    939 {
    940   delete [] which_;
    941 }
    942 CbcBranchingObject *
     943}
     944CbcBranchingObject *
    943945CbcBranchAllDifferent::createCbcBranch(OsiSolverInterface * /*solver*/
    944                                        ,const OsiBranchingInformation * /*info*/,
    945                                        int /*way*/)
    946 {
    947   // by default way must be -1
    948   //assert (way==-1);
    949   const double * solution = model_->testSolution();
    950   double * values = new double[numberInSet_];
    951   int * which = new int[numberInSet_];
    952   int i;
    953   for (i=0;i<numberInSet_;i++) {
    954     int iColumn = which_[i];
    955     values[i]=solution[iColumn];
    956     which[i]=iColumn;
    957   }
    958   CoinSort_2(values,values+numberInSet_,which);
    959   double last = -1.0;
    960   double closest=1.0;
    961   int worst=-1;
    962   for (i=0;i<numberInSet_;i++) {
    963     if (values[i]-last<closest) {
    964       closest=values[i]-last;
    965       worst=i-1;
    966     }
    967     last=values[i];
    968   }
    969   assert (closest<=0.99999);
    970   OsiRowCut down;
    971   down.setLb(-COIN_DBL_MAX);
    972   down.setUb(-1.0);
    973   int pair[2];
    974   double elements[]={1.0,-1.0};
    975   pair[0]=which[worst];
    976   pair[1]=which[worst+1];
    977   delete [] values;
    978   delete [] which;
    979   down.setRow(2,pair,elements);
    980   // up is same - just with rhs changed
    981   OsiRowCut up = down;
    982   up.setLb(1.0);
    983   up.setUb(COIN_DBL_MAX);
    984   // Say is not a fix type branch
    985   CbcCutBranchingObject * newObject =
    986     new CbcCutBranchingObject(model_,down,up,false);
    987   if (model_->messageHandler()->logLevel()>1)
    988     printf("creating cut in CbcBranchCut\n");
    989   return newObject;
    990 }
    991 double 
     946                                       , const OsiBranchingInformation * /*info*/,
     947                                       int /*way*/)
     948{
     949    // by default way must be -1
     950    //assert (way==-1);
     951    const double * solution = model_->testSolution();
     952    double * values = new double[numberInSet_];
     953    int * which = new int[numberInSet_];
     954    int i;
     955    for (i = 0; i < numberInSet_; i++) {
     956        int iColumn = which_[i];
     957        values[i] = solution[iColumn];
     958        which[i] = iColumn;
     959    }
     960    CoinSort_2(values, values + numberInSet_, which);
     961    double last = -1.0;
     962    double closest = 1.0;
     963    int worst = -1;
     964    for (i = 0; i < numberInSet_; i++) {
     965        if (values[i] - last < closest) {
     966            closest = values[i] - last;
     967            worst = i - 1;
     968        }
     969        last = values[i];
     970    }
     971    assert (closest <= 0.99999);
     972    OsiRowCut down;
     973    down.setLb(-COIN_DBL_MAX);
     974    down.setUb(-1.0);
     975    int pair[2];
     976    double elements[] = {1.0, -1.0};
     977    pair[0] = which[worst];
     978    pair[1] = which[worst+1];
     979    delete [] values;
     980    delete [] which;
     981    down.setRow(2, pair, elements);
     982    // up is same - just with rhs changed
     983    OsiRowCut up = down;
     984    up.setLb(1.0);
     985    up.setUb(COIN_DBL_MAX);
     986    // Say is not a fix type branch
     987    CbcCutBranchingObject * newObject =
     988        new CbcCutBranchingObject(model_, down, up, false);
     989    if (model_->messageHandler()->logLevel() > 1)
     990        printf("creating cut in CbcBranchCut\n");
     991    return newObject;
     992}
     993double
    992994CbcBranchAllDifferent::infeasibility(const OsiBranchingInformation * /*info*/,
    993                                int &preferredWay) const
    994 {
    995   preferredWay=-1;
    996   //OsiSolverInterface * solver = model_->solver();
    997   const double * solution = model_->testSolution();
    998   //const double * lower = solver->getColLower();
    999   //const double * upper = solver->getColUpper();
    1000   double * values = new double[numberInSet_];
    1001   int i;
    1002   for (i=0;i<numberInSet_;i++) {
    1003     int iColumn = which_[i];
    1004     values[i]=solution[iColumn];
    1005   }
    1006   std::sort(values,values+numberInSet_);
    1007   double last = -1.0;
    1008   double closest=1.0;
    1009   for (i=0;i<numberInSet_;i++) {
    1010     if (values[i]-last<closest) {
    1011       closest=values[i]-last;
    1012     }
    1013     last=values[i];
    1014   }
    1015   delete [] values;
    1016   if (closest>0.99999)
    1017     return 0.0;
    1018   else
    1019     return 0.5*(1.0-closest);
    1020 }
     995                                     int &preferredWay) const
     996{
     997    preferredWay = -1;
     998    //OsiSolverInterface * solver = model_->solver();
     999    const double * solution = model_->testSolution();
     1000    //const double * lower = solver->getColLower();
     1001    //const double * upper = solver->getColUpper();
     1002    double * values = new double[numberInSet_];
     1003    int i;
     1004    for (i = 0; i < numberInSet_; i++) {
     1005        int iColumn = which_[i];
     1006        values[i] = solution[iColumn];
     1007    }
     1008    std::sort(values, values + numberInSet_);
     1009    double last = -1.0;
     1010    double closest = 1.0;
     1011    for (i = 0; i < numberInSet_; i++) {
     1012        if (values[i] - last < closest) {
     1013            closest = values[i] - last;
     1014        }
     1015        last = values[i];
     1016    }
     1017    delete [] values;
     1018    if (closest > 0.99999)
     1019        return 0.0;
     1020    else
     1021        return 0.5*(1.0 - closest);
     1022}
Note: See TracChangeset for help on using the changeset viewer.