1 // (C) Copyright International Business Machines (IBM) 2006, 2007
2 // All Rights Reserved.
3 // This code is published under the Eclipse Public License.
4 //
5 // Authors :
6 // Pierre Bonami, IBM
7 //
8 // Date : 26/09/2006
9 
10 
11 #ifndef TNLPSolver_H
12 #define TNLPSolver_H
13 #include "IpTNLP.hpp"
14 #include "BonTMINLP2TNLP.hpp"
15 
16 //Some declarations
17 #include "IpOptionsList.hpp"
18 #include "CoinWarmStart.hpp"
19 #include "BonRegisteredOptions.hpp"
20 #include "CoinTime.hpp"
21 namespace Bonmin  {
22 /** This is a generic class for calling an NLP solver to solve a TNLP.
23     A TNLPSolver is able to solve and resolve a problem, it has some options (stored
24     with Ipopt OptionList structure and registeredOptions) it produces some statistics (in SolveStatisctics and sometimes some errorCodes.
25 */
26 class TNLPSolver: public Ipopt::ReferencedObject{
27  public:
28 
29   enum ReturnStatus /** Standard return statuses for a solver*/{
30     iterationLimit = -3/** Solver reached iteration limit. */,
31     timeLimit = 5/** Solver reached iteration limit. */,
32     doesNotConverge = -8/** Algorithm does not converge.*/,
33     computationError = -2/** Some error was made in the computations. */,
34     notEnoughFreedom = -1/** not enough degrees of freedom.*/,
35     illDefinedProblem = -4/** The solver finds that the problem is not well defined. */,
36     illegalOption =-5/** An option is not valid. */,
37     externalException =-6/** Some unrecovered exception occured in an external tool used by the solver. */,
38     exception =-7/** Some unrocevered exception */,
39     solvedOptimal = 1/** Problem solved to an optimal solution.*/,
40     solvedOptimalTol =2/** Problem solved to "acceptable level of tolerance. */,
41     provenInfeasible =3/** Infeasibility Proven. */,
42     unbounded = 4/** Problem is unbounded.*/,
43     numReturnCodes/**Fake member to know size*/
44   };
45 
46 
47 
48 //#############################################################################
49 
50   /** We will throw this error when a problem is not solved.
51       Eventually store the error code from solver*/
52   class UnsolvedError
53   {
54   public:
55     /** Constructor */
UnsolvedError(int errorNum=-10000,Ipopt::SmartPtr<TMINLP2TNLP> model=NULL,std::string name="")56     UnsolvedError(int errorNum = -10000,
57                   Ipopt::SmartPtr<TMINLP2TNLP> model = NULL,
58                   std::string name="")
59     :
60      errorNum_(errorNum),
61      model_(model),
62      name_(name)
63     {if(name_=="")
64 {
65 #ifndef NDEBUG
66 	std::cerr<<"FIXME"<<std::endl;
67 #endif
68 }}
69     /** Print error message.*/
70     void printError(std::ostream & os);
71     /** Get the string corresponding to error.*/
72     virtual const std::string& errorName() const = 0;
73     /** Return the name of the solver. */
74     virtual const std::string& solverName() const = 0;
75     /** Return error number. */
errorNum() const76     int errorNum() const{
77     return errorNum_;}
78     /** destructor. */
~UnsolvedError()79     virtual ~UnsolvedError(){}
80     /** write files with differences between input model and
81         this one */
82     void writeDiffFiles(const std::string prefix=std::string()) const;
83   private:
84     /** Error code (solver dependent). */
85     int errorNum_;
86 
87     /** model_ on which error occured*/
88     Ipopt::SmartPtr< TMINLP2TNLP > model_;
89 
90     /** name of the model on which error occured. */
91     std::string name_;
92   }
93   ;
94 
95   virtual UnsolvedError * newUnsolvedError(int num,
96 					   Ipopt::SmartPtr<TMINLP2TNLP> problem,
97 					   std::string name) = 0;
98 
99 
100 
101   /// default Constructor
102    TNLPSolver();
103 
104   ///Constructor with options initialization
105 TNLPSolver(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions,
106            Ipopt::SmartPtr<Ipopt::OptionsList> options,
107            Ipopt::SmartPtr<Ipopt::Journalist> journalist,
108            const std::string & prefix);
109 
110   ///virtual copy constructor
111   virtual Ipopt::SmartPtr<TNLPSolver> clone() = 0;
112 
113    /// Virtual destructor
114    virtual ~TNLPSolver();
115 
116    /** Initialize the TNLPSolver (read options from params_file)
117    */
118    virtual bool Initialize(std::string params_file) = 0;
119 
120    /** Initialize the TNLPSolver (read options from istream is)
121    */
122    virtual bool Initialize(std::istream& is) = 0;
123 
124    /** @name Solve methods */
125    //@{
126    /// Solves a problem expresses as a TNLP
127    virtual ReturnStatus OptimizeTNLP(const Ipopt::SmartPtr<Ipopt::TNLP> & tnlp) = 0;
128 
129    /// Resolves a problem expresses as a TNLP
130    virtual ReturnStatus ReOptimizeTNLP(const Ipopt::SmartPtr<Ipopt::TNLP> & tnlp) = 0;
131 
132   /// Set the warm start in the solver
133   virtual bool setWarmStart(const CoinWarmStart * warm,
134                             Ipopt::SmartPtr<TMINLP2TNLP> tnlp) = 0;
135 
136 /// Get warm start used in last optimization
137   virtual CoinWarmStart * getUsedWarmStart(Ipopt::SmartPtr<TMINLP2TNLP> tnlp) const = 0;
138 
139   /// Get the warm start form the solver
140   virtual CoinWarmStart * getWarmStart(Ipopt::SmartPtr<TMINLP2TNLP> tnlp) const = 0;
141 
142   virtual CoinWarmStart * getEmptyWarmStart() const = 0;
143 
144   /** Check that warm start object is valid.*/
145   virtual bool warmStartIsValid(const CoinWarmStart * ws) const = 0;
146 
147   /// Enable the warm start options in the solver
148   virtual void enableWarmStart() = 0;
149 
150   /// Disable the warm start options in the solver
151   virtual void disableWarmStart() = 0;
152    //@}
153 
154   ///Get a pointer to a journalist
journalist()155   Ipopt::SmartPtr<Ipopt::Journalist> journalist(){
156     return journalist_;}
157 
158    ///Get a pointer to RegisteredOptions (generally used to add new ones)
roptions()159    Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions(){
160      return roptions_;}
161 
162    /// Get the options (for getting their values).
options() const163    Ipopt::SmartPtr<const Ipopt::OptionsList> options() const {
164      return ConstPtr(options_);}
165 
166    /// Get the options (for getting and setting their values).
options()167    Ipopt::SmartPtr<Ipopt::OptionsList> options() {
168      return options_;}
169 
170   /// Get the prefix
prefix()171   const char * prefix(){
172     return prefix_.c_str();
173   }
174    /// Register this solver options into passed roptions
RegisterOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions)175 static void RegisterOptions(Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions){}
176 
177    /// Get the CpuTime of the last optimization.
178    virtual double CPUTime() = 0;
179 
180    /// Get the iteration count of the last optimization.
181    virtual int IterationCount() = 0;
182 
183 
184   /// turn off all output from the solver
185   virtual void setOutputToDefault() = 0 ;
186   /// turn on all output from the solver
187   virtual void forceSolverOutput(int log_level) = 0;
188   /// Get the solver name
189   virtual std::string & solverName() = 0;
190 
191     /** Say if an optimization status for a problem which failed is recoverable
192         (problem may be solvable).*/
193   bool isRecoverable(ReturnStatus &r);
194 
195   /** Setup for a global time limit for solver.*/
setup_global_time_limit(double time_limit)196   void setup_global_time_limit(double time_limit){
197     time_limit_ = time_limit + 5;
198     start_time_ = CoinCpuTime();
199   }
200 
201   /** Say if return status is an error.*/
isError(ReturnStatus & r)202   bool isError(ReturnStatus &r){
203     return r < 0;}
204   /** Error code (solver specific).*/
205 virtual int errorCode() const = 0;
206 protected:
207    /** Determine if problem is of dimension zero and if it is check if solution
208        is feasible.*/
209    bool zeroDimension(const Ipopt::SmartPtr<Ipopt::TNLP> &tnlp,
210 		     ReturnStatus &optimization_status);
211 
212    /** Initializes options and journalist.*/
213    void initializeOptionsAndJournalist();
214 
215     /** Storage of Journalist for output */
216     Ipopt::SmartPtr<Ipopt::Journalist> journalist_;
217 
218     /** List of Options */
219     Ipopt::SmartPtr<Ipopt::OptionsList> options_;
220 
221     /** Registered Options */
222     Ipopt::SmartPtr<Bonmin::RegisteredOptions> roptions_;
223 
224     /** Prefix to use for reading bonmin's options.*/
225    std::string prefix_;
226    /** Global start time.*/
227    double start_time_;
228 
229    /** Global time limit.*/
230    double time_limit_;
231 
232    /** To record default log level.*/
233    int default_log_level_;
234   /// Copy Constructor
235   TNLPSolver(const TNLPSolver & other);
236 
237 };
238 }
239 #endif
240 
241 
242