00001
00002
00003 #ifndef CbcNode_H
00004 #define CbcNode_H
00005
00006 #include <string>
00007 #include <vector>
00008
00009 #include "CoinWarmStartBasis.hpp"
00010 #include "CoinSearchTree.hpp"
00011 #include "CbcBranchBase.hpp"
00012
00013 class OsiSolverInterface;
00014 class OsiSolverBranch;
00015
00016 class OsiCuts;
00017 class OsiRowCut;
00018 class OsiRowCutDebugger;
00019 class CoinWarmStartBasis;
00020 class CbcCountRowCut;
00021 class CbcModel;
00022 class CbcNode;
00023
00024
00061 class CbcNodeInfo {
00062
00063 public:
00064
00071 CbcNodeInfo ();
00072
00074 CbcNodeInfo ( const CbcNodeInfo &);
00075
00076 #if 0
00077
00082 CbcNodeInfo (CbcNodeInfo * parent);
00083 #endif
00084
00089 CbcNodeInfo (CbcNodeInfo * parent, CbcNode * owner);
00090
00096 virtual ~CbcNodeInfo();
00098
00099
00105 virtual void applyToModel (CbcModel *model, CoinWarmStartBasis *&basis,
00106 CbcCountRowCut **addCuts,
00107 int ¤tNumberCuts) const = 0 ;
00109 virtual int applyBounds(int iColumn, double & lower, double & upper,int force) = 0;
00110
00115 virtual CbcNodeInfo * buildRowBasis(CoinWarmStartBasis & basis) const = 0;
00117 virtual CbcNodeInfo * clone() const = 0;
00119 virtual void allBranchesGone() {}
00120 #if 1
00122 inline void increment(int amount=1)
00123 {numberPointingToThis_+=amount;}
00124
00126 inline int decrement(int amount=1)
00127 {numberPointingToThis_-=amount;return numberPointingToThis_;}
00128 #else
00130 void increment(int amount=1);
00132 int decrement(int amount=1);
00133 #endif
00134
00139 inline void initializeInfo(int number)
00140 {numberPointingToThis_=number;numberBranchesLeft_=number;}
00141
00143 inline int numberBranchesLeft() const
00144 {return numberBranchesLeft_;}
00145
00147 inline int numberPointingToThis() const
00148 {return numberPointingToThis_;}
00149
00151 inline void setNumberPointingToThis(int number)
00152 {numberPointingToThis_=number;}
00153
00155 inline int branchedOn()
00156 {numberPointingToThis_--;numberBranchesLeft_--;return numberBranchesLeft_;}
00157
00159 inline void throwAway()
00160 {numberPointingToThis_-=numberBranchesLeft_;numberBranchesLeft_=0;}
00161
00163 CbcNodeInfo * parent() const
00164 {return parent_;}
00166 inline void nullParent()
00167 { parent_=NULL;}
00168
00169 void addCuts(OsiCuts & cuts,int numberToBranch, int * whichGenerator);
00170 void addCuts(int numberCuts, CbcCountRowCut ** cuts,int numberToBranch);
00174 void deleteCuts(int numberToDelete,CbcCountRowCut ** cuts);
00175 void deleteCuts(int numberToDelete,int * which);
00176
00178 void deleteCut(int whichOne);
00179
00181 void decrementCuts(int change=1);
00182
00184 void incrementCuts(int change=1);
00185
00187 void decrementParentCuts(CbcModel * model, int change=1);
00188
00190 void incrementParentCuts(CbcModel * model, int change=1);
00191
00193 inline CbcCountRowCut ** cuts() const
00194 {return cuts_;}
00195
00197 inline int numberCuts() const
00198 {return numberCuts_;}
00199 inline void setNumberCuts(int value)
00200 {numberCuts_=value;}
00201
00203 inline void nullOwner()
00204 { owner_=NULL;}
00205 const inline CbcNode * owner() const
00206 { return owner_;}
00207 inline CbcNode * mutableOwner() const
00208 { return owner_;}
00210 inline int nodeNumber() const
00211 { return nodeNumber_;}
00212 inline void setNodeNumber(int node)
00213 { nodeNumber_=node;}
00219 void deactivate(int mode=3);
00221 inline bool allActivated() const
00222 { return (active_==7);}
00224 inline bool marked() const
00225 { return ((active_&8)!=0);}
00227 inline void mark()
00228 { active_ |= 8;}
00230 inline void unmark()
00231 { active_ &= ~8;}
00232
00234 inline const OsiBranchingObject * parentBranch() const
00235 { return parentBranch_;}
00236 protected:
00237
00245 int numberPointingToThis_;
00246
00248 CbcNodeInfo * parent_;
00249
00251 OsiBranchingObject * parentBranch_;
00252
00254 CbcNode * owner_;
00255
00257 int numberCuts_;
00258
00260 int nodeNumber_;
00261
00263 CbcCountRowCut ** cuts_;
00264
00267 int numberRows_;
00268
00275 int numberBranchesLeft_;
00281 int active_;
00282
00283 private:
00284
00286 CbcNodeInfo & operator=(const CbcNodeInfo& rhs);
00287
00289 void setParentBasedData();
00290 };
00291
00303 class CbcFullNodeInfo : public CbcNodeInfo {
00304
00305 public:
00306
00316 virtual void applyToModel (CbcModel *model, CoinWarmStartBasis *&basis,
00317 CbcCountRowCut **addCuts,
00318 int ¤tNumberCuts) const ;
00319
00321 virtual int applyBounds(int iColumn, double & lower, double & upper,int force) ;
00322
00327 virtual CbcNodeInfo * buildRowBasis(CoinWarmStartBasis & basis) const ;
00328
00329 CbcFullNodeInfo ();
00330
00333 CbcFullNodeInfo (CbcModel * model,
00334 int numberRowsAtContinuous);
00335
00336
00337 CbcFullNodeInfo ( const CbcFullNodeInfo &);
00338
00339
00340 ~CbcFullNodeInfo ();
00341
00343 virtual CbcNodeInfo * clone() const;
00345 inline const double * lower() const
00346 { return lower_;}
00348 inline const double * upper() const
00349 { return upper_;}
00350 protected:
00351
00357 CoinWarmStartBasis *basis_;
00358 int numberIntegers_;
00359
00360 double * lower_;
00361 double * upper_;
00362 private:
00364 CbcFullNodeInfo & operator=(const CbcFullNodeInfo& rhs);
00365 };
00366
00367
00368
00377 class CbcPartialNodeInfo : public CbcNodeInfo {
00378
00379 public:
00380
00386 virtual void applyToModel (CbcModel *model, CoinWarmStartBasis *&basis,
00387 CbcCountRowCut **addCuts,
00388 int ¤tNumberCuts) const ;
00389
00391 virtual int applyBounds(int iColumn, double & lower, double & upper,int force) ;
00396 virtual CbcNodeInfo * buildRowBasis(CoinWarmStartBasis & basis ) const ;
00397
00398 CbcPartialNodeInfo ();
00399
00400
00401 CbcPartialNodeInfo (CbcNodeInfo * parent, CbcNode * owner,
00402 int numberChangedBounds,const int * variables,
00403 const double * boundChanges,
00404 const CoinWarmStartDiff *basisDiff) ;
00405
00406
00407 CbcPartialNodeInfo ( const CbcPartialNodeInfo &);
00408
00409
00410 ~CbcPartialNodeInfo ();
00411
00413 virtual CbcNodeInfo * clone() const;
00415 inline const CoinWarmStartDiff *basisDiff() const
00416 { return basisDiff_ ;}
00418 inline const int * variables() const
00419 { return variables_;}
00420
00421 inline const double * newBounds() const
00422 { return newBounds_;}
00424 inline int numberChangedBounds() const
00425 { return numberChangedBounds_;}
00426 protected:
00427
00428
00430 CoinWarmStartDiff *basisDiff_ ;
00432 int * variables_;
00433
00434 double * newBounds_;
00436 int numberChangedBounds_;
00437 private:
00438
00440 CbcPartialNodeInfo & operator=(const CbcPartialNodeInfo& rhs);
00441 };
00442
00443
00444
00462 class CbcNode : public CoinTreeNode {
00463
00464 public:
00465
00467 CbcNode ();
00468
00470 CbcNode (CbcModel * model, CbcNode * lastNode);
00471
00473 CbcNode (const CbcNode &);
00474
00476 CbcNode & operator= (const CbcNode& rhs);
00477
00479 ~CbcNode ();
00480
00496 void
00497 createInfo(CbcModel * model,
00498 CbcNode * lastNode,
00499 const CoinWarmStartBasis *lastws,
00500 const double * lastLower, const double * lastUpper,
00501 int numberOldActiveCuts,int numberNewCuts);
00502
00523 int chooseBranch (CbcModel * model,
00524 CbcNode * lastNode,
00525 int numberPassesLeft);
00551 int chooseDynamicBranch (CbcModel * model,
00552 CbcNode * lastNode,
00553 OsiSolverBranch * & branches,
00554 int numberPassesLeft);
00581 int chooseOsiBranch (CbcModel * model,
00582 CbcNode * lastNode,
00583 OsiBranchingInformation * usefulInfo,
00584 int branchState);
00600 int chooseClpBranch (CbcModel * model,
00601 CbcNode * lastNode);
00602 int analyze(CbcModel * model,double * results);
00604 void decrementCuts(int change=1);
00605
00607 void decrementParentCuts(CbcModel * model, int change=1);
00608
00610 void nullNodeInfo();
00619 void initializeInfo();
00620
00622 int branch(OsiSolverInterface * solver);
00623
00627 double checkIsCutoff(double cutoff);
00628
00629 inline CbcNodeInfo * nodeInfo() const
00630 {return nodeInfo_;}
00631
00632
00633 inline double objectiveValue() const
00634 { return objectiveValue_;}
00635 inline void setObjectiveValue(double value)
00636 { objectiveValue_=value;}
00638 inline int numberBranches() const
00639 { if (branch_)
00640 return (branch_->numberBranches()) ;
00641 else
00642 return (-1) ; }
00643
00644
00645
00646
00647
00648
00649
00650 int way() const;
00652 inline int depth() const
00653 {return depth_;}
00655 inline int numberUnsatisfied() const
00656 { return numberUnsatisfied_;}
00658 inline void setNumberUnsatisfied(int value)
00659 { numberUnsatisfied_ = value;}
00661 inline double sumInfeasibilities() const
00662 { return sumInfeasibilities_;}
00664 inline void setSumInfeasibilities(double value)
00665 { sumInfeasibilities_ = value;}
00666
00667 inline double guessedObjectiveValue() const
00668 {return guessedObjectiveValue_;}
00669 inline void setGuessedObjectiveValue(double value)
00670 {guessedObjectiveValue_=value;}
00672 inline const OsiBranchingObject * branchingObject() const
00673 { return branch_;}
00675 inline OsiBranchingObject * modifiableBranchingObject() const
00676 { return branch_;}
00678 inline void setBranchingObject(OsiBranchingObject * branchingObject)
00679 { branch_ = branchingObject;}
00681 inline int nodeNumber() const
00682 { return nodeNumber_;}
00683 inline void setNodeNumber(int node)
00684 { nodeNumber_=node;}
00686 inline bool onTree() const
00687 { return (state_&1)!=0;}
00689 inline void setOnTree(bool yesNo)
00690 { if(yesNo) state_ |= 1; else state_ &= ~1; }
00692 inline bool active() const
00693 { return (state_&2)!=0;}
00695 inline void setActive(bool yesNo)
00696 { if(yesNo) state_ |= 2; else state_ &= ~2; }
00698 void print() const;
00700 inline void checkInfo() const
00701 { assert (nodeInfo_->numberBranchesLeft()==
00702 branch_->numberBranchesLeft());}
00703
00704 private:
00705
00707 CbcNodeInfo * nodeInfo_;
00709 double objectiveValue_;
00711 double guessedObjectiveValue_;
00713 double sumInfeasibilities_;
00715 OsiBranchingObject * branch_;
00717 int depth_;
00719 int numberUnsatisfied_;
00721 int nodeNumber_;
00726 int state_;
00727 };
00728
00729
00730 #endif