OsiAuxInfo.hpp 8.42 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
// 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
*/