Changeset 1351 for branches/sandbox


Ignore:
Timestamp:
Dec 4, 2009 11:26:41 AM (10 years ago)
Author:
EdwinStraver
Message:

Combined CbcBranchDynamic?.cpp with CbcDynamicPseudoCostBranchingObject?
Combined CbcBranchCut? with CbcCutBranchingObject?
Combined CbcLotsize? with CbcBranchLotsize?.cpp

Location:
branches/sandbox/Cbc
Files:
6 deleted
11 edited

Legend:

Unmodified
Added
Removed
  • branches/sandbox/Cbc/MSVisualStudio/v9/libCbc/libCbc.vcproj

    r1350 r1351  
    233233                        </File>
    234234                        <File
    235                                 RelativePath="..\..\..\..\Cbc\src\CbcBranchLotsize.cpp"
    236                                 >
    237                                 <FileConfiguration
    238                                         Name="Debug|Win32"
    239                                         >
    240                                         <Tool
    241                                                 Name="VCCLCompilerTool"
    242                                                 Optimization="0"
    243                                                 AdditionalIncludeDirectories=""
    244                                                 PreprocessorDefinitions=""
    245                                                 BasicRuntimeChecks="3"
    246                                         />
    247                                 </FileConfiguration>
    248                                 <FileConfiguration
    249                                         Name="Release|Win32"
    250                                         >
    251                                         <Tool
    252                                                 Name="VCCLCompilerTool"
    253                                                 Optimization="2"
    254                                                 AdditionalIncludeDirectories=""
    255                                                 PreprocessorDefinitions=""
    256                                         />
    257                                 </FileConfiguration>
     235                                RelativePath="..\..\..\src\CbcBranchLotsize.cpp"
     236                                >
    258237                        </File>
    259238                        <File
     
    336315                        </File>
    337316                        <File
    338                                 RelativePath="..\..\..\src\CbcCutBranchingObject.cpp"
    339                                 >
    340                         </File>
    341                         <File
    342317                                RelativePath="..\..\..\..\Cbc\src\CbcCutGenerator.cpp"
    343318                                >
     
    377352                        </File>
    378353                        <File
    379                                 RelativePath="..\..\..\src\CbcDynamicPseudoCostBranchingObject.cpp"
    380                                 >
    381                         </File>
    382                         <File
    383354                                RelativePath="..\..\..\..\Cbc\src\CbcEventHandler.cpp"
    384355                                >
     
    815786                                        />
    816787                                </FileConfiguration>
    817                         </File>
    818                         <File
    819                                 RelativePath="..\..\..\src\CbcLotsize.cpp"
    820                                 >
    821788                        </File>
    822789                        <File
     
    11101077                        </File>
    11111078                        <File
    1112                                 RelativePath="..\..\..\..\Cbc\src\CbcBranchLotsize.hpp"
     1079                                RelativePath="..\..\..\src\CbcBranchLotsize.hpp"
    11131080                                >
    11141081                        </File>
     
    11661133                        </File>
    11671134                        <File
    1168                                 RelativePath="..\..\..\src\CbcCutBranchingObject.hpp"
    1169                                 >
    1170                         </File>
    1171                         <File
    11721135                                RelativePath="..\..\..\..\Cbc\src\CbcCutGenerator.hpp"
    11731136                                >
     
    11861149                        </File>
    11871150                        <File
    1188                                 RelativePath="..\..\..\src\CbcDynamicPseudoCostBranchingObject.hpp"
    1189                                 >
    1190                         </File>
    1191                         <File
    11921151                                RelativePath="..\..\..\..\Cbc\src\CbcEventHandler.hpp"
    11931152                                >
     
    12871246                        <File
    12881247                                RelativePath="..\..\..\src\CbcLinked.hpp"
    1289                                 >
    1290                         </File>
    1291                         <File
    1292                                 RelativePath="..\..\..\src\CbcLotsize.hpp"
    12931248                                >
    12941249                        </File>
  • branches/sandbox/Cbc/src/CbcBranchAllDifferent.hpp

    r1305 r1351  
    66#include "OsiRowCut.hpp"
    77#include "CoinPackedMatrix.hpp"
    8 #include "CbcCutBranchingObject.hpp"
     8#include "CbcBranchCut.hpp"
    99
    1010/** Define a branch class that branches so that it is only satsified if all
  • branches/sandbox/Cbc/src/CbcBranchCut.cpp

    r1305 r1351  
    125125}
    126126
     127// Default Constructor
     128CbcCutBranchingObject::CbcCutBranchingObject()
     129        : CbcBranchingObject()
     130{
     131    down_ = OsiRowCut();
     132    up_ = OsiRowCut();
     133    canFix_ = false;
     134}
     135
     136// Useful constructor
     137CbcCutBranchingObject::CbcCutBranchingObject (CbcModel * model,
     138        OsiRowCut & down,
     139        OsiRowCut &up,
     140        bool canFix)
     141        : CbcBranchingObject(model, 0, -1, 0.0)
     142{
     143    down_ = down;
     144    up_ = up;
     145    canFix_ = canFix;
     146}
     147
     148// Copy constructor
     149CbcCutBranchingObject::CbcCutBranchingObject ( const CbcCutBranchingObject & rhs) : CbcBranchingObject(rhs)
     150{
     151    down_ = rhs.down_;
     152    up_ = rhs.up_;
     153    canFix_ = rhs.canFix_;
     154}
     155
     156// Assignment operator
     157CbcCutBranchingObject &
     158CbcCutBranchingObject::operator=( const CbcCutBranchingObject & rhs)
     159{
     160    if (this != &rhs) {
     161        CbcBranchingObject::operator=(rhs);
     162        down_ = rhs.down_;
     163        up_ = rhs.up_;
     164        canFix_ = rhs.canFix_;
     165    }
     166    return *this;
     167}
     168CbcBranchingObject *
     169CbcCutBranchingObject::clone() const
     170{
     171    return (new CbcCutBranchingObject(*this));
     172}
     173
     174
     175// Destructor
     176CbcCutBranchingObject::~CbcCutBranchingObject ()
     177{
     178}
     179
     180/*
     181  Perform a branch by adjusting bounds and/or adding a cut. Note
     182  that each arm of the branch advances the object to the next arm by
     183  advancing the value of way_.
     184
     185  Returns change in guessed objective on next branch
     186*/
     187double
     188CbcCutBranchingObject::branch()
     189{
     190    decrementNumberBranchesLeft();
     191    OsiRowCut * cut;
     192    if (way_ < 0) {
     193        cut = &down_;
     194        way_ = 1;
     195    } else {
     196        cut = &up_;
     197        way_ = -1;        // Swap direction
     198    }
     199    printf("CUT %s ", (way_ == -1) ? "up" : "down");
     200    cut->print();
     201    // See if cut just fixes variables
     202    double lb = cut->lb();
     203    double ub = cut->ub();
     204    int n = cut->row().getNumElements();
     205    const int * column = cut->row().getIndices();
     206    const double * element = cut->row().getElements();
     207    OsiSolverInterface * solver = model_->solver();
     208    const double * upper = solver->getColUpper();
     209    const double * lower = solver->getColLower();
     210    double low = 0.0;
     211    double high = 0.0;
     212    for (int i = 0; i < n; i++) {
     213        int iColumn = column[i];
     214        double value = element[i];
     215        if (value > 0.0) {
     216            high += upper[iColumn] * value;
     217            low += lower[iColumn] * value;
     218        } else {
     219            high += lower[iColumn] * value;
     220            low += upper[iColumn] * value;
     221        }
     222    }
     223    // leave as cut
     224    //model_->setNextRowCut(*cut);
     225    //return 0.0;
     226    // assume cut was cunningly constructed so we need not worry too much about tolerances
     227    if (low + 1.0e-8 >= ub && canFix_) {
     228        // fix
     229        for (int i = 0; i < n; i++) {
     230            int iColumn = column[i];
     231            double value = element[i];
     232            if (value > 0.0) {
     233                solver->setColUpper(iColumn, lower[iColumn]);
     234            } else {
     235                solver->setColLower(iColumn, upper[iColumn]);
     236            }
     237        }
     238    } else if (high - 1.0e-8 <= lb && canFix_) {
     239        // fix
     240        for (int i = 0; i < n; i++) {
     241            int iColumn = column[i];
     242            double value = element[i];
     243            if (value > 0.0) {
     244                solver->setColLower(iColumn, upper[iColumn]);
     245            } else {
     246                solver->setColUpper(iColumn, lower[iColumn]);
     247            }
     248        }
     249    } else {
     250        // leave as cut
     251        model_->setNextRowCut(*cut);
     252    }
     253    return 0.0;
     254}
     255// Print what would happen
     256void
     257CbcCutBranchingObject::print()
     258{
     259    OsiRowCut * cut;
     260    if (way_ < 0) {
     261        cut = &down_;
     262        printf("CbcCut would branch down");
     263    } else {
     264        cut = &up_;
     265        printf("CbcCut would branch up");
     266    }
     267    double lb = cut->lb();
     268    double ub = cut->ub();
     269    int n = cut->row().getNumElements();
     270    const int * column = cut->row().getIndices();
     271    const double * element = cut->row().getElements();
     272    if (n > 5) {
     273        printf(" - %d elements, lo=%g, up=%g\n", n, lb, ub);
     274    } else {
     275        printf(" - %g <=", lb);
     276        for (int i = 0; i < n; i++) {
     277            int iColumn = column[i];
     278            double value = element[i];
     279            printf(" (%d,%g)", iColumn, value);
     280        }
     281        printf(" <= %g\n", ub);
     282    }
     283}
     284
     285// Return true if branch should fix variables
     286bool
     287CbcCutBranchingObject::boundBranch() const
     288{
     289    return false;
     290}
     291
     292/** Compare the original object of \c this with the original object of \c
     293    brObj. Assumes that there is an ordering of the original objects.
     294    This method should be invoked only if \c this and brObj are of the same
     295    type.
     296    Return negative/0/positive depending on whether \c this is
     297    smaller/same/larger than the argument.
     298*/
     299int
     300CbcCutBranchingObject::compareOriginalObject
     301(const CbcBranchingObject* brObj) const
     302{
     303    const CbcCutBranchingObject* br =
     304        dynamic_cast<const CbcCutBranchingObject*>(brObj);
     305    assert(br);
     306    const OsiRowCut& r0 = way_ == -1 ? down_ : up_;
     307    const OsiRowCut& r1 = br->way_ == -1 ? br->down_ : br->up_;
     308    return r0.row().compare(r1.row());
     309}
     310
     311/** Compare the \c this with \c brObj. \c this and \c brObj must be os the
     312    same type and must have the same original object, but they may have
     313    different feasible regions.
     314    Return the appropriate CbcRangeCompare value (first argument being the
     315    sub/superset if that's the case). In case of overlap (and if \c
     316    replaceIfOverlap is true) replace the current branching object with one
     317    whose feasible region is the overlap.
     318*/
     319
     320CbcRangeCompare
     321CbcCutBranchingObject::compareBranchingObject
     322(const CbcBranchingObject* brObj, const bool replaceIfOverlap)
     323{
     324    const CbcCutBranchingObject* br =
     325        dynamic_cast<const CbcCutBranchingObject*>(brObj);
     326    assert(br);
     327    OsiRowCut& r0 = way_ == -1 ? down_ : up_;
     328    const OsiRowCut& r1 = br->way_ == -1 ? br->down_ : br->up_;
     329    double thisBd[2];
     330    thisBd[0] = r0.lb();
     331    thisBd[1] = r0.ub();
     332    double otherBd[2];
     333    otherBd[0] = r1.lb();
     334    otherBd[1] = r1.ub();
     335    CbcRangeCompare comp = CbcCompareRanges(thisBd, otherBd, replaceIfOverlap);
     336    if (comp != CbcRangeOverlap || (comp == CbcRangeOverlap && !replaceIfOverlap)) {
     337        return comp;
     338    }
     339    r0.setLb(thisBd[0]);
     340    r0.setUb(thisBd[1]);
     341    return comp;
     342}
  • branches/sandbox/Cbc/src/CbcBranchCut.hpp

    r1305 r1351  
    88#include "OsiRowCut.hpp"
    99#include "CoinPackedMatrix.hpp"
    10 #include "CbcCutBranchingObject.hpp"
    1110
    1211/** Define a cut branching class.
     
    10099
    101100};
     101/** Cut branching object
     102
     103  This object can specify a two-way branch in terms of two cuts
     104*/
     105
     106class CbcCutBranchingObject : public CbcBranchingObject {
     107
     108public:
     109
     110    /// Default constructor
     111    CbcCutBranchingObject ();
     112
     113    /** Create a cut branching object
     114
     115        Cut down will applied on way=-1, up on way==1
     116        Assumed down will be first so way_ set to -1
     117    */
     118    CbcCutBranchingObject (CbcModel * model, OsiRowCut & down, OsiRowCut &up, bool canFix);
     119
     120    /// Copy constructor
     121    CbcCutBranchingObject ( const CbcCutBranchingObject &);
     122
     123    /// Assignment operator
     124    CbcCutBranchingObject & operator= (const CbcCutBranchingObject& rhs);
     125
     126    /// Clone
     127    virtual CbcBranchingObject * clone() const;
     128
     129    /// Destructor
     130    virtual ~CbcCutBranchingObject ();
     131
     132    using CbcBranchingObject::branch ;
     133    /** \brief Sets the bounds for variables or adds a cut depending on the
     134               current arm of the branch and advances the object state to the next arm.
     135           Returns change in guessed objective on next branch
     136    */
     137    virtual double branch();
     138
     139#if 0
     140    // No need to override. Default works fine.
     141    /** Reset every information so that the branching object appears to point to
     142        the previous child. This method does not need to modify anything in any
     143        solver. */
     144    virtual void previousBranch();
    102145#endif
     146
     147    using CbcBranchingObject::print ;
     148    /** \brief Print something about branch - only if log level high
     149    */
     150    virtual void print();
     151
     152    /** \brief Return true if branch should fix variables
     153    */
     154    virtual bool boundBranch() const;
     155
     156    /** Return the type (an integer identifier) of \c this */
     157    virtual int type() const {
     158        return 200;
     159    }
     160
     161    /** Compare the original object of \c this with the original object of \c
     162        brObj. Assumes that there is an ordering of the original objects.
     163        This method should be invoked only if \c this and brObj are of the same
     164        type.
     165        Return negative/0/positive depending on whether \c this is
     166        smaller/same/larger than the argument.
     167    */
     168    virtual int compareOriginalObject(const CbcBranchingObject* brObj) const;
     169
     170    /** Compare the \c this with \c brObj. \c this and \c brObj must be os the
     171        same type and must have the same original object, but they may have
     172        different feasible regions.
     173        Return the appropriate CbcRangeCompare value (first argument being the
     174        sub/superset if that's the case). In case of overlap (and if \c
     175        replaceIfOverlap is true) replace the current branching object with one
     176        whose feasible region is the overlap.
     177     */
     178    virtual CbcRangeCompare compareBranchingObject
     179    (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false);
     180
     181protected:
     182    /// Cut for the down arm (way_ = -1)
     183    OsiRowCut down_;
     184    /// Cut for the up arm (way_ = 1)
     185    OsiRowCut up_;
     186    /// True if one way can fix variables
     187    bool canFix_;
     188};
     189#endif
  • branches/sandbox/Cbc/src/CbcBranchDynamic.cpp

    r1308 r1351  
    605605}
    606606#endif
     607
     608// Default Constructor
     609CbcDynamicPseudoCostBranchingObject::CbcDynamicPseudoCostBranchingObject()
     610        : CbcIntegerBranchingObject()
     611{
     612    changeInGuessed_ = 1.0e-5;
     613    object_ = NULL;
     614}
     615
     616// Useful constructor
     617CbcDynamicPseudoCostBranchingObject::CbcDynamicPseudoCostBranchingObject (CbcModel * model,
     618        int variable,
     619        int way , double value,
     620        CbcSimpleIntegerDynamicPseudoCost * object)
     621        : CbcIntegerBranchingObject(model, variable, way, value)
     622{
     623    changeInGuessed_ = 1.0e-5;
     624    object_ = object;
     625}
     626// Does part of work for constructor
     627void
     628CbcDynamicPseudoCostBranchingObject::fillPart (int variable,
     629        int way , double value,
     630        CbcSimpleIntegerDynamicPseudoCost * object)
     631{
     632    CbcIntegerBranchingObject::fillPart(variable, way, value);
     633    changeInGuessed_ = 1.0e-5;
     634    object_ = object;
     635}
     636// Useful constructor for fixing
     637CbcDynamicPseudoCostBranchingObject::CbcDynamicPseudoCostBranchingObject (CbcModel * model,
     638        int variable, int way,
     639        double lowerValue,
     640        double /*upperValue*/)
     641        : CbcIntegerBranchingObject(model, variable, way, lowerValue)
     642{
     643    changeInGuessed_ = 1.0e100;
     644    object_ = NULL;
     645}
     646
     647
     648// Copy constructor
     649CbcDynamicPseudoCostBranchingObject::CbcDynamicPseudoCostBranchingObject (
     650    const CbcDynamicPseudoCostBranchingObject & rhs)
     651        : CbcIntegerBranchingObject(rhs)
     652{
     653    changeInGuessed_ = rhs.changeInGuessed_;
     654    object_ = rhs.object_;
     655}
     656
     657// Assignment operator
     658CbcDynamicPseudoCostBranchingObject &
     659CbcDynamicPseudoCostBranchingObject::operator=( const CbcDynamicPseudoCostBranchingObject & rhs)
     660{
     661    if (this != &rhs) {
     662        CbcIntegerBranchingObject::operator=(rhs);
     663        changeInGuessed_ = rhs.changeInGuessed_;
     664        object_ = rhs.object_;
     665    }
     666    return *this;
     667}
     668CbcBranchingObject *
     669CbcDynamicPseudoCostBranchingObject::clone() const
     670{
     671    return (new CbcDynamicPseudoCostBranchingObject(*this));
     672}
     673
     674// Destructor
     675CbcDynamicPseudoCostBranchingObject::~CbcDynamicPseudoCostBranchingObject ()
     676{
     677}
     678
     679/*
     680  Perform a branch by adjusting the bounds of the specified variable. Note
     681  that each arm of the branch advances the object to the next arm by
     682  advancing the value of way_.
     683
     684  Providing new values for the variable's lower and upper bounds for each
     685  branching direction gives a little bit of additional flexibility and will
     686  be easily extensible to multi-way branching.
     687  Returns change in guessed objective on next branch
     688*/
     689double
     690CbcDynamicPseudoCostBranchingObject::branch()
     691{
     692    CbcIntegerBranchingObject::branch();
     693    return changeInGuessed_;
     694}
     695/* Some branchingObjects may claim to be able to skip
     696   strong branching.  If so they have to fill in CbcStrongInfo.
     697   The object mention in incoming CbcStrongInfo must match.
     698   Returns nonzero if skip is wanted */
     699int
     700CbcDynamicPseudoCostBranchingObject::fillStrongInfo( CbcStrongInfo & info)
     701{
     702    assert (object_);
     703    assert (info.possibleBranch == this);
     704    info.upMovement = object_->upDynamicPseudoCost() * (ceil(value_) - value_);
     705    info.downMovement = object_->downDynamicPseudoCost() * (value_ - floor(value_));
     706    info.numIntInfeasUp  -= static_cast<int> (object_->sumUpDecrease() /
     707                            (1.0e-12 + static_cast<double> (object_->numberTimesUp())));
     708    info.numIntInfeasUp = CoinMax(info.numIntInfeasUp, 0);
     709    info.numObjInfeasUp = 0;
     710    info.finishedUp = false;
     711    info.numItersUp = 0;
     712    info.numIntInfeasDown  -= static_cast<int> (object_->sumDownDecrease() /
     713                              (1.0e-12 + static_cast<double> (object_->numberTimesDown())));
     714    info.numIntInfeasDown = CoinMax(info.numIntInfeasDown, 0);
     715    info.numObjInfeasDown = 0;
     716    info.finishedDown = false;
     717    info.numItersDown = 0;
     718    info.fix = 0;
     719    if (object_->numberTimesUp() < object_->numberBeforeTrust() +
     720            2*object_->numberTimesUpInfeasible() ||
     721            object_->numberTimesDown() < object_->numberBeforeTrust() +
     722            2*object_->numberTimesDownInfeasible()) {
     723        return 0;
     724    } else {
     725        return 1;
     726    }
     727}
  • branches/sandbox/Cbc/src/CbcBranchDynamic.hpp

    r1347 r1351  
    77#include "CoinPackedMatrix.hpp"
    88#include "CbcSimpleIntegerDynamicPseudoCost.hpp"
    9 #include "CbcDynamicPseudoCostBranchingObject.hpp"
    109#include "CbcBranchActual.hpp"
    1110
     
    9897    CbcBranchingObject * bestObject_;
    9998};
     99/** Simple branching object for an integer variable with pseudo costs
     100
     101  This object can specify a two-way branch on an integer variable. For each
     102  arm of the branch, the upper and lower bounds on the variable can be
     103  independently specified.
     104
     105  Variable_ holds the index of the integer variable in the integerVariable_
     106  array of the model.
     107*/
     108
     109class CbcDynamicPseudoCostBranchingObject : public CbcIntegerBranchingObject {
     110
     111public:
     112
     113    /// Default constructor
     114    CbcDynamicPseudoCostBranchingObject ();
     115
     116    /** Create a standard floor/ceiling branch object
     117
     118      Specifies a simple two-way branch. Let \p value = x*. One arm of the
     119      branch will be is lb <= x <= floor(x*), the other ceil(x*) <= x <= ub.
     120      Specify way = -1 to set the object state to perform the down arm first,
     121      way = 1 for the up arm.
     122    */
     123    CbcDynamicPseudoCostBranchingObject (CbcModel *model, int variable,
     124                                         int way , double value,
     125                                         CbcSimpleIntegerDynamicPseudoCost * object) ;
     126
     127    /** Create a degenerate branch object
     128
     129      Specifies a `one-way branch'. Calling branch() for this object will
     130      always result in lowerValue <= x <= upperValue. Used to fix a variable
     131      when lowerValue = upperValue.
     132    */
     133
     134    CbcDynamicPseudoCostBranchingObject (CbcModel *model, int variable, int way,
     135                                         double lowerValue, double upperValue) ;
     136
     137    /// Copy constructor
     138    CbcDynamicPseudoCostBranchingObject ( const CbcDynamicPseudoCostBranchingObject &);
     139
     140    /// Assignment operator
     141    CbcDynamicPseudoCostBranchingObject & operator= (const CbcDynamicPseudoCostBranchingObject& rhs);
     142
     143    /// Clone
     144    virtual CbcBranchingObject * clone() const;
     145
     146    /// Destructor
     147    virtual ~CbcDynamicPseudoCostBranchingObject ();
     148
     149    /// Does part of constructor
     150    void fillPart (int variable,
     151                   int way , double value,
     152                   CbcSimpleIntegerDynamicPseudoCost * object) ;
     153
     154    using CbcBranchingObject::branch ;
     155    /** \brief Sets the bounds for the variable according to the current arm
     156           of the branch and advances the object state to the next arm.
     157           This version also changes guessed objective value
     158    */
     159    virtual double branch();
     160
     161    /** Some branchingObjects may claim to be able to skip
     162        strong branching.  If so they have to fill in CbcStrongInfo.
     163        The object mention in incoming CbcStrongInfo must match.
     164        Returns nonzero if skip is wanted */
     165    virtual int fillStrongInfo( CbcStrongInfo & info);
     166
     167    /// Change in guessed
     168    inline double changeInGuessed() const {
     169        return changeInGuessed_;
     170    }
     171    /// Set change in guessed
     172    inline void setChangeInGuessed(double value) {
     173        changeInGuessed_ = value;
     174    }
     175    /// Return object
     176    inline CbcSimpleIntegerDynamicPseudoCost * object() const {
     177        return object_;
     178    }
     179    /// Set object
     180    inline void setObject(CbcSimpleIntegerDynamicPseudoCost * object) {
     181        object_ = object;
     182    }
     183
     184    /** Return the type (an integer identifier) of \c this */
     185    virtual int type() const {
     186        return 400;
     187    }
     188
     189    // LL: compareOriginalObject and compareBranchingObject are inherited from
     190    // CbcIntegerBranchingObject thus need not be declared/defined here. After
     191    // all, this kind of branching object is simply using pseudocosts to make
     192    // decisions, but once the decisions are made they are the same kind as in
     193    // the underlying class.
     194
     195protected:
     196    /// Change in guessed objective value for next branch
     197    double changeInGuessed_;
     198    /// Pointer back to object
     199    CbcSimpleIntegerDynamicPseudoCost * object_;
     200
     201};
     202
    100203#endif
  • branches/sandbox/Cbc/src/CbcBranchLotsize.cpp

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

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

    r1305 r1351  
    77#include "OsiRowCut.hpp"
    88#include "CoinPackedMatrix.hpp"
    9 #include "CbcCutBranchingObject.hpp"
    109
    1110/** Define a branch class that branches so that one way variables are fixed
  • branches/sandbox/Cbc/src/Makefile.am

    r1350 r1351  
    4242        CbcCompare.hpp \
    4343        CbcCountRowCut.cpp CbcCountRowCut.hpp \
    44         CbcCutBranchingObject.cpp CbcCutBranchingObject.hpp \
    4544        CbcCutGenerator.cpp CbcCutGenerator.hpp \
    4645        CbcCutModifier.cpp CbcCutModifier.hpp \
    4746        CbcCutSubsetModifier.cpp CbcCutSubsetModifier.hpp \
    4847        CbcDummyBranchingObject.cpp CbcDummyBranchingObject.hpp \
    49         CbcDynamicPseudoCostBranchingObject.cpp CbcDynamicPseudoCostBranchingObject.hpp \
    5048        CbcEventHandler.cpp CbcEventHandler.hpp \
    5149        CbcFathom.cpp CbcFathom.hpp \
     
    7169        CbcHeuristicRandRound.cpp CbcHeuristicRandRound.hpp \
    7270        CbcHeuristicRINS.cpp CbcHeuristicRINS.hpp \
    73         CbcLotsize.cpp CbcLotsize.hpp \
    7471        CbcMessage.cpp CbcMessage.hpp \
    7572        CbcModel.cpp CbcModel.hpp \
     
    345342        CbcBranchBase.hpp \
    346343        CbcBranchDynamic.hpp \
    347         CbcBranchLotsize.hpp \
    348344        CbcBranchCut.hpp \
    349345        CbcBranchDecision.hpp \
    350346        CbcBranchDefaultDecision.hpp \
    351347        CbcBranchingObject.hpp \
     348        CbcBranchLotsize.hpp \
    352349        CbcBranchToFixLots.hpp \
    353350        CbcCompareActual.hpp \
     
    360357        CbcClique.hpp \
    361358        CbcCompare.hpp \
    362         CbcCutBranchingObject.hpp \
    363359        CbcCutGenerator.hpp \
    364360        CbcCutModifier.hpp \
    365361        CbcCutSubsetModifier.hpp \
    366362        CbcDummyBranchingObject.hpp \
    367         CbcDynamicPseudoCostBranchingObject.hpp \
    368363        CbcFathom.hpp \
    369364        CbcEventHandler.hpp \
     
    388383        CbcHeuristicRandRound.hpp \
    389384        CbcHeuristicRINS.hpp \
    390         CbcLotsize.hpp \
    391385        CbcMessage.hpp \
    392386        CbcModel.hpp \
  • branches/sandbox/Cbc/src/Makefile.in

    r1350 r1351  
    167167        CbcBranchToFixLots.lo CbcCompareDefault.lo CbcCompareDepth.lo \
    168168        CbcCompareEstimate.lo CbcCompareObjective.lo CbcConsequence.lo \
    169         CbcClique.lo CbcCountRowCut.lo CbcCutBranchingObject.lo \
    170         CbcCutGenerator.lo CbcCutModifier.lo CbcCutSubsetModifier.lo \
    171         CbcDummyBranchingObject.lo \
    172         CbcDynamicPseudoCostBranchingObject.lo CbcEventHandler.lo \
    173         CbcFathom.lo CbcFathomDynamicProgramming.lo CbcFixVariable.lo \
     169        CbcClique.lo CbcCountRowCut.lo CbcCutGenerator.lo \
     170        CbcCutModifier.lo CbcCutSubsetModifier.lo \
     171        CbcDummyBranchingObject.lo CbcEventHandler.lo CbcFathom.lo \
     172        CbcFathomDynamicProgramming.lo CbcFixVariable.lo \
    174173        CbcFullNodeInfo.lo CbcFollowOn.lo CbcGeneral.lo \
    175174        CbcGeneralDepth.lo CbcHeuristic.lo CbcHeuristicDive.lo \
     
    179178        CbcHeuristicFPump.lo CbcHeuristicGreedy.lo \
    180179        CbcHeuristicLocal.lo CbcHeuristicPivotAndFix.lo \
    181         CbcHeuristicRandRound.lo CbcHeuristicRINS.lo CbcLotsize.lo \
    182         CbcMessage.lo CbcModel.lo CbcNode.lo CbcNodeInfo.lo CbcNWay.lo \
    183         CbcObject.lo CbcObjectUpdateData.lo CbcPartialNodeInfo.lo \
     180        CbcHeuristicRandRound.lo CbcHeuristicRINS.lo CbcMessage.lo \
     181        CbcModel.lo CbcNode.lo CbcNodeInfo.lo CbcNWay.lo CbcObject.lo \
     182        CbcObjectUpdateData.lo CbcPartialNodeInfo.lo \
    184183        CbcSimpleInteger.lo CbcSimpleIntegerDynamicPseudoCost.lo \
    185184        CbcSimpleIntegerPseudoCost.lo CbcSOS.lo CbcStatistics.lo \
     
    539538        CbcCompare.hpp \
    540539        CbcCountRowCut.cpp CbcCountRowCut.hpp \
    541         CbcCutBranchingObject.cpp CbcCutBranchingObject.hpp \
    542540        CbcCutGenerator.cpp CbcCutGenerator.hpp \
    543541        CbcCutModifier.cpp CbcCutModifier.hpp \
    544542        CbcCutSubsetModifier.cpp CbcCutSubsetModifier.hpp \
    545543        CbcDummyBranchingObject.cpp CbcDummyBranchingObject.hpp \
    546         CbcDynamicPseudoCostBranchingObject.cpp CbcDynamicPseudoCostBranchingObject.hpp \
    547544        CbcEventHandler.cpp CbcEventHandler.hpp \
    548545        CbcFathom.cpp CbcFathom.hpp \
     
    568565        CbcHeuristicRandRound.cpp CbcHeuristicRandRound.hpp \
    569566        CbcHeuristicRINS.cpp CbcHeuristicRINS.hpp \
    570         CbcLotsize.cpp CbcLotsize.hpp \
    571567        CbcMessage.cpp CbcMessage.hpp \
    572568        CbcModel.cpp CbcModel.hpp \
     
    705701        CbcBranchBase.hpp \
    706702        CbcBranchDynamic.hpp \
    707         CbcBranchLotsize.hpp \
    708703        CbcBranchCut.hpp \
    709704        CbcBranchDecision.hpp \
    710705        CbcBranchDefaultDecision.hpp \
    711706        CbcBranchingObject.hpp \
     707        CbcBranchLotsize.hpp \
    712708        CbcBranchToFixLots.hpp \
    713709        CbcCompareActual.hpp \
     
    720716        CbcClique.hpp \
    721717        CbcCompare.hpp \
    722         CbcCutBranchingObject.hpp \
    723718        CbcCutGenerator.hpp \
    724719        CbcCutModifier.hpp \
    725720        CbcCutSubsetModifier.hpp \
    726721        CbcDummyBranchingObject.hpp \
    727         CbcDynamicPseudoCostBranchingObject.hpp \
    728722        CbcFathom.hpp \
    729723        CbcEventHandler.hpp \
     
    748742        CbcHeuristicRandRound.hpp \
    749743        CbcHeuristicRINS.hpp \
    750         CbcLotsize.hpp \
    751744        CbcMessage.hpp \
    752745        CbcModel.hpp \
     
    898891@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcConsequence.Plo@am__quote@
    899892@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcCountRowCut.Plo@am__quote@
    900 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcCutBranchingObject.Plo@am__quote@
    901893@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcCutGenerator.Plo@am__quote@
    902894@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcCutModifier.Plo@am__quote@
    903895@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcCutSubsetModifier.Plo@am__quote@
    904896@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcDummyBranchingObject.Plo@am__quote@
    905 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcDynamicPseudoCostBranchingObject.Plo@am__quote@
    906897@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcEventHandler.Plo@am__quote@
    907898@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcFathom.Plo@am__quote@
     
    939930@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcHeuristicRandRound.Plo@am__quote@
    940931@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcLinked.Plo@am__quote@
    941 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcLotsize.Plo@am__quote@
    942932@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcMessage.Plo@am__quote@
    943933@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/CbcModel.Plo@am__quote@
Note: See TracChangeset for help on using the changeset viewer.