Changeset 1313 for branches/sandbox


Ignore:
Timestamp:
Nov 24, 2009 3:13:03 PM (10 years ago)
Author:
EdwinStraver
Message:

Created CbcNodeInfo?, CbcPartialNodeInfo? and CbcFullNodeInfo? out of CbcNode?.cpp
Also updated makefiles, and spreadsheets.

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

Legend:

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

    r1308 r1313  
    7878CbcMessage.cpp,,,,,13,104,87,191,x,,,,CbcMessage,,
    7979CbcModel.cpp,,,,,0,16557,2622,19179,x,,,,CbcModel,,
    80 CbcNode.cpp,,,,,0,5135,806,5941,x,,,,CbcNode,"CbcNodeInfo, CbcFullNodeInfo, CbcPartialNodeInfo, ",
     80CbcNode.cpp,,Node,Edwin,,0,5135,806,5941,x,,,,CbcNode,"CbcNodeInfo, CbcFullNodeInfo, CbcPartialNodeInfo, ",
     81,CbcFullNodeInfo.cpp,Node,Edwin,,,,,,,,,,,,
     82,CbcNodeInfo.cpp,Node,Edwin,,,,,,,,,,,,
     83,CbcPartialNodeInfo.cpp,Node,Edwin,,,,,,,,,,,,
    8184CbcParam.cpp,,Solver,Bjarni,,24,502,237,739,x,,,,CbcParam,,
    8285CbcSolver.cpp,,Solver,Bjarni,,0,11365,,11365,,x,,,CbcSolver,CbcMain,
  • branches/sandbox/Cbc/MSVisualStudio/v9/libCbc/libCbc.vcproj

    r1308 r1313  
    473473                        </File>
    474474                        <File
     475                                RelativePath="..\..\..\src\CbcFullNodeInfo.cpp"
     476                                >
     477                        </File>
     478                        <File
    475479                                RelativePath="..\..\..\src\CbcGenCtlBlk.cpp"
    476480                                >
     
    917921                        </File>
    918922                        <File
     923                                RelativePath="..\..\..\src\CbcNodeInfo.cpp"
     924                                >
     925                        </File>
     926                        <File
    919927                                RelativePath="..\..\..\src\CbcNWay.cpp"
    920928                                >
     
    960968                                        />
    961969                                </FileConfiguration>
     970                        </File>
     971                        <File
     972                                RelativePath="..\..\..\src\CbcPartialNodeInfo.cpp"
     973                                >
    962974                        </File>
    963975                        <File
     
    12231235                        </File>
    12241236                        <File
     1237                                RelativePath="..\..\..\src\CbcFullNodeInfo.hpp"
     1238                                >
     1239                        </File>
     1240                        <File
    12251241                                RelativePath="..\..\..\src\CbcGenCtlBlk.hpp"
    12261242                                >
     
    13271343                        </File>
    13281344                        <File
     1345                                RelativePath="..\..\..\src\CbcNodeInfo.hpp"
     1346                                >
     1347                        </File>
     1348                        <File
    13291349                                RelativePath="..\..\..\src\CbcNWay.hpp"
    13301350                                >
     
    13521372                        <File
    13531373                                RelativePath="..\..\..\..\Cbc\src\CbcParam.hpp"
     1374                                >
     1375                        </File>
     1376                        <File
     1377                                RelativePath="..\..\..\src\CbcPartialNodeInfo.hpp"
    13541378                                >
    13551379                        </File>
  • branches/sandbox/Cbc/src/CbcNode.cpp

    r1286 r1313  
    4141using namespace std;
    4242#include "CglCutGenerator.hpp"
    43 // Default Constructor
    44 CbcNodeInfo::CbcNodeInfo ()
    45         :
    46         numberPointingToThis_(0),
    47         parent_(NULL),
    48         parentBranch_(NULL),
    49         owner_(NULL),
    50         numberCuts_(0),
    51         nodeNumber_(0),
    52         cuts_(NULL),
    53         numberRows_(0),
    54         numberBranchesLeft_(0),
    55         active_(7)
    56 {
    57 #ifdef CHECK_NODE
    58     printf("CbcNodeInfo %x Constructor\n", this);
    59 #endif
    60 }
    61 
    62 void
    63 CbcNodeInfo::setParentBasedData()
    64 {
    65     if (parent_) {
    66         numberRows_ = parent_->numberRows_ + parent_->numberCuts_;
    67         //parent_->increment();
    68         if (parent_->owner()) {
    69             const OsiBranchingObject* br = parent_->owner()->branchingObject();
    70             assert(br);
    71             parentBranch_ = br->clone();
    72         }
    73     }
    74 }
    75 
    76 void
    77 CbcNodeInfo::unsetParentBasedData()
    78 {
    79     if (parent_) {
    80         numberRows_ = 0;
    81         if (parent_->owner()) {
    82             delete parentBranch_;
    83             parentBranch_ = NULL;
    84         }
    85     }
    86 }
    87 
    88 #if 0
    89 // Constructor given parent
    90 CbcNodeInfo::CbcNodeInfo (CbcNodeInfo * parent)
    91         :
    92         numberPointingToThis_(2),
    93         parent_(parent),
    94         parentBranch_(NULL),
    95         owner_(NULL),
    96         numberCuts_(0),
    97         nodeNumber_(0),
    98         cuts_(NULL),
    99         numberRows_(0),
    100         numberBranchesLeft_(2),
    101         active_(7)
    102 {
    103 #ifdef CHECK_NODE
    104     printf("CbcNodeInfo %x Constructor from parent %x\n", this, parent_);
    105 #endif
    106     //setParentBasedData();
    107 }
    108 #endif
    109 
    110 // Copy Constructor
    111 CbcNodeInfo::CbcNodeInfo (const CbcNodeInfo & rhs)
    112         :
    113         numberPointingToThis_(rhs.numberPointingToThis_),
    114         parent_(rhs.parent_),
    115         parentBranch_(NULL),
    116         owner_(rhs.owner_),
    117         numberCuts_(rhs.numberCuts_),
    118         nodeNumber_(rhs.nodeNumber_),
    119         cuts_(NULL),
    120         numberRows_(rhs.numberRows_),
    121         numberBranchesLeft_(rhs.numberBranchesLeft_),
    122         active_(rhs.active_)
    123 {
    124 #ifdef CHECK_NODE
    125     printf("CbcNodeInfo %x Copy constructor\n", this);
    126 #endif
    127     if (numberCuts_) {
    128         cuts_ = new CbcCountRowCut * [numberCuts_];
    129         int n = 0;
    130         for (int i = 0; i < numberCuts_; i++) {
    131             CbcCountRowCut * thisCut = rhs.cuts_[i];
    132             if (thisCut) {
    133                 // I think this is correct - new one should take priority
    134                 thisCut->setInfo(this, n);
    135                 thisCut->increment(numberBranchesLeft_);
    136                 cuts_[n++] = thisCut;
    137             }
    138         }
    139         numberCuts_ = n;
    140     }
    141     if (rhs.parentBranch_) {
    142         parentBranch_ = rhs.parentBranch_->clone();
    143     }
    144 }
    145 // Constructor given parent and owner
    146 CbcNodeInfo::CbcNodeInfo (CbcNodeInfo * parent, CbcNode * owner)
    147         :
    148         numberPointingToThis_(2),
    149         parent_(parent),
    150         parentBranch_(NULL),
    151         owner_(owner),
    152         numberCuts_(0),
    153         nodeNumber_(0),
    154         cuts_(NULL),
    155         numberRows_(0),
    156         numberBranchesLeft_(2),
    157         active_(7)
    158 {
    159 #ifdef CHECK_NODE
    160     printf("CbcNodeInfo %x Constructor from parent %x\n", this, parent_);
    161 #endif
    162     //setParentBasedData();
    163 }
    164 
    165 /**
    166    Take care to detach from the owning CbcNode and decrement the reference
    167    count in the parent.  If this is the last nodeInfo object pointing to the
    168    parent, make a recursive call to delete the parent.
    169 */
    170 CbcNodeInfo::~CbcNodeInfo()
    171 {
    172 #ifdef CHECK_NODE
    173     printf("CbcNodeInfo %x Destructor parent %x\n", this, parent_);
    174 #endif
    175 
    176     assert(!numberPointingToThis_);
    177     // But there may be some left (max nodes?)
    178     for (int i = 0; i < numberCuts_; i++) {
    179         if (cuts_[i]) {
    180 #ifndef GLOBAL_CUTS_JUST_POINTERS
    181             delete cuts_[i];
    182 #else
    183             if (cuts_[i]->globallyValidAsInteger() != 2)
    184                 delete cuts_[i];
    185 #endif
    186         }
    187     }
    188     delete [] cuts_;
    189     if (owner_)
    190         owner_->nullNodeInfo();
    191     if (parent_) {
    192         int numberLinks = parent_->decrement();
    193         if (!numberLinks) delete parent_;
    194     }
    195     delete parentBranch_;
    196 }
    197 
    198 
    199 //#define ALLCUTS
    200 void
    201 CbcNodeInfo::decrementCuts(int change)
    202 {
    203     int i;
    204     // get rid of all remaining if negative
    205     int changeThis;
    206     if (change < 0)
    207         changeThis = numberBranchesLeft_;
    208     else
    209         changeThis = change;
    210     // decrement cut counts
    211     for (i = 0; i < numberCuts_; i++) {
    212         if (cuts_[i]) {
    213             int number = cuts_[i]->decrement(changeThis);
    214             if (!number) {
    215                 //printf("info %x del cut %d %x\n",this,i,cuts_[i]);
    216 #ifndef GLOBAL_CUTS_JUST_POINTERS
    217                 delete cuts_[i];
    218 #else
    219                 if (cuts_[i]->globallyValidAsInteger() != 2)
    220                     delete cuts_[i];
    221 #endif
    222                 cuts_[i] = NULL;
    223             }
    224         }
    225     }
    226 }
    227 void
    228 CbcNodeInfo::incrementCuts(int change)
    229 {
    230     int i;
    231     assert (change > 0);
    232     // increment cut counts
    233     for (i = 0; i < numberCuts_; i++) {
    234         if (cuts_[i])
    235             cuts_[i]->increment(change);
    236     }
    237 }
    238 void
    239 CbcNodeInfo::decrementParentCuts(CbcModel * model, int change)
    240 {
    241     if (parent_) {
    242         // get rid of all remaining if negative
    243         int changeThis;
    244         if (change < 0)
    245             changeThis = numberBranchesLeft_;
    246         else
    247             changeThis = change;
    248         int i;
    249         // Get over-estimate of space needed for basis
    250         CoinWarmStartBasis & dummy = model->workingBasis();
    251         dummy.setSize(0, numberRows_ + numberCuts_);
    252         buildRowBasis(dummy);
    253         /* everything is zero (i.e. free) so we can use to see
    254            if latest basis */
    255         CbcNodeInfo * thisInfo = parent_;
    256         while (thisInfo)
    257             thisInfo = thisInfo->buildRowBasis(dummy);
    258         // decrement cut counts
    259         thisInfo = parent_;
    260         int numberRows = numberRows_;
    261         while (thisInfo) {
    262             for (i = thisInfo->numberCuts_ - 1; i >= 0; i--) {
    263                 CoinWarmStartBasis::Status status = dummy.getArtifStatus(--numberRows);
    264 #ifdef ALLCUTS
    265                 status = CoinWarmStartBasis::isFree;
    266 #endif
    267                 if (thisInfo->cuts_[i]) {
    268                     int number = 1;
    269                     if (status != CoinWarmStartBasis::basic) {
    270                         // tight - drop 1 or 2
    271                         if (change < 0)
    272                             number = thisInfo->cuts_[i]->decrement(changeThis);
    273                         else
    274                             number = thisInfo->cuts_[i]->decrement(change);
    275                     }
    276                     if (!number) {
    277 #ifndef GLOBAL_CUTS_JUST_POINTERS
    278                         delete thisInfo->cuts_[i];
    279 #else
    280                         if (thisInfo->cuts_[i]->globallyValidAsInteger() != 2)
    281                             delete thisInfo->cuts_[i];
    282 #endif
    283                         thisInfo->cuts_[i] = NULL;
    284                     }
    285                 }
    286             }
    287             thisInfo = thisInfo->parent_;
    288         }
    289     }
    290 }
    291 #if 0
    292 void
    293 CbcNodeInfo::incrementParentCuts(CbcModel * model, int change)
    294 {
    295     if (parent_) {
    296         int i;
    297         // Get over-estimate of space needed for basis
    298         CoinWarmStartBasis & dummy = model->workingBasis();
    299         dummy.setSize(0, numberRows_ + numberCuts_);
    300         /* everything is zero (i.e. free) so we can use to see
    301            if latest basis */
    302         buildRowBasis(dummy);
    303         CbcNodeInfo * thisInfo = parent_;
    304         while (thisInfo)
    305             thisInfo = thisInfo->buildRowBasis(dummy);
    306         // increment cut counts
    307         thisInfo = parent_;
    308         int numberRows = numberRows_;
    309         while (thisInfo) {
    310             for (i = thisInfo->numberCuts_ - 1; i >= 0; i--) {
    311                 CoinWarmStartBasis::Status status = dummy.getArtifStatus(--numberRows);
    312 #ifdef ALLCUTS
    313                 status = CoinWarmStartBasis::isFree;
    314 #endif
    315                 if (thisInfo->cuts_[i] && status != CoinWarmStartBasis::basic) {
    316                     thisInfo->cuts_[i]->increment(change);
    317                 }
    318             }
    319             thisInfo = thisInfo->parent_;
    320         }
    321     }
    322 }
    323 #endif
    324 /*
    325   Append cuts to the cuts_ array in a nodeInfo. The initial reference count
    326   is set to numberToBranchOn, which will normally be the number of arms
    327   defined for the CbcBranchingObject attached to the CbcNode that owns this
    328   CbcNodeInfo.
    329 */
    330 void
    331 CbcNodeInfo::addCuts (OsiCuts & cuts, int numberToBranchOn,
    332                       /*int * whichGenerator,*/int numberPointingToThis)
    333 {
    334     int numberCuts = cuts.sizeRowCuts();
    335     if (numberCuts) {
    336         int i;
    337         if (!numberCuts_) {
    338             cuts_ = new CbcCountRowCut * [numberCuts];
    339         } else {
    340             CbcCountRowCut ** temp = new CbcCountRowCut * [numberCuts+numberCuts_];
    341             memcpy(temp, cuts_, numberCuts_*sizeof(CbcCountRowCut *));
    342             delete [] cuts_;
    343             cuts_ = temp;
    344         }
    345         for (i = 0; i < numberCuts; i++) {
    346             CbcCountRowCut * thisCut = new CbcCountRowCut(*cuts.rowCutPtr(i),
    347                     this, numberCuts_,
    348                     -1, numberPointingToThis);
    349             thisCut->increment(numberToBranchOn);
    350             cuts_[numberCuts_++] = thisCut;
    351 #ifdef CBC_DEBUG
    352 #if CBC_DEBUG>1
    353             int n = thisCut->row().getNumElements();
    354             printf("Cut %d has %d entries, rhs %g %g =>", i, n, thisCut->lb(),
    355                    thisCut->ub());
    356             int j;
    357             const int * index = thisCut->row().getIndices();
    358             const double * element = thisCut->row().getElements();
    359             for (j = 0; j < n; j++) {
    360                 printf(" (%d,%g)", index[j], element[j]);
    361                 assert(fabs(element[j]) > 1.00e-12);
    362             }
    363             printf("\n");
    364 #else
    365             int n = thisCut->row().getNumElements();
    366             int j;
    367             const double * element = thisCut->row().getElements();
    368             for (j = 0; j < n; j++) {
    369                 assert(fabs(element[j]) > 1.00e-12);
    370             }
    371 #endif
    372 #endif
    373         }
    374     }
    375 }
    376 
    377 void
    378 CbcNodeInfo::addCuts(int numberCuts, CbcCountRowCut ** cut,
    379                      int numberToBranchOn)
    380 {
    381     if (numberCuts) {
    382         int i;
    383         if (!numberCuts_) {
    384             cuts_ = new CbcCountRowCut * [numberCuts];
    385         } else {
    386             CbcCountRowCut ** temp = new CbcCountRowCut * [numberCuts+numberCuts_];
    387             memcpy(temp, cuts_, numberCuts_*sizeof(CbcCountRowCut *));
    388             delete [] cuts_;
    389             cuts_ = temp;
    390         }
    391         for (i = 0; i < numberCuts; i++) {
    392             CbcCountRowCut * thisCut = cut[i];
    393             thisCut->setInfo(this, numberCuts_);
    394             //printf("info %x cut %d %x\n",this,i,thisCut);
    395             thisCut->increment(numberToBranchOn);
    396             cuts_[numberCuts_++] = thisCut;
    397 #ifdef CBC_DEBUG
    398             int n = thisCut->row().getNumElements();
    399 #if CBC_DEBUG>1
    400             printf("Cut %d has %d entries, rhs %g %g =>", i, n, thisCut->lb(),
    401                    thisCut->ub());
    402 #endif
    403             int j;
    404 #if CBC_DEBUG>1
    405             const int * index = thisCut->row().getIndices();
    406 #endif
    407             const double * element = thisCut->row().getElements();
    408             for (j = 0; j < n; j++) {
    409 #if CBC_DEBUG>1
    410                 printf(" (%d,%g)", index[j], element[j]);
    411 #endif
    412                 assert(fabs(element[j]) > 1.00e-12);
    413             }
    414             printf("\n");
    415 #endif
    416         }
    417     }
    418 }
    419 
    420 // delete cuts
    421 void
    422 CbcNodeInfo::deleteCuts(int numberToDelete, CbcCountRowCut ** cuts)
    423 {
    424     int i;
    425     int j;
    426     int last = -1;
    427     for (i = 0; i < numberToDelete; i++) {
    428         CbcCountRowCut * next = cuts[i];
    429         for (j = last + 1; j < numberCuts_; j++) {
    430             if (next == cuts_[j])
    431                 break;
    432         }
    433         if (j == numberCuts_) {
    434             // start from beginning
    435             for (j = 0; j < last; j++) {
    436                 if (next == cuts_[j])
    437                     break;
    438             }
    439             assert(j < last);
    440         }
    441         last = j;
    442         int number = cuts_[j]->decrement();
    443         if (!number) {
    444 #ifndef GLOBAL_CUTS_JUST_POINTERS
    445             delete cuts_[j];
    446 #else
    447             if (cuts_[j]->globallyValidAsInteger() != 2)
    448                 delete cuts_[j];
    449 #endif
    450         }
    451         cuts_[j] = NULL;
    452     }
    453     j = 0;
    454     for (i = 0; i < numberCuts_; i++) {
    455         if (cuts_[i])
    456             cuts_[j++] = cuts_[i];
    457     }
    458     numberCuts_ = j;
    459 }
    460 
    461 // delete cuts
    462 void
    463 CbcNodeInfo::deleteCuts(int numberToDelete, int * which)
    464 {
    465     int i;
    466     for (i = 0; i < numberToDelete; i++) {
    467         int iCut = which[i];
    468         int number = cuts_[iCut]->decrement();
    469         if (!number) {
    470 #ifndef GLOBAL_CUTS_JUST_POINTERS
    471             delete cuts_[iCut];
    472 #else
    473             if (cuts_[iCut]->globallyValidAsInteger() != 2)
    474                 delete cuts_[iCut];
    475 #endif
    476         }
    477         cuts_[iCut] = NULL;
    478     }
    479     int j = 0;
    480     for (i = 0; i < numberCuts_; i++) {
    481         if (cuts_[i])
    482             cuts_[j++] = cuts_[i];
    483     }
    484     numberCuts_ = j;
    485 }
    486 
    487 // Really delete a cut
    488 void
    489 CbcNodeInfo::deleteCut(int whichOne)
    490 {
    491     assert(whichOne < numberCuts_);
    492     cuts_[whichOne] = NULL;
    493 }
    494 /* Deactivate node information.
    495    1 - bounds
    496    2 - cuts
    497    4 - basis!
    498 */
    499 void
    500 CbcNodeInfo::deactivate(int mode)
    501 {
    502     active_ &= (~mode);
    503 }
    504 
    505 CbcFullNodeInfo::CbcFullNodeInfo() :
    506         CbcNodeInfo(),
    507         basis_(),
    508         numberIntegers_(0),
    509         lower_(NULL),
    510         upper_(NULL)
    511 {
    512 }
    513 CbcFullNodeInfo::CbcFullNodeInfo(CbcModel * model,
    514                                  int numberRowsAtContinuous) :
    515         CbcNodeInfo(NULL, model->currentNode())
    516 {
    517     OsiSolverInterface * solver = model->solver();
    518     numberRows_ = numberRowsAtContinuous;
    519     numberIntegers_ = model->numberIntegers();
    520     int numberColumns = model->getNumCols();
    521     lower_ = new double [numberColumns];
    522     upper_ = new double [numberColumns];
    523     const double * lower = solver->getColLower();
    524     const double * upper = solver->getColUpper();
    525     int i;
    526 
    527     for (i = 0; i < numberColumns; i++) {
    528         lower_[i] = lower[i];
    529         upper_[i] = upper[i];
    530     }
    531 
    532     basis_ =  dynamic_cast<CoinWarmStartBasis*>(solver->getWarmStart());
    533 }
    534 
    535 CbcFullNodeInfo::CbcFullNodeInfo(const CbcFullNodeInfo & rhs) :
    536         CbcNodeInfo(rhs)
    537 {
    538     basis_ = dynamic_cast<CoinWarmStartBasis *>(rhs.basis_->clone()) ;
    539     numberIntegers_ = rhs.numberIntegers_;
    540     lower_ = NULL;
    541     upper_ = NULL;
    542     if (rhs.lower_ != NULL) {
    543         int numberColumns = basis_->getNumStructural();
    544         lower_ = new double [numberColumns];
    545         upper_ = new double [numberColumns];
    546         assert (upper_ != NULL);
    547         memcpy(lower_, rhs.lower_, numberColumns*sizeof(double));
    548         memcpy(upper_, rhs.upper_, numberColumns*sizeof(double));
    549     }
    550 }
    551 
    552 CbcNodeInfo *
    553 CbcFullNodeInfo::clone() const
    554 {
    555     return (new CbcFullNodeInfo(*this));
    556 }
    557 
    558 CbcFullNodeInfo::~CbcFullNodeInfo ()
    559 {
    560     delete basis_ ;
    561     delete [] lower_;
    562     delete [] upper_;
    563 }
    564 
    565 /*
    566   The basis supplied as a parameter is deleted and replaced with a new basis
    567   appropriate for the node, and lower and upper bounds on variables are
    568   reset according to the stored bounds arrays. Any cuts associated with this
    569   node are added to the list in addCuts, but not actually added to the
    570   constraint system in the model.
    571 
    572   Why pass in a basis at all? The short answer is ``We need the parameter to
    573   pass out a basis, so might as well use it to pass in the size.''
    574 
    575   A longer answer is that in practice we take a memory allocation hit up in
    576   addCuts1 (the only place applyToModel is called) when we setSize() the
    577   basis that's passed in. It's immediately tossed here in favour of a clone
    578   of the basis attached to this nodeInfo. This can probably be fixed, given
    579   a bit of thought.
    580 */
    581 
    582 void CbcFullNodeInfo::applyToModel (CbcModel *model,
    583                                     CoinWarmStartBasis *&basis,
    584                                     CbcCountRowCut **addCuts,
    585                                     int &currentNumberCuts) const
    586 
    587 {
    588     OsiSolverInterface *solver = model->solver() ;
    589 
    590     // branch - do bounds
    591     assert (active_ == 7 || active_ == 15);
    592     int i;
    593     solver->setColLower(lower_);
    594     solver->setColUpper(upper_);
    595     int numberColumns = model->getNumCols();
    596     // move basis - but make sure size stays
    597     // for bon-min - should not be needed int numberRows = model->getNumRows();
    598     int numberRows = basis->getNumArtificial();
    599     delete basis ;
    600     if (basis_) {
    601         basis = dynamic_cast<CoinWarmStartBasis *>(basis_->clone()) ;
    602         basis->resize(numberRows, numberColumns);
    603 #ifdef CBC_CHECK_BASIS
    604         std::cout << "Basis (after applying root " << this << ") " << std::endl ;
    605         basis->print() ;
    606 #endif
    607     } else {
    608         // We have a solver without a basis
    609         basis = NULL;
    610     }
    611     for (i = 0; i < numberCuts_; i++)
    612         addCuts[currentNumberCuts+i] = cuts_[i];
    613     currentNumberCuts += numberCuts_;
    614     assert(!parent_);
    615     return ;
    616 }
    617 // Just apply bounds to one variable (1=>infeasible)
    618 int
    619 CbcFullNodeInfo::applyBounds(int iColumn, double & lower, double & upper, int force)
    620 {
    621     if ((force && 1) == 0) {
    622         if (lower > lower_[iColumn])
    623             printf("%d odd lower going from %g to %g\n", iColumn, lower, lower_[iColumn]);
    624         lower = lower_[iColumn];
    625     } else {
    626         lower_[iColumn] = lower;
    627     }
    628     if ((force && 2) == 0) {
    629         if (upper < upper_[iColumn])
    630             printf("%d odd upper going from %g to %g\n", iColumn, upper, upper_[iColumn]);
    631         upper = upper_[iColumn];
    632     } else {
    633         upper_[iColumn] = upper;
    634     }
    635     return (upper_[iColumn] >= lower_[iColumn]) ? 0 : 1;
    636 }
    637 
    638 /* Builds up row basis backwards (until original model).
    639    Returns NULL or previous one to apply .
    640    Depends on Free being 0 and impossible for cuts
    641 */
    642 CbcNodeInfo *
    643 CbcFullNodeInfo::buildRowBasis(CoinWarmStartBasis & basis ) const
    644 {
    645     const unsigned int * saved =
    646         reinterpret_cast<const unsigned int *> (basis_->getArtificialStatus());
    647     unsigned int * now =
    648         reinterpret_cast<unsigned int *> (basis.getArtificialStatus());
    649     int number = basis_->getNumArtificial() >> 4;;
    650     int i;
    651     for (i = 0; i < number; i++) {
    652         if (!now[i])
    653             now[i] = saved[i];
    654     }
    655     return NULL;
    656 }
    657 
    658 
    659 // Default constructor
    660 CbcPartialNodeInfo::CbcPartialNodeInfo()
    661 
    662         : CbcNodeInfo(),
    663         basisDiff_(NULL),
    664         variables_(NULL),
    665         newBounds_(NULL),
    666         numberChangedBounds_(0)
    667 
    668 { /* this space intentionally left blank */ }
    669 
    670 // Constructor from current state
    671 CbcPartialNodeInfo::CbcPartialNodeInfo (CbcNodeInfo *parent, CbcNode *owner,
    672                                         int numberChangedBounds,
    673                                         const int *variables,
    674                                         const double *boundChanges,
    675                                         const CoinWarmStartDiff *basisDiff)
    676         : CbcNodeInfo(parent, owner)
    677 {
    678     basisDiff_ = basisDiff->clone() ;
    679 #ifdef CBC_CHECK_BASIS
    680     std::cout << "Constructor (" << this << ") " << std::endl ;
    681 #endif
    682 
    683     numberChangedBounds_ = numberChangedBounds;
    684     int size = numberChangedBounds_ * (sizeof(double) + sizeof(int));
    685     char * temp = new char [size];
    686     newBounds_ = reinterpret_cast<double *> (temp);
    687     variables_ = reinterpret_cast<int *> (newBounds_ + numberChangedBounds_);
    688 
    689     int i ;
    690     for (i = 0; i < numberChangedBounds_; i++) {
    691         variables_[i] = variables[i];
    692         newBounds_[i] = boundChanges[i];
    693     }
    694 }
    695 
    696 CbcPartialNodeInfo::CbcPartialNodeInfo (const CbcPartialNodeInfo & rhs)
    697 
    698         : CbcNodeInfo(rhs)
    699 
    700 {
    701     basisDiff_ = rhs.basisDiff_->clone() ;
    702 
    703 #ifdef CBC_CHECK_BASIS
    704     std::cout << "Copy constructor (" << this << ") from " << this << std::endl ;
    705 #endif
    706     numberChangedBounds_ = rhs.numberChangedBounds_;
    707     int size = numberChangedBounds_ * (sizeof(double) + sizeof(int));
    708     char * temp = new char [size];
    709     newBounds_ = reinterpret_cast<double *> (temp);
    710     variables_ = reinterpret_cast<int *> (newBounds_ + numberChangedBounds_);
    711 
    712     int i ;
    713     for (i = 0; i < numberChangedBounds_; i++) {
    714         variables_[i] = rhs.variables_[i];
    715         newBounds_[i] = rhs.newBounds_[i];
    716     }
    717 }
    718 
    719 CbcNodeInfo *
    720 CbcPartialNodeInfo::clone() const
    721 {
    722     return (new CbcPartialNodeInfo(*this));
    723 }
    724 
    725 
    726 CbcPartialNodeInfo::~CbcPartialNodeInfo ()
    727 {
    728     delete basisDiff_ ;
    729     delete [] newBounds_;
    730 }
    731 
    732 
    733 /**
    734    The basis supplied as a parameter is incrementally modified, and lower and
    735    upper bounds on variables in the model are incrementally modified. Any
    736    cuts associated with this node are added to the list in addCuts.
    737 */
    738 
    739 void CbcPartialNodeInfo::applyToModel (CbcModel *model,
    740                                        CoinWarmStartBasis *&basis,
    741                                        CbcCountRowCut **addCuts,
    742                                        int &currentNumberCuts) const
    743 
    744 {
    745     OsiSolverInterface *solver = model->solver();
    746     if ((active_&4) != 0) {
    747         basis->applyDiff(basisDiff_) ;
    748 #ifdef CBC_CHECK_BASIS
    749         std::cout << "Basis (after applying " << this << ") " << std::endl ;
    750         basis->print() ;
    751 #endif
    752     }
    753 
    754     // branch - do bounds
    755     int i;
    756     if ((active_&1) != 0) {
    757         for (i = 0; i < numberChangedBounds_; i++) {
    758             int variable = variables_[i];
    759             int k = variable & 0x3fffffff;
    760             if ((variable&0x80000000) == 0) {
    761                 // lower bound changing
    762                 //#define CBC_PRINT2
    763 #ifdef CBC_PRINT2
    764                 if (solver->getColLower()[k] != newBounds_[i])
    765                     printf("lower change for column %d - from %g to %g\n", k, solver->getColLower()[k], newBounds_[i]);
    766 #endif
    767 #ifndef NDEBUG
    768                 if ((variable&0x40000000) == 0 && false) {
    769                     double oldValue = solver->getColLower()[k];
    770                     assert (newBounds_[i] > oldValue - 1.0e-8);
    771                     if (newBounds_[i] < oldValue + 1.0e-8)
    772                         printf("bad null lower change for column %d - bound %g\n", k, oldValue);
    773                 }
    774 #endif
    775                 solver->setColLower(k, newBounds_[i]);
    776             } else {
    777                 // upper bound changing
    778 #ifdef CBC_PRINT2
    779                 if (solver->getColUpper()[k] != newBounds_[i])
    780                     printf("upper change for column %d - from %g to %g\n", k, solver->getColUpper()[k], newBounds_[i]);
    781 #endif
    782 #ifndef NDEBUG
    783                 if ((variable&0x40000000) == 0 && false) {
    784                     double oldValue = solver->getColUpper()[k];
    785                     assert (newBounds_[i] < oldValue + 1.0e-8);
    786                     if (newBounds_[i] > oldValue - 1.0e-8)
    787                         printf("bad null upper change for column %d - bound %g\n", k, oldValue);
    788                 }
    789 #endif
    790                 solver->setColUpper(k, newBounds_[i]);
    791             }
    792         }
    793     }
    794     if ((active_&2) != 0) {
    795         for (i = 0; i < numberCuts_; i++) {
    796             addCuts[currentNumberCuts+i] = cuts_[i];
    797             if (cuts_[i] && model->messageHandler()->logLevel() > 4) {
    798                 cuts_[i]->print();
    799             }
    800         }
    801 
    802         currentNumberCuts += numberCuts_;
    803     }
    804     return ;
    805 }
    806 // Just apply bounds to one variable (1=>infeasible)
    807 int
    808 CbcPartialNodeInfo::applyBounds(int iColumn, double & lower, double & upper, int force)
    809 {
    810     // branch - do bounds
    811     int i;
    812     int found = 0;
    813     double newLower = -COIN_DBL_MAX;
    814     double newUpper = COIN_DBL_MAX;
    815     for (i = 0; i < numberChangedBounds_; i++) {
    816         int variable = variables_[i];
    817         int k = variable & 0x3fffffff;
    818         if (k == iColumn) {
    819             if ((variable&0x80000000) == 0) {
    820                 // lower bound changing
    821                 found |= 1;
    822                 newLower = CoinMax(newLower, newBounds_[i]);
    823                 if ((force&1) == 0) {
    824                     if (lower > newBounds_[i])
    825                         printf("%d odd lower going from %g to %g\n", iColumn, lower, newBounds_[i]);
    826                     lower = newBounds_[i];
    827                 } else {
    828                     newBounds_[i] = lower;
    829                     variables_[i] |= 0x40000000; // say can go odd way
    830                 }
    831             } else {
    832                 // upper bound changing
    833                 found |= 2;
    834                 newUpper = CoinMin(newUpper, newBounds_[i]);
    835                 if ((force&2) == 0) {
    836                     if (upper < newBounds_[i])
    837                         printf("%d odd upper going from %g to %g\n", iColumn, upper, newBounds_[i]);
    838                     upper = newBounds_[i];
    839                 } else {
    840                     newBounds_[i] = upper;
    841                     variables_[i] |= 0x40000000; // say can go odd way
    842                 }
    843             }
    844         }
    845     }
    846     newLower = CoinMax(newLower, lower);
    847     newUpper = CoinMin(newUpper, upper);
    848     int nAdd = 0;
    849     if ((force&2) != 0 && (found&2) == 0) {
    850         // need to add new upper
    851         nAdd++;
    852     }
    853     if ((force&1) != 0 && (found&1) == 0) {
    854         // need to add new lower
    855         nAdd++;
    856     }
    857     if (nAdd) {
    858         int size = (numberChangedBounds_ + nAdd) * (sizeof(double) + sizeof(int));
    859         char * temp = new char [size];
    860         double * newBounds = reinterpret_cast<double *> (temp);
    861         int * variables = reinterpret_cast<int *> (newBounds + numberChangedBounds_ + nAdd);
    862 
    863         int i ;
    864         for (i = 0; i < numberChangedBounds_; i++) {
    865             variables[i] = variables_[i];
    866             newBounds[i] = newBounds_[i];
    867         }
    868         delete [] newBounds_;
    869         newBounds_ = newBounds;
    870         variables_ = variables;
    871         if ((force&2) != 0 && (found&2) == 0) {
    872             // need to add new upper
    873             int variable = iColumn | 0x80000000;
    874             variables_[numberChangedBounds_] = variable;
    875             newBounds_[numberChangedBounds_++] = newUpper;
    876         }
    877         if ((force&1) != 0 && (found&1) == 0) {
    878             // need to add new lower
    879             int variable = iColumn;
    880             variables_[numberChangedBounds_] = variable;
    881             newBounds_[numberChangedBounds_++] = newLower;
    882         }
    883     }
    884 
    885     return (newUpper >= newLower) ? 0 : 1;
    886 }
    887 
    888 /* Builds up row basis backwards (until original model).
    889    Returns NULL or previous one to apply .
    890    Depends on Free being 0 and impossible for cuts
    891 */
    892 
    893 CbcNodeInfo *
    894 CbcPartialNodeInfo::buildRowBasis(CoinWarmStartBasis & basis ) const
    895 
    896 {
    897     basis.applyDiff(basisDiff_) ;
    898 
    899     return parent_ ;
    900 }
     43
     44
    90145CbcNode::CbcNode() :
    90246        nodeInfo_(NULL),
  • branches/sandbox/Cbc/src/CbcNode.hpp

    r1286 r1313  
    1111#include "CoinSearchTree.hpp"
    1212#include "CbcBranchBase.hpp"
     13#include "CbcNodeInfo.hpp"
     14#include "CbcFullNodeInfo.hpp"
     15#include "CbcPartialNodeInfo.hpp"
    1316
    1417class OsiSolverInterface;
     
    2427class CbcSubProblem;
    2528class CbcGeneralBranchingObject;
    26 
    27 //#############################################################################
    28 /** Information required to recreate the subproblem at this node
    29 
    30   When a subproblem is initially created, it is represented by a CbcNode
    31   object and an attached CbcNodeInfo object.
    32 
    33   The CbcNode contains information needed while the subproblem remains live.
    34   The CbcNode is deleted when the last branch arm has been evaluated.
    35 
    36   The CbcNodeInfo contains information required to maintain the branch-and-cut
    37   search tree structure (links and reference counts) and to recreate the
    38   subproblem for this node (basis, variable bounds, cutting planes). A
    39   CbcNodeInfo object remains in existence until all nodes have been pruned from
    40   the subtree rooted at this node.
    41 
    42   The principle used to maintain the reference count is that the reference
    43   count is always the sum of all potential and actual children of the node.
    44   Specifically,
    45   <ul>
    46     <li> Once it's determined how the node will branch, the reference count
    47          is set to the number of potential children (<i>i.e.</i>, the number
    48          of arms of the branch).
    49     <li> As each child is created by CbcNode::branch() (converting a potential
    50          child to the active subproblem), the reference count is decremented.
    51     <li> If the child survives and will become a node in the search tree
    52          (converting the active subproblem into an actual child), increment the
    53          reference count.
    54   </ul>
    55   Notice that the active subproblem lives in a sort of limbo, neither a
    56   potential or an actual node in the branch-and-cut tree.
    57 
    58   CbcNodeInfo objects come in two flavours. A CbcFullNodeInfo object contains
    59   a full record of the information required to recreate a subproblem.
    60   A CbcPartialNodeInfo object expresses this information in terms of
    61   differences from the parent.
    62 */
    63 
    64 class CbcNodeInfo {
    65 
    66 public:
    67 
    68     /** \name Constructors & destructors */
    69 //@{
    70     /** Default Constructor
    71 
    72       Creates an empty NodeInfo object.
    73     */
    74     CbcNodeInfo ();
    75 
    76     /// Copy constructor
    77     CbcNodeInfo ( const CbcNodeInfo &);
    78 
    79 #if 0
    80     /** Construct with parent
    81 
    82       Creates a NodeInfo object which knows its parent and assumes it will
    83       in turn have two children.
    84     */
    85     CbcNodeInfo (CbcNodeInfo * parent);
    86 #endif
    87 
    88     /** Construct with parent and owner
    89 
    90       As for `construct with parent', and attached to \p owner.
    91     */
    92     CbcNodeInfo (CbcNodeInfo * parent, CbcNode * owner);
    93 
    94     /** Destructor
    95 
    96       Note that the destructor will recursively delete the parent if this
    97       nodeInfo is the last child.
    98     */
    99     virtual ~CbcNodeInfo();
    100 //@}
    101 
    102 
    103     /** \brief Modify model according to information at node
    104 
    105         The routine modifies the model according to bound and basis
    106         information at node and adds any cuts to the addCuts array.
    107     */
    108     virtual void applyToModel (CbcModel *model, CoinWarmStartBasis *&basis,
    109                                CbcCountRowCut **addCuts,
    110                                int &currentNumberCuts) const = 0 ;
    111     /// Just apply bounds to one variable - force means overwrite by lower,upper (1=>infeasible)
    112     virtual int applyBounds(int iColumn, double & lower, double & upper, int force) = 0;
    113 
    114     /** Builds up row basis backwards (until original model).
    115         Returns NULL or previous one to apply .
    116         Depends on Free being 0 and impossible for cuts
    117     */
    118     virtual CbcNodeInfo * buildRowBasis(CoinWarmStartBasis & basis) const = 0;
    119     /// Clone
    120     virtual CbcNodeInfo * clone() const = 0;
    121     /// Called when number branches left down to zero
    122     virtual void allBranchesGone() {}
    123 #if 1
    124     /// Increment number of references
    125     inline void increment(int amount = 1) {
    126         numberPointingToThis_ += amount;/*printf("CbcNodeInfo %x incremented by %d to %d\n",this,amount,numberPointingToThis_);*/
    127     }
    128 
    129     /// Decrement number of references and return number left
    130     inline int decrement(int amount = 1) {
    131         numberPointingToThis_ -= amount;/*printf("CbcNodeInfo %x decremented by %d to %d\n",this,amount,numberPointingToThis_);*/
    132         return numberPointingToThis_;
    133     }
    134 #else
    135     /// Increment number of references
    136     void increment(int amount = 1);
    137     /// Decrement number of references and return number left
    138     int decrement(int amount = 1);
    139 #endif
    140     /** Initialize reference counts
    141 
    142       Initialize the reference counts used for tree maintenance.
    143     */
    144 
    145     inline void initializeInfo(int number) {
    146         numberPointingToThis_ = number;
    147         numberBranchesLeft_ = number;
    148     }
    149 
    150     /// Return number of branches left in object
    151     inline int numberBranchesLeft() const {
    152         return numberBranchesLeft_;
    153     }
    154 
    155     /// Set number of branches left in object
    156     inline void setNumberBranchesLeft(int value) {
    157         numberBranchesLeft_ = value;
    158     }
    159 
    160     /// Return number of objects pointing to this
    161     inline int numberPointingToThis() const {
    162         return numberPointingToThis_;
    163     }
    164 
    165     /// Set number of objects pointing to this
    166     inline void setNumberPointingToThis(int number) {
    167         numberPointingToThis_ = number;
    168     }
    169 
    170     /// Increment number of objects pointing to this
    171     inline void incrementNumberPointingToThis() {
    172         numberPointingToThis_ ++;
    173     }
    174 
    175     /// Say one branch taken
    176     inline int branchedOn() {
    177         numberPointingToThis_--;
    178         numberBranchesLeft_--;
    179         return numberBranchesLeft_;
    180     }
    181 
    182     /// Say thrown away
    183     inline void throwAway() {
    184         numberPointingToThis_ -= numberBranchesLeft_;
    185         numberBranchesLeft_ = 0;
    186     }
    187 
    188     /// Parent of this
    189     CbcNodeInfo * parent() const {
    190         return parent_;
    191     }
    192     /// Set parent null
    193     inline void nullParent() {
    194         parent_ = NULL;
    195     }
    196 
    197     void addCuts(OsiCuts & cuts, int numberToBranch, //int * whichGenerator,
    198                  int numberPointingToThis);
    199     void addCuts(int numberCuts, CbcCountRowCut ** cuts, int numberToBranch);
    200     /** Delete cuts (decrements counts)
    201         Slow unless cuts in same order as saved
    202     */
    203     void deleteCuts(int numberToDelete, CbcCountRowCut ** cuts);
    204     void deleteCuts(int numberToDelete, int * which);
    205 
    206     /// Really delete a cut
    207     void deleteCut(int whichOne);
    208 
    209     /// Decrement active cut counts
    210     void decrementCuts(int change = 1);
    211 
    212     /// Increment active cut counts
    213     void incrementCuts(int change = 1);
    214 
    215     /// Decrement all active cut counts in chain starting at parent
    216     void decrementParentCuts(CbcModel * model, int change = 1);
    217 
    218     /// Increment all active cut counts in parent chain
    219     void incrementParentCuts(CbcModel * model, int change = 1);
    220 
    221     /// Array of pointers to cuts
    222     inline CbcCountRowCut ** cuts() const {
    223         return cuts_;
    224     }
    225 
    226     /// Number of row cuts (this node)
    227     inline int numberCuts() const {
    228         return numberCuts_;
    229     }
    230     inline void setNumberCuts(int value) {
    231         numberCuts_ = value;
    232     }
    233 
    234     /// Set owner null
    235     inline void nullOwner() {
    236         owner_ = NULL;
    237     }
    238     const inline CbcNode * owner() const {
    239         return owner_;
    240     }
    241     inline CbcNode * mutableOwner() const {
    242         return owner_;
    243     }
    244     /// The node number
    245     inline int nodeNumber() const {
    246         return nodeNumber_;
    247     }
    248     inline void setNodeNumber(int node) {
    249         nodeNumber_ = node;
    250     }
    251     /** Deactivate node information.
    252         1 - bounds
    253         2 - cuts
    254         4 - basis!
    255     */
    256     void deactivate(int mode = 3);
    257     /// Say if normal
    258     inline bool allActivated() const {
    259         return (active_ == 7);
    260     }
    261     /// Say if marked
    262     inline bool marked() const {
    263         return ((active_&8) != 0);
    264     }
    265     /// Mark
    266     inline void mark() {
    267         active_ |= 8;
    268     }
    269     /// Unmark
    270     inline void unmark() {
    271         active_ &= ~8;
    272     }
    273 
    274     /// Branching object for the parent
    275     inline const OsiBranchingObject * parentBranch() const {
    276         return parentBranch_;
    277     }
    278     /// If we need to take off parent based data
    279     void unsetParentBasedData();
    280 protected:
    281 
    282     /** Number of other nodes pointing to this node.
    283 
    284       Number of existing and potential search tree nodes pointing to this node.
    285       `Existing' means referenced by #parent_ of some other CbcNodeInfo.
    286       `Potential' means children still to be created (#numberBranchesLeft_ of
    287       this CbcNodeInfo).
    288     */
    289     int numberPointingToThis_;
    290 
    291     /// parent
    292     CbcNodeInfo * parent_;
    293 
    294     /// Copy of the branching object of the parent when the node is created
    295     OsiBranchingObject * parentBranch_;
    296 
    297     /// Owner
    298     CbcNode * owner_;
    299 
    300     /// Number of row cuts (this node)
    301     int numberCuts_;
    302 
    303     /// The node number
    304     int nodeNumber_;
    305 
    306     /// Array of pointers to cuts
    307     CbcCountRowCut ** cuts_;
    308 
    309     /** Number of rows in problem (before these cuts).  This
    310         means that for top of chain it must be rows at continuous */
    311     int numberRows_;
    312 
    313     /** Number of branch arms left to explore at this node
    314 
    315       \todo There seems to be redundancy between this field and
    316         CbcBranchingObject::numberBranchesLeft_. It'd be good to sort out if
    317         both are necessary.
    318     */
    319     int numberBranchesLeft_;
    320     /** Active node information.
    321         1 - bounds
    322         2 - cuts
    323         4 - basis!
    324     */
    325     int active_;
    326 
    327 private:
    328 
    329     /// Illegal Assignment operator
    330     CbcNodeInfo & operator=(const CbcNodeInfo& rhs);
    331 
    332     /// routine common to constructors
    333     void setParentBasedData();
    334 };
    335 
    336 /** \brief Holds complete information for recreating a subproblem.
    337 
    338   A CbcFullNodeInfo object contains all necessary information (bounds, basis,
    339   and cuts) required to recreate a subproblem.
    340 
    341   \todo While there's no explicit statement, the code often makes the implicit
    342         assumption that an CbcFullNodeInfo structure will appear only at the
    343         root node of the search tree. Things will break if this assumption
    344         is violated.
    345 */
    346 
    347 class CbcFullNodeInfo : public CbcNodeInfo {
    348 
    349 public:
    350 
    351     /** \brief Modify model according to information at node
    352 
    353         The routine modifies the model according to bound information at node,
    354         creates a new basis according to information at node, but with the size
    355         passed in through basis, and adds any cuts to the addCuts array.
    356 
    357       \note The basis passed in via basis is solely a vehicle for passing in
    358         the desired basis size. It will be deleted and a new basis returned.
    359     */
    360     virtual void applyToModel (CbcModel *model, CoinWarmStartBasis *&basis,
    361                                CbcCountRowCut **addCuts,
    362                                int &currentNumberCuts) const ;
    363 
    364     /// Just apply bounds to one variable - force means overwrite by lower,upper (1=>infeasible)
    365     virtual int applyBounds(int iColumn, double & lower, double & upper, int force) ;
    366 
    367     /** Builds up row basis backwards (until original model).
    368         Returns NULL or previous one to apply .
    369         Depends on Free being 0 and impossible for cuts
    370     */
    371     virtual CbcNodeInfo * buildRowBasis(CoinWarmStartBasis & basis) const ;
    372     // Default Constructor
    373     CbcFullNodeInfo ();
    374 
    375     /** Constructor from continuous or satisfied
    376     */
    377     CbcFullNodeInfo (CbcModel * model,
    378                      int numberRowsAtContinuous);
    379 
    380     // Copy constructor
    381     CbcFullNodeInfo ( const CbcFullNodeInfo &);
    382 
    383     // Destructor
    384     ~CbcFullNodeInfo ();
    385 
    386     /// Clone
    387     virtual CbcNodeInfo * clone() const;
    388     /// Lower bounds
    389     inline const double * lower() const {
    390         return lower_;
    391     }
    392     /// Upper bounds
    393     inline const double * upper() const {
    394         return upper_;
    395     }
    396 protected:
    397     // Data
    398     /** Full basis
    399 
    400       This MUST BE A POINTER to avoid cutting extra information in derived
    401       warm start classes.
    402     */
    403     CoinWarmStartBasis *basis_;
    404     int numberIntegers_;
    405     // Bounds stored in full
    406     double * lower_;
    407     double * upper_;
    408 private:
    409     /// Illegal Assignment operator
    410     CbcFullNodeInfo & operator=(const CbcFullNodeInfo& rhs);
    411 };
    412 
    413 
    414 
    415 /** \brief Holds information for recreating a subproblem by incremental change
    416            from the parent.
    417 
    418   A CbcPartialNodeInfo object contains changes to the bounds and basis, and
    419   additional cuts, required to recreate a subproblem by modifying and
    420   augmenting the parent subproblem.
    421 */
    422 
    423 class CbcPartialNodeInfo : public CbcNodeInfo {
    424 
    425 public:
    426 
    427     /** \brief Modify model according to information at node
    428 
    429         The routine modifies the model according to bound and basis change
    430         information at node and adds any cuts to the addCuts array.
    431     */
    432     virtual void applyToModel (CbcModel *model, CoinWarmStartBasis *&basis,
    433                                CbcCountRowCut **addCuts,
    434                                int &currentNumberCuts) const ;
    435 
    436     /// Just apply bounds to one variable - force means overwrite by lower,upper (1=>infeasible)
    437     virtual int applyBounds(int iColumn, double & lower, double & upper, int force) ;
    438     /** Builds up row basis backwards (until original model).
    439         Returns NULL or previous one to apply .
    440         Depends on Free being 0 and impossible for cuts
    441     */
    442     virtual CbcNodeInfo * buildRowBasis(CoinWarmStartBasis & basis ) const ;
    443     // Default Constructor
    444     CbcPartialNodeInfo ();
    445 
    446     // Constructor from current state
    447     CbcPartialNodeInfo (CbcNodeInfo * parent, CbcNode * owner,
    448                         int numberChangedBounds, const int * variables,
    449                         const double * boundChanges,
    450                         const CoinWarmStartDiff *basisDiff) ;
    451 
    452     // Copy constructor
    453     CbcPartialNodeInfo ( const CbcPartialNodeInfo &);
    454 
    455     // Destructor
    456     ~CbcPartialNodeInfo ();
    457 
    458     /// Clone
    459     virtual CbcNodeInfo * clone() const;
    460     /// Basis diff information
    461     inline const CoinWarmStartDiff *basisDiff() const {
    462         return basisDiff_ ;
    463     }
    464     /// Which variable (top bit if upper bound changing)
    465     inline const int * variables() const {
    466         return variables_;
    467     }
    468     // New bound
    469     inline const double * newBounds() const {
    470         return newBounds_;
    471     }
    472     /// Number of bound changes
    473     inline int numberChangedBounds() const {
    474         return numberChangedBounds_;
    475     }
    476 protected:
    477     /* Data values */
    478 
    479     /// Basis diff information
    480     CoinWarmStartDiff *basisDiff_ ;
    481     /// Which variable (top bit if upper bound changing)
    482     int * variables_;
    483     // New bound
    484     double * newBounds_;
    485     /// Number of bound changes
    486     int numberChangedBounds_;
    487 private:
    488 
    489     /// Illegal Assignment operator
    490     CbcPartialNodeInfo & operator=(const CbcPartialNodeInfo& rhs);
    491 };
    492 
    49329
    49430/** Information required while the node is live
  • branches/sandbox/Cbc/src/Makefile.am

    r1308 r1313  
    5050        CbcFixingBranchingObject.cpp CbcFixingBranchingObject.hpp \
    5151        CbcFixVariable.cpp CbcFixVariable.hpp \
     52        CbcFullNodeInfo.cpp CbcFullNodeInfo.hpp \
    5253        CbcFollowOn.cpp CbcFollowOn.hpp \
    5354        CbcGeneral.cpp CbcGeneral.hpp \
     
    7576        CbcModel.cpp CbcModel.hpp \
    7677        CbcNode.cpp CbcNode.hpp \
     78        CbcNodeInfo.cpp CbcNodeInfo.hpp \
    7779        CbcNWay.cpp CbcNWay.hpp \
    7880        CbcNWayBranchingObject.cpp CbcNWayBranchingObject.hpp \
     
    8082        CbcObjectUpdateData.cpp CbcObjectUpdateData.hpp \
    8183        CbcOneGeneralBranchingObject.cpp CbcOneGeneralBranchingObject.hpp \
     84        CbcPartialNodeInfo.cpp CbcPartialNodeInfo.hpp \
    8285        CbcSimpleInteger.cpp CbcSimpleInteger.hpp \
    8386        CbcSimpleIntegerDynamicPseudoCost.cpp CbcSimpleIntegerDynamicPseudoCost.hpp \
     
    368371        CbcFixVariable.hpp \
    369372        CbcFollowOn.hpp \
     373        CbcFullNodeInfo.hpp \
    370374        CbcGeneral.hpp \
    371375        CbcGeneralBranchingObject.hpp \
     
    392396        CbcModel.hpp \
    393397        CbcNode.hpp \
     398        CbcNodeInfo.hpp \
    394399        CbcNWay.hpp \
    395400        CbcNWayBranchingObject.hpp \
     
    397402        CbcObjectUpdateData.hpp \
    398403        CbcOneGeneralBranchingObject.hpp \
     404        CbcPartialNodeInfo.hpp \
    399405        CbcSimpleInteger.hpp \
    400406        CbcSimpleIntegerDynamicPseudoCost.hpp \
  • branches/sandbox/Cbc/src/Makefile.in

    r1312 r1313  
    172172        CbcDynamicPseudoCostBranchingObject.lo CbcEventHandler.lo \
    173173        CbcFathom.lo CbcFathomDynamicProgramming.lo \
    174         CbcFixingBranchingObject.lo CbcFixVariable.lo CbcFollowOn.lo \
    175         CbcGeneral.lo CbcGeneralBranchingObject.lo CbcGeneralDepth.lo \
     174        CbcFixingBranchingObject.lo CbcFixVariable.lo \
     175        CbcFullNodeInfo.lo CbcFollowOn.lo CbcGeneral.lo \
     176        CbcGeneralBranchingObject.lo CbcGeneralDepth.lo \
    176177        CbcHeuristic.lo CbcHeuristicDive.lo \
    177178        CbcHeuristicDiveCoefficient.lo CbcHeuristicDiveFractional.lo \
     
    183184        CbcIntegerBranchingObject.lo \
    184185        CbcIntegerPseudoCostBranchingObject.lo CbcLotsize.lo \
    185         CbcMessage.lo CbcModel.lo CbcNode.lo CbcNWay.lo \
     186        CbcMessage.lo CbcModel.lo CbcNode.lo CbcNodeInfo.lo CbcNWay.lo \
    186187        CbcNWayBranchingObject.lo CbcObject.lo CbcObjectUpdateData.lo \
    187         CbcOneGeneralBranchingObject.lo CbcSimpleInteger.lo \
    188         CbcSimpleIntegerDynamicPseudoCost.lo \
     188        CbcOneGeneralBranchingObject.lo CbcPartialNodeInfo.lo \
     189        CbcSimpleInteger.lo CbcSimpleIntegerDynamicPseudoCost.lo \
    189190        CbcSimpleIntegerPseudoCost.lo CbcSOS.lo \
    190191        CbcSOSBranchingObject.lo CbcStatistics.lo CbcStrategy.lo \
     
    552553        CbcFixingBranchingObject.cpp CbcFixingBranchingObject.hpp \
    553554        CbcFixVariable.cpp CbcFixVariable.hpp \
     555        CbcFullNodeInfo.cpp CbcFullNodeInfo.hpp \
    554556        CbcFollowOn.cpp CbcFollowOn.hpp \
    555557        CbcGeneral.cpp CbcGeneral.hpp \
     
    577579        CbcModel.cpp CbcModel.hpp \
    578580        CbcNode.cpp CbcNode.hpp \
     581        CbcNodeInfo.cpp CbcNodeInfo.hpp \
    579582        CbcNWay.cpp CbcNWay.hpp \
    580583        CbcNWayBranchingObject.cpp CbcNWayBranchingObject.hpp \
     
    582585        CbcObjectUpdateData.cpp CbcObjectUpdateData.hpp \
    583586        CbcOneGeneralBranchingObject.cpp CbcOneGeneralBranchingObject.hpp \
     587        CbcPartialNodeInfo.cpp CbcPartialNodeInfo.hpp \
    584588        CbcSimpleInteger.cpp CbcSimpleInteger.hpp \
    585589        CbcSimpleIntegerDynamicPseudoCost.cpp CbcSimpleIntegerDynamicPseudoCost.hpp \
     
    733737        CbcFixVariable.hpp \
    734738        CbcFollowOn.hpp \
     739        CbcFullNodeInfo.hpp \
    735740        CbcGeneral.hpp \
    736741        CbcGeneralBranchingObject.hpp \
     
    757762        CbcModel.hpp \
    758763        CbcNode.hpp \
     764        CbcNodeInfo.hpp \
    759765        CbcNWay.hpp \
    760766        CbcNWayBranchingObject.hpp \
     
    762768        CbcObjectUpdateData.hpp \
    763769        CbcOneGeneralBranchingObject.hpp \
     770        CbcPartialNodeInfo.hpp \
    764771        CbcSimpleInteger.hpp \
    765772        CbcSimpleIntegerDynamicPseudoCost.hpp \
     
    912919@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcFixingBranchingObject.Plo@am__quote@
    913920@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcFollowOn.Plo@am__quote@
     921@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcFullNodeInfo.Plo@am__quote@
    914922@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcGenBaB.Po@am__quote@
    915923@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcGenCbcParam.Po@am__quote@
     
    951959@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcNWayBranchingObject.Plo@am__quote@
    952960@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcNode.Plo@am__quote@
     961@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcNodeInfo.Plo@am__quote@
    953962@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcObject.Plo@am__quote@
    954963@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcObjectUpdateData.Plo@am__quote@
    955964@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcOneGeneralBranchingObject.Plo@am__quote@
     965@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcPartialNodeInfo.Plo@am__quote@
    956966@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcSOS.Plo@am__quote@
    957967@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcSOSBranchingObject.Plo@am__quote@
Note: See TracChangeset for help on using the changeset viewer.