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_ = numberWays;}
00151 inline void setWhichWay(int way)
00152 { whichWay_ = 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_=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;}
00325 int columnNumber() const;
00328 virtual void print(const OsiSolverInterface * solver=NULL) const {}
00329
00330 protected:
00331
00333 double value_;
00334
00336 const OsiObject * originalObject_;
00337
00340 int numberBranches_;
00341
00345 short branchIndex_;
00346
00347 };
00348
00349
00350
00351
00352 class OsiBranchingInformation {
00353
00354 public:
00355
00357 OsiBranchingInformation ();
00358
00363 OsiBranchingInformation (const OsiSolverInterface * solver, bool normalSolver,bool copySolution=false);
00364
00366 OsiBranchingInformation ( const OsiBranchingInformation &);
00367
00369 OsiBranchingInformation & operator=( const OsiBranchingInformation& rhs);
00370
00372 virtual OsiBranchingInformation * clone() const;
00373
00375 virtual ~OsiBranchingInformation ();
00376
00377
00378 public:
00380
00387 int stateOfSearch_;
00389 double objectiveValue_;
00391 double cutoff_;
00393 double direction_;
00395 double integerTolerance_;
00397 double primalTolerance_;
00399 double timeRemaining_;
00401 double defaultDual_;
00403 mutable const OsiSolverInterface * solver_;
00405 int numberColumns_;
00407 mutable const double * lower_;
00409 mutable const double * solution_;
00411 mutable const double * upper_;
00413 const double * hotstartSolution_;
00415 const double * pi_;
00417 const double * rowActivity_;
00419 const double * objective_;
00421 const double * rowLower_;
00423 const double * rowUpper_;
00425 const double * elementByColumn_;
00427 const CoinBigIndex * columnStart_;
00429 const int * columnLength_;
00431 const int * row_;
00437 double * usefulRegion_;
00439 int * indexRegion_;
00441 int numberSolutions_;
00443 int numberBranchingSolutions_;
00445 int depth_;
00447 bool owningSolution_;
00448 };
00449
00451
00452 class OsiTwoWayBranchingObject : public OsiBranchingObject {
00453
00454 public:
00455
00457 OsiTwoWayBranchingObject ();
00458
00465 OsiTwoWayBranchingObject (OsiSolverInterface *solver,const OsiObject * originalObject,
00466 int way , double value) ;
00467
00469 OsiTwoWayBranchingObject ( const OsiTwoWayBranchingObject &);
00470
00472 OsiTwoWayBranchingObject & operator= (const OsiTwoWayBranchingObject& rhs);
00473
00475 virtual ~OsiTwoWayBranchingObject ();
00476
00477 using OsiBranchingObject::branch ;
00483 virtual double branch(OsiSolverInterface * solver)=0;
00484
00485 inline int firstBranch() const { return firstBranch_; }
00487 inline int way() const
00488 { return !branchIndex_ ? firstBranch_ : -firstBranch_;}
00489 protected:
00491 int firstBranch_;
00492 };
00494
00495
00496 class OsiSimpleInteger : public OsiObject2 {
00497
00498 public:
00499
00501 OsiSimpleInteger ();
00502
00504 OsiSimpleInteger (const OsiSolverInterface * solver, int iColumn);
00505
00507 OsiSimpleInteger (int iColumn, double lower, double upper);
00508
00510 OsiSimpleInteger ( const OsiSimpleInteger &);
00511
00513 virtual OsiObject * clone() const;
00514
00516 OsiSimpleInteger & operator=( const OsiSimpleInteger& rhs);
00517
00519 virtual ~OsiSimpleInteger ();
00520
00521 using OsiObject::infeasibility ;
00523 virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const;
00524
00525 using OsiObject::feasibleRegion ;
00531 virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const;
00532
00537 virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const;
00538
00539
00541 inline void setColumnNumber(int value)
00542 {columnNumber_=value;}
00543
00548 virtual int columnNumber() const;
00549
00551 inline double originalLowerBound() const
00552 { return originalLower_;}
00553 inline void setOriginalLowerBound(double value)
00554 { originalLower_=value;}
00555 inline double originalUpperBound() const
00556 { return originalUpper_;}
00557 inline void setOriginalUpperBound(double value)
00558 { originalUpper_=value;}
00563 virtual void resetBounds(const OsiSolverInterface * solver) ;
00566 virtual void resetSequenceEtc(int numberColumns, const int * originalColumns);
00567
00569 virtual double upEstimate() const;
00571 virtual double downEstimate() const;
00573 virtual bool canHandleShadowPrices() const
00574 { return false;}
00575 protected:
00578 double originalLower_;
00580 double originalUpper_;
00582 int columnNumber_;
00583
00584 };
00592 class OsiIntegerBranchingObject : public OsiTwoWayBranchingObject {
00593
00594 public:
00595
00597 OsiIntegerBranchingObject ();
00598
00606 OsiIntegerBranchingObject (OsiSolverInterface *solver,const OsiSimpleInteger * originalObject,
00607 int way , double value) ;
00615 OsiIntegerBranchingObject (OsiSolverInterface *solver,const OsiSimpleInteger * originalObject,
00616 int way , double value, double downUpperBound, double upLowerBound) ;
00617
00619 OsiIntegerBranchingObject ( const OsiIntegerBranchingObject &);
00620
00622 OsiIntegerBranchingObject & operator= (const OsiIntegerBranchingObject& rhs);
00623
00625 virtual OsiBranchingObject * clone() const;
00626
00628 virtual ~OsiIntegerBranchingObject ();
00629
00630 using OsiBranchingObject::branch ;
00636 virtual double branch(OsiSolverInterface * solver);
00637
00638 using OsiBranchingObject::print ;
00641 virtual void print(const OsiSolverInterface * solver=NULL);
00642
00643 protected:
00644
00646 double down_[2];
00648 double up_[2];
00649 };
00650
00651
00659 class OsiSOS : public OsiObject2 {
00660
00661 public:
00662
00663
00664 OsiSOS ();
00665
00670 OsiSOS (const OsiSolverInterface * solver, int numberMembers,
00671 const int * which, const double * weights, int type=1);
00672
00673
00674 OsiSOS ( const OsiSOS &);
00675
00677 virtual OsiObject * clone() const;
00678
00679
00680 OsiSOS & operator=( const OsiSOS& rhs);
00681
00682
00683 virtual ~OsiSOS ();
00684
00685 using OsiObject::infeasibility ;
00687 virtual double infeasibility(const OsiBranchingInformation * info,int & whichWay) const;
00688
00689 using OsiObject::feasibleRegion ;
00695 virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const;
00696
00701 virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const;
00703 virtual double upEstimate() const;
00705 virtual double downEstimate() const;
00706
00708 virtual void resetSequenceEtc(int numberColumns, const int * originalColumns);
00709
00711 inline int numberMembers() const
00712 {return numberMembers_;}
00713
00715 inline const int * members() const
00716 {return members_;}
00717
00719 inline int sosType() const
00720 {return sosType_;}
00721
00723 inline int setType() const
00724 {return sosType_;}
00725
00727 inline const double * weights() const
00728 { return weights_;}
00729
00732 virtual bool canDoHeuristics() const
00733 {return (sosType_==1&&integerValued_);}
00735 inline void setIntegerValued(bool yesNo)
00736 { integerValued_=yesNo;}
00738 virtual bool canHandleShadowPrices() const
00739 { return true;}
00741 inline void setNumberMembers(int value)
00742 {numberMembers_=value;}
00743
00745 inline int * mutableMembers() const
00746 {return members_;}
00747
00749 inline void setSosType(int value)
00750 {sosType_=value;}
00751
00753 inline double * mutableWeights() const
00754 { return weights_;}
00755 protected:
00757
00759 int * members_;
00761 double * weights_;
00762
00764 int numberMembers_;
00766 int sosType_;
00768 bool integerValued_;
00769 };
00770
00774 class OsiSOSBranchingObject : public OsiTwoWayBranchingObject {
00775
00776 public:
00777
00778
00779 OsiSOSBranchingObject ();
00780
00781
00782 OsiSOSBranchingObject (OsiSolverInterface * solver, const OsiSOS * originalObject,
00783 int way,
00784 double separator);
00785
00786
00787 OsiSOSBranchingObject ( const OsiSOSBranchingObject &);
00788
00789
00790 OsiSOSBranchingObject & operator=( const OsiSOSBranchingObject& rhs);
00791
00793 virtual OsiBranchingObject * clone() const;
00794
00795
00796 virtual ~OsiSOSBranchingObject ();
00797
00798 using OsiBranchingObject::branch ;
00800 virtual double branch(OsiSolverInterface * solver);
00801
00802 using OsiBranchingObject::print ;
00805 virtual void print(const OsiSolverInterface * solver=NULL);
00806 private:
00808 };
00812 class OsiLotsize : public OsiObject2 {
00813
00814 public:
00815
00816
00817 OsiLotsize ();
00818
00819
00820
00821
00822 OsiLotsize (const OsiSolverInterface * solver, int iColumn,
00823 int numberPoints, const double * points, bool range=false);
00824
00825
00826 OsiLotsize ( const OsiLotsize &);
00827
00829 virtual OsiObject * clone() const;
00830
00831
00832 OsiLotsize & operator=( const OsiLotsize& rhs);
00833
00834
00835 ~OsiLotsize ();
00836
00837 using OsiObject::infeasibility ;
00839 virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const;
00840
00841 using OsiObject::feasibleRegion ;
00849 virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const;
00850
00855 virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const;
00856
00857
00859 inline void setColumnNumber(int value)
00860 {columnNumber_=value;}
00861
00866 virtual int columnNumber() const;
00872 virtual void resetBounds(const OsiSolverInterface * solver);
00873
00877 bool findRange(double value, double integerTolerance) const;
00878
00881 virtual void floorCeiling(double & floorLotsize, double & ceilingLotsize, double value,
00882 double tolerance) const;
00883
00885 inline double originalLowerBound() const
00886 { return bound_[0];}
00887 inline double originalUpperBound() const
00888 { return bound_[rangeType_*numberRanges_-1];}
00890 inline int rangeType() const
00891 { return rangeType_;}
00893 inline int numberRanges() const
00894 { return numberRanges_;}
00896 inline double * bound() const
00897 { return bound_;}
00900 virtual void resetSequenceEtc(int numberColumns, const int * originalColumns);
00901
00903 virtual double upEstimate() const;
00905 virtual double downEstimate() const;
00907 virtual bool canHandleShadowPrices() const
00908 { return true;}
00911 virtual bool canDoHeuristics() const
00912 {return false;}
00913
00914 private:
00916
00918 int columnNumber_;
00920 int rangeType_;
00922 int numberRanges_;
00923
00924 double largestGap_;
00926 double * bound_;
00928 mutable int range_;
00929 };
00930
00931
00942 class OsiLotsizeBranchingObject : public OsiTwoWayBranchingObject {
00943
00944 public:
00945
00947 OsiLotsizeBranchingObject ();
00948
00956 OsiLotsizeBranchingObject (OsiSolverInterface *solver,const OsiLotsize * originalObject,
00957 int way , double value) ;
00958
00960 OsiLotsizeBranchingObject ( const OsiLotsizeBranchingObject &);
00961
00963 OsiLotsizeBranchingObject & operator= (const OsiLotsizeBranchingObject& rhs);
00964
00966 virtual OsiBranchingObject * clone() const;
00967
00969 virtual ~OsiLotsizeBranchingObject ();
00970
00971 using OsiBranchingObject::branch ;
00977 virtual double branch(OsiSolverInterface * solver);
00978
00979 using OsiBranchingObject::print ;
00982 virtual void print(const OsiSolverInterface * solver=NULL);
00983
00984 protected:
00986 double down_[2];
00988 double up_[2];
00989 };
00990 #endif