// Copyright (C) 2002, International Business Machines // Corporation and others. All Rights Reserved. #ifndef CbcCompareBase_H #define CbcCompareBase_H //############################################################################# /* These are alternative strategies for node traversal. They can take data etc for fine tuning At present the node list is stored as a heap and the "test" comparison function returns true if node y is better than node x. This is rather inflexible so if the comparison functions wants it can signal to use alternative criterion on a complete pass throgh tree. */ #include "CbcNode.hpp" #include "CbcConfig.h" class CbcModel; class CbcTree; class CbcCompareBase { public: // Default Constructor CbcCompareBase () {test_=NULL;threaded_=false;} // This allows any method to change behavior as it is called // after each solution virtual void newSolution(CbcModel * model) {} // This Also allows any method to change behavior as it is called // after each solution virtual void newSolution(CbcModel * model, double objectiveAtContinuous, int numberInfeasibilitiesAtContinuous) {} // This allows any method to change behavior as it is called // after every 1000 nodes. // Return true if want tree re-sorted virtual bool every1000Nodes(CbcModel * model,int numberNodes) {return false;} /** Returns true if wants code to do scan with alternate criterion NOTE - this is temporarily disabled */ virtual bool fullScan() const { return false;} virtual ~CbcCompareBase() {} /// Create C++ lines to get to current state virtual void generateCpp( FILE * fp) {} // Copy constructor CbcCompareBase ( const CbcCompareBase & rhs) {test_=rhs.test_;threaded_=rhs.threaded_;} // Assignment operator CbcCompareBase & operator=( const CbcCompareBase& rhs) { if (this!=&rhs) {test_=rhs.test_;threaded_=rhs.threaded_;} return *this; } /// Clone virtual CbcCompareBase * clone() const { abort(); return NULL;} /// This is test function virtual bool test (CbcNode * x, CbcNode * y) {return true;} /// This is alternate test function virtual bool alternateTest (CbcNode * x, CbcNode * y) {return test(x,y);} bool operator() (CbcNode * x, CbcNode * y) { return test(x,y); } /// Further test if everything else equal inline bool equalityTest (CbcNode * x, CbcNode * y) const { assert (x); assert (y); if (!threaded_) { CbcNodeInfo * infoX = x->nodeInfo(); assert (infoX); int nodeNumberX = infoX->nodeNumber(); CbcNodeInfo * infoY = y->nodeInfo(); assert (infoY); int nodeNumberY = infoY->nodeNumber(); assert (nodeNumberX!=nodeNumberY); return (nodeNumberX>nodeNumberY); } else { assert (x->nodeNumber()!=y->nodeNumber()); return (x->nodeNumber()>y->nodeNumber()); } } /// Say threaded inline void sayThreaded() { threaded_ = true;} protected: CbcCompareBase * test_; // If not threaded we can use better way to break ties bool threaded_; }; class CbcCompare { public: CbcCompareBase * test_; // Default Constructor CbcCompare () {test_=NULL;} virtual ~CbcCompare() {} bool operator() (CbcNode * x, CbcNode * y) { return test_->test(x,y); } bool compareNodes (CbcNode * x, CbcNode * y) { return test_->test(x,y); } /// This is alternate test function inline bool alternateTest (CbcNode * x, CbcNode * y) {return test_->alternateTest(x,y);} /// return comparison object inline CbcCompareBase * comparisonObject() const { return test_;} }; //############################################################################# /* These can be alternative strategies for choosing variables Any descendant can be passed in by setVariableChoice */ class CbcChooseVariable { public: // Default Constructor CbcChooseVariable () {} virtual ~CbcChooseVariable() {} /** If strong branching, then only those passed in (and movement is that length) . If not strong branching then all passed in and ignore movement. Returns which one chosen (or -1 if none). way should be +1 if branching up, -1 if down */ virtual int chosen (const CbcModel * model,int numberToLookAt, const int * which, const double * downMovement, const double * upMovement, const double * solution, int & way, double & value)=0; }; #endif