Changeset 1308 for branches


Ignore:
Timestamp:
Nov 17, 2009 5:19:19 PM (10 years ago)
Author:
EdwinStraver
Message:

Broke up CbcBranchDynamic? and CbcBranchLotsize?.cpp.
Updated spreadsheets.

Location:
branches/sandbox/Cbc
Files:
6 added
8 edited

Legend:

Unmodified
Added
Removed
  • branches/sandbox/Cbc/CbcSourceFilesTable2.csv

    r1307 r1308  
    3333,CbcCutBranchingObject,Branch,Edwin,,,,,,,,,,,,
    3434CbcBranchDynamic.cpp,,Branch,Edwin,,8,1911,557,2468,x,,,,CbcSimpleIntegerDynamicPseudoCost,"CbcDynamicPseudoCostBranchingObject, CbcBranchDynamicDecision",
     35,CbcDynamicPseudoCostBranchingObject,Branch,Edwin,,,,,,,,,,,,
     36,CbcSimpleIntegerDynamicPseudoCost,Branch,Edwin,,,,,,,,,,,,
    3537CbcBranchLotsize.cpp,,Branch,Edwin,,15,809,250,1059,x,,,,CbcLotsize,CbcLotsizeBranchingObject,
    3638CbcCbcParam.cpp,,Solver,Bjarni,,24,1,,1,x,,,,"#include ""CbcOrClpParam.cpp""",,
  • branches/sandbox/Cbc/MSVisualStudio/v9/libCbc/libCbc.vcproj

    r1305 r1308  
    382382                        </File>
    383383                        <File
     384                                RelativePath="..\..\..\src\CbcDynamicPseudoCostBranchingObject.cpp"
     385                                >
     386                        </File>
     387                        <File
    384388                                RelativePath="..\..\..\..\Cbc\src\CbcEventHandler.cpp"
    385389                                >
     
    834838                        </File>
    835839                        <File
     840                                RelativePath="..\..\..\src\CbcLotsize.cpp"
     841                                >
     842                        </File>
     843                        <File
    836844                                RelativePath="..\..\..\..\Cbc\src\CbcMessage.cpp"
    837845                                >
     
    955963                        <File
    956964                                RelativePath="..\..\..\src\CbcSimpleInteger.cpp"
     965                                >
     966                        </File>
     967                        <File
     968                                RelativePath="..\..\..\src\CbcSimpleIntegerDynamicPseudoCost.cpp"
    957969                                >
    958970                        </File>
     
    11791191                        </File>
    11801192                        <File
     1193                                RelativePath="..\..\..\src\CbcDynamicPseudoCostBranchingObject.hpp"
     1194                                >
     1195                        </File>
     1196                        <File
    11811197                                RelativePath="..\..\..\..\Cbc\src\CbcEventHandler.hpp"
    11821198                                >
     
    12951311                        </File>
    12961312                        <File
     1313                                RelativePath="..\..\..\src\CbcLotsize.hpp"
     1314                                >
     1315                        </File>
     1316                        <File
    12971317                                RelativePath="..\..\..\..\Cbc\src\CbcMessage.hpp"
    12981318                                >
     
    13361356                        <File
    13371357                                RelativePath="..\..\..\src\CbcSimpleInteger.hpp"
     1358                                >
     1359                        </File>
     1360                        <File
     1361                                RelativePath="..\..\..\src\CbcSimpleIntegerDynamicPseudoCost.hpp"
    13381362                                >
    13391363                        </File>
  • branches/sandbox/Cbc/src/CbcBranchDynamic.cpp

    r1286 r1308  
    103103}
    104104#endif
    105 /** Default Constructor
    106 
    107   Equivalent to an unspecified binary variable.
    108 */
    109 CbcSimpleIntegerDynamicPseudoCost::CbcSimpleIntegerDynamicPseudoCost ()
    110         : CbcSimpleInteger(),
    111         downDynamicPseudoCost_(1.0e-5),
    112         upDynamicPseudoCost_(1.0e-5),
    113         upDownSeparator_(-1.0),
    114         sumDownCost_(0.0),
    115         sumUpCost_(0.0),
    116         sumDownChange_(0.0),
    117         sumUpChange_(0.0),
    118         downShadowPrice_(0.0),
    119         upShadowPrice_(0.0),
    120         sumDownDecrease_(0.0),
    121         sumUpDecrease_(0.0),
    122         lastDownCost_(0.0),
    123         lastUpCost_(0.0),
    124         lastDownDecrease_(0),
    125         lastUpDecrease_(0),
    126         numberTimesDown_(0),
    127         numberTimesUp_(0),
    128         numberTimesDownInfeasible_(0),
    129         numberTimesUpInfeasible_(0),
    130         numberBeforeTrust_(0),
    131         numberTimesDownLocalFixed_(0),
    132         numberTimesUpLocalFixed_(0),
    133         numberTimesDownTotalFixed_(0.0),
    134         numberTimesUpTotalFixed_(0.0),
    135         numberTimesProbingTotal_(0),
    136         method_(0)
    137 {
    138 }
    139 
    140 /** Useful constructor
    141 
    142   Loads dynamic upper & lower bounds for the specified variable.
    143 */
    144 CbcSimpleIntegerDynamicPseudoCost::CbcSimpleIntegerDynamicPseudoCost (CbcModel * model,
    145         int iColumn, double breakEven)
    146         : CbcSimpleInteger(model, iColumn, breakEven),
    147         upDownSeparator_(-1.0),
    148         sumDownCost_(0.0),
    149         sumUpCost_(0.0),
    150         sumDownChange_(0.0),
    151         sumUpChange_(0.0),
    152         downShadowPrice_(0.0),
    153         upShadowPrice_(0.0),
    154         sumDownDecrease_(0.0),
    155         sumUpDecrease_(0.0),
    156         lastDownCost_(0.0),
    157         lastUpCost_(0.0),
    158         lastDownDecrease_(0),
    159         lastUpDecrease_(0),
    160         numberTimesDown_(0),
    161         numberTimesUp_(0),
    162         numberTimesDownInfeasible_(0),
    163         numberTimesUpInfeasible_(0),
    164         numberBeforeTrust_(0),
    165         numberTimesDownLocalFixed_(0),
    166         numberTimesUpLocalFixed_(0),
    167         numberTimesDownTotalFixed_(0.0),
    168         numberTimesUpTotalFixed_(0.0),
    169         numberTimesProbingTotal_(0),
    170         method_(0)
    171 {
    172     const double * cost = model->getObjCoefficients();
    173     double costValue = CoinMax(1.0e-5, fabs(cost[iColumn]));
    174     // treat as if will cost what it says up
    175     upDynamicPseudoCost_ = costValue;
    176     // and balance at breakeven
    177     downDynamicPseudoCost_ = ((1.0 - breakEven_) * upDynamicPseudoCost_) / breakEven_;
    178     // so initial will have some effect
    179     sumUpCost_ = 2.0 * upDynamicPseudoCost_;
    180     sumUpChange_ = 2.0;
    181     numberTimesUp_ = 2;
    182     sumDownCost_ = 2.0 * downDynamicPseudoCost_;
    183     sumDownChange_ = 2.0;
    184     numberTimesDown_ = 2;
    185 #define TYPE2 0
    186 #if TYPE2==0
    187     // No
    188     sumUpCost_ = 0.0;
    189     sumUpChange_ = 0.0;
    190     numberTimesUp_ = 0;
    191     sumDownCost_ = 0.0;
    192     sumDownChange_ = 0.0;
    193     numberTimesDown_ = 0;
    194 #else
    195     sumUpCost_ = 1.0 * upDynamicPseudoCost_;
    196     sumUpChange_ = 1.0;
    197     numberTimesUp_ = 1;
    198     sumDownCost_ = 1.0 * downDynamicPseudoCost_;
    199     sumDownChange_ = 1.0;
    200     numberTimesDown_ = 1;
    201 #endif
    202 }
    203 
    204 /** Useful constructor
    205 
    206   Loads dynamic upper & lower bounds for the specified variable.
    207 */
    208 CbcSimpleIntegerDynamicPseudoCost::CbcSimpleIntegerDynamicPseudoCost (CbcModel * model,
    209         int iColumn, double downDynamicPseudoCost,
    210         double upDynamicPseudoCost)
    211         : CbcSimpleInteger(model, iColumn),
    212         upDownSeparator_(-1.0),
    213         sumDownCost_(0.0),
    214         sumUpCost_(0.0),
    215         sumDownChange_(0.0),
    216         sumUpChange_(0.0),
    217         downShadowPrice_(0.0),
    218         upShadowPrice_(0.0),
    219         sumDownDecrease_(0.0),
    220         sumUpDecrease_(0.0),
    221         lastDownCost_(0.0),
    222         lastUpCost_(0.0),
    223         lastDownDecrease_(0),
    224         lastUpDecrease_(0),
    225         numberTimesDown_(0),
    226         numberTimesUp_(0),
    227         numberTimesDownInfeasible_(0),
    228         numberTimesUpInfeasible_(0),
    229         numberBeforeTrust_(0),
    230         numberTimesDownLocalFixed_(0),
    231         numberTimesUpLocalFixed_(0),
    232         numberTimesDownTotalFixed_(0.0),
    233         numberTimesUpTotalFixed_(0.0),
    234         numberTimesProbingTotal_(0),
    235         method_(0)
    236 {
    237     downDynamicPseudoCost_ = downDynamicPseudoCost;
    238     upDynamicPseudoCost_ = upDynamicPseudoCost;
    239     breakEven_ = upDynamicPseudoCost_ / (upDynamicPseudoCost_ + downDynamicPseudoCost_);
    240     // so initial will have some effect
    241     sumUpCost_ = 2.0 * upDynamicPseudoCost_;
    242     sumUpChange_ = 2.0;
    243     numberTimesUp_ = 2;
    244     sumDownCost_ = 2.0 * downDynamicPseudoCost_;
    245     sumDownChange_ = 2.0;
    246     numberTimesDown_ = 2;
    247 #if TYPE2==0
    248     // No
    249     sumUpCost_ = 0.0;
    250     sumUpChange_ = 0.0;
    251     numberTimesUp_ = 0;
    252     sumDownCost_ = 0.0;
    253     sumDownChange_ = 0.0;
    254     numberTimesDown_ = 0;
    255     sumUpCost_ = 1.0e-4 * upDynamicPseudoCost_;
    256     sumDownCost_ = 1.0e-4 * downDynamicPseudoCost_;
    257 #else
    258     sumUpCost_ = 1.0 * upDynamicPseudoCost_;
    259     sumUpChange_ = 1.0;
    260     numberTimesUp_ = 1;
    261     sumDownCost_ = 1.0 * downDynamicPseudoCost_;
    262     sumDownChange_ = 1.0;
    263     numberTimesDown_ = 1;
    264 #endif
    265 }
    266 /** Useful constructor
    267 
    268   Loads dynamic upper & lower bounds for the specified variable.
    269 */
    270 CbcSimpleIntegerDynamicPseudoCost::CbcSimpleIntegerDynamicPseudoCost (CbcModel * model,
    271         int /*dummy*/,
    272         int iColumn, double downDynamicPseudoCost,
    273         double upDynamicPseudoCost)
    274 {
    275     CbcSimpleIntegerDynamicPseudoCost(model, iColumn, downDynamicPseudoCost, upDynamicPseudoCost);
    276 }
    277 
    278 // Copy constructor
    279 CbcSimpleIntegerDynamicPseudoCost::CbcSimpleIntegerDynamicPseudoCost ( const CbcSimpleIntegerDynamicPseudoCost & rhs)
    280         : CbcSimpleInteger(rhs),
    281         downDynamicPseudoCost_(rhs.downDynamicPseudoCost_),
    282         upDynamicPseudoCost_(rhs.upDynamicPseudoCost_),
    283         upDownSeparator_(rhs.upDownSeparator_),
    284         sumDownCost_(rhs.sumDownCost_),
    285         sumUpCost_(rhs.sumUpCost_),
    286         sumDownChange_(rhs.sumDownChange_),
    287         sumUpChange_(rhs.sumUpChange_),
    288         downShadowPrice_(rhs.downShadowPrice_),
    289         upShadowPrice_(rhs.upShadowPrice_),
    290         sumDownDecrease_(rhs.sumDownDecrease_),
    291         sumUpDecrease_(rhs.sumUpDecrease_),
    292         lastDownCost_(rhs.lastDownCost_),
    293         lastUpCost_(rhs.lastUpCost_),
    294         lastDownDecrease_(rhs.lastDownDecrease_),
    295         lastUpDecrease_(rhs.lastUpDecrease_),
    296         numberTimesDown_(rhs.numberTimesDown_),
    297         numberTimesUp_(rhs.numberTimesUp_),
    298         numberTimesDownInfeasible_(rhs.numberTimesDownInfeasible_),
    299         numberTimesUpInfeasible_(rhs.numberTimesUpInfeasible_),
    300         numberBeforeTrust_(rhs.numberBeforeTrust_),
    301         numberTimesDownLocalFixed_(rhs.numberTimesDownLocalFixed_),
    302         numberTimesUpLocalFixed_(rhs.numberTimesUpLocalFixed_),
    303         numberTimesDownTotalFixed_(rhs.numberTimesDownTotalFixed_),
    304         numberTimesUpTotalFixed_(rhs.numberTimesUpTotalFixed_),
    305         numberTimesProbingTotal_(rhs.numberTimesProbingTotal_),
    306         method_(rhs.method_)
    307 
    308 {
    309 }
    310 
    311 // Clone
    312 CbcObject *
    313 CbcSimpleIntegerDynamicPseudoCost::clone() const
    314 {
    315     return new CbcSimpleIntegerDynamicPseudoCost(*this);
    316 }
    317 
    318 // Assignment operator
    319 CbcSimpleIntegerDynamicPseudoCost &
    320 CbcSimpleIntegerDynamicPseudoCost::operator=( const CbcSimpleIntegerDynamicPseudoCost & rhs)
    321 {
    322     if (this != &rhs) {
    323         CbcSimpleInteger::operator=(rhs);
    324         downDynamicPseudoCost_ = rhs.downDynamicPseudoCost_;
    325         upDynamicPseudoCost_ = rhs.upDynamicPseudoCost_;
    326         upDownSeparator_ = rhs.upDownSeparator_;
    327         sumDownCost_ = rhs.sumDownCost_;
    328         sumUpCost_ = rhs.sumUpCost_;
    329         sumDownChange_ = rhs.sumDownChange_;
    330         sumUpChange_ = rhs.sumUpChange_;
    331         downShadowPrice_ = rhs.downShadowPrice_;
    332         upShadowPrice_ = rhs.upShadowPrice_;
    333         sumDownDecrease_ = rhs.sumDownDecrease_;
    334         sumUpDecrease_ = rhs.sumUpDecrease_;
    335         lastDownCost_ = rhs.lastDownCost_;
    336         lastUpCost_ = rhs.lastUpCost_;
    337         lastDownDecrease_ = rhs.lastDownDecrease_;
    338         lastUpDecrease_ = rhs.lastUpDecrease_;
    339         numberTimesDown_ = rhs.numberTimesDown_;
    340         numberTimesUp_ = rhs.numberTimesUp_;
    341         numberTimesDownInfeasible_ = rhs.numberTimesDownInfeasible_;
    342         numberTimesUpInfeasible_ = rhs.numberTimesUpInfeasible_;
    343         numberBeforeTrust_ = rhs.numberBeforeTrust_;
    344         numberTimesDownLocalFixed_ = rhs.numberTimesDownLocalFixed_;
    345         numberTimesUpLocalFixed_ = rhs.numberTimesUpLocalFixed_;
    346         numberTimesDownTotalFixed_ = rhs.numberTimesDownTotalFixed_;
    347         numberTimesUpTotalFixed_ = rhs.numberTimesUpTotalFixed_;
    348         numberTimesProbingTotal_ = rhs.numberTimesProbingTotal_;
    349         method_ = rhs.method_;
    350     }
    351     return *this;
    352 }
    353 
    354 // Destructor
    355 CbcSimpleIntegerDynamicPseudoCost::~CbcSimpleIntegerDynamicPseudoCost ()
    356 {
    357 }
    358 // Copy some information i.e. just variable stuff
    359 void
    360 CbcSimpleIntegerDynamicPseudoCost::copySome(const CbcSimpleIntegerDynamicPseudoCost * otherObject)
    361 {
    362     downDynamicPseudoCost_ = otherObject->downDynamicPseudoCost_;
    363     upDynamicPseudoCost_ = otherObject->upDynamicPseudoCost_;
    364     sumDownCost_ = otherObject->sumDownCost_;
    365     sumUpCost_ = otherObject->sumUpCost_;
    366     sumDownChange_ = otherObject->sumDownChange_;
    367     sumUpChange_ = otherObject->sumUpChange_;
    368     downShadowPrice_ = otherObject->downShadowPrice_;
    369     upShadowPrice_ = otherObject->upShadowPrice_;
    370     sumDownDecrease_ = otherObject->sumDownDecrease_;
    371     sumUpDecrease_ = otherObject->sumUpDecrease_;
    372     lastDownCost_ = otherObject->lastDownCost_;
    373     lastUpCost_ = otherObject->lastUpCost_;
    374     lastDownDecrease_ = otherObject->lastDownDecrease_;
    375     lastUpDecrease_ = otherObject->lastUpDecrease_;
    376     numberTimesDown_ = otherObject->numberTimesDown_;
    377     numberTimesUp_ = otherObject->numberTimesUp_;
    378     numberTimesDownInfeasible_ = otherObject->numberTimesDownInfeasible_;
    379     numberTimesUpInfeasible_ = otherObject->numberTimesUpInfeasible_;
    380     numberTimesDownLocalFixed_ = otherObject->numberTimesDownLocalFixed_;
    381     numberTimesUpLocalFixed_ = otherObject->numberTimesUpLocalFixed_;
    382     numberTimesDownTotalFixed_ = otherObject->numberTimesDownTotalFixed_;
    383     numberTimesUpTotalFixed_ = otherObject->numberTimesUpTotalFixed_;
    384     numberTimesProbingTotal_ = otherObject->numberTimesProbingTotal_;
    385 }
    386 // Updates stuff like pseudocosts before threads
    387 void
    388 CbcSimpleIntegerDynamicPseudoCost::updateBefore(const OsiObject * rhs)
    389 {
    390 #ifndef NDEBUG
    391     const CbcSimpleIntegerDynamicPseudoCost * rhsObject =
    392         dynamic_cast <const CbcSimpleIntegerDynamicPseudoCost *>(rhs) ;
    393     assert (rhsObject);
    394 #else
    395     const CbcSimpleIntegerDynamicPseudoCost * rhsObject =
    396         static_cast <const CbcSimpleIntegerDynamicPseudoCost *>(rhs) ;
    397 #endif
    398     copySome(rhsObject);
    399 }
    400 // was 1 - but that looks flakey
    401 #define INFEAS 1
    402 // Updates stuff like pseudocosts after threads finished
    403 void
    404 CbcSimpleIntegerDynamicPseudoCost::updateAfter(const OsiObject * rhs, const OsiObject * baseObjectX)
    405 {
    406 #ifndef NDEBUG
    407     const CbcSimpleIntegerDynamicPseudoCost * rhsObject =
    408         dynamic_cast <const CbcSimpleIntegerDynamicPseudoCost *>(rhs) ;
    409     assert (rhsObject);
    410     const CbcSimpleIntegerDynamicPseudoCost * baseObject =
    411         dynamic_cast <const CbcSimpleIntegerDynamicPseudoCost *>(baseObjectX) ;
    412     assert (baseObject);
    413 #else
    414     const CbcSimpleIntegerDynamicPseudoCost * rhsObject =
    415         static_cast <const CbcSimpleIntegerDynamicPseudoCost *>(rhs) ;
    416     const CbcSimpleIntegerDynamicPseudoCost * baseObject =
    417         static_cast <const CbcSimpleIntegerDynamicPseudoCost *>(baseObjectX) ;
    418 #endif
    419     // compute current
    420     double sumDown = downDynamicPseudoCost_ * numberTimesDown_;
    421     sumDown -= baseObject->downDynamicPseudoCost_ * baseObject->numberTimesDown_;
    422     sumDown = CoinMax(sumDown, 0.0);
    423     sumDown += rhsObject->downDynamicPseudoCost_ * rhsObject->numberTimesDown_;
    424     assert (rhsObject->numberTimesDown_ >= baseObject->numberTimesDown_);
    425     assert (rhsObject->numberTimesDownInfeasible_ >= baseObject->numberTimesDownInfeasible_);
    426     assert( rhsObject->sumDownCost_ >= baseObject->sumDownCost_);
    427     double sumUp = upDynamicPseudoCost_ * numberTimesUp_;
    428     sumUp -= baseObject->upDynamicPseudoCost_ * baseObject->numberTimesUp_;
    429     sumUp = CoinMax(sumUp, 0.0);
    430     sumUp += rhsObject->upDynamicPseudoCost_ * rhsObject->numberTimesUp_;
    431     assert (rhsObject->numberTimesUp_ >= baseObject->numberTimesUp_);
    432     assert (rhsObject->numberTimesUpInfeasible_ >= baseObject->numberTimesUpInfeasible_);
    433     assert( rhsObject->sumUpCost_ >= baseObject->sumUpCost_);
    434     sumDownCost_ += rhsObject->sumDownCost_ - baseObject->sumDownCost_;
    435     sumUpCost_ += rhsObject->sumUpCost_ - baseObject->sumUpCost_;
    436     sumDownChange_ += rhsObject->sumDownChange_ - baseObject->sumDownChange_;
    437     sumUpChange_ += rhsObject->sumUpChange_ - baseObject->sumUpChange_;
    438     downShadowPrice_ = 0.0;
    439     upShadowPrice_ = 0.0;
    440     sumDownDecrease_ += rhsObject->sumDownDecrease_ - baseObject->sumDownDecrease_;
    441     sumUpDecrease_ += rhsObject->sumUpDecrease_ - baseObject->sumUpDecrease_;
    442     lastDownCost_ += rhsObject->lastDownCost_ - baseObject->lastDownCost_;
    443     lastUpCost_ += rhsObject->lastUpCost_ - baseObject->lastUpCost_;
    444     lastDownDecrease_ += rhsObject->lastDownDecrease_ - baseObject->lastDownDecrease_;
    445     lastUpDecrease_ += rhsObject->lastUpDecrease_ - baseObject->lastUpDecrease_;
    446     numberTimesDown_ += rhsObject->numberTimesDown_ - baseObject->numberTimesDown_;
    447     numberTimesUp_ += rhsObject->numberTimesUp_ - baseObject->numberTimesUp_;
    448     numberTimesDownInfeasible_ += rhsObject->numberTimesDownInfeasible_ - baseObject->numberTimesDownInfeasible_;
    449     numberTimesUpInfeasible_ += rhsObject->numberTimesUpInfeasible_ - baseObject->numberTimesUpInfeasible_;
    450     numberTimesDownLocalFixed_ += rhsObject->numberTimesDownLocalFixed_ - baseObject->numberTimesDownLocalFixed_;
    451     numberTimesUpLocalFixed_ += rhsObject->numberTimesUpLocalFixed_ - baseObject->numberTimesUpLocalFixed_;
    452     numberTimesDownTotalFixed_ += rhsObject->numberTimesDownTotalFixed_ - baseObject->numberTimesDownTotalFixed_;
    453     numberTimesUpTotalFixed_ += rhsObject->numberTimesUpTotalFixed_ - baseObject->numberTimesUpTotalFixed_;
    454     numberTimesProbingTotal_ += rhsObject->numberTimesProbingTotal_ - baseObject->numberTimesProbingTotal_;
    455     if (numberTimesDown_ > 0) {
    456         setDownDynamicPseudoCost(sumDown / static_cast<double> (numberTimesDown_));
    457     }
    458     if (numberTimesUp_ > 0) {
    459         setUpDynamicPseudoCost(sumUp / static_cast<double> (numberTimesUp_));
    460     }
    461     //printf("XX %d down %d %d %g up %d %d %g\n",columnNumber_,numberTimesDown_,numberTimesDownInfeasible_,downDynamicPseudoCost_,
    462     // numberTimesUp_,numberTimesUpInfeasible_,upDynamicPseudoCost_);
    463     assert (downDynamicPseudoCost_ > 1.0e-40 && upDynamicPseudoCost_ > 1.0e-40);
    464 }
    465 // Same - returns true if contents match(ish)
    466 bool
    467 CbcSimpleIntegerDynamicPseudoCost::same(const CbcSimpleIntegerDynamicPseudoCost * otherObject) const
    468 {
    469     bool okay = true;
    470     if (downDynamicPseudoCost_ != otherObject->downDynamicPseudoCost_)
    471         okay = false;
    472     if (upDynamicPseudoCost_ != otherObject->upDynamicPseudoCost_)
    473         okay = false;
    474     if (sumDownCost_ != otherObject->sumDownCost_)
    475         okay = false;
    476     if (sumUpCost_ != otherObject->sumUpCost_)
    477         okay = false;
    478     if (sumDownChange_ != otherObject->sumDownChange_)
    479         okay = false;
    480     if (sumUpChange_ != otherObject->sumUpChange_)
    481         okay = false;
    482     if (downShadowPrice_ != otherObject->downShadowPrice_)
    483         okay = false;
    484     if (upShadowPrice_ != otherObject->upShadowPrice_)
    485         okay = false;
    486     if (sumDownDecrease_ != otherObject->sumDownDecrease_)
    487         okay = false;
    488     if (sumUpDecrease_ != otherObject->sumUpDecrease_)
    489         okay = false;
    490     if (lastDownCost_ != otherObject->lastDownCost_)
    491         okay = false;
    492     if (lastUpCost_ != otherObject->lastUpCost_)
    493         okay = false;
    494     if (lastDownDecrease_ != otherObject->lastDownDecrease_)
    495         okay = false;
    496     if (lastUpDecrease_ != otherObject->lastUpDecrease_)
    497         okay = false;
    498     if (numberTimesDown_ != otherObject->numberTimesDown_)
    499         okay = false;
    500     if (numberTimesUp_ != otherObject->numberTimesUp_)
    501         okay = false;
    502     if (numberTimesDownInfeasible_ != otherObject->numberTimesDownInfeasible_)
    503         okay = false;
    504     if (numberTimesUpInfeasible_ != otherObject->numberTimesUpInfeasible_)
    505         okay = false;
    506     if (numberTimesDownLocalFixed_ != otherObject->numberTimesDownLocalFixed_)
    507         okay = false;
    508     if (numberTimesUpLocalFixed_ != otherObject->numberTimesUpLocalFixed_)
    509         okay = false;
    510     if (numberTimesDownTotalFixed_ != otherObject->numberTimesDownTotalFixed_)
    511         okay = false;
    512     if (numberTimesUpTotalFixed_ != otherObject->numberTimesUpTotalFixed_)
    513         okay = false;
    514     if (numberTimesProbingTotal_ != otherObject->numberTimesProbingTotal_)
    515         okay = false;
    516     return okay;
    517 }
    518 /* Create an OsiSolverBranch object
    519 
    520 This returns NULL if branch not represented by bound changes
    521 */
    522 OsiSolverBranch *
    523 CbcSimpleIntegerDynamicPseudoCost::solverBranch() const
    524 {
    525     OsiSolverInterface * solver = model_->solver();
    526     const double * solution = model_->testSolution();
    527     const double * lower = solver->getColLower();
    528     const double * upper = solver->getColUpper();
    529     double value = solution[columnNumber_];
    530     value = CoinMax(value, lower[columnNumber_]);
    531     value = CoinMin(value, upper[columnNumber_]);
    532     assert (upper[columnNumber_] > lower[columnNumber_]);
    533 #ifndef NDEBUG
    534     double nearest = floor(value + 0.5);
    535     double integerTolerance =
    536         model_->getDblParam(CbcModel::CbcIntegerTolerance);
    537     assert (fabs(value - nearest) > integerTolerance);
    538 #endif
    539     OsiSolverBranch * branch = new OsiSolverBranch();
    540     branch->addBranch(columnNumber_, value);
    541     return branch;
    542 }
    543 //#define FUNNY_BRANCHING
    544 double
    545 CbcSimpleIntegerDynamicPseudoCost::infeasibility(const OsiBranchingInformation * info,
    546         int &preferredWay) const
    547 {
    548     assert (downDynamicPseudoCost_ > 1.0e-40 && upDynamicPseudoCost_ > 1.0e-40);
    549     const double * solution = model_->testSolution();
    550     const double * lower = model_->getCbcColLower();
    551     const double * upper = model_->getCbcColUpper();
    552 #ifdef FUNNY_BRANCHING
    553     const double * dj = model_->getCbcReducedCost();
    554     double djValue = dj[columnNumber_];
    555     lastDownDecrease_++;
    556     if (djValue > 1.0e-6) {
    557         // wants to go down
    558         if (true || lower[columnNumber_] > originalLower_) {
    559             // Lower bound active
    560             lastUpDecrease_++;
    561         }
    562     } else if (djValue < -1.0e-6) {
    563         // wants to go up
    564         if (true || upper[columnNumber_] < originalUpper_) {
    565             // Upper bound active
    566             lastUpDecrease_++;
    567         }
    568     }
    569 #endif
    570     if (upper[columnNumber_] == lower[columnNumber_]) {
    571         // fixed
    572         preferredWay = 1;
    573         return 0.0;
    574     }
    575     assert (breakEven_ > 0.0 && breakEven_ < 1.0);
    576     double value = solution[columnNumber_];
    577     value = CoinMax(value, lower[columnNumber_]);
    578     value = CoinMin(value, upper[columnNumber_]);
    579     /*printf("%d %g %g %g %g\n",columnNumber_,value,lower[columnNumber_],
    580       solution[columnNumber_],upper[columnNumber_]);*/
    581     double nearest = floor(value + 0.5);
    582     double integerTolerance =
    583         model_->getDblParam(CbcModel::CbcIntegerTolerance);
    584     double below = floor(value + integerTolerance);
    585     double above = below + 1.0;
    586     if (above > upper[columnNumber_]) {
    587         above = below;
    588         below = above - 1;
    589     }
    590 #if INFEAS==1
    591     double distanceToCutoff = 0.0;
    592     double objectiveValue = model_->getCurrentMinimizationObjValue();
    593     distanceToCutoff =  model_->getCutoff()  - objectiveValue;
    594     if (distanceToCutoff < 1.0e20)
    595         distanceToCutoff *= 10.0;
    596     else
    597         distanceToCutoff = 1.0e2 + fabs(objectiveValue);
    598     distanceToCutoff = CoinMax(distanceToCutoff, 1.0e-12 * (1.0 + fabs(objectiveValue)));
    599 #endif
    600     double sum;
    601     double number;
    602     double downCost = CoinMax(value - below, 0.0);
    603 #if TYPE2==0
    604     sum = sumDownCost_;
    605     number = numberTimesDown_;
    606 #if INFEAS==1
    607     sum += numberTimesDownInfeasible_ * CoinMax(distanceToCutoff / (downCost + 1.0e-12), sumDownCost_);
    608 #endif
    609 #elif TYPE2==1
    610     sum = sumDownCost_;
    611     number = sumDownChange_;
    612 #if INFEAS==1
    613     sum += numberTimesDownInfeasible_ * CoinMax(distanceToCutoff / (downCost + 1.0e-12), sumDownCost_);
    614 #endif
    615 #elif TYPE2==2
    616     abort();
    617 #if INFEAS==1
    618     sum += numberTimesDownInfeasible_ * (distanceToCutoff / (downCost + 1.0e-12));
    619 #endif
    620 #endif
    621 #define MOD_SHADOW 1
    622 #if MOD_SHADOW>0
    623     if (!downShadowPrice_) {
    624         if (number > 0.0)
    625             downCost *= sum / number;
    626         else
    627             downCost  *=  downDynamicPseudoCost_;
    628     } else if (downShadowPrice_ > 0.0) {
    629         downCost *= downShadowPrice_;
    630     } else {
    631         downCost *= (downDynamicPseudoCost_ - downShadowPrice_);
    632     }
    633 #else
    634     if (downShadowPrice_ <= 0.0) {
    635         if (number > 0.0)
    636             downCost *= sum / number;
    637         else
    638             downCost  *=  downDynamicPseudoCost_;
    639     } else {
    640         downCost *= downShadowPrice_;
    641     }
    642 #endif
    643     double upCost = CoinMax((above - value), 0.0);
    644 #if TYPE2==0
    645     sum = sumUpCost_;
    646     number = numberTimesUp_;
    647 #if INFEAS==1
    648     sum += numberTimesUpInfeasible_ * CoinMax(distanceToCutoff / (upCost + 1.0e-12), sumUpCost_);
    649 #endif
    650 #elif TYPE2==1
    651     sum = sumUpCost_;
    652     number = sumUpChange_;
    653 #if INFEAS==1
    654     sum += numberTimesUpInfeasible_ * CoinMax(distanceToCutoff / (upCost + 1.0e-12), sumUpCost_);
    655 #endif
    656 #elif TYPE2==1
    657     abort();
    658 #if INFEAS==1
    659     sum += numberTimesUpInfeasible_ * (distanceToCutoff / (upCost + 1.0e-12));
    660 #endif
    661 #endif
    662 #if MOD_SHADOW>0
    663     if (!upShadowPrice_) {
    664         if (number > 0.0)
    665             upCost *= sum / number;
    666         else
    667             upCost  *=  upDynamicPseudoCost_;
    668     } else if (upShadowPrice_ > 0.0) {
    669         upCost *= upShadowPrice_;
    670     } else {
    671         upCost *= (upDynamicPseudoCost_ - upShadowPrice_);
    672     }
    673 #else
    674     if (upShadowPrice_ <= 0.0) {
    675         if (number > 0.0)
    676             upCost *= sum / number;
    677         else
    678             upCost  *=  upDynamicPseudoCost_;
    679     } else {
    680         upCost *= upShadowPrice_;
    681     }
    682 #endif
    683     if (downCost >= upCost)
    684         preferredWay = 1;
    685     else
    686         preferredWay = -1;
    687     // See if up down choice set
    688     if (upDownSeparator_ > 0.0) {
    689         preferredWay = (value - below >= upDownSeparator_) ? 1 : -1;
    690     }
    691 #ifdef FUNNY_BRANCHING
    692     if (fabs(value - nearest) > integerTolerance) {
    693         double ratio = (100.0 + lastUpDecrease_) / (100.0 + lastDownDecrease_);
    694         downCost *= ratio;
    695         upCost *= ratio;
    696         if ((lastUpDecrease_ % 100) == -1)
    697             printf("col %d total %d djtimes %d\n",
    698                    columnNumber_, lastDownDecrease_, lastUpDecrease_);
    699     }
    700 #endif
    701     if (preferredWay_)
    702         preferredWay = preferredWay_;
    703     if (info->hotstartSolution_) {
    704         double targetValue = info->hotstartSolution_[columnNumber_];
    705         if (value > targetValue)
    706             preferredWay = -1;
    707         else
    708             preferredWay = 1;
    709     }
    710     // weight at 1.0 is max min
    711 #define WEIGHT_AFTER 0.8
    712 #define WEIGHT_BEFORE 0.1
    713     //Stolen from Constraint Integer Programming book (with epsilon change)
    714 #define WEIGHT_PRODUCT
    715     if (fabs(value - nearest) <= integerTolerance) {
    716         if (priority_ != -999)
    717             return 0.0;
    718         else
    719             return 1.0e-13;
    720     } else {
    721         int stateOfSearch = model_->stateOfSearch() % 10;
    722         double returnValue = 0.0;
    723         double minValue = CoinMin(downCost, upCost);
    724         double maxValue = CoinMax(downCost, upCost);
    725         char where;
    726         // was <= 10
    727         //if (stateOfSearch<=1||model_->currentNode()->depth()<=-10 /* was ||maxValue>0.2*distanceToCutoff*/) {
    728         if (stateOfSearch <= 2) {
    729             // no branching solution
    730             where = 'i';
    731             returnValue = WEIGHT_BEFORE * minValue + (1.0 - WEIGHT_BEFORE) * maxValue;
    732             if (0) {
    733                 double sum;
    734                 int number;
    735                 double downCost2 = CoinMax(value - below, 0.0);
    736                 sum = sumDownCost_;
    737                 number = numberTimesDown_;
    738                 if (number > 0)
    739                     downCost2 *= sum / static_cast<double> (number);
    740                 else
    741                     downCost2  *=  downDynamicPseudoCost_;
    742                 double upCost2 = CoinMax((above - value), 0.0);
    743                 sum = sumUpCost_;
    744                 number = numberTimesUp_;
    745                 if (number > 0)
    746                     upCost2 *= sum / static_cast<double> (number);
    747                 else
    748                     upCost2  *=  upDynamicPseudoCost_;
    749                 double minValue2 = CoinMin(downCost2, upCost2);
    750                 double maxValue2 = CoinMax(downCost2, upCost2);
    751                 printf("%d value %g downC %g upC %g minV %g maxV %g downC2 %g upC2 %g minV2 %g maxV2 %g\n",
    752                        columnNumber_, value, downCost, upCost, minValue, maxValue,
    753                        downCost2, upCost2, minValue2, maxValue2);
    754             }
    755         } else {
    756             // some solution
    757             where = 'I';
    758 #ifndef WEIGHT_PRODUCT
    759             returnValue = WEIGHT_AFTER * minValue + (1.0 - WEIGHT_AFTER) * maxValue;
    760 #else
    761             double minProductWeight = model_->getDblParam(CbcModel::CbcSmallChange);
    762             returnValue = CoinMax(minValue, minProductWeight) * CoinMax(maxValue, minProductWeight);
    763             //returnValue += minProductWeight*minValue;
    764 #endif
    765         }
    766         if (numberTimesUp_ < numberBeforeTrust_ ||
    767                 numberTimesDown_ < numberBeforeTrust_) {
    768             //if (returnValue<1.0e10)
    769             //returnValue += 1.0e12;
    770             //else
    771             returnValue *= 1.0e3;
    772             if (!numberTimesUp_ && !numberTimesDown_)
    773                 returnValue *= 1.0e10;
    774         }
    775         //if (fabs(value-0.5)<1.0e-5) {
    776         //returnValue = 3.0*returnValue + 0.2;
    777         //} else if (value>0.9) {
    778         //returnValue = 2.0*returnValue + 0.1;
    779         //}
    780         if (method_ == 1) {
    781             // probing
    782             // average
    783             double up = 1.0e-15;
    784             double down = 1.0e-15;
    785             if (numberTimesProbingTotal_) {
    786                 up += numberTimesUpTotalFixed_ / static_cast<double> (numberTimesProbingTotal_);
    787                 down += numberTimesDownTotalFixed_ / static_cast<double> (numberTimesProbingTotal_);
    788             }
    789             returnValue = 1 + 10.0 * CoinMin(numberTimesDownLocalFixed_, numberTimesUpLocalFixed_) +
    790                           CoinMin(down, up);
    791             returnValue *= 1.0e-3;
    792         }
    793 #ifdef COIN_DEVELOP
    794         History hist;
    795         hist.where_ = where;
    796         hist.status_ = ' ';
    797         hist.sequence_ = columnNumber_;
    798         hist.numberUp_ = numberTimesUp_;
    799         hist.numberUpInf_ = numberTimesUpInfeasible_;
    800         hist.sumUp_ = sumUpCost_;
    801         hist.upEst_ = upCost;
    802         hist.numberDown_ = numberTimesDown_;
    803         hist.numberDownInf_ = numberTimesDownInfeasible_;
    804         hist.sumDown_ = sumDownCost_;
    805         hist.downEst_ = downCost;
    806         if (stateOfSearch)
    807             addRecord(hist);
    808 #endif
    809         return CoinMax(returnValue, 1.0e-15);
    810     }
    811 }
    812 // Creates a branching object
    813 CbcBranchingObject *
    814 CbcSimpleIntegerDynamicPseudoCost::createCbcBranch(OsiSolverInterface * /*solver*/,
    815         const OsiBranchingInformation * info, int way)
    816 {
    817     double value = info->solution_[columnNumber_];
    818     value = CoinMax(value, info->lower_[columnNumber_]);
    819     value = CoinMin(value, info->upper_[columnNumber_]);
    820     assert (info->upper_[columnNumber_] > info->lower_[columnNumber_]);
    821     if (!info->hotstartSolution_ && priority_ != -999) {
    822 #ifndef NDEBUG
    823         double nearest = floor(value + 0.5);
    824         assert (fabs(value - nearest) > info->integerTolerance_);
    825 #endif
    826     } else if (info->hotstartSolution_) {
    827         double targetValue = info->hotstartSolution_[columnNumber_];
    828         if (way > 0)
    829             value = targetValue - 0.1;
    830         else
    831             value = targetValue + 0.1;
    832     } else {
    833         if (value <= info->lower_[columnNumber_])
    834             value += 0.1;
    835         else if (value >= info->upper_[columnNumber_])
    836             value -= 0.1;
    837     }
    838     assert (value >= info->lower_[columnNumber_] &&
    839             value <= info->upper_[columnNumber_]);
    840     CbcDynamicPseudoCostBranchingObject * newObject =
    841         new CbcDynamicPseudoCostBranchingObject(model_, columnNumber_, way,
    842                                                 value, this);
    843     double up =  upDynamicPseudoCost_ * (ceil(value) - value);
    844     double down =  downDynamicPseudoCost_ * (value - floor(value));
    845     double changeInGuessed = up - down;
    846     if (way > 0)
    847         changeInGuessed = - changeInGuessed;
    848     changeInGuessed = CoinMax(0.0, changeInGuessed);
    849     //if (way>0)
    850     //changeInGuessed += 1.0e8; // bias to stay up
    851     newObject->setChangeInGuessed(changeInGuessed);
    852     newObject->setOriginalObject(this);
    853     return newObject;
    854 }
    855 
    856 // Return "up" estimate
    857 double
    858 CbcSimpleIntegerDynamicPseudoCost::upEstimate() const
    859 {
    860     const double * solution = model_->testSolution();
    861     const double * lower = model_->getCbcColLower();
    862     const double * upper = model_->getCbcColUpper();
    863     double value = solution[columnNumber_];
    864     value = CoinMax(value, lower[columnNumber_]);
    865     value = CoinMin(value, upper[columnNumber_]);
    866     if (upper[columnNumber_] == lower[columnNumber_]) {
    867         // fixed
    868         return 0.0;
    869     }
    870     double integerTolerance =
    871         model_->getDblParam(CbcModel::CbcIntegerTolerance);
    872     double below = floor(value + integerTolerance);
    873     double above = below + 1.0;
    874     if (above > upper[columnNumber_]) {
    875         above = below;
    876         below = above - 1;
    877     }
    878     double upCost = CoinMax((above - value) * upDynamicPseudoCost_, 0.0);
    879     return upCost;
    880 }
    881 // Return "down" estimate
    882 double
    883 CbcSimpleIntegerDynamicPseudoCost::downEstimate() const
    884 {
    885     const double * solution = model_->testSolution();
    886     const double * lower = model_->getCbcColLower();
    887     const double * upper = model_->getCbcColUpper();
    888     double value = solution[columnNumber_];
    889     value = CoinMax(value, lower[columnNumber_]);
    890     value = CoinMin(value, upper[columnNumber_]);
    891     if (upper[columnNumber_] == lower[columnNumber_]) {
    892         // fixed
    893         return 0.0;
    894     }
    895     double integerTolerance =
    896         model_->getDblParam(CbcModel::CbcIntegerTolerance);
    897     double below = floor(value + integerTolerance);
    898     double above = below + 1.0;
    899     if (above > upper[columnNumber_]) {
    900         above = below;
    901         below = above - 1;
    902     }
    903     double downCost = CoinMax((value - below) * downDynamicPseudoCost_, 0.0);
    904     return downCost;
    905 }
    906 // Set down pseudo cost
    907 void
    908 CbcSimpleIntegerDynamicPseudoCost::setDownDynamicPseudoCost(double value)
    909 {
    910 #ifdef TRACE_ONE
    911     double oldDown = sumDownCost_;
    912 #endif
    913     downDynamicPseudoCost_ = value;
    914     sumDownCost_ = CoinMax(sumDownCost_, value * numberTimesDown_);
    915 #ifdef TRACE_ONE
    916     if (columnNumber_ == TRACE_ONE) {
    917         double down = downDynamicPseudoCost_ * numberTimesDown_;
    918         printf("For %d sumDown %g (%d), inf (%d) - pseudo %g - sumDown was %g -> %g\n",
    919                TRACE_ONE, down, numberTimesDown_,
    920                numberTimesDownInfeasible_, downDynamicPseudoCost_,
    921                oldDown, sumDownCost_);
    922     }
    923 #endif
    924 }
    925 // Modify down pseudo cost in a slightly different way
    926 void
    927 CbcSimpleIntegerDynamicPseudoCost::updateDownDynamicPseudoCost(double value)
    928 {
    929     sumDownCost_ += value;
    930     numberTimesDown_++;
    931     downDynamicPseudoCost_ = sumDownCost_ / static_cast<double>(numberTimesDown_);
    932 }
    933 // Set up pseudo cost
    934 void
    935 CbcSimpleIntegerDynamicPseudoCost::setUpDynamicPseudoCost(double value)
    936 {
    937 #ifdef TRACE_ONE
    938     double oldUp = sumUpCost_;
    939 #endif
    940     upDynamicPseudoCost_ = value;
    941     sumUpCost_ = CoinMax(sumUpCost_, value * numberTimesUp_);
    942 #ifdef TRACE_ONE
    943     if (columnNumber_ == TRACE_ONE) {
    944         double up = upDynamicPseudoCost_ * numberTimesUp_;
    945         printf("For %d sumUp %g (%d), inf (%d) - pseudo %g - sumUp was %g -> %g\n",
    946                TRACE_ONE, up, numberTimesUp_,
    947                numberTimesUpInfeasible_, upDynamicPseudoCost_,
    948                oldUp, sumUpCost_);
    949     }
    950 #endif
    951 }
    952 // Modify up pseudo cost in a slightly different way
    953 void
    954 CbcSimpleIntegerDynamicPseudoCost::updateUpDynamicPseudoCost(double value)
    955 {
    956     sumUpCost_ += value;
    957     numberTimesUp_++;
    958     upDynamicPseudoCost_ = sumUpCost_ / static_cast<double>(numberTimesUp_);
    959 }
    960 /* Pass in information on branch just done and create CbcObjectUpdateData instance.
    961    If object does not need data then backward pointer will be NULL.
    962    Assumes can get information from solver */
    963 CbcObjectUpdateData
    964 CbcSimpleIntegerDynamicPseudoCost::createUpdateInformation(const OsiSolverInterface * solver,
    965         const CbcNode * node,
    966         const CbcBranchingObject * branchingObject)
    967 {
    968     double originalValue = node->objectiveValue();
    969     int originalUnsatisfied = node->numberUnsatisfied();
    970     double objectiveValue = solver->getObjValue() * solver->getObjSense();
    971     int unsatisfied = 0;
    972     int i;
    973     //might be base model - doesn't matter
    974     int numberIntegers = model_->numberIntegers();;
    975     const double * solution = solver->getColSolution();
    976     //const double * lower = solver->getColLower();
    977     //const double * upper = solver->getColUpper();
    978     double change = CoinMax(0.0, objectiveValue - originalValue);
    979     int iStatus;
    980     if (solver->isProvenOptimal())
    981         iStatus = 0; // optimal
    982     else if (solver->isIterationLimitReached()
    983              && !solver->isDualObjectiveLimitReached())
    984         iStatus = 2; // unknown
    985     else
    986         iStatus = 1; // infeasible
    987 
    988     bool feasible = iStatus != 1;
    989     if (feasible) {
    990         double integerTolerance =
    991             model_->getDblParam(CbcModel::CbcIntegerTolerance);
    992         const int * integerVariable = model_->integerVariable();
    993         for (i = 0; i < numberIntegers; i++) {
    994             int j = integerVariable[i];
    995             double value = solution[j];
    996             double nearest = floor(value + 0.5);
    997             if (fabs(value - nearest) > integerTolerance)
    998                 unsatisfied++;
    999         }
    1000     }
    1001     int way = branchingObject->way();
    1002     way = - way; // because after branch so moved on
    1003     double value = branchingObject->value();
    1004     CbcObjectUpdateData newData (this, way,
    1005                                  change, iStatus,
    1006                                  originalUnsatisfied - unsatisfied, value);
    1007     newData.originalObjective_ = originalValue;
    1008     // Solvers know about direction
    1009     double direction = solver->getObjSense();
    1010     solver->getDblParam(OsiDualObjectiveLimit, newData.cutoff_);
    1011     newData.cutoff_ *= direction;
    1012     return newData;
    1013 }
    1014 // Just update using feasible branches and keep count of infeasible
    1015 #undef INFEAS
    1016 // Update object by CbcObjectUpdateData
    1017 void
    1018 CbcSimpleIntegerDynamicPseudoCost::updateInformation(const CbcObjectUpdateData & data)
    1019 {
    1020     bool feasible = data.status_ != 1;
    1021     int way = data.way_;
    1022     double value = data.branchingValue_;
    1023     double change = data.change_;
    1024 #define TYPERATIO 0.9
    1025 #define MINIMUM_MOVEMENT 0.1
    1026 #ifdef COIN_DEVELOP
    1027     History hist;
    1028     hist.where_ = 'U'; // need to tell if hot
    1029 #endif
    1030     double movement = 0.0;
    1031     if (way < 0) {
    1032         // down
    1033         movement = value - floor(value);
    1034         if (feasible) {
    1035 #ifdef COIN_DEVELOP
    1036             hist.status_ = 'D';
    1037 #endif
    1038             movement = CoinMax(movement, MINIMUM_MOVEMENT);
    1039             //printf("(down change %g value down %g ",change,movement);
    1040             incrementNumberTimesDown();
    1041             addToSumDownChange(1.0e-30 + movement);
    1042             addToSumDownDecrease(data.intDecrease_);
    1043 #if TYPE2==0
    1044             addToSumDownCost(change / (1.0e-30 + movement));
    1045             setDownDynamicPseudoCost(sumDownCost() / static_cast<double>( numberTimesDown()));
    1046 #elif TYPE2==1
    1047             addToSumDownCost(change);
    1048             setDownDynamicPseudoCost(sumDownCost() / sumDownChange());
    1049 #elif TYPE2==2
    1050             addToSumDownCost(change*TYPERATIO + (1.0 - TYPERATIO)*change / (1.0e-30 + movement));
    1051             setDownDynamicPseudoCost(sumDownCost()*(TYPERATIO / sumDownChange() + (1.0 - TYPERATIO) / (double) numberTimesDown()));
    1052 #endif
    1053         } else {
    1054 #ifdef COIN_DEVELOP
    1055             hist.status_ = 'd';
    1056 #endif
    1057             //printf("(down infeasible value down %g ",change,movement);
    1058             incrementNumberTimesDown();
    1059             incrementNumberTimesDownInfeasible();
    1060 #if INFEAS==2
    1061             double distanceToCutoff = 0.0;
    1062             double objectiveValue = model->getCurrentMinimizationObjValue();
    1063             distanceToCutoff =  model->getCutoff()  - originalValue;
    1064             if (distanceToCutoff < 1.0e20)
    1065                 change = distanceToCutoff * 2.0;
    1066             else
    1067                 change = downDynamicPseudoCost() * movement * 10.0;
    1068             change = CoinMax(1.0e-12 * (1.0 + fabs(originalValue)), change);
    1069             addToSumDownChange(1.0e-30 + movement);
    1070             addToSumDownDecrease(data.intDecrease_);
    1071 #if TYPE2==0
    1072             addToSumDownCost(change / (1.0e-30 + movement));
    1073             setDownDynamicPseudoCost(sumDownCost() / (double) numberTimesDown());
    1074 #elif TYPE2==1
    1075             addToSumDownCost(change);
    1076             setDownDynamicPseudoCost(sumDownCost() / sumDownChange());
    1077 #elif TYPE2==2
    1078             addToSumDownCost(change*TYPERATIO + (1.0 - TYPERATIO)*change / (1.0e-30 + movement));
    1079             setDownDynamicPseudoCost(sumDownCost()*(TYPERATIO / sumDownChange() + (1.0 - TYPERATIO) / (double) numberTimesDown()));
    1080 #endif
    1081 #endif
    1082         }
    1083 #if INFEAS==1
    1084         double sum = sumDownCost_;
    1085         int number = numberTimesDown_;
    1086         double originalValue = data.originalObjective_;
    1087         assert (originalValue != COIN_DBL_MAX);
    1088         double distanceToCutoff =  data.cutoff_  - originalValue;
    1089         if (distanceToCutoff > 1.0e20)
    1090             distanceToCutoff = 10.0 + fabs(originalValue);
    1091         sum += numberTimesDownInfeasible_ * CoinMax(distanceToCutoff, 1.0e-12 * (1.0 + fabs(originalValue)));
    1092         setDownDynamicPseudoCost(sum / static_cast<double> (number));
    1093 #endif
    1094     } else {
    1095         // up
    1096         movement = ceil(value) - value;
    1097         if (feasible) {
    1098 #ifdef COIN_DEVELOP
    1099             hist.status_ = 'U';
    1100 #endif
    1101             movement = CoinMax(movement, MINIMUM_MOVEMENT);
    1102             //printf("(up change %g value down %g ",change,movement);
    1103             incrementNumberTimesUp();
    1104             addToSumUpChange(1.0e-30 + movement);
    1105             addToSumUpDecrease(data.intDecrease_);
    1106 #if TYPE2==0
    1107             addToSumUpCost(change / (1.0e-30 + movement));
    1108             setUpDynamicPseudoCost(sumUpCost() / static_cast<double> (numberTimesUp()));
    1109 #elif TYPE2==1
    1110             addToSumUpCost(change);
    1111             setUpDynamicPseudoCost(sumUpCost() / sumUpChange());
    1112 #elif TYPE2==2
    1113             addToSumUpCost(change*TYPERATIO + (1.0 - TYPERATIO)*change / (1.0e-30 + movement));
    1114             setUpDynamicPseudoCost(sumUpCost()*(TYPERATIO / sumUpChange() + (1.0 - TYPERATIO) / (double) numberTimesUp()));
    1115 #endif
    1116         } else {
    1117 #ifdef COIN_DEVELOP
    1118             hist.status_ = 'u';
    1119 #endif
    1120             //printf("(up infeasible value down %g ",change,movement);
    1121             incrementNumberTimesUp();
    1122             incrementNumberTimesUpInfeasible();
    1123 #if INFEAS==2
    1124             double distanceToCutoff = 0.0;
    1125             double objectiveValue = model->getCurrentMinimizationObjValue();
    1126             distanceToCutoff =  model->getCutoff()  - originalValue;
    1127             if (distanceToCutoff < 1.0e20)
    1128                 change = distanceToCutoff * 2.0;
    1129             else
    1130                 change = upDynamicPseudoCost() * movement * 10.0;
    1131             change = CoinMax(1.0e-12 * (1.0 + fabs(originalValue)), change);
    1132             addToSumUpChange(1.0e-30 + movement);
    1133             addToSumUpDecrease(data.intDecrease_);
    1134 #if TYPE2==0
    1135             addToSumUpCost(change / (1.0e-30 + movement));
    1136             setUpDynamicPseudoCost(sumUpCost() / (double) numberTimesUp());
    1137 #elif TYPE2==1
    1138             addToSumUpCost(change);
    1139             setUpDynamicPseudoCost(sumUpCost() / sumUpChange());
    1140 #elif TYPE2==2
    1141             addToSumUpCost(change*TYPERATIO + (1.0 - TYPERATIO)*change / (1.0e-30 + movement));
    1142             setUpDynamicPseudoCost(sumUpCost()*(TYPERATIO / sumUpChange() + (1.0 - TYPERATIO) / (double) numberTimesUp()));
    1143 #endif
    1144 #endif
    1145         }
    1146 #if INFEAS==1
    1147         double sum = sumUpCost_;
    1148         int number = numberTimesUp_;
    1149         double originalValue = data.originalObjective_;
    1150         assert (originalValue != COIN_DBL_MAX);
    1151         double distanceToCutoff =  data.cutoff_  - originalValue;
    1152         if (distanceToCutoff > 1.0e20)
    1153             distanceToCutoff = 10.0 + fabs(originalValue);
    1154         sum += numberTimesUpInfeasible_ * CoinMax(distanceToCutoff, 1.0e-12 * (1.0 + fabs(originalValue)));
    1155         setUpDynamicPseudoCost(sum / static_cast<double> (number));
    1156 #endif
    1157     }
    1158     if (data.way_ < 0)
    1159         assert (numberTimesDown_ > 0);
    1160     else
    1161         assert (numberTimesUp_ > 0);
    1162     assert (downDynamicPseudoCost_ >= 0.0 && downDynamicPseudoCost_ < 1.0e100);
    1163     downDynamicPseudoCost_ = CoinMax(1.0e-10, downDynamicPseudoCost_);
    1164     assert (upDynamicPseudoCost_ >= 0.0 && upDynamicPseudoCost_ < 1.0e100);
    1165     upDynamicPseudoCost_ = CoinMax(1.0e-10, upDynamicPseudoCost_);
    1166 #ifdef COIN_DEVELOP
    1167     hist.sequence_ = columnNumber_;
    1168     hist.numberUp_ = numberTimesUp_;
    1169     hist.numberUpInf_ = numberTimesUpInfeasible_;
    1170     hist.sumUp_ = sumUpCost_;
    1171     hist.upEst_ = change;
    1172     hist.numberDown_ = numberTimesDown_;
    1173     hist.numberDownInf_ = numberTimesDownInfeasible_;
    1174     hist.sumDown_ = sumDownCost_;
    1175     hist.downEst_ = movement;
    1176     addRecord(hist);
    1177 #endif
    1178     //print(1,0.5);
    1179     assert (downDynamicPseudoCost_ > 1.0e-40 && upDynamicPseudoCost_ > 1.0e-40);
    1180 #if MOD_SHADOW>1
    1181     if (upShadowPrice_ > 0.0 && numberTimesDown_ >= numberBeforeTrust_
    1182             && numberTimesUp_ >= numberBeforeTrust_) {
    1183         // Set negative
    1184         upShadowPrice_ = -upShadowPrice_;
    1185         assert (downShadowPrice_ > 0.0);
    1186         downShadowPrice_ = - downShadowPrice_;
    1187     }
    1188 #endif
    1189 }
    1190 // Updates stuff like pseudocosts after mini branch and bound
    1191 void
    1192 CbcSimpleIntegerDynamicPseudoCost::updateAfterMini(int numberDown, int numberDownInfeasible,
    1193         double sumDown, int numberUp,
    1194         int numberUpInfeasible, double sumUp)
    1195 {
    1196     numberTimesDown_ = numberDown;
    1197     numberTimesDownInfeasible_ = numberDownInfeasible;
    1198     sumDownCost_ = sumDown;
    1199     numberTimesUp_ = numberUp;
    1200     numberTimesUpInfeasible_ = numberUpInfeasible;
    1201     sumUpCost_ = sumUp;
    1202     if (numberTimesDown_ > 0) {
    1203         setDownDynamicPseudoCost(sumDownCost_ / static_cast<double> (numberTimesDown_));
    1204         assert (downDynamicPseudoCost_ > 0.0 && downDynamicPseudoCost_ < 1.0e50);
    1205     }
    1206     if (numberTimesUp_ > 0) {
    1207         setUpDynamicPseudoCost(sumUpCost_ / static_cast<double> (numberTimesUp_));
    1208         assert (upDynamicPseudoCost_ > 0.0 && upDynamicPseudoCost_ < 1.0e50);
    1209     }
    1210     assert (downDynamicPseudoCost_ > 1.0e-40 && upDynamicPseudoCost_ > 1.0e-40);
    1211 }
    1212 // Pass in probing information
    1213 void
    1214 CbcSimpleIntegerDynamicPseudoCost::setProbingInformation(int fixedDown, int fixedUp)
    1215 {
    1216     numberTimesProbingTotal_++;
    1217     numberTimesDownLocalFixed_ = fixedDown;
    1218     numberTimesDownTotalFixed_ += fixedDown;
    1219     numberTimesUpLocalFixed_ = fixedUp;
    1220     numberTimesUpTotalFixed_ += fixedUp;
    1221 }
    1222 // Print
    1223 void
    1224 CbcSimpleIntegerDynamicPseudoCost::print(int type, double value) const
    1225 {
    1226     if (!type) {
    1227         double meanDown = 0.0;
    1228         double devDown = 0.0;
    1229         if (numberTimesDown_) {
    1230             meanDown = sumDownCost_ / static_cast<double> (numberTimesDown_);
    1231             devDown = meanDown * meanDown - 2.0 * meanDown * sumDownCost_;
    1232             if (devDown >= 0.0)
    1233                 devDown = sqrt(devDown);
    1234         }
    1235         double meanUp = 0.0;
    1236         double devUp = 0.0;
    1237         if (numberTimesUp_) {
    1238             meanUp = sumUpCost_ / static_cast<double> (numberTimesUp_);
    1239             devUp = meanUp * meanUp - 2.0 * meanUp * sumUpCost_;
    1240             if (devUp >= 0.0)
    1241                 devUp = sqrt(devUp);
    1242         }
    1243         printf("%d down %d times (%d inf) mean %g (dev %g) up %d times (%d inf) mean %g (dev %g)\n",
    1244                columnNumber_,
    1245                numberTimesDown_, numberTimesDownInfeasible_, meanDown, devDown,
    1246                numberTimesUp_, numberTimesUpInfeasible_, meanUp, devUp);
    1247     } else {
    1248         const double * upper = model_->getCbcColUpper();
    1249         double integerTolerance =
    1250             model_->getDblParam(CbcModel::CbcIntegerTolerance);
    1251         double below = floor(value + integerTolerance);
    1252         double above = below + 1.0;
    1253         if (above > upper[columnNumber_]) {
    1254             above = below;
    1255             below = above - 1;
    1256         }
    1257         double objectiveValue = model_->getCurrentMinimizationObjValue();
    1258         double distanceToCutoff =  model_->getCutoff() - objectiveValue;
    1259         if (distanceToCutoff < 1.0e20)
    1260             distanceToCutoff *= 10.0;
    1261         else
    1262             distanceToCutoff = 1.0e2 + fabs(objectiveValue);
    1263         distanceToCutoff = CoinMax(distanceToCutoff, 1.0e-12 * (1.0 + fabs(objectiveValue)));
    1264         double sum;
    1265         int number;
    1266         double downCost = CoinMax(value - below, 0.0);
    1267         double downCost0 = downCost * downDynamicPseudoCost_;
    1268         sum = sumDownCost();
    1269         number = numberTimesDown();
    1270         sum += numberTimesDownInfeasible() * (distanceToCutoff / (downCost + 1.0e-12));
    1271         if (number > 0)
    1272             downCost *= sum / static_cast<double> (number);
    1273         else
    1274             downCost  *=  downDynamicPseudoCost_;
    1275         double upCost = CoinMax((above - value), 0.0);
    1276         double upCost0 = upCost * upDynamicPseudoCost_;
    1277         sum = sumUpCost();
    1278         number = numberTimesUp();
    1279         sum += numberTimesUpInfeasible() * (distanceToCutoff / (upCost + 1.0e-12));
    1280         if (number > 0)
    1281             upCost *= sum / static_cast<double> (number);
    1282         else
    1283             upCost  *=  upDynamicPseudoCost_;
    1284         printf("%d down %d times %g (est %g)  up %d times %g (est %g)\n",
    1285                columnNumber_,
    1286                numberTimesDown_, downCost, downCost0,
    1287                numberTimesUp_, upCost, upCost0);
    1288     }
    1289 }
    1290 
    1291 // Default Constructor
    1292 CbcDynamicPseudoCostBranchingObject::CbcDynamicPseudoCostBranchingObject()
    1293         : CbcIntegerBranchingObject()
    1294 {
    1295     changeInGuessed_ = 1.0e-5;
    1296     object_ = NULL;
    1297 }
    1298 
    1299 // Useful constructor
    1300 CbcDynamicPseudoCostBranchingObject::CbcDynamicPseudoCostBranchingObject (CbcModel * model,
    1301         int variable,
    1302         int way , double value,
    1303         CbcSimpleIntegerDynamicPseudoCost * object)
    1304         : CbcIntegerBranchingObject(model, variable, way, value)
    1305 {
    1306     changeInGuessed_ = 1.0e-5;
    1307     object_ = object;
    1308 }
    1309 // Does part of work for constructor
    1310 void
    1311 CbcDynamicPseudoCostBranchingObject::fillPart (int variable,
    1312         int way , double value,
    1313         CbcSimpleIntegerDynamicPseudoCost * object)
    1314 {
    1315     CbcIntegerBranchingObject::fillPart(variable, way, value);
    1316     changeInGuessed_ = 1.0e-5;
    1317     object_ = object;
    1318 }
    1319 // Useful constructor for fixing
    1320 CbcDynamicPseudoCostBranchingObject::CbcDynamicPseudoCostBranchingObject (CbcModel * model,
    1321         int variable, int way,
    1322         double lowerValue,
    1323         double /*upperValue*/)
    1324         : CbcIntegerBranchingObject(model, variable, way, lowerValue)
    1325 {
    1326     changeInGuessed_ = 1.0e100;
    1327     object_ = NULL;
    1328 }
    1329 
    1330 
    1331 // Copy constructor
    1332 CbcDynamicPseudoCostBranchingObject::CbcDynamicPseudoCostBranchingObject (
    1333     const CbcDynamicPseudoCostBranchingObject & rhs)
    1334         : CbcIntegerBranchingObject(rhs)
    1335 {
    1336     changeInGuessed_ = rhs.changeInGuessed_;
    1337     object_ = rhs.object_;
    1338 }
    1339 
    1340 // Assignment operator
    1341 CbcDynamicPseudoCostBranchingObject &
    1342 CbcDynamicPseudoCostBranchingObject::operator=( const CbcDynamicPseudoCostBranchingObject & rhs)
    1343 {
    1344     if (this != &rhs) {
    1345         CbcIntegerBranchingObject::operator=(rhs);
    1346         changeInGuessed_ = rhs.changeInGuessed_;
    1347         object_ = rhs.object_;
    1348     }
    1349     return *this;
    1350 }
    1351 CbcBranchingObject *
    1352 CbcDynamicPseudoCostBranchingObject::clone() const
    1353 {
    1354     return (new CbcDynamicPseudoCostBranchingObject(*this));
    1355 }
    1356 
    1357 // Destructor
    1358 CbcDynamicPseudoCostBranchingObject::~CbcDynamicPseudoCostBranchingObject ()
    1359 {
    1360 }
    1361 
    1362 /*
    1363   Perform a branch by adjusting the bounds of the specified variable. Note
    1364   that each arm of the branch advances the object to the next arm by
    1365   advancing the value of way_.
    1366 
    1367   Providing new values for the variable's lower and upper bounds for each
    1368   branching direction gives a little bit of additional flexibility and will
    1369   be easily extensible to multi-way branching.
    1370   Returns change in guessed objective on next branch
    1371 */
    1372 double
    1373 CbcDynamicPseudoCostBranchingObject::branch()
    1374 {
    1375     CbcIntegerBranchingObject::branch();
    1376     return changeInGuessed_;
    1377 }
    1378 /* Some branchingObjects may claim to be able to skip
    1379    strong branching.  If so they have to fill in CbcStrongInfo.
    1380    The object mention in incoming CbcStrongInfo must match.
    1381    Returns nonzero if skip is wanted */
    1382 int
    1383 CbcDynamicPseudoCostBranchingObject::fillStrongInfo( CbcStrongInfo & info)
    1384 {
    1385     assert (object_);
    1386     assert (info.possibleBranch == this);
    1387     info.upMovement = object_->upDynamicPseudoCost() * (ceil(value_) - value_);
    1388     info.downMovement = object_->downDynamicPseudoCost() * (value_ - floor(value_));
    1389     info.numIntInfeasUp  -= static_cast<int> (object_->sumUpDecrease() /
    1390                             (1.0e-12 + static_cast<double> (object_->numberTimesUp())));
    1391     info.numIntInfeasUp = CoinMax(info.numIntInfeasUp, 0);
    1392     info.numObjInfeasUp = 0;
    1393     info.finishedUp = false;
    1394     info.numItersUp = 0;
    1395     info.numIntInfeasDown  -= static_cast<int> (object_->sumDownDecrease() /
    1396                               (1.0e-12 + static_cast<double> (object_->numberTimesDown())));
    1397     info.numIntInfeasDown = CoinMax(info.numIntInfeasDown, 0);
    1398     info.numObjInfeasDown = 0;
    1399     info.finishedDown = false;
    1400     info.numItersDown = 0;
    1401     info.fix = 0;
    1402     if (object_->numberTimesUp() < object_->numberBeforeTrust() +
    1403             2*object_->numberTimesUpInfeasible() ||
    1404             object_->numberTimesDown() < object_->numberBeforeTrust() +
    1405             2*object_->numberTimesDownInfeasible()) {
    1406         return 0;
    1407     } else {
    1408         return 1;
    1409     }
    1410 }
     105
    1411106
    1412107// Default Constructor
  • branches/sandbox/Cbc/src/CbcBranchDynamic.hpp

    r1286 r1308  
    77#include "CbcBranchActual.hpp"
    88#include "CoinPackedMatrix.hpp"
     9#include "CbcSimpleIntegerDynamicPseudoCost.hpp"
     10#include "CbcDynamicPseudoCostBranchingObject.hpp"
    911
    10 
    11 /** Define a single integer class but with dynamic pseudo costs.
    12     Based on work by Achterberg, Koch and Martin.
    13 
    14     It is wild overkill but to keep design all twiddly things are in each.
    15     This could be used for fine tuning.
    16 
    17  */
    18 
    19 
    20 class CbcSimpleIntegerDynamicPseudoCost : public CbcSimpleInteger {
    21 
    22 public:
    23 
    24     // Default Constructor
    25     CbcSimpleIntegerDynamicPseudoCost ();
    26 
    27     // Useful constructor - passed  model index
    28     CbcSimpleIntegerDynamicPseudoCost (CbcModel * model,  int iColumn, double breakEven = 0.5);
    29 
    30     // Useful constructor - passed  model index and pseudo costs
    31     CbcSimpleIntegerDynamicPseudoCost (CbcModel * model, int iColumn,
    32                                        double downDynamicPseudoCost, double upDynamicPseudoCost);
    33 
    34     // Useful constructor - passed  model index and pseudo costs
    35     CbcSimpleIntegerDynamicPseudoCost (CbcModel * model, int dummy, int iColumn,
    36                                        double downDynamicPseudoCost, double upDynamicPseudoCost);
    37 
    38     // Copy constructor
    39     CbcSimpleIntegerDynamicPseudoCost ( const CbcSimpleIntegerDynamicPseudoCost &);
    40 
    41     /// Clone
    42     virtual CbcObject * clone() const;
    43 
    44     // Assignment operator
    45     CbcSimpleIntegerDynamicPseudoCost & operator=( const CbcSimpleIntegerDynamicPseudoCost& rhs);
    46 
    47     // Destructor
    48     virtual ~CbcSimpleIntegerDynamicPseudoCost ();
    49 
    50     /// Infeasibility - large is 0.5
    51     virtual double infeasibility(const OsiBranchingInformation * info,
    52                                  int &preferredWay) const;
    53 
    54     /// Creates a branching object
    55     virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ;
    56 
    57 
    58     /// Fills in a created branching object
    59     void fillCreateBranch(CbcIntegerBranchingObject * branching, const OsiBranchingInformation * info, int way) ;
    60 
    61 
    62     /** Pass in information on branch just done and create CbcObjectUpdateData instance.
    63         If object does not need data then backward pointer will be NULL.
    64         Assumes can get information from solver */
    65     virtual CbcObjectUpdateData createUpdateInformation(const OsiSolverInterface * solver,
    66             const CbcNode * node,
    67             const CbcBranchingObject * branchingObject);
    68     /// Update object by CbcObjectUpdateData
    69     virtual void updateInformation(const CbcObjectUpdateData & data) ;
    70     /// Copy some information i.e. just variable stuff
    71     void copySome(const CbcSimpleIntegerDynamicPseudoCost * otherObject);
    72     /// Updates stuff like pseudocosts before threads
    73     virtual void updateBefore(const OsiObject * rhs) ;
    74     /// Updates stuff like pseudocosts after threads finished
    75     virtual void updateAfter(const OsiObject * rhs, const OsiObject * baseObject) ;
    76     /// Updates stuff like pseudocosts after mini branch and bound
    77     void updateAfterMini(int numberDown, int numberDownInfeasible, double sumDown,
    78                          int numberUp, int numberUpInfeasible, double sumUp);
    79 
    80     using CbcSimpleInteger::solverBranch ;
    81     /** Create an OsiSolverBranch object
    82 
    83         This returns NULL if branch not represented by bound changes
    84     */
    85     virtual OsiSolverBranch * solverBranch() const;
    86 
    87     /// Down pseudo cost
    88     inline double downDynamicPseudoCost() const {
    89         return downDynamicPseudoCost_;
    90     }
    91     /// Set down pseudo cost
    92     void setDownDynamicPseudoCost(double value) ;
    93     /// Modify down pseudo cost in a slightly different way
    94     void updateDownDynamicPseudoCost(double value);
    95 
    96     /// Up pseudo cost
    97     inline double upDynamicPseudoCost() const {
    98         return upDynamicPseudoCost_;
    99     }
    100     /// Set up pseudo cost
    101     void setUpDynamicPseudoCost(double value);
    102     /// Modify up pseudo cost in a slightly different way
    103     void updateUpDynamicPseudoCost(double value);
    104 
    105     /// Down pseudo shadow price cost
    106     inline double downShadowPrice() const {
    107         return downShadowPrice_;
    108     }
    109     /// Set down pseudo shadow price cost
    110     inline void setDownShadowPrice(double value) {
    111         downShadowPrice_ = value;
    112     }
    113     /// Up pseudo shadow price cost
    114     inline double upShadowPrice() const {
    115         return upShadowPrice_;
    116     }
    117     /// Set up pseudo shadow price cost
    118     inline void setUpShadowPrice(double value) {
    119         upShadowPrice_ = value;
    120     }
    121 
    122     /// Up down separator
    123     inline double upDownSeparator() const {
    124         return upDownSeparator_;
    125     }
    126     /// Set up down separator
    127     inline void setUpDownSeparator(double value) {
    128         upDownSeparator_ = value;
    129     }
    130 
    131     /// Down sum cost
    132     inline double sumDownCost() const {
    133         return sumDownCost_;
    134     }
    135     /// Set down sum cost
    136     inline void setSumDownCost(double value) {
    137         sumDownCost_ = value;
    138     }
    139     /// Add to down sum cost and set last and square
    140     inline void addToSumDownCost(double value) {
    141         sumDownCost_ += value;
    142         lastDownCost_ = value;
    143     }
    144 
    145     /// Up sum cost
    146     inline double sumUpCost() const {
    147         return sumUpCost_;
    148     }
    149     /// Set up sum cost
    150     inline void setSumUpCost(double value) {
    151         sumUpCost_ = value;
    152     }
    153     /// Add to up sum cost and set last and square
    154     inline void addToSumUpCost(double value) {
    155         sumUpCost_ += value;
    156         lastUpCost_ = value;
    157     }
    158 
    159     /// Down sum change
    160     inline double sumDownChange() const {
    161         return sumDownChange_;
    162     }
    163     /// Set down sum change
    164     inline void setSumDownChange(double value) {
    165         sumDownChange_ = value;
    166     }
    167     /// Add to down sum change
    168     inline void addToSumDownChange(double value) {
    169         sumDownChange_ += value;
    170     }
    171 
    172     /// Up sum change
    173     inline double sumUpChange() const {
    174         return sumUpChange_;
    175     }
    176     /// Set up sum change
    177     inline void setSumUpChange(double value) {
    178         sumUpChange_ = value;
    179     }
    180     /// Add to up sum change and set last and square
    181     inline void addToSumUpChange(double value) {
    182         sumUpChange_ += value;
    183     }
    184 
    185     /// Sum down decrease number infeasibilities from strong or actual
    186     inline double sumDownDecrease() const {
    187         return sumDownDecrease_;
    188     }
    189     /// Set sum down decrease number infeasibilities from strong or actual
    190     inline void setSumDownDecrease(double value) {
    191         sumDownDecrease_ = value;
    192     }
    193     /// Add to sum down decrease number infeasibilities from strong or actual
    194     inline void addToSumDownDecrease(double value) {
    195         sumDownDecrease_ += value;/*lastDownDecrease_ = (int) value;*/
    196     }
    197 
    198     /// Sum up decrease number infeasibilities from strong or actual
    199     inline double sumUpDecrease() const {
    200         return sumUpDecrease_;
    201     }
    202     /// Set sum up decrease number infeasibilities from strong or actual
    203     inline void setSumUpDecrease(double value) {
    204         sumUpDecrease_ = value;
    205     }
    206     /// Add to sum up decrease number infeasibilities from strong or actual
    207     inline void addToSumUpDecrease(double value) {
    208         sumUpDecrease_ += value;/*lastUpDecrease_ = (int) value;*/
    209     }
    210 
    211     /// Down number times
    212     inline int numberTimesDown() const {
    213         return numberTimesDown_;
    214     }
    215     /// Set down number times
    216     inline void setNumberTimesDown(int value) {
    217         numberTimesDown_ = value;
    218     }
    219     /// Increment down number times
    220     inline void incrementNumberTimesDown() {
    221         numberTimesDown_++;
    222     }
    223 
    224     /// Up number times
    225     inline int numberTimesUp() const {
    226         return numberTimesUp_;
    227     }
    228     /// Set up number times
    229     inline void setNumberTimesUp(int value) {
    230         numberTimesUp_ = value;
    231     }
    232     /// Increment up number times
    233     inline void incrementNumberTimesUp() {
    234         numberTimesUp_++;
    235     }
    236 
    237     /// Down number times infeasible
    238     inline int numberTimesDownInfeasible() const {
    239         return numberTimesDownInfeasible_;
    240     }
    241     /// Set down number times infeasible
    242     inline void setNumberTimesDownInfeasible(int value) {
    243         numberTimesDownInfeasible_ = value;
    244     }
    245     /// Increment down number times infeasible
    246     inline void incrementNumberTimesDownInfeasible() {
    247         numberTimesDownInfeasible_++;
    248     }
    249 
    250     /// Up number times infeasible
    251     inline int numberTimesUpInfeasible() const {
    252         return numberTimesUpInfeasible_;
    253     }
    254     /// Set up number times infeasible
    255     inline void setNumberTimesUpInfeasible(int value) {
    256         numberTimesUpInfeasible_ = value;
    257     }
    258     /// Increment up number times infeasible
    259     inline void incrementNumberTimesUpInfeasible() {
    260         numberTimesUpInfeasible_++;
    261     }
    262 
    263     /// Number of times before trusted
    264     inline int numberBeforeTrust() const {
    265         return numberBeforeTrust_;
    266     }
    267     /// Set number of times before trusted
    268     inline void setNumberBeforeTrust(int value) {
    269         numberBeforeTrust_ = value;
    270     }
    271     /// Increment number of times before trusted
    272     inline void incrementNumberBeforeTrust() {
    273         numberBeforeTrust_++;
    274     }
    275 
    276     /// Return "up" estimate
    277     virtual double upEstimate() const;
    278     /// Return "down" estimate (default 1.0e-5)
    279     virtual double downEstimate() const;
    280 
    281     /// method - see below for details
    282     inline int method() const {
    283         return method_;
    284     }
    285     /// Set method
    286     inline void setMethod(int value) {
    287         method_ = value;
    288     }
    289 
    290     /// Pass in information on a down branch
    291     void setDownInformation(double changeObjectiveDown, int changeInfeasibilityDown);
    292     /// Pass in information on a up branch
    293     void setUpInformation(double changeObjectiveUp, int changeInfeasibilityUp);
    294     /// Pass in probing information
    295     void setProbingInformation(int fixedDown, int fixedUp);
    296 
    297     /// Print - 0 -summary, 1 just before strong
    298     void print(int type = 0, double value = 0.0) const;
    299     /// Same - returns true if contents match(ish)
    300     bool same(const CbcSimpleIntegerDynamicPseudoCost * obj) const;
    301 protected:
    302     /// data
    303 
    304     /// Down pseudo cost
    305     double downDynamicPseudoCost_;
    306     /// Up pseudo cost
    307     double upDynamicPseudoCost_;
    308     /** Up/down separator
    309         If >0.0 then do first branch up if value-floor(value)
    310         >= this value
    311     */
    312     double upDownSeparator_;
    313     /// Sum down cost from strong or actual
    314     double sumDownCost_;
    315     /// Sum up cost from strong or actual
    316     double sumUpCost_;
    317     /// Sum of all changes to x when going down
    318     double sumDownChange_;
    319     /// Sum of all changes to x when going up
    320     double sumUpChange_;
    321     /// Current pseudo-shadow price estimate down
    322     mutable double downShadowPrice_;
    323     /// Current pseudo-shadow price estimate up
    324     mutable double upShadowPrice_;
    325     /// Sum down decrease number infeasibilities from strong or actual
    326     double sumDownDecrease_;
    327     /// Sum up decrease number infeasibilities from strong or actual
    328     double sumUpDecrease_;
    329     /// Last down cost from strong (i.e. as computed by last strong)
    330     double lastDownCost_;
    331     /// Last up cost from strong (i.e. as computed by last strong)
    332     double lastUpCost_;
    333     /// Last down decrease number infeasibilities from strong (i.e. as computed by last strong)
    334     mutable int lastDownDecrease_;
    335     /// Last up decrease number infeasibilities from strong (i.e. as computed by last strong)
    336     mutable int lastUpDecrease_;
    337     /// Number of times we have gone down
    338     int numberTimesDown_;
    339     /// Number of times we have gone up
    340     int numberTimesUp_;
    341     /// Number of times we have been infeasible going down
    342     int numberTimesDownInfeasible_;
    343     /// Number of times we have been infeasible going up
    344     int numberTimesUpInfeasible_;
    345     /// Number of branches before we trust
    346     int numberBeforeTrust_;
    347     /// Number of local probing fixings going down
    348     int numberTimesDownLocalFixed_;
    349     /// Number of local probing fixings going up
    350     int numberTimesUpLocalFixed_;
    351     /// Number of total probing fixings going down
    352     double numberTimesDownTotalFixed_;
    353     /// Number of total probing fixings going up
    354     double numberTimesUpTotalFixed_;
    355     /// Number of times probing done
    356     int numberTimesProbingTotal_;
    357     /// Number of times infeasible when tested
    358     /** Method -
    359         0 - pseudo costs
    360         1 - probing
    361     */
    362     int method_;
    363 };
    364 
    365 
    366 /** Simple branching object for an integer variable with pseudo costs
    367 
    368   This object can specify a two-way branch on an integer variable. For each
    369   arm of the branch, the upper and lower bounds on the variable can be
    370   independently specified.
    371 
    372   Variable_ holds the index of the integer variable in the integerVariable_
    373   array of the model.
    374 */
    375 
    376 class CbcDynamicPseudoCostBranchingObject : public CbcIntegerBranchingObject {
    377 
    378 public:
    379 
    380     /// Default constructor
    381     CbcDynamicPseudoCostBranchingObject ();
    382 
    383     /** Create a standard floor/ceiling branch object
    384 
    385       Specifies a simple two-way branch. Let \p value = x*. One arm of the
    386       branch will be is lb <= x <= floor(x*), the other ceil(x*) <= x <= ub.
    387       Specify way = -1 to set the object state to perform the down arm first,
    388       way = 1 for the up arm.
    389     */
    390     CbcDynamicPseudoCostBranchingObject (CbcModel *model, int variable,
    391                                          int way , double value,
    392                                          CbcSimpleIntegerDynamicPseudoCost * object) ;
    393 
    394     /** Create a degenerate branch object
    395 
    396       Specifies a `one-way branch'. Calling branch() for this object will
    397       always result in lowerValue <= x <= upperValue. Used to fix a variable
    398       when lowerValue = upperValue.
    399     */
    400 
    401     CbcDynamicPseudoCostBranchingObject (CbcModel *model, int variable, int way,
    402                                          double lowerValue, double upperValue) ;
    403 
    404     /// Copy constructor
    405     CbcDynamicPseudoCostBranchingObject ( const CbcDynamicPseudoCostBranchingObject &);
    406 
    407     /// Assignment operator
    408     CbcDynamicPseudoCostBranchingObject & operator= (const CbcDynamicPseudoCostBranchingObject& rhs);
    409 
    410     /// Clone
    411     virtual CbcBranchingObject * clone() const;
    412 
    413     /// Destructor
    414     virtual ~CbcDynamicPseudoCostBranchingObject ();
    415 
    416     /// Does part of constructor
    417     void fillPart (int variable,
    418                    int way , double value,
    419                    CbcSimpleIntegerDynamicPseudoCost * object) ;
    420 
    421     using CbcBranchingObject::branch ;
    422     /** \brief Sets the bounds for the variable according to the current arm
    423            of the branch and advances the object state to the next arm.
    424            This version also changes guessed objective value
    425     */
    426     virtual double branch();
    427 
    428     /** Some branchingObjects may claim to be able to skip
    429         strong branching.  If so they have to fill in CbcStrongInfo.
    430         The object mention in incoming CbcStrongInfo must match.
    431         Returns nonzero if skip is wanted */
    432     virtual int fillStrongInfo( CbcStrongInfo & info);
    433 
    434     /// Change in guessed
    435     inline double changeInGuessed() const {
    436         return changeInGuessed_;
    437     }
    438     /// Set change in guessed
    439     inline void setChangeInGuessed(double value) {
    440         changeInGuessed_ = value;
    441     }
    442     /// Return object
    443     inline CbcSimpleIntegerDynamicPseudoCost * object() const {
    444         return object_;
    445     }
    446     /// Set object
    447     inline void setObject(CbcSimpleIntegerDynamicPseudoCost * object) {
    448         object_ = object;
    449     }
    450 
    451     /** Return the type (an integer identifier) of \c this */
    452     virtual int type() const {
    453         return 400;
    454     }
    455 
    456     // LL: compareOriginalObject and compareBranchingObject are inherited from
    457     // CbcIntegerBranchingObject thus need not be declared/defined here. After
    458     // all, this kind of branching object is simply using pseudocosts to make
    459     // decisions, but once the decisions are made they are the same kind as in
    460     // the underlying class.
    461 
    462 protected:
    463     /// Change in guessed objective value for next branch
    464     double changeInGuessed_;
    465     /// Pointer back to object
    466     CbcSimpleIntegerDynamicPseudoCost * object_;
    467 
    468 };
    46912/** Branching decision dynamic class
    47013
  • branches/sandbox/Cbc/src/CbcBranchLotsize.cpp

    r1286 r1308  
    1717#include "CoinSort.hpp"
    1818#include "CoinError.hpp"
    19 /*
    20   CBC_PRINT 1 just does sanity checks - no printing
    21             2
    22 */
    23 //#define CBC_PRINT 1
    24 // First/last variable to print info on
    25 #if CBC_PRINT
    26 // preset does all - change to x,x to just do x
    27 static int firstPrint = 0;
    28 static int lastPrint = 1000000;
    29 static CbcModel * saveModel = NULL;
    30 #endif
    31 // Just for debug (CBC_PRINT defined in CbcBranchLotsize.cpp)
    32 void
    33 #if CBC_PRINT
    34 CbcLotsize::printLotsize(double value, bool condition, int type) const
    35 #else
    36 CbcLotsize::printLotsize(double , bool , int ) const
    37 #endif
    38 {
    39 #if CBC_PRINT
    40     if (columnNumber_ >= firstPrint && columnNumber_ <= lastPrint) {
    41         int printIt = CBC_PRINT - 1;
    42         // Get details
    43         OsiSolverInterface * solver = saveModel->solver();
    44         double currentLower = solver->getColLower()[columnNumber_];
    45         double currentUpper = solver->getColUpper()[columnNumber_];
    46         int i;
    47         // See if in a valid range (with two tolerances)
    48         bool inRange = false;
    49         bool inRange2 = false;
    50         double integerTolerance =
    51             model_->getDblParam(CbcModel::CbcIntegerTolerance);
    52         // increase if type 2
    53         if (type == 2) {
    54             integerTolerance *= 100.0;
    55             type = 0;
    56             printIt = 2; // always print
    57         }
    58         // bounds should match some bound
    59         int rangeL = -1;
    60         int rangeU = -1;
    61         if (rangeType_ == 1) {
    62             for (i = 0; i < numberRanges_; i++) {
    63                 if (fabs(currentLower - bound_[i]) < 1.0e-12)
    64                     rangeL = i;
    65                 if (fabs(currentUpper - bound_[i]) < 1.0e-12)
    66                     rangeU = i;
    67                 if (fabs(value - bound_[i]) < integerTolerance)
    68                     inRange = true;
    69                 if (fabs(value - bound_[i]) < 1.0e8)
    70                     inRange2 = true;
    71             }
    72         } else {
    73             for (i = 0; i < numberRanges_; i++) {
    74                 if (fabs(currentLower - bound_[2*i]) < 1.0e-12)
    75                     rangeL = i;
    76                 if (fabs(currentUpper - bound_[2*i+1]) < 1.0e-12)
    77                     rangeU = i;
    78                 if (value > bound_[2*i] - integerTolerance &&
    79                         value < bound_[2*i+1] + integerTolerance)
    80                     inRange = true;
    81                 if (value > bound_[2*i] - integerTolerance &&
    82                         value < bound_[2*i+1] + integerTolerance)
    83                     inRange = true;
    84             }
    85         }
    86         assert (rangeL >= 0 && rangeU >= 0);
    87         bool abortIt = false;
    88         switch (type) {
    89             // returning from findRange (fall through to just check)
    90         case 0:
    91             if (printIt) {
    92                 printf("findRange returns %s for column %d and value %g",
    93                        condition ? "true" : "false", columnNumber_, value);
    94                 if (printIt > 1)
    95                     printf(" LP bounds %g, %g", currentLower, currentUpper);
    96                 printf("\n");
    97             }
    98             // Should match
    99         case 1:
    100             if (inRange != condition) {
    101                 printIt = 2;
    102                 abortIt = true;
    103             }
    104             break;
    105             //
    106         case 2:
    107             break;
    108             //
    109         case 3:
    110             break;
    111             //
    112         case 4:
    113             break;
    114         }
    115     }
    116 #endif
    117 }
    118 /** Default Constructor
    119 
    120 */
    121 CbcLotsize::CbcLotsize ()
    122         : CbcObject(),
    123         columnNumber_(-1),
    124         rangeType_(0),
    125         numberRanges_(0),
    126         largestGap_(0),
    127         bound_(NULL),
    128         range_(0)
    129 {
    130 }
    131 
    132 /** Useful constructor
    133 
    134   Loads actual upper & lower bounds for the specified variable.
    135 */
    136 CbcLotsize::CbcLotsize (CbcModel * model,
    137                         int iColumn, int numberPoints,
    138                         const double * points, bool range)
    139         : CbcObject(model)
    140 {
    141 #if CBC_PRINT
    142     if (!saveModel)
    143         saveModel = model;
    144 #endif
    145     assert (numberPoints > 0);
    146     columnNumber_ = iColumn ;
    147     // and set id so can be used for branching
    148     id_ = iColumn;
    149     // sort ranges
    150     int * sort = new int[numberPoints];
    151     double * weight = new double [numberPoints];
    152     int i;
    153     if (range) {
    154         rangeType_ = 2;
    155     } else {
    156         rangeType_ = 1;
    157     }
    158     for (i = 0; i < numberPoints; i++) {
    159         sort[i] = i;
    160         weight[i] = points[i*rangeType_];
    161     }
    162     CoinSort_2(weight, weight + numberPoints, sort);
    163     numberRanges_ = 1;
    164     largestGap_ = 0;
    165     if (rangeType_ == 1) {
    166         bound_ = new double[numberPoints+1];
    167         bound_[0] = weight[0];
    168         for (i = 1; i < numberPoints; i++) {
    169             if (weight[i] != weight[i-1])
    170                 bound_[numberRanges_++] = weight[i];
    171         }
    172         // and for safety
    173         bound_[numberRanges_] = bound_[numberRanges_-1];
    174         for (i = 1; i < numberRanges_; i++) {
    175             largestGap_ = CoinMax(largestGap_, bound_[i] - bound_[i-1]);
    176         }
    177     } else {
    178         bound_ = new double[2*numberPoints+2];
    179         bound_[0] = points[sort[0] * 2];
    180         bound_[1] = points[sort[0] * 2 + 1];
    181         double lo = bound_[0];
    182         double hi = bound_[1];
    183         assert (hi >= lo);
    184         for (i = 1; i < numberPoints; i++) {
    185             double thisLo = points[sort[i] * 2];
    186             double thisHi = points[sort[i] * 2 + 1];
    187             assert (thisHi >= thisLo);
    188             if (thisLo > hi) {
    189                 bound_[2*numberRanges_] = thisLo;
    190                 bound_[2*numberRanges_+1] = thisHi;
    191                 numberRanges_++;
    192                 lo = thisLo;
    193                 hi = thisHi;
    194             } else {
    195                 //overlap
    196                 hi = CoinMax(hi, thisHi);
    197                 bound_[2*numberRanges_-1] = hi;
    198             }
    199         }
    200         // and for safety
    201         bound_[2*numberRanges_] = bound_[2*numberRanges_-2];
    202         bound_[2*numberRanges_+1] = bound_[2*numberRanges_-1];
    203         for (i = 1; i < numberRanges_; i++) {
    204             largestGap_ = CoinMax(largestGap_, bound_[2*i] - bound_[2*i-1]);
    205         }
    206     }
    207     delete [] sort;
    208     delete [] weight;
    209     range_ = 0;
    210 }
    211 
    212 // Copy constructor
    213 CbcLotsize::CbcLotsize ( const CbcLotsize & rhs)
    214         : CbcObject(rhs)
    215 
    216 {
    217     columnNumber_ = rhs.columnNumber_;
    218     rangeType_ = rhs.rangeType_;
    219     numberRanges_ = rhs.numberRanges_;
    220     range_ = rhs.range_;
    221     largestGap_ = rhs.largestGap_;
    222     if (numberRanges_) {
    223         assert (rangeType_ > 0 && rangeType_ < 3);
    224         bound_ = new double [(numberRanges_+1)*rangeType_];
    225         memcpy(bound_, rhs.bound_, (numberRanges_ + 1)*rangeType_*sizeof(double));
    226     } else {
    227         bound_ = NULL;
    228     }
    229 }
    230 
    231 // Clone
    232 CbcObject *
    233 CbcLotsize::clone() const
    234 {
    235     return new CbcLotsize(*this);
    236 }
    237 
    238 // Assignment operator
    239 CbcLotsize &
    240 CbcLotsize::operator=( const CbcLotsize & rhs)
    241 {
    242     if (this != &rhs) {
    243         CbcObject::operator=(rhs);
    244         columnNumber_ = rhs.columnNumber_;
    245         rangeType_ = rhs.rangeType_;
    246         numberRanges_ = rhs.numberRanges_;
    247         largestGap_ = rhs.largestGap_;
    248         delete [] bound_;
    249         range_ = rhs.range_;
    250         if (numberRanges_) {
    251             assert (rangeType_ > 0 && rangeType_ < 3);
    252             bound_ = new double [(numberRanges_+1)*rangeType_];
    253             memcpy(bound_, rhs.bound_, (numberRanges_ + 1)*rangeType_*sizeof(double));
    254         } else {
    255             bound_ = NULL;
    256         }
    257     }
    258     return *this;
    259 }
    260 
    261 // Destructor
    262 CbcLotsize::~CbcLotsize ()
    263 {
    264     delete [] bound_;
    265 }
    266 /* Finds range of interest so value is feasible in range range_ or infeasible
    267    between hi[range_] and lo[range_+1].  Returns true if feasible.
    268 */
    269 bool
    270 CbcLotsize::findRange(double value) const
    271 {
    272     assert (range_ >= 0 && range_ < numberRanges_ + 1);
    273     double integerTolerance =
    274         model_->getDblParam(CbcModel::CbcIntegerTolerance);
    275     int iLo;
    276     int iHi;
    277     double infeasibility = 0.0;
    278     if (rangeType_ == 1) {
    279         if (value < bound_[range_] - integerTolerance) {
    280             iLo = 0;
    281             iHi = range_ - 1;
    282         } else if (value < bound_[range_] + integerTolerance) {
    283 #if CBC_PRINT
    284             printLotsize(value, true, 0);
    285 #endif
    286             return true;
    287         } else if (value < bound_[range_+1] - integerTolerance) {
    288 #ifdef CBC_PRINT
    289             printLotsize(value, false, 0);
    290 #endif
    291             return false;
    292         } else {
    293             iLo = range_ + 1;
    294             iHi = numberRanges_ - 1;
    295         }
    296         // check lo and hi
    297         bool found = false;
    298         if (value > bound_[iLo] - integerTolerance && value < bound_[iLo+1] + integerTolerance) {
    299             range_ = iLo;
    300             found = true;
    301         } else if (value > bound_[iHi] - integerTolerance && value < bound_[iHi+1] + integerTolerance) {
    302             range_ = iHi;
    303             found = true;
    304         } else {
    305             range_ = (iLo + iHi) >> 1;
    306         }
    307         //points
    308         while (!found) {
    309             if (value < bound_[range_]) {
    310                 if (value >= bound_[range_-1]) {
    311                     // found
    312                     range_--;
    313                     break;
    314                 } else {
    315                     iHi = range_;
    316                 }
    317             } else {
    318                 if (value < bound_[range_+1]) {
    319                     // found
    320                     break;
    321                 } else {
    322                     iLo = range_;
    323                 }
    324             }
    325             range_ = (iLo + iHi) >> 1;
    326         }
    327         if (value - bound_[range_] <= bound_[range_+1] - value) {
    328             infeasibility = value - bound_[range_];
    329         } else {
    330             infeasibility = bound_[range_+1] - value;
    331             if (infeasibility < integerTolerance)
    332                 range_++;
    333         }
    334 #ifdef CBC_PRINT
    335         printLotsize(value, (infeasibility < integerTolerance), 0);
    336 #endif
    337         return (infeasibility < integerTolerance);
    338     } else {
    339         // ranges
    340         if (value < bound_[2*range_] - integerTolerance) {
    341             iLo = 0;
    342             iHi = range_ - 1;
    343         } else if (value < bound_[2*range_+1] + integerTolerance) {
    344 #ifdef CBC_PRINT
    345             printLotsize(value, true, 0);
    346 #endif
    347             return true;
    348         } else if (value < bound_[2*range_+2] - integerTolerance) {
    349 #ifdef CBC_PRINT
    350             printLotsize(value, false, 0);
    351 #endif
    352             return false;
    353         } else {
    354             iLo = range_ + 1;
    355             iHi = numberRanges_ - 1;
    356         }
    357         // check lo and hi
    358         bool found = false;
    359         if (value > bound_[2*iLo] - integerTolerance && value < bound_[2*iLo+2] - integerTolerance) {
    360             range_ = iLo;
    361             found = true;
    362         } else if (value >= bound_[2*iHi] - integerTolerance) {
    363             range_ = iHi;
    364             found = true;
    365         } else {
    366             range_ = (iLo + iHi) >> 1;
    367         }
    368         //points
    369         while (!found) {
    370             if (value < bound_[2*range_]) {
    371                 if (value >= bound_[2*range_-2]) {
    372                     // found
    373                     range_--;
    374                     break;
    375                 } else {
    376                     iHi = range_;
    377                 }
    378             } else {
    379                 if (value < bound_[2*range_+2]) {
    380                     // found
    381                     break;
    382                 } else {
    383                     iLo = range_;
    384                 }
    385             }
    386             range_ = (iLo + iHi) >> 1;
    387         }
    388         if (value >= bound_[2*range_] - integerTolerance && value <= bound_[2*range_+1] + integerTolerance)
    389             infeasibility = 0.0;
    390         else if (value - bound_[2*range_+1] < bound_[2*range_+2] - value) {
    391             infeasibility = value - bound_[2*range_+1];
    392         } else {
    393             infeasibility = bound_[2*range_+2] - value;
    394         }
    395 #ifdef CBC_PRINT
    396         printLotsize(value, (infeasibility < integerTolerance), 0);
    397 #endif
    398         return (infeasibility < integerTolerance);
    399     }
    400 }
    401 /* Returns floor and ceiling
    402  */
    403 void
    404 CbcLotsize::floorCeiling(double & floorLotsize, double & ceilingLotsize, double value,
    405                          double /*tolerance*/) const
    406 {
    407     bool feasible = findRange(value);
    408     if (rangeType_ == 1) {
    409         floorLotsize = bound_[range_];
    410         ceilingLotsize = bound_[range_+1];
    411         // may be able to adjust
    412         if (feasible && fabs(value - floorLotsize) > fabs(value - ceilingLotsize)) {
    413             floorLotsize = bound_[range_+1];
    414             ceilingLotsize = bound_[range_+2];
    415         }
    416     } else {
    417         // ranges
    418         assert (value >= bound_[2*range_+1]);
    419         floorLotsize = bound_[2*range_+1];
    420         ceilingLotsize = bound_[2*range_+2];
    421     }
    422 }
    423 double
    424 CbcLotsize::infeasibility(const OsiBranchingInformation * /*info*/,
    425                           int &preferredWay) const
    426 {
    427     OsiSolverInterface * solver = model_->solver();
    428     const double * solution = model_->testSolution();
    429     const double * lower = solver->getColLower();
    430     const double * upper = solver->getColUpper();
    431     double value = solution[columnNumber_];
    432     value = CoinMax(value, lower[columnNumber_]);
    433     value = CoinMin(value, upper[columnNumber_]);
    434     double integerTolerance =
    435         model_->getDblParam(CbcModel::CbcIntegerTolerance);
    436     /*printf("%d %g %g %g %g\n",columnNumber_,value,lower[columnNumber_],
    437       solution[columnNumber_],upper[columnNumber_]);*/
    438     assert (value >= bound_[0] - integerTolerance
    439             && value <= bound_[rangeType_*numberRanges_-1] + integerTolerance);
    440     double infeasibility = 0.0;
    441     bool feasible = findRange(value);
    442     if (!feasible) {
    443         if (rangeType_ == 1) {
    444             if (value - bound_[range_] < bound_[range_+1] - value) {
    445                 preferredWay = -1;
    446                 infeasibility = value - bound_[range_];
    447             } else {
    448                 preferredWay = 1;
    449                 infeasibility = bound_[range_+1] - value;
    450             }
    451         } else {
    452             // ranges
    453             if (value - bound_[2*range_+1] < bound_[2*range_+2] - value) {
    454                 preferredWay = -1;
    455                 infeasibility = value - bound_[2*range_+1];
    456             } else {
    457                 preferredWay = 1;
    458                 infeasibility = bound_[2*range_+2] - value;
    459             }
    460         }
    461     } else {
    462         // always satisfied
    463         preferredWay = -1;
    464     }
    465     if (infeasibility < integerTolerance)
    466         infeasibility = 0.0;
    467     else
    468         infeasibility /= largestGap_;
    469 #ifdef CBC_PRINT
    470     printLotsize(value, infeasibility, 1);
    471 #endif
    472     return infeasibility;
    473 }
    474 /* Column number if single column object -1 otherwise,
    475    so returns >= 0
    476    Used by heuristics
    477 */
    478 int
    479 CbcLotsize::columnNumber() const
    480 {
    481     return columnNumber_;
    482 }
    483 // This looks at solution and sets bounds to contain solution
    484 /** More precisely: it first forces the variable within the existing
    485     bounds, and then tightens the bounds to make sure the variable is feasible
    486 */
    487 void
    488 CbcLotsize::feasibleRegion()
    489 {
    490     OsiSolverInterface * solver = model_->solver();
    491     const double * lower = solver->getColLower();
    492     const double * upper = solver->getColUpper();
    493     const double * solution = model_->testSolution();
    494     double value = solution[columnNumber_];
    495     value = CoinMax(value, lower[columnNumber_]);
    496     value = CoinMin(value, upper[columnNumber_]);
    497     findRange(value);
    498     double nearest;
    499     if (rangeType_ == 1) {
    500         nearest = bound_[range_];
    501         solver->setColLower(columnNumber_, nearest);
    502         solver->setColUpper(columnNumber_, nearest);
    503     } else {
    504         // ranges
    505         solver->setColLower(columnNumber_, bound_[2*range_]);
    506         solver->setColUpper(columnNumber_, bound_[2*range_+1]);
    507         if (value > bound_[2*range_+1])
    508             nearest = bound_[2*range_+1];
    509         else if (value < bound_[2*range_])
    510             nearest = bound_[2*range_];
    511         else
    512             nearest = value;
    513     }
    514 #ifdef CBC_PRINT
    515     // print details
    516     printLotsize(value, true, 2);
    517 #endif
    518     // Scaling may have moved it a bit
    519     // Lotsizing variables could be a lot larger
    520 #ifndef NDEBUG
    521     double integerTolerance =
    522         model_->getDblParam(CbcModel::CbcIntegerTolerance);
    523     assert (fabs(value - nearest) <= (100.0 + 10.0*fabs(nearest))*integerTolerance);
    524 #endif
    525 }
    526 CbcBranchingObject *
    527 CbcLotsize::createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * /*info*/, int way)
    528 {
    529     //OsiSolverInterface * solver = model_->solver();
    530     const double * solution = model_->testSolution();
    531     const double * lower = solver->getColLower();
    532     const double * upper = solver->getColUpper();
    533     double value = solution[columnNumber_];
    534     value = CoinMax(value, lower[columnNumber_]);
    535     value = CoinMin(value, upper[columnNumber_]);
    536     assert (!findRange(value));
    537     return new CbcLotsizeBranchingObject(model_, columnNumber_, way,
    538                                          value, this);
    539 }
    540 
    541 
    542 /* Given valid solution (i.e. satisfied) and reduced costs etc
    543    returns a branching object which would give a new feasible
    544    point in direction reduced cost says would be cheaper.
    545    If no feasible point returns null
    546 */
    547 CbcBranchingObject *
    548 CbcLotsize::preferredNewFeasible() const
    549 {
    550     OsiSolverInterface * solver = model_->solver();
    551 
    552     assert (findRange(model_->testSolution()[columnNumber_]));
    553     double dj = solver->getObjSense() * solver->getReducedCost()[columnNumber_];
    554     CbcLotsizeBranchingObject * object = NULL;
    555     double lo, up;
    556     if (dj >= 0.0) {
    557         // can we go down
    558         if (range_) {
    559             // yes
    560             if (rangeType_ == 1) {
    561                 lo = bound_[range_-1];
    562                 up = bound_[range_-1];
    563             } else {
    564                 lo = bound_[2*range_-2];
    565                 up = bound_[2*range_-1];
    566             }
    567             object = new CbcLotsizeBranchingObject(model_, columnNumber_, -1,
    568                                                    lo, up);
    569         }
    570     } else {
    571         // can we go up
    572         if (range_ < numberRanges_ - 1) {
    573             // yes
    574             if (rangeType_ == 1) {
    575                 lo = bound_[range_+1];
    576                 up = bound_[range_+1];
    577             } else {
    578                 lo = bound_[2*range_+2];
    579                 up = bound_[2*range_+3];
    580             }
    581             object = new CbcLotsizeBranchingObject(model_, columnNumber_, -1,
    582                                                    lo, up);
    583         }
    584     }
    585     return object;
    586 }
    587 
    588 /* Given valid solution (i.e. satisfied) and reduced costs etc
    589    returns a branching object which would give a new feasible
    590    point in direction opposite to one reduced cost says would be cheaper.
    591    If no feasible point returns null
    592 */
    593 CbcBranchingObject *
    594 CbcLotsize::notPreferredNewFeasible() const
    595 {
    596     OsiSolverInterface * solver = model_->solver();
    597 
    598 #ifndef NDEBUG
    599     double value = model_->testSolution()[columnNumber_];
    600     double nearest = floor(value + 0.5);
    601     double integerTolerance =
    602         model_->getDblParam(CbcModel::CbcIntegerTolerance);
    603     // Scaling may have moved it a bit
    604     // Lotsizing variables could be a lot larger
    605     assert (fabs(value - nearest) <= (10.0 + 10.0*fabs(nearest))*integerTolerance);
    606 #endif
    607     double dj = solver->getObjSense() * solver->getReducedCost()[columnNumber_];
    608     CbcLotsizeBranchingObject * object = NULL;
    609     double lo, up;
    610     if (dj <= 0.0) {
    611         // can we go down
    612         if (range_) {
    613             // yes
    614             if (rangeType_ == 1) {
    615                 lo = bound_[range_-1];
    616                 up = bound_[range_-1];
    617             } else {
    618                 lo = bound_[2*range_-2];
    619                 up = bound_[2*range_-1];
    620             }
    621             object = new CbcLotsizeBranchingObject(model_, columnNumber_, -1,
    622                                                    lo, up);
    623         }
    624     } else {
    625         // can we go up
    626         if (range_ < numberRanges_ - 1) {
    627             // yes
    628             if (rangeType_ == 1) {
    629                 lo = bound_[range_+1];
    630                 up = bound_[range_+1];
    631             } else {
    632                 lo = bound_[2*range_+2];
    633                 up = bound_[2*range_+3];
    634             }
    635             object = new CbcLotsizeBranchingObject(model_, columnNumber_, -1,
    636                                                    lo, up);
    637         }
    638     }
    639     return object;
    640 }
    641 
    642 /*
    643   Bounds may be tightened, so it may be good to be able to refresh the local
    644   copy of the original bounds.
    645  */
    646 void
    647 CbcLotsize::resetBounds(const OsiSolverInterface * /*solver*/)
    648 {
    649 }
    65019
    65120
  • branches/sandbox/Cbc/src/CbcBranchLotsize.hpp

    r1286 r1308  
    66
    77#include "CbcBranchBase.hpp"
    8 
    9 /** Lotsize class */
    10 
    11 
    12 class CbcLotsize : public CbcObject {
    13 
    14 public:
    15 
    16     // Default Constructor
    17     CbcLotsize ();
    18 
    19     /* Useful constructor - passed model index.
    20        Also passed valid values - if range then pairs
    21     */
    22     CbcLotsize (CbcModel * model, int iColumn,
    23                 int numberPoints, const double * points, bool range = false);
    24 
    25     // Copy constructor
    26     CbcLotsize ( const CbcLotsize &);
    27 
    28     /// Clone
    29     virtual CbcObject * clone() const;
    30 
    31     // Assignment operator
    32     CbcLotsize & operator=( const CbcLotsize& rhs);
    33 
    34     // Destructor
    35     ~CbcLotsize ();
    36 
    37     /// Infeasibility - large is 0.5
    38     virtual double infeasibility(const OsiBranchingInformation * info,
    39                                  int &preferredWay) const;
    40 
    41     using CbcObject::feasibleRegion ;
    42     /** Set bounds to contain the current solution.
    43 
    44       More precisely, for the variable associated with this object, take the
    45       value given in the current solution, force it within the current bounds
    46       if required, then set the bounds to fix the variable at the integer
    47       nearest the solution value.
    48     */
    49     virtual void feasibleRegion();
    50 
    51     /// Creates a branching object
    52     virtual CbcBranchingObject * createCbcBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) ;
    53 
    54     /** \brief Given a valid solution (with reduced costs, etc.),
    55         return a branching object which would give a new feasible
    56         point in the good direction.
    57 
    58       The preferred branching object will force the variable to be +/-1 from
    59       its current value, depending on the reduced cost and objective sense.  If
    60       movement in the direction which improves the objective is impossible due
    61       to bounds on the variable, the branching object will move in the other
    62       direction.  If no movement is possible, the method returns NULL.
    63 
    64       Only the bounds on this variable are considered when determining if the new
    65       point is feasible.
    66     */
    67     virtual CbcBranchingObject * preferredNewFeasible() const;
    68 
    69     /** \brief Given a valid solution (with reduced costs, etc.),
    70         return a branching object which would give a new feasible
    71         point in a bad direction.
    72 
    73       As for preferredNewFeasible(), but the preferred branching object will
    74       force movement in a direction that degrades the objective.
    75     */
    76     virtual CbcBranchingObject * notPreferredNewFeasible() const ;
    77 
    78     /** Reset original upper and lower bound values from the solver.
    79 
    80       Handy for updating bounds held in this object after bounds held in the
    81       solver have been tightened.
    82      */
    83     virtual void resetBounds(const OsiSolverInterface * solver);
    84 
    85     /** Finds range of interest so value is feasible in range range_ or infeasible
    86         between hi[range_] and lo[range_+1].  Returns true if feasible.
    87     */
    88     bool findRange(double value) const;
    89 
    90     /** Returns floor and ceiling
    91     */
    92     virtual void floorCeiling(double & floorLotsize, double & ceilingLotsize, double value,
    93                               double tolerance) const;
    94 
    95     /// Model column number
    96     inline int modelSequence() const {
    97         return columnNumber_;
    98     }
    99     /// Set model column number
    100     inline void setModelSequence(int value) {
    101         columnNumber_ = value;
    102     }
    103 
    104     /** Column number if single column object -1 otherwise,
    105         so returns >= 0
    106         Used by heuristics
    107     */
    108     virtual int columnNumber() const;
    109     /// Original bounds
    110     inline double originalLowerBound() const {
    111         return bound_[0];
    112     }
    113     inline double originalUpperBound() const {
    114         return bound_[rangeType_*numberRanges_-1];
    115     }
    116     /// Type - 1 points, 2 ranges
    117     inline int rangeType() const {
    118         return rangeType_;
    119     }
    120     /// Number of points
    121     inline int numberRanges() const {
    122         return numberRanges_;
    123     }
    124     /// Ranges
    125     inline double * bound() const {
    126         return bound_;
    127     }
    128     /** \brief Return true if object can take part in normal heuristics
    129     */
    130     virtual bool canDoHeuristics() const {
    131         return false;
    132     }
    133 
    134 private:
    135     /// Just for debug (CBC_PRINT defined in CbcBranchLotsize.cpp)
    136     void printLotsize(double value, bool condition, int type) const;
    137 
    138 private:
    139     /// data
    140 
    141     /// Column number in model
    142     int columnNumber_;
    143     /// Type - 1 points, 2 ranges
    144     int rangeType_;
    145     /// Number of points
    146     int numberRanges_;
    147     // largest gap
    148     double largestGap_;
    149     /// Ranges
    150     double * bound_;
    151     /// Current range
    152     mutable int range_;
    153 };
    154 
     8#include "CbcLotsize.hpp"
    1559
    15610/** Lotsize branching object
  • branches/sandbox/Cbc/src/Makefile.am

    r1306 r1308  
    4343        CbcCutGenerator.cpp CbcCutGenerator.hpp \
    4444        CbcDummyBranchingObject.cpp CbcDummyBranchingObject.hpp \
     45        CbcDynamicPseudoCostBranchingObject.cpp CbcDynamicPseudoCostBranchingObject.hpp \
    4546        CbcEventHandler.cpp CbcEventHandler.hpp \
    4647        CbcFathom.cpp CbcFathom.hpp \
     
    7071        CbcIntegerPseudoCostBranchingObject.cpp \
    7172        CbcIntegerPseudoCostBranchingObject.hpp \
     73        CbcLotsize.cpp CbcLotsize.hpp \
    7274        CbcMessage.cpp CbcMessage.hpp \
    7375        CbcModel.cpp CbcModel.hpp \
     
    7981        CbcOneGeneralBranchingObject.cpp CbcOneGeneralBranchingObject.hpp \
    8082        CbcSimpleInteger.cpp CbcSimpleInteger.hpp \
     83        CbcSimpleIntegerDynamicPseudoCost.cpp CbcSimpleIntegerDynamicPseudoCost.hpp \
    8184        CbcSimpleIntegerPseudoCost.cpp CbcSimpleIntegerPseudoCost.hpp \
    8285        CbcSOS.cpp CbcSOS.hpp \
     
    358361        CbcCutGenerator.hpp \
    359362        CbcDummyBranchingObject.hpp \
     363        CbcDynamicPseudoCostBranchingObject.hpp \
    360364        CbcFathom.hpp \
    361365        CbcEventHandler.hpp \
     
    384388        CbcIntegerPseudoCostBranchingObject.hpp \
    385389        CbcLongCliqueBranchingObject.hpp \
     390        CbcLotsize.hpp \
    386391        CbcMessage.hpp \
    387392        CbcModel.hpp \
     
    393398        CbcOneGeneralBranchingObject.hpp \
    394399        CbcSimpleInteger.hpp \
     400        CbcSimpleIntegerDynamicPseudoCost.hpp \
    395401        CbcSimpleIntegerPseudoCost.hpp \
    396402        CbcStrategy.hpp \
Note: See TracChangeset for help on using the changeset viewer.