/home/coin/SVN-release/Smi-0.92.1/Cbc/src/CbcBranchBase.hpp

Go to the documentation of this file.
00001 // Copyright (C) 2002, International Business Machines
00002 // Corporation and others.  All Rights Reserved.
00003 #ifndef CbcBranchBase_H
00004 #define CbcBranchBase_H
00005 
00006 #include <string>
00007 #include <vector>
00008 #include "OsiBranchingObject.hpp"
00009 class OsiSolverInterface;
00010 class OsiSolverBranch;
00011 
00012 class CbcModel;
00013 class CbcNode;
00014 class CbcNodeInfo;
00015 class CbcBranchingObject;
00016 class OsiChooseVariable;
00017 class CbcObjectUpdateData;
00018 
00019 //#############################################################################
00020 
00021 enum CbcRangeCompare {
00022   CbcRangeSame,
00023   CbcRangeDisjoint,
00024   CbcRangeSubset,
00025   CbcRangeSuperset,
00026   CbcRangeOverlap
00027 };
00028 
00029 //#############################################################################
00030 
00056 // This can be used if object wants to skip strong branching
00057   typedef struct {
00058     CbcBranchingObject * possibleBranch; // what a branch would do
00059     double upMovement; // cost going up (and initial away from feasible)
00060     double downMovement; // cost going down
00061     int numIntInfeasUp ; // without odd ones
00062     int numObjInfeasUp ; // just odd ones
00063     bool finishedUp; // true if solver finished
00064     int numItersUp ; // number of iterations in solver
00065     int numIntInfeasDown ; // without odd ones
00066     int numObjInfeasDown ; // just odd ones
00067     bool finishedDown; // true if solver finished
00068     int numItersDown; // number of iterations in solver
00069     int objectNumber; // Which object it is
00070     int fix; // 0 if no fix, 1 if we can fix up, -1 if we can fix down
00071   } CbcStrongInfo;
00072 
00073 class CbcObject : public OsiObject {
00074 
00075 public:
00076 
00077   // Default Constructor 
00078   CbcObject ();
00079 
00080   // Useful constructor
00081   CbcObject (CbcModel * model);
00082   
00083   // Copy constructor 
00084   CbcObject ( const CbcObject &);
00085    
00086   // Assignment operator 
00087   CbcObject & operator=( const CbcObject& rhs);
00088 
00090   virtual CbcObject * clone() const=0;
00091 
00093   virtual ~CbcObject ();
00094 
00109   virtual double infeasibility(int &preferredWay) const = 0;
00111   virtual double infeasibility(const OsiBranchingInformation * info,
00112                                int &preferredWay) const;
00113 
00117   virtual void feasibleRegion() = 0;
00119   virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const;
00120 
00126   virtual CbcBranchingObject * createBranch(int way) = 0;
00127   
00144   virtual double infeasibility(const OsiSolverInterface * solver,int &preferredWay) const;
00145   
00150   virtual double feasibleRegion(OsiSolverInterface * solver) const ;
00151   
00157   virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, int way) const;
00163   virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver,const OsiBranchingInformation * info, int way) const;
00168   virtual OsiSolverBranch * solverBranch() const;
00169   
00178   virtual CbcBranchingObject * preferredNewFeasible() const 
00179   { return NULL;}
00180   
00189   virtual CbcBranchingObject * notPreferredNewFeasible() const 
00190   { return NULL;}
00191 
00196   virtual void resetBounds(const OsiSolverInterface * solver) {}
00197   
00200   virtual void floorCeiling(double & floorValue, double & ceilingValue, double value,
00201                             double tolerance) const;
00202 
00206   virtual CbcObjectUpdateData createUpdateInformation(const OsiSolverInterface * solver, 
00207                                                         const CbcNode * node,
00208                                                         const CbcBranchingObject * branchingObject);
00209 
00211   virtual void updateInformation(const CbcObjectUpdateData & data) {}
00212 
00214   inline int id() const
00215   { return id_;}
00216   
00218   inline void setModel(CbcModel * model)
00219   { model_ = model;}
00220   
00222   inline CbcModel * model() const
00223   {return  model_;}
00224 
00226   inline int preferredWay() const
00227   { return preferredWay_;}
00229   inline void setPreferredWay(int value)
00230   { preferredWay_=value;}
00232   virtual void redoSequenceEtc(CbcModel * model, int numberColumns, const int * originalColumns) {}
00233   
00234 protected:
00236 
00238   CbcModel * model_;
00240   int id_;
00242   int preferredWay_;
00243 
00244 };
00245 
00264 class CbcBranchingObject : public OsiBranchingObject {
00265 
00266 public:
00267 
00269   CbcBranchingObject ();
00270 
00272   CbcBranchingObject (CbcModel * model, int variable, int way , double value);
00273   
00275   CbcBranchingObject ( const CbcBranchingObject &);
00276    
00278   CbcBranchingObject & operator=( const CbcBranchingObject& rhs);
00279 
00281   virtual CbcBranchingObject * clone() const=0;
00282 
00284   virtual ~CbcBranchingObject ();
00285 
00290   virtual int fillStrongInfo( CbcStrongInfo & info) {return 0;}
00292   inline void resetNumberBranchesLeft()
00293   { branchIndex_=0;}
00295   inline void setNumberBranches(int value)
00296   { branchIndex_=0;numberBranches_=value;}
00297 
00304   virtual double branch()=0;
00311   virtual double branch(OsiSolverInterface * solver)
00312   { return branch();}
00315   virtual void fix(OsiSolverInterface * solver,
00316                    double * lower, double * upper,
00317                    int branchState) const {}
00318 
00322   virtual void previousBranch() {
00323     assert(branchIndex_ > 0);
00324     branchIndex_--;
00325     way_ = -way_;
00326   }
00327 
00328   using OsiBranchingObject::print ;
00331   virtual void print() const {}
00332 
00344   inline int variable() const
00345   {return variable_;}
00346 
00354   inline int way() const
00355   {return way_;}
00356 
00361   inline void way(int way)
00362   {way_=way;}
00363 
00365   inline void setModel(CbcModel * model)
00366   { model_ = model;}
00368   inline CbcModel * model() const
00369   {return  model_;}
00370 
00372   inline CbcObject * object() const
00373   {return  originalCbcObject_;}
00375   inline void setOriginalObject(CbcObject * object)
00376   {originalCbcObject_=object;}
00377 
00378   // Methods used in heuristics
00379   
00381   virtual int type() const = 0;
00382 
00390   virtual int compareOriginalObject(const CbcBranchingObject* brObj) const
00391   {
00392     const CbcBranchingObject* br=dynamic_cast<const CbcBranchingObject*>(brObj);
00393     return variable() - br->variable();
00394   }
00395 
00404   virtual CbcRangeCompare compareBranchingObject
00405   (const CbcBranchingObject* brObj, const bool replaceIfOverlap = false) = 0;
00406 
00407 protected:
00408 
00410   CbcModel * model_;
00412   CbcObject * originalCbcObject_;
00413 
00415   int variable_;
00416   // was - Way to branch - -1 down (first), 1 up, -2 down (second), 2 up (second)
00424   int way_;
00425 
00426 };
00427 
00428 
00442 class CbcBranchDecision {
00443 public:
00445   CbcBranchDecision ();
00446 
00447   // Copy constructor 
00448   CbcBranchDecision ( const CbcBranchDecision &);
00449    
00451   virtual ~CbcBranchDecision();
00452 
00454   virtual CbcBranchDecision * clone() const = 0;
00455 
00457   virtual void initialize(CbcModel * model) = 0;
00458 
00468   virtual int
00469   betterBranch (CbcBranchingObject * thisOne,
00470                 CbcBranchingObject * bestSoFar,
00471                 double changeUp, int numberInfeasibilitiesUp,
00472                 double changeDown, int numberInfeasibilitiesDown) = 0 ;
00473 
00480   virtual int
00481   bestBranch (CbcBranchingObject ** objects, int numberObjects, int numberUnsatisfied,
00482               double * changeUp, int * numberInfeasibilitiesUp,
00483               double * changeDown, int * numberInfeasibilitiesDown,
00484               double objectiveValue) ;
00485 
00488   virtual int whichMethod() {return 2;}
00489 
00492   virtual void saveBranchingObject(OsiBranchingObject * object) {}
00495   virtual void updateInformation(OsiSolverInterface * solver, 
00496                                  const CbcNode * node) {}
00498   virtual void setBestCriterion(double value) {}
00499   virtual double getBestCriterion() const {return 0.0;}
00501   virtual void generateCpp( FILE * fp) {}
00503   inline CbcModel * cbcModel() const
00504   { return model_;}
00505   /* If chooseMethod_ id non-null then the rest is fairly pointless
00506      as choosemethod_ will be doing all work
00507   */
00508   OsiChooseVariable * chooseMethod() const
00509   { return chooseMethod_;}
00511   void setChooseMethod(const OsiChooseVariable & method);
00512 
00513 protected:
00514   
00515   // Clone of branching object
00516   CbcBranchingObject * object_;
00518   CbcModel * model_;
00519   /* If chooseMethod_ id non-null then the rest is fairly pointless
00520      as choosemethod_ will be doing all work
00521   */
00522   OsiChooseVariable * chooseMethod_;
00523 private:
00525   CbcBranchDecision & operator=(const CbcBranchDecision& rhs);
00526   
00527 };
00537 class CbcConsequence {
00538 
00539 public:
00540 
00541   // Default Constructor 
00542   CbcConsequence ();
00543 
00544   // Copy constructor 
00545   CbcConsequence ( const CbcConsequence & rhs);
00546    
00547   // Assignment operator 
00548   CbcConsequence & operator=( const CbcConsequence & rhs);
00549 
00551   virtual CbcConsequence * clone() const=0;
00552 
00554   virtual ~CbcConsequence ();
00555 
00558   virtual void applyToSolver(OsiSolverInterface * solver, int state) const=0;
00559   
00560 protected:
00561 };
00562 /*  This stores data so an object can be updated
00563  */
00564 class CbcObjectUpdateData {
00565 
00566 public:
00567 
00569   CbcObjectUpdateData ();
00570 
00572   CbcObjectUpdateData (CbcObject * object,
00573                        int way,
00574                        double change,
00575                        int status,
00576                        int intDecrease_,
00577                        double branchingValue);
00578   
00580   CbcObjectUpdateData ( const CbcObjectUpdateData &);
00581    
00583   CbcObjectUpdateData & operator=( const CbcObjectUpdateData& rhs);
00584 
00586   virtual ~CbcObjectUpdateData ();
00587 
00588   
00589 public:
00591 
00593   CbcObject * object_;
00595   int way_;
00597   int objectNumber_;
00599   double change_;
00601   int status_;
00603   int intDecrease_;
00605   double branchingValue_;
00607   double originalObjective_;
00609   double cutoff_;
00610 
00611 };
00612 
00613 //##############################################################################
00614 
00621 static inline CbcRangeCompare
00622 CbcCompareRanges(double* thisBd, const double* otherBd,
00623                  const bool replaceIfOverlap)
00624 {
00625   const double lbDiff = thisBd[0] - otherBd[0];
00626   if (lbDiff < 0) { // lb of this < lb of other
00627     if (thisBd[1] >= otherBd[1]) { // ub of this >= ub of other
00628       return CbcRangeSuperset;
00629     } else if (thisBd[1] < otherBd[0]) {
00630       return CbcRangeDisjoint;
00631     } else {
00632       // overlap
00633       if (replaceIfOverlap) {
00634         thisBd[0] = otherBd[0];
00635       }
00636       return CbcRangeOverlap;
00637     }
00638   } else if (lbDiff > 0) { // lb of this > lb of other
00639     if (thisBd[1] <= otherBd[1]) { // ub of this <= ub of other
00640       return CbcRangeSubset;
00641     } else if (thisBd[0] > otherBd[1]) {
00642       return CbcRangeDisjoint;
00643     } else {
00644       // overlap
00645       if (replaceIfOverlap) {
00646         thisBd[1] = otherBd[1];
00647       }
00648       return CbcRangeOverlap;
00649     }
00650   } else { // lb of this == lb of other
00651     if (thisBd[1] == otherBd[1]) {
00652       return CbcRangeSame;
00653     }
00654     return thisBd[1] < otherBd[1] ? CbcRangeSubset : CbcRangeSuperset;
00655   }
00656 
00657   return CbcRangeSame; // fake return
00658 
00659 }
00660 
00661 //#############################################################################
00662 
00663 #endif

Generated on Mon Sep 22 03:08:56 2008 by  doxygen 1.4.7