1 /* $Id$
2  *
3  * Name:    CouenneSolverInterface.hpp
4  * Authors: Pietro Belotti, Carnegie Mellon University
5  * Purpose: OsiSolverInterface with a pointer to a CouenneCutGenerator object
6  *
7  * (C) Carnegie-Mellon University, 2007-09.
8  * This file is licensed under the Eclipse Public License (EPL)
9  */
10 
11 #ifndef COUENNESOLVERINTERFACE_HPP
12 #define COUENNESOLVERINTERFACE_HPP
13 
14 class OsiSolverInterface;
15 
16 namespace Couenne {
17 
18 class CouenneCutGenerator;
19 
20 /// Solver interface class with a pointer to a Couenne cut
21 /// generator. Its main purposes are:
22 ///
23 /// 1) to apply bound tightening before re-solving
24 /// 2) to replace OsiSolverInterface::isInteger () with problem_ -> [expression] -> isInteger ()
25 /// 3) to use NLP solution at branching
26 
27 template <class T> class CouenneSolverInterface: public T {
28 
29 public:
30 
31   /// Constructor
32   CouenneSolverInterface (CouenneCutGenerator *cg = NULL);
33 
34   /// Copy constructor
35   CouenneSolverInterface (const CouenneSolverInterface &src);
36 
37   /// Destructor
38   ~CouenneSolverInterface ();
39 
40   /// Clone
clone(bool copyData=true) const41   virtual OsiSolverInterface * clone (bool copyData = true) const
42   {return new CouenneSolverInterface (*this);}
43 
44   /// we need to overwrite this since we might have internal knowledge
45   virtual bool isProvenPrimalInfeasible () const;
46 
47   /// we need to overwrite this since we might have internal knowledge
48   virtual bool isProvenOptimal () const;
49 
50   /// Return cut generator pointer
CutGen()51   CouenneCutGenerator *CutGen ()
52   {return cutgen_;}
53 
54   /// Set cut generator pointer after setup, to avoid changes in the
55   /// pointer due to cut generator cloning (it happens twice in the
56   /// algorithm)
setCutGenPtr(CouenneCutGenerator * cg)57   void setCutGenPtr (CouenneCutGenerator *cg) {
58     cutgen_ = cg;
59     //if (cutgen_ && !(cutgen_ -> enableLpImpliedBounds ()))
60     //specialOptions_ = specialOptions_ | 262144;
61   }
62 
63   /// Solve initial LP relaxation
64   virtual void initialSolve ();
65 
66   /// Resolve an LP relaxation after problem modification
67   virtual void resolve ();
68 
69   /// Resolve an LP without applying bound tightening beforehand
resolve_nobt()70   virtual void resolve_nobt ()
71   {T::resolve ();}
72 
73   /** @name Methods for strong branching.
74    */
75   //@{
76   /// Create a hot start snapshot of the optimization process.
77   virtual void markHotStart();
78 
79   /// Optimize starting from the hot start snapshot.
80   virtual void solveFromHotStart();
81 
82   /// Delete the hot start snapshot.
83   virtual void unmarkHotStart();
84   //@}
85 
86   /// Tighten bounds on all variables (including continuous).
87   virtual int tightenBounds (int lightweight);
88 
89   /// set doingResolve_
90   //bool &doingResolve ()
91   //{return doingResolve_;}
92 
93   /// is this problem unbounded?
94   bool isProvenDualInfeasible () const;
95   //{return knowDualInfeasible_;}
96 
97   /// Get the objective function value. Modified due to possible
98   /// constant objectives passed to Couenne
99   virtual double getObjValue() const;
100 
101   // /// returns LP optimum at root node
102   // double rootLB () const
103   // {return rootLB_;}
104 
105 protected:
106 
107   /// Copy of the Clp version --- not light version
108   virtual int tightenBoundsCLP (int lightweight);
109 
110   /// Copy of the Clp version --- light version
111   virtual int tightenBoundsCLP_Light (int lightweight);
112 
113   /// The pointer to the Couenne cut generator. Gives us a lot of
114   /// information, for instance the nlp solver pointer, and the chance
115   /// to do bound tightening before resolve ().
116   CouenneCutGenerator *cutgen_;
117 
118   /// Flag indicating that infeasibility was detected during solveFromHotStart
119   bool knowInfeasible_;
120 
121   /// Flag indicating that optimality was detected during solveFromHotStart
122   bool knowOptimal_;
123 
124   /// Flag indicating this problem's continuous relaxation is unbounded
125   bool knowDualInfeasible_;
126 
127   // /// First (root) LP not solved yet -- use this flag to obtain root
128   // /// lower bound and print an alternative gap
129   // bool beforeFirstRootLP_;
130 
131   // /// First (root) LP bound -- used to get an alternative gap
132   // double rootLB_;
133 };
134 
135 }
136 
137 // These source files are #included due to the template classes
138 // defined in there
139 
140 #include "CouenneSolverInterface.cpp"
141 #include "CouenneLPtightenBounds.cpp"
142 #include "CouenneLPtightenBoundsCLP-light.cpp"
143 #include "CouenneLPtightenBoundsCLP.cpp"
144 
145 #endif
146