// 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