00001
00002
00003 #ifndef OsiBranchingObject_H
00004 #define OsiBranchingObject_H
00005
00006 #include <cassert>
00007 #include <string>
00008 #include <vector>
00009
00010 class OsiSolverInterface;
00011 class OsiSolverBranch;
00012
00013 class OsiBranchingObject;
00014 class OsiBranchingInformation;
00015
00016
00017
00018
00019
00020
00051 class OsiObject {
00052
00053 public:
00054
00056 OsiObject ();
00057
00059 OsiObject ( const OsiObject &);
00060
00062 OsiObject & operator=( const OsiObject& rhs);
00063
00065 virtual OsiObject * clone() const=0;
00066
00068 virtual ~OsiObject ();
00069
00091 virtual double infeasibility(const OsiSolverInterface * solver,int &whichWay) const ;
00092
00093 virtual double infeasibility(const OsiBranchingInformation * info, int &whichWay) const =0;
00094
00095 virtual double checkInfeasibility(const OsiBranchingInformation * info) const;
00096
00101 virtual double feasibleRegion(OsiSolverInterface * solver) const ;
00107 virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const =0;
00108
00114 virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const = 0;
00115
00118 virtual bool canDoHeuristics() const
00119 {return true;}
00122 virtual bool canMoveToNearest() const
00123 {return false;}
00127 virtual int columnNumber() const;
00129 inline int priority() const
00130 { return priority_;}
00132 inline void setPriority(int priority)
00133 { priority_ = priority;}
00136 virtual bool boundBranch() const
00137 {return true;}
00139 virtual bool canHandleShadowPrices() const
00140 { return false;}
00142 inline int numberWays() const
00143 { return numberWays_;}
00145 inline void setNumberWays(int numberWays)
00146 { numberWays_ = static_cast<short int>(numberWays) ; }
00151 inline void setWhichWay(int way)
00152 { whichWay_ = static_cast<short int>(way) ; }
00157 inline int whichWay() const
00158 { return whichWay_;}
00160 virtual int preferredWay() const
00161 { return -1;}
00163 inline double infeasibility() const
00164 { return infeasibility_;}
00166 virtual double upEstimate() const;
00168 virtual double downEstimate() const;
00173 virtual void resetBounds(const OsiSolverInterface * solver) {}
00176 virtual void resetSequenceEtc(int numberColumns, const int * originalColumns) {}
00178 virtual void updateBefore(const OsiObject * rhs) {}
00180 virtual void updateAfter(const OsiObject * rhs, const OsiObject * baseObject) {}
00181
00182 protected:
00184
00186 mutable double infeasibility_;
00188 mutable short whichWay_;
00190 short numberWays_;
00192 int priority_;
00193
00194 };
00197
00198
00199 class OsiObject2 : public OsiObject {
00200
00201 public:
00202
00204 OsiObject2 ();
00205
00207 OsiObject2 ( const OsiObject2 &);
00208
00210 OsiObject2 & operator=( const OsiObject2& rhs);
00211
00213 virtual ~OsiObject2 ();
00214
00216 inline void setPreferredWay(int value)
00217 {preferredWay_=value;}
00218
00220 virtual int preferredWay() const
00221 { return preferredWay_;}
00222 protected:
00224 int preferredWay_;
00226 mutable double otherInfeasibility_;
00227
00228 };
00229
00247 class OsiBranchingObject {
00248
00249 public:
00250
00252 OsiBranchingObject ();
00253
00255 OsiBranchingObject (OsiSolverInterface * solver, double value);
00256
00258 OsiBranchingObject ( const OsiBranchingObject &);
00259
00261 OsiBranchingObject & operator=( const OsiBranchingObject& rhs);
00262
00264 virtual OsiBranchingObject * clone() const=0;
00265
00267 virtual ~OsiBranchingObject ();
00268
00270 inline int numberBranches() const
00271 {return numberBranches_;}
00272
00274 inline int numberBranchesLeft() const
00275 {return numberBranches_-branchIndex_;}
00276
00280 inline void setNumberBranchesLeft(int value)
00281 {assert (value==1&&!branchIndex_); numberBranches_=1;}
00282
00284 inline void decrementNumberBranchesLeft()
00285 {branchIndex_++;}
00286
00292 virtual double branch(OsiSolverInterface * solver)=0;
00298 virtual double branch() {return branch(NULL);}
00301 virtual bool boundBranch() const
00302 {return true;}
00306 inline int branchIndex() const
00307 {return branchIndex_;}
00308
00311 inline void setBranchingIndex(int branchIndex)
00312 { branchIndex_ = static_cast<short int>(branchIndex) ; }
00313
00315 inline double value() const
00316 {return value_;}
00317
00319 inline const OsiObject * originalObject() const
00320 {return originalObject_;}
00322 inline void setOriginalObject(const OsiObject * object)
00323 {originalObject_=object;}
00327 virtual void checkIsCutoff(double cutoff) {}
00329 int columnNumber() const;
00332 virtual void print(const OsiSolverInterface * solver=NULL) const {}
00333
00334 protected:
00335
00337 double value_;
00338
00340 const OsiObject * originalObject_;
00341
00344 int numberBranches_;
00345
00349 short branchIndex_;
00350
00351 };
00352
00353
00354
00355
00356 class OsiBranchingInformation {
00357
00358 public:
00359
00361 OsiBranchingInformation ();
00362
00367 OsiBranchingInformation (const OsiSolverInterface * solver, bool normalSolver,bool copySolution=false);
00368
00370 OsiBranchingInformation ( const OsiBranchingInformation &);
00371
00373 OsiBranchingInformation & operator=( const OsiBranchingInformation& rhs);
00374
00376 virtual OsiBranchingInformation * clone() const;
00377
00379 virtual ~OsiBranchingInformation ();
00380
00381
00382 public:
00384
00391 int stateOfSearch_;
00393 double objectiveValue_;
00395 double cutoff_;
00397 double direction_;
00399 double integerTolerance_;
00401 double primalTolerance_;
00403 double timeRemaining_;
00405 double defaultDual_;
00407 mutable const OsiSolverInterface * solver_;
00409 int numberColumns_;
00411 mutable const double * lower_;
00413 mutable const double * solution_;
00415 mutable const double * upper_;
00417 const double * hotstartSolution_;
00419 const double * pi_;
00421 const double * rowActivity_;
00423 const double * objective_;
00425 const double * rowLower_;
00427 const double * rowUpper_;
00429 const double * elementByColumn_;
00431 const CoinBigIndex * columnStart_;
00433 const int * columnLength_;
00435 const int * row_;
00441 double * usefulRegion_;
00443 int * indexRegion_;
00445 int numberSolutions_;
00447 int numberBranchingSolutions_;
00449 int depth_;
00451 bool owningSolution_;
00452 };
00453
00455
00456 class OsiTwoWayBranchingObject : public OsiBranchingObject {
00457
00458 public:
00459
00461 OsiTwoWayBranchingObject ();
00462
00469 OsiTwoWayBranchingObject (OsiSolverInterface *solver,const OsiObject * originalObject,
00470 int way , double value) ;
00471
00473 OsiTwoWayBranchingObject ( const OsiTwoWayBranchingObject &);
00474
00476 OsiTwoWayBranchingObject & operator= (const OsiTwoWayBranchingObject& rhs);
00477
00479 virtual ~OsiTwoWayBranchingObject ();
00480
00481 using OsiBranchingObject::branch ;
00487 virtual double branch(OsiSolverInterface * solver)=0;
00488
00489 inline int firstBranch() const { return firstBranch_; }
00491 inline int way() const
00492 { return !branchIndex_ ? firstBranch_ : -firstBranch_;}
00493 protected:
00495 int firstBranch_;
00496 };
00498
00499
00500 class OsiSimpleInteger : public OsiObject2 {
00501
00502 public:
00503
00505 OsiSimpleInteger ();
00506
00508 OsiSimpleInteger (const OsiSolverInterface * solver, int iColumn);
00509
00511 OsiSimpleInteger (int iColumn, double lower, double upper);
00512
00514 OsiSimpleInteger ( const OsiSimpleInteger &);
00515
00517 virtual OsiObject * clone() const;
00518
00520 OsiSimpleInteger & operator=( const OsiSimpleInteger& rhs);
00521
00523 virtual ~OsiSimpleInteger ();
00524
00525 using OsiObject::infeasibility ;
00527 virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const;
00528
00529 using OsiObject::feasibleRegion ;
00535 virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const;
00536
00541 virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const;
00542
00543
00545 inline void setColumnNumber(int value)
00546 {columnNumber_=value;}
00547
00552 virtual int columnNumber() const;
00553
00555 inline double originalLowerBound() const
00556 { return originalLower_;}
00557 inline void setOriginalLowerBound(double value)
00558 { originalLower_=value;}
00559 inline double originalUpperBound() const
00560 { return originalUpper_;}
00561 inline void setOriginalUpperBound(double value)
00562 { originalUpper_=value;}
00567 virtual void resetBounds(const OsiSolverInterface * solver) ;
00570 virtual void resetSequenceEtc(int numberColumns, const int * originalColumns);
00571
00573 virtual double upEstimate() const;
00575 virtual double downEstimate() const;
00577 virtual bool canHandleShadowPrices() const
00578 { return false;}
00579 protected:
00582 double originalLower_;
00584 double originalUpper_;
00586 int columnNumber_;
00587
00588 };
00596 class OsiIntegerBranchingObject : public OsiTwoWayBranchingObject {
00597
00598 public:
00599
00601 OsiIntegerBranchingObject ();
00602
00610 OsiIntegerBranchingObject (OsiSolverInterface *solver,const OsiSimpleInteger * originalObject,
00611 int way , double value) ;
00619 OsiIntegerBranchingObject (OsiSolverInterface *solver,const OsiSimpleInteger * originalObject,
00620 int way , double value, double downUpperBound, double upLowerBound) ;
00621
00623 OsiIntegerBranchingObject ( const OsiIntegerBranchingObject &);
00624
00626 OsiIntegerBranchingObject & operator= (const OsiIntegerBranchingObject& rhs);
00627
00629 virtual OsiBranchingObject * clone() const;
00630
00632 virtual ~OsiIntegerBranchingObject ();
00633
00634 using OsiBranchingObject::branch ;
00640 virtual double branch(OsiSolverInterface * solver);
00641
00642 using OsiBranchingObject::print ;
00645 virtual void print(const OsiSolverInterface * solver=NULL);
00646
00647 protected:
00648
00650 double down_[2];
00652 double up_[2];
00653 };
00654
00655
00663 class OsiSOS : public OsiObject2 {
00664
00665 public:
00666
00667
00668 OsiSOS ();
00669
00674 OsiSOS (const OsiSolverInterface * solver, int numberMembers,
00675 const int * which, const double * weights, int type=1);
00676
00677
00678 OsiSOS ( const OsiSOS &);
00679
00681 virtual OsiObject * clone() const;
00682
00683
00684 OsiSOS & operator=( const OsiSOS& rhs);
00685
00686
00687 virtual ~OsiSOS ();
00688
00689 using OsiObject::infeasibility ;
00691 virtual double infeasibility(const OsiBranchingInformation * info,int & whichWay) const;
00692
00693 using OsiObject::feasibleRegion ;
00699 virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const;
00700
00705 virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const;
00707 virtual double upEstimate() const;
00709 virtual double downEstimate() const;
00710
00712 virtual void resetSequenceEtc(int numberColumns, const int * originalColumns);
00713
00715 inline int numberMembers() const
00716 {return numberMembers_;}
00717
00719 inline const int * members() const
00720 {return members_;}
00721
00723 inline int sosType() const
00724 {return sosType_;}
00725
00727 inline int setType() const
00728 {return sosType_;}
00729
00731 inline const double * weights() const
00732 { return weights_;}
00733
00736 virtual bool canDoHeuristics() const
00737 {return (sosType_==1&&integerValued_);}
00739 inline void setIntegerValued(bool yesNo)
00740 { integerValued_=yesNo;}
00742 virtual bool canHandleShadowPrices() const
00743 { return true;}
00745 inline void setNumberMembers(int value)
00746 {numberMembers_=value;}
00747
00749 inline int * mutableMembers() const
00750 {return members_;}
00751
00753 inline void setSosType(int value)
00754 {sosType_=value;}
00755
00757 inline double * mutableWeights() const
00758 { return weights_;}
00759 protected:
00761
00763 int * members_;
00765 double * weights_;
00766
00768 int numberMembers_;
00770 int sosType_;
00772 bool integerValued_;
00773 };
00774
00778 class OsiSOSBranchingObject : public OsiTwoWayBranchingObject {
00779
00780 public:
00781
00782
00783 OsiSOSBranchingObject ();
00784
00785
00786 OsiSOSBranchingObject (OsiSolverInterface * solver, const OsiSOS * originalObject,
00787 int way,
00788 double separator);
00789
00790
00791 OsiSOSBranchingObject ( const OsiSOSBranchingObject &);
00792
00793
00794 OsiSOSBranchingObject & operator=( const OsiSOSBranchingObject& rhs);
00795
00797 virtual OsiBranchingObject * clone() const;
00798
00799
00800 virtual ~OsiSOSBranchingObject ();
00801
00802 using OsiBranchingObject::branch ;
00804 virtual double branch(OsiSolverInterface * solver);
00805
00806 using OsiBranchingObject::print ;
00809 virtual void print(const OsiSolverInterface * solver=NULL);
00810 private:
00812 };
00816 class OsiLotsize : public OsiObject2 {
00817
00818 public:
00819
00820
00821 OsiLotsize ();
00822
00823
00824
00825
00826 OsiLotsize (const OsiSolverInterface * solver, int iColumn,
00827 int numberPoints, const double * points, bool range=false);
00828
00829
00830 OsiLotsize ( const OsiLotsize &);
00831
00833 virtual OsiObject * clone() const;
00834
00835
00836 OsiLotsize & operator=( const OsiLotsize& rhs);
00837
00838
00839 ~OsiLotsize ();
00840
00841 using OsiObject::infeasibility ;
00843 virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const;
00844
00845 using OsiObject::feasibleRegion ;
00853 virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const;
00854
00859 virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const;
00860
00861
00863 inline void setColumnNumber(int value)
00864 {columnNumber_=value;}
00865
00870 virtual int columnNumber() const;
00876 virtual void resetBounds(const OsiSolverInterface * solver);
00877
00881 bool findRange(double value, double integerTolerance) const;
00882
00885 virtual void floorCeiling(double & floorLotsize, double & ceilingLotsize, double value,
00886 double tolerance) const;
00887
00889 inline double originalLowerBound() const
00890 { return bound_[0];}
00891 inline double originalUpperBound() const
00892 { return bound_[rangeType_*numberRanges_-1];}
00894 inline int rangeType() const
00895 { return rangeType_;}
00897 inline int numberRanges() const
00898 { return numberRanges_;}
00900 inline double * bound() const
00901 { return bound_;}
00904 virtual void resetSequenceEtc(int numberColumns, const int * originalColumns);
00905
00907 virtual double upEstimate() const;
00909 virtual double downEstimate() const;
00911 virtual bool canHandleShadowPrices() const
00912 { return true;}
00915 virtual bool canDoHeuristics() const
00916 {return false;}
00917
00918 private:
00920
00922 int columnNumber_;
00924 int rangeType_;
00926 int numberRanges_;
00927
00928 double largestGap_;
00930 double * bound_;
00932 mutable int range_;
00933 };
00934
00935
00946 class OsiLotsizeBranchingObject : public OsiTwoWayBranchingObject {
00947
00948 public:
00949
00951 OsiLotsizeBranchingObject ();
00952
00960 OsiLotsizeBranchingObject (OsiSolverInterface *solver,const OsiLotsize * originalObject,
00961 int way , double value) ;
00962
00964 OsiLotsizeBranchingObject ( const OsiLotsizeBranchingObject &);
00965
00967 OsiLotsizeBranchingObject & operator= (const OsiLotsizeBranchingObject& rhs);
00968
00970 virtual OsiBranchingObject * clone() const;
00971
00973 virtual ~OsiLotsizeBranchingObject ();
00974
00975 using OsiBranchingObject::branch ;
00981 virtual double branch(OsiSolverInterface * solver);
00982
00983 using OsiBranchingObject::print ;
00986 virtual void print(const OsiSolverInterface * solver=NULL);
00987
00988 protected:
00990 double down_[2];
00992 double up_[2];
00993 };
00994 #endif