// Copyright (C) 2006, International Business Machines // Corporation and others. All Rights Reserved. // This code is licensed under the terms of the Eclipse Public License (EPL). #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; } /// Set pointer to extra stuff inline void setExtraPointer(void *extraInfo) { extraInfo_ = extraInfo; } /// get pointer to extra info inline void *getExtraPointer() const { return extraInfo_; } 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_; /// Pointer to extra info void *extraInfo_; /** 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 /* vi: softtabstop=2 shiftwidth=2 expandtab tabstop=2 */