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 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 * ,
00115 const OsiBranchingInformation * ,
00116 int ) const {throw CoinError("Need code","createBranch","OsiBranchingObject");}
00117
00120 virtual bool canDoHeuristics() const
00121 {return true;}
00124 virtual bool canMoveToNearest() const
00125 {return false;}
00129 virtual int columnNumber() const;
00131 inline int priority() const
00132 { return priority_;}
00134 inline void setPriority(int priority)
00135 { priority_ = priority;}
00138 virtual bool boundBranch() const
00139 {return true;}
00141 virtual bool canHandleShadowPrices() const
00142 { return false;}
00144 inline int numberWays() const
00145 { return numberWays_;}
00147 inline void setNumberWays(int numberWays)
00148 { numberWays_ = static_cast<short int>(numberWays) ; }
00153 inline void setWhichWay(int way)
00154 { whichWay_ = static_cast<short int>(way) ; }
00159 inline int whichWay() const
00160 { return whichWay_;}
00162 virtual int preferredWay() const
00163 { return -1;}
00165 inline double infeasibility() const
00166 { return infeasibility_;}
00168 virtual double upEstimate() const;
00170 virtual double downEstimate() const;
00175 virtual void resetBounds(const OsiSolverInterface * ) {}
00178 virtual void resetSequenceEtc(int , const int * ) {}
00180 virtual void updateBefore(const OsiObject * ) {}
00182 virtual void updateAfter(const OsiObject * , const OsiObject * ) {}
00183
00184 protected:
00186
00188 mutable double infeasibility_;
00190 mutable short whichWay_;
00192 short numberWays_;
00194 int priority_;
00195
00196 };
00199
00200
00201 class OsiObject2 : public OsiObject {
00202
00203 public:
00204
00206 OsiObject2 ();
00207
00209 OsiObject2 ( const OsiObject2 &);
00210
00212 OsiObject2 & operator=( const OsiObject2& rhs);
00213
00215 virtual ~OsiObject2 ();
00216
00218 inline void setPreferredWay(int value)
00219 {preferredWay_=value;}
00220
00222 virtual int preferredWay() const
00223 { return preferredWay_;}
00224 protected:
00226 int preferredWay_;
00228 mutable double otherInfeasibility_;
00229
00230 };
00231
00249 class OsiBranchingObject {
00250
00251 public:
00252
00254 OsiBranchingObject ();
00255
00257 OsiBranchingObject (OsiSolverInterface * solver, double value);
00258
00260 OsiBranchingObject ( const OsiBranchingObject &);
00261
00263 OsiBranchingObject & operator=( const OsiBranchingObject& rhs);
00264
00266 virtual OsiBranchingObject * clone() const=0;
00267
00269 virtual ~OsiBranchingObject ();
00270
00272 inline int numberBranches() const
00273 {return numberBranches_;}
00274
00276 inline int numberBranchesLeft() const
00277 {return numberBranches_-branchIndex_;}
00278
00280 inline void incrementNumberBranchesLeft()
00281 { numberBranches_ ++;}
00282
00286 inline void setNumberBranchesLeft(int )
00287 { numberBranches_=1;}
00288
00290 inline void decrementNumberBranchesLeft()
00291 {branchIndex_++;}
00292
00298 virtual double branch(OsiSolverInterface * solver)=0;
00304 virtual double branch() {return branch(NULL);}
00307 virtual bool boundBranch() const
00308 {return true;}
00312 inline int branchIndex() const
00313 {return branchIndex_;}
00314
00317 inline void setBranchingIndex(int branchIndex)
00318 { branchIndex_ = static_cast<short int>(branchIndex) ; }
00319
00321 inline double value() const
00322 {return value_;}
00323
00325 inline const OsiObject * originalObject() const
00326 {return originalObject_;}
00328 inline void setOriginalObject(const OsiObject * object)
00329 {originalObject_=object;}
00333 virtual void checkIsCutoff(double ) {}
00335 int columnNumber() const;
00338 virtual void print(const OsiSolverInterface * =NULL) const {}
00339
00340 protected:
00341
00343 double value_;
00344
00346 const OsiObject * originalObject_;
00347
00350 int numberBranches_;
00351
00355 short branchIndex_;
00356
00357 };
00358
00359
00360
00361
00362 class OsiBranchingInformation {
00363
00364 public:
00365
00367 OsiBranchingInformation ();
00368
00373 OsiBranchingInformation (const OsiSolverInterface * solver, bool normalSolver,bool copySolution=false);
00374
00376 OsiBranchingInformation ( const OsiBranchingInformation &);
00377
00379 OsiBranchingInformation & operator=( const OsiBranchingInformation& rhs);
00380
00382 virtual OsiBranchingInformation * clone() const;
00383
00385 virtual ~OsiBranchingInformation ();
00386
00387
00388 public:
00390
00397 int stateOfSearch_;
00399 double objectiveValue_;
00401 double cutoff_;
00403 double direction_;
00405 double integerTolerance_;
00407 double primalTolerance_;
00409 double timeRemaining_;
00411 double defaultDual_;
00413 mutable const OsiSolverInterface * solver_;
00415 int numberColumns_;
00417 mutable const double * lower_;
00419 mutable const double * solution_;
00421 mutable const double * upper_;
00423 const double * hotstartSolution_;
00425 const double * pi_;
00427 const double * rowActivity_;
00429 const double * objective_;
00431 const double * rowLower_;
00433 const double * rowUpper_;
00435 const double * elementByColumn_;
00437 const CoinBigIndex * columnStart_;
00439 const int * columnLength_;
00441 const int * row_;
00447 double * usefulRegion_;
00449 int * indexRegion_;
00451 int numberSolutions_;
00453 int numberBranchingSolutions_;
00455 int depth_;
00457 bool owningSolution_;
00458 };
00459
00461
00462 class OsiTwoWayBranchingObject : public OsiBranchingObject {
00463
00464 public:
00465
00467 OsiTwoWayBranchingObject ();
00468
00475 OsiTwoWayBranchingObject (OsiSolverInterface *solver,const OsiObject * originalObject,
00476 int way , double value) ;
00477
00479 OsiTwoWayBranchingObject ( const OsiTwoWayBranchingObject &);
00480
00482 OsiTwoWayBranchingObject & operator= (const OsiTwoWayBranchingObject& rhs);
00483
00485 virtual ~OsiTwoWayBranchingObject ();
00486
00487 using OsiBranchingObject::branch ;
00493 virtual double branch(OsiSolverInterface * solver)=0;
00494
00495 inline int firstBranch() const { return firstBranch_; }
00497 inline int way() const
00498 { return !branchIndex_ ? firstBranch_ : -firstBranch_;}
00499 protected:
00501 int firstBranch_;
00502 };
00504
00505
00506 class OsiSimpleInteger : public OsiObject2 {
00507
00508 public:
00509
00511 OsiSimpleInteger ();
00512
00514 OsiSimpleInteger (const OsiSolverInterface * solver, int iColumn);
00515
00517 OsiSimpleInteger (int iColumn, double lower, double upper);
00518
00520 OsiSimpleInteger ( const OsiSimpleInteger &);
00521
00523 virtual OsiObject * clone() const;
00524
00526 OsiSimpleInteger & operator=( const OsiSimpleInteger& rhs);
00527
00529 virtual ~OsiSimpleInteger ();
00530
00531 using OsiObject::infeasibility ;
00533 virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const;
00534
00535 using OsiObject::feasibleRegion ;
00541 virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const;
00542
00547 virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const;
00548
00549
00551 inline void setColumnNumber(int value)
00552 {columnNumber_=value;}
00553
00558 virtual int columnNumber() const;
00559
00561 inline double originalLowerBound() const
00562 { return originalLower_;}
00563 inline void setOriginalLowerBound(double value)
00564 { originalLower_=value;}
00565 inline double originalUpperBound() const
00566 { return originalUpper_;}
00567 inline void setOriginalUpperBound(double value)
00568 { originalUpper_=value;}
00573 virtual void resetBounds(const OsiSolverInterface * solver) ;
00576 virtual void resetSequenceEtc(int numberColumns, const int * originalColumns);
00577
00579 virtual double upEstimate() const;
00581 virtual double downEstimate() const;
00583 virtual bool canHandleShadowPrices() const
00584 { return false;}
00585 protected:
00588 double originalLower_;
00590 double originalUpper_;
00592 int columnNumber_;
00593
00594 };
00602 class OsiIntegerBranchingObject : public OsiTwoWayBranchingObject {
00603
00604 public:
00605
00607 OsiIntegerBranchingObject ();
00608
00616 OsiIntegerBranchingObject (OsiSolverInterface *solver,const OsiSimpleInteger * originalObject,
00617 int way , double value) ;
00625 OsiIntegerBranchingObject (OsiSolverInterface *solver,const OsiSimpleInteger * originalObject,
00626 int way , double value, double downUpperBound, double upLowerBound) ;
00627
00629 OsiIntegerBranchingObject ( const OsiIntegerBranchingObject &);
00630
00632 OsiIntegerBranchingObject & operator= (const OsiIntegerBranchingObject& rhs);
00633
00635 virtual OsiBranchingObject * clone() const;
00636
00638 virtual ~OsiIntegerBranchingObject ();
00639
00640 using OsiBranchingObject::branch ;
00646 virtual double branch(OsiSolverInterface * solver);
00647
00648 using OsiBranchingObject::print ;
00651 virtual void print(const OsiSolverInterface * solver=NULL);
00652
00653 protected:
00654
00656 double down_[2];
00658 double up_[2];
00659 };
00660
00661
00669 class OsiSOS : public OsiObject2 {
00670
00671 public:
00672
00673
00674 OsiSOS ();
00675
00680 OsiSOS (const OsiSolverInterface * solver, int numberMembers,
00681 const int * which, const double * weights, int type=1);
00682
00683
00684 OsiSOS ( const OsiSOS &);
00685
00687 virtual OsiObject * clone() const;
00688
00689
00690 OsiSOS & operator=( const OsiSOS& rhs);
00691
00692
00693 virtual ~OsiSOS ();
00694
00695 using OsiObject::infeasibility ;
00697 virtual double infeasibility(const OsiBranchingInformation * info,int & whichWay) const;
00698
00699 using OsiObject::feasibleRegion ;
00705 virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const;
00706
00711 virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const;
00713 virtual double upEstimate() const;
00715 virtual double downEstimate() const;
00716
00718 virtual void resetSequenceEtc(int numberColumns, const int * originalColumns);
00719
00721 inline int numberMembers() const
00722 {return numberMembers_;}
00723
00725 inline const int * members() const
00726 {return members_;}
00727
00729 inline int sosType() const
00730 {return sosType_;}
00731
00733 inline int setType() const
00734 {return sosType_;}
00735
00737 inline const double * weights() const
00738 { return weights_;}
00739
00742 virtual bool canDoHeuristics() const
00743 {return (sosType_==1&&integerValued_);}
00745 inline void setIntegerValued(bool yesNo)
00746 { integerValued_=yesNo;}
00748 virtual bool canHandleShadowPrices() const
00749 { return true;}
00751 inline void setNumberMembers(int value)
00752 {numberMembers_=value;}
00753
00755 inline int * mutableMembers() const
00756 {return members_;}
00757
00759 inline void setSosType(int value)
00760 {sosType_=value;}
00761
00763 inline double * mutableWeights() const
00764 { return weights_;}
00765 protected:
00767
00769 int * members_;
00771 double * weights_;
00772
00774 int numberMembers_;
00776 int sosType_;
00778 bool integerValued_;
00779 };
00780
00784 class OsiSOSBranchingObject : public OsiTwoWayBranchingObject {
00785
00786 public:
00787
00788
00789 OsiSOSBranchingObject ();
00790
00791
00792 OsiSOSBranchingObject (OsiSolverInterface * solver, const OsiSOS * originalObject,
00793 int way,
00794 double separator);
00795
00796
00797 OsiSOSBranchingObject ( const OsiSOSBranchingObject &);
00798
00799
00800 OsiSOSBranchingObject & operator=( const OsiSOSBranchingObject& rhs);
00801
00803 virtual OsiBranchingObject * clone() const;
00804
00805
00806 virtual ~OsiSOSBranchingObject ();
00807
00808 using OsiBranchingObject::branch ;
00810 virtual double branch(OsiSolverInterface * solver);
00811
00812 using OsiBranchingObject::print ;
00815 virtual void print(const OsiSolverInterface * solver=NULL);
00816 private:
00818 };
00822 class OsiLotsize : public OsiObject2 {
00823
00824 public:
00825
00826
00827 OsiLotsize ();
00828
00829
00830
00831
00832 OsiLotsize (const OsiSolverInterface * solver, int iColumn,
00833 int numberPoints, const double * points, bool range=false);
00834
00835
00836 OsiLotsize ( const OsiLotsize &);
00837
00839 virtual OsiObject * clone() const;
00840
00841
00842 OsiLotsize & operator=( const OsiLotsize& rhs);
00843
00844
00845 ~OsiLotsize ();
00846
00847 using OsiObject::infeasibility ;
00849 virtual double infeasibility(const OsiBranchingInformation * info, int & whichWay) const;
00850
00851 using OsiObject::feasibleRegion ;
00859 virtual double feasibleRegion(OsiSolverInterface * solver, const OsiBranchingInformation * info) const;
00860
00865 virtual OsiBranchingObject * createBranch(OsiSolverInterface * solver, const OsiBranchingInformation * info, int way) const;
00866
00867
00869 inline void setColumnNumber(int value)
00870 {columnNumber_=value;}
00871
00876 virtual int columnNumber() const;
00882 virtual void resetBounds(const OsiSolverInterface * solver);
00883
00887 bool findRange(double value, double integerTolerance) const;
00888
00891 virtual void floorCeiling(double & floorLotsize, double & ceilingLotsize, double value,
00892 double tolerance) const;
00893
00895 inline double originalLowerBound() const
00896 { return bound_[0];}
00897 inline double originalUpperBound() const
00898 { return bound_[rangeType_*numberRanges_-1];}
00900 inline int rangeType() const
00901 { return rangeType_;}
00903 inline int numberRanges() const
00904 { return numberRanges_;}
00906 inline double * bound() const
00907 { return bound_;}
00910 virtual void resetSequenceEtc(int numberColumns, const int * originalColumns);
00911
00913 virtual double upEstimate() const;
00915 virtual double downEstimate() const;
00917 virtual bool canHandleShadowPrices() const
00918 { return true;}
00921 virtual bool canDoHeuristics() const
00922 {return false;}
00923
00924 private:
00926
00928 int columnNumber_;
00930 int rangeType_;
00932 int numberRanges_;
00933
00934 double largestGap_;
00936 double * bound_;
00938 mutable int range_;
00939 };
00940
00941
00952 class OsiLotsizeBranchingObject : public OsiTwoWayBranchingObject {
00953
00954 public:
00955
00957 OsiLotsizeBranchingObject ();
00958
00966 OsiLotsizeBranchingObject (OsiSolverInterface *solver,const OsiLotsize * originalObject,
00967 int way , double value) ;
00968
00970 OsiLotsizeBranchingObject ( const OsiLotsizeBranchingObject &);
00971
00973 OsiLotsizeBranchingObject & operator= (const OsiLotsizeBranchingObject& rhs);
00974
00976 virtual OsiBranchingObject * clone() const;
00977
00979 virtual ~OsiLotsizeBranchingObject ();
00980
00981 using OsiBranchingObject::branch ;
00987 virtual double branch(OsiSolverInterface * solver);
00988
00989 using OsiBranchingObject::print ;
00992 virtual void print(const OsiSolverInterface * solver=NULL);
00993
00994 protected:
00996 double down_[2];
00998 double up_[2];
00999 };
01000 #endif