// Copyright (C) 2006, International Business Machines // Corporation and others. All Rights Reserved. #ifndef OsiAuxInfo_H #define OsiAuxInfo_H class OsiSolverInterface; //############################################################################# /** This class allows for a more structured use of algorithmic tweaking to an OsiSolverInterface. It is designed to replace the simple use of appData_ pointer. This has been done to make it easier to use NonLinear solvers and other exotic beasts in a branch and bound mode. After this class definition there is one for a derived class for just such a purpose. */ class OsiAuxInfo { public: // Default Constructor OsiAuxInfo (void * appData = NULL); // Copy Constructor OsiAuxInfo (const OsiAuxInfo & rhs); // Destructor virtual ~OsiAuxInfo(); /// Clone virtual OsiAuxInfo * clone() const; /// Assignment operator OsiAuxInfo & operator=(const OsiAuxInfo& rhs); /// Get application data inline void * getApplicationData() const { return appData_;} protected: /// Pointer to user-defined data structure void * appData_; }; //############################################################################# /** This class allows for the use of more exotic solvers e.g. Non-Linear or Volume. You can derive from this although at present I can't see the need. */ class OsiBabSolver : public OsiAuxInfo { public: // Default Constructor OsiBabSolver (int solverType=0); // Copy Constructor OsiBabSolver (const OsiBabSolver & rhs); // Destructor virtual ~OsiBabSolver(); /// Clone virtual OsiAuxInfo * clone() const; /// Assignment operator OsiBabSolver & operator=(const OsiBabSolver& rhs); /// Update solver inline void setSolver(const OsiSolverInterface * solver) { solver_ = solver;} /// Update solver inline void setSolver(const OsiSolverInterface & solver) { solver_ = &solver;} /** returns 0 if no heuristic solution, 1 if valid solution with better objective value than one passed in Sets solution values if good, sets objective value numberColumns is size of newSolution */ int solution(double & objectiveValue, double * newSolution, int numberColumns); /** Set solution and objective value. Number of columns and optimization direction taken from current solver. Size of solution is numberColumns (may be padded or truncated in function) */ void setSolution(const double * solution, int numberColumns, double objectiveValue); /** returns true if the object stores a solution, false otherwise. If there is a solution then solutionValue and solution will be filled out as well. In that case the user needs to allocate solution to be a big enough array. */ bool hasSolution(double & solutionValue, double * solution); /** Sets solver type 0 - normal LP solver 1 - DW - may also return heuristic solutions 2 - NLP solver or similar - can't compute objective value just from solution check solver to see if feasible and what objective value is - may also return heuristic solution 3 - NLP solver or similar - can't compute objective value just from solution check this (rather than solver) to see if feasible and what objective value is. Using Outer Approximation so called lp based - may also return heuristic solution 4 - normal solver but cuts are needed for integral solution */ inline void setSolverType(int value) { solverType_=value;} /** gets solver type 0 - normal LP solver 1 - DW - may also return heuristic solutions 2 - NLP solver or similar - can't compute objective value just from solution check this (rather than solver) to see if feasible and what objective value is - may also return heuristic solution 3 - NLP solver or similar - can't compute objective value just from solution check this (rather than solver) to see if feasible and what objective value is. Using Outer Approximation so called lp based - may also return heuristic solution 4 - normal solver but cuts are needed for integral solution */ inline int solverType() const { return solverType_;} /** Return true if getting solution may add cuts so hot start etc will be obsolete */ inline bool solutionAddsCuts() const { return solverType_==3;} /// Return true if we should try cuts at root even if looks satisfied inline bool alwaysTryCutsAtRootNode() const { return solverType_==4;} /** Returns true if can use solver objective or feasible values, otherwise use mipBound etc */ inline bool solverAccurate() const { return solverType_==0||solverType_==2||solverType_==4;} /// Returns true if can use reduced costs for fixing inline bool reducedCostsAccurate() const { return solverType_==0||solverType_==4;} /// Get objective (well mip bound) double mipBound() const; /// Returns true if node feasible bool mipFeasible() const; /// Set mip bound (only used for some solvers) inline void setMipBound(double value) { mipBound_ = value;} /// Get objective value of saved solution inline double bestObjectiveValue() const { return bestObjectiveValue_;} /// Says whether we want to try cuts at all inline bool tryCuts() const { return solverType_!=2;} /// Says whether we have a warm start (so can do strong branching) inline bool warmStart() const { return solverType_!=2;} /** Get bit mask for odd actions of solvers 1 - solution or bound arrays may move in mysterious ways e.g. cplex 2 - solver may want bounds before branch */ inline int extraCharacteristics() const { return extraCharacteristics_;} /** Set bit mask for odd actions of solvers 1 - solution or bound arrays may move in mysterious ways e.g. cplex 2 - solver may want bounds before branch */ inline void setExtraCharacteristics(int value) { extraCharacteristics_=value;} /// Pointer to lower bounds before branch (only if extraCharacteristics set) inline const double * beforeLower() const { return beforeLower_;} /// Set pointer to lower bounds before branch (only if extraCharacteristics set) inline void setBeforeLower(const double * array) { beforeLower_ = array;} /// Pointer to upper bounds before branch (only if extraCharacteristics set) inline const double * beforeUpper() const { return beforeUpper_;} /// Set pointer to upper bounds before branch (only if extraCharacteristics set) inline void setBeforeUpper(const double * array) { beforeUpper_ = array;} protected: /// Objective value of best solution (if there is one) (minimization) double bestObjectiveValue_; /// Current lower bound on solution ( if > 1.0e50 infeasible) double mipBound_; /// Solver to use for getting/setting solutions etc const OsiSolverInterface * solver_; /// Best integer feasible solution double * bestSolution_; /// Pointer to lower bounds before branch (only if extraCharacteristics set) const double * beforeLower_; /// Pointer to upper bounds before branch (only if extraCharacteristics set) const double * beforeUpper_; /** Solver type 0 - normal LP solver 1 - DW - may also return heuristic solutions 2 - NLP solver or similar - can't compute objective value just from solution check this (rather than solver) to see if feasible and what objective value is - may also return heuristic solution 3 - NLP solver or similar - can't compute objective value just from solution check this (rather than solver) to see if feasible and what objective value is. Using Outer Approximation so called lp based - may also return heuristic solution */ int solverType_; /// Size of solution int sizeSolution_; /** Bit mask for odd actions of solvers 1 - solution or bound arrays may move in mysterious ways e.g. cplex 2 - solver may want bounds before branch */ int extraCharacteristics_; }; #endif