00001
00002
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
00057 typedef struct {
00058 CbcBranchingObject * possibleBranch;
00059 double upMovement;
00060 double downMovement;
00061 int numIntInfeasUp ;
00062 int numObjInfeasUp ;
00063 bool finishedUp;
00064 int numItersUp ;
00065 int numIntInfeasDown ;
00066 int numObjInfeasDown ;
00067 bool finishedDown;
00068 int numItersDown;
00069 int objectNumber;
00070 int fix;
00071 } CbcStrongInfo;
00072
00073 class CbcObject : public OsiObject {
00074
00075 public:
00076
00077
00078 CbcObject ();
00079
00080
00081 CbcObject (CbcModel * model);
00082
00083
00084 CbcObject ( const CbcObject &);
00085
00086
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
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
00424 int way_;
00425
00426 };
00427
00428
00442 class CbcBranchDecision {
00443 public:
00445 CbcBranchDecision ();
00446
00447
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
00506
00507
00508 OsiChooseVariable * chooseMethod() const
00509 { return chooseMethod_;}
00511 void setChooseMethod(const OsiChooseVariable & method);
00512
00513 protected:
00514
00515
00516 CbcBranchingObject * object_;
00518 CbcModel * model_;
00519
00520
00521
00522 OsiChooseVariable * chooseMethod_;
00523 private:
00525 CbcBranchDecision & operator=(const CbcBranchDecision& rhs);
00526
00527 };
00537 class CbcConsequence {
00538
00539 public:
00540
00541
00542 CbcConsequence ();
00543
00544
00545 CbcConsequence ( const CbcConsequence & rhs);
00546
00547
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
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) {
00627 if (thisBd[1] >= otherBd[1]) {
00628 return CbcRangeSuperset;
00629 } else if (thisBd[1] < otherBd[0]) {
00630 return CbcRangeDisjoint;
00631 } else {
00632
00633 if (replaceIfOverlap) {
00634 thisBd[0] = otherBd[0];
00635 }
00636 return CbcRangeOverlap;
00637 }
00638 } else if (lbDiff > 0) {
00639 if (thisBd[1] <= otherBd[1]) {
00640 return CbcRangeSubset;
00641 } else if (thisBd[0] > otherBd[1]) {
00642 return CbcRangeDisjoint;
00643 } else {
00644
00645 if (replaceIfOverlap) {
00646 thisBd[1] = otherBd[1];
00647 }
00648 return CbcRangeOverlap;
00649 }
00650 } else {
00651 if (thisBd[1] == otherBd[1]) {
00652 return CbcRangeSame;
00653 }
00654 return thisBd[1] < otherBd[1] ? CbcRangeSubset : CbcRangeSuperset;
00655 }
00656
00657 return CbcRangeSame;
00658
00659 }
00660
00661
00662
00663 #endif