source: trunk/Bonmin/src/IpoptInterface/TMINLP2TNLP.hpp @ 1

Last change on this file since 1 was 1, checked in by andreasw, 13 years ago

imported initial code

  • Property svn:eol-style set to native
  • Property svn:keywords set to "Author Date Id Revision"
File size: 12.3 KB
Line 
1// (C) Copyright International Business Machines Corporation and Carnegie Mellon University 2004
2// All Rights Reserved.
3// This code is published under the Common Public License.
4//
5// Authors :
6// Pierre Bonami, Carnegie Mellon University,
7// Carl D. Laird, Carnegie Mellon University,
8// Andreas Waechter, International Business Machines Corporation
9//
10// Date : 12/01/2004
11
12#ifndef __TMINLP2TNLP_HPP__
13#define __TMINLP2TNLP_HPP__
14
15#include "IpTNLP.hpp"
16#include "TMINLP.hpp"
17#include "IpSmartPtr.hpp"
18#include "IpIpoptApplication.hpp"
19#include "IpOptionsList.hpp"
20#include "IpoptInteriorWarmStarter.hpp"
21
22namespace Ipopt
23{
24  /** This is an adapter class that converts a TMINLP to
25   *  a TNLP to be solved by Ipopt. It allows an external
26   *  caller to modify the bounds of variables, allowing
27   *  the treatment of binary and integer variables as
28   *  relaxed, or fixed
29   */
30  class TMINLP2TNLP : public TNLP
31  {
32  public:
33    /**@name Constructors/Destructors */
34    //@{
35    TMINLP2TNLP(const SmartPtr<TMINLP> tminlp,
36        const OptionsList& options);
37
38    /** Default destructor */
39    virtual ~TMINLP2TNLP();
40    //@}
41
42    /** Copies the modification made to TNLP by the user (modifications
43    such as changing bound changing starting point,...).
44    this and other should be two instances of the same problem
45    I am trying to mimic a copy construction for Cbc
46    use with great care not safe.
47    */
48    void copyUserModification(TMINLP2TNLP& other);
49
50
51    DECLARE_STD_EXCEPTION(TMINLP_INVALID_VARIABLE_BOUNDS);
52
53    /**@name Methods to modify the MINLP and form the NLP */
54    //@{
55
56    /** Get the number of variables */
57    Index num_variables()
58    {
59      return n_;
60    }
61
62    /** Get the number of constraints */
63    Index num_constraints()
64    {
65      return m_;
66    }
67    /** Get the nomber of nz in hessian */
68    Index nnz_h_lag()
69    {
70      return nnz_h_lag_;
71    }
72    /** Get the variable types */
73    const TMINLP::VariableType* var_types()
74    {
75      return var_types_;
76    }
77
78    //Print variable types to screen
79    void printVarTypes()
80    {
81      //       for (int i = 0 ; i < n_ ; i++)
82      //        {
83      //          std::cout<<i<<"\t"<<var_types_[i]<<std::endl;
84      //        }
85    }
86
87    /** Get the current values for the lower bounds */
88    const Number* x_l()
89    {
90      return x_l_;
91    }
92    /** Get the current values for the upper bounds */
93    const Number* x_u()
94    {
95      return x_u_;
96    }
97
98    /** Get the original values for the lower bounds */
99    const Number* orig_x_l() const
100    {
101      return orig_x_l_;
102    }
103    /** Get the original values for the upper bounds */
104    const Number* orig_x_u() const
105    {
106      return orig_x_u_;
107    }
108
109    /** Get the current values for constraints lower bounds */
110    const Number* g_l()
111    {
112      return g_l_;
113    }
114    /** Get the current values for constraints upper bounds */
115    const Number* g_u()
116    {
117      return g_u_;
118    }
119
120    /** get the starting primal point */
121    const Number * x_init() const
122    {
123      return x_init_;
124    }
125
126    /** get the starting dual point */
127    const Number * duals_init() const
128    {
129      return duals_init_;
130    }
131
132    /** get the solution values */
133    const Number* x_sol() const
134    {
135      return x_sol_;
136    }
137
138    /** get the g solution (activities) */
139    const Number* g_sol() const
140    {
141      return g_sol_;
142    }
143
144    /** get the dual values */
145    const Number* duals_sol() const
146    {
147      return duals_sol_;
148    }
149
150    /** Get Optimization status */
151    SolverReturn optimization_status()
152    {
153      return return_status_;
154    }
155
156    /** Get the objective value */
157    Number obj_value()
158    {
159      return obj_value_;
160    }
161
162    /** Manually set objective value. */
163    void set_obj_value(Number value)
164    {
165      obj_value_ = value;
166    }
167
168    /** force solution to be fractionnal.*/
169    void force_fractionnal_sol();
170
171    /** Change the bounds on the variable */
172    void SetVariableBounds(Index var_no, Number x_l, Number x_u);
173
174    /** Change the lower bound on the variable */
175    void SetVariableLowerBound(Index var_no, Number x_l);
176
177    /** Change the upper bound on the variable */
178    void SetVariableUpperBound(Index var_no, Number x_u);
179
180    /** Change the starting point */
181    void SetStartingPoint(Index n, const Number* x_init);
182
183    /** reset the starting point to original one. */
184    void resetStartingPoint();
185
186    /** Set component ind of the starting point. */
187    void setxInit(Index ind,const Number val);
188
189    /** set the starting point to x_init */
190    void setxInit(Index n,const Number* x_init);
191
192    /** Set component ind of the dual starting point. */
193    void setDualInit(Index ind, const Number val);
194
195    /** set the dual starting point to duals_init */
196    void setDualsInit(Index n, const Number* duals_init);
197
198
199    /** Set the contiuous solution */
200    void Set_x_sol(Index n, const Number* x_sol);
201
202    /** Change the type of the variable */
203    void SetVariableType(Index n, TMINLP::VariableType type);
204    //@}
205    /** Procedure to ouptut relevant informations to reproduce a sub-problem.
206      Compare the current problem to the problem to solve
207      and writes files with bounds which have changed and current starting point.
208      */
209    void outputDiffs(const std::string& probName, const std::string* varNames);
210
211    /**@name methods to gather information about the NLP */
212    //@{
213    /** This call is just passed onto the TMINLP object */
214    virtual bool get_nlp_info(Index& n, Index& m, Index& nnz_jac_g,
215        Index& nnz_h_lag,
216        TNLP::IndexStyleEnum& index_style);
217
218    /** The caller is allowed to modify the bounds, so this
219     *  method returns the internal bounds information
220     */
221    virtual bool get_bounds_info(Index n, Number* x_l, Number* x_u,
222        Index m, Number* g_l, Number* g_u);
223
224    /** Method called by Ipopt to get the starting point. The bools
225     *  init_x and init_lambda are both inputs and outputs. As inputs,
226     *  they indicate whether or not the algorithm wants you to
227     *  initialize x and lambda respectively. If, for some reason, the
228     *  algorithm wants you to initialize these and you cannot, set
229     *  the respective bool to false.
230     */
231    virtual bool get_starting_point(Index n, bool init_x, Number* x,
232        bool init_z, Number* z_L, Number* z_U,
233        Index m, bool init_lambda,
234        Number* lambda);
235
236    /** Methat that returns an Ipopt IteratesVector that has the
237     *  starting point for all internal varibles. */
238    virtual bool get_warm_start_iterate(IteratesVector& warm_start_iterate);
239
240    /** Returns the value of the objective function in x*/
241    virtual bool eval_f(Index n, const Number* x, bool new_x,
242        Number& obj_value);
243
244    /** Returns the vector of the gradient of
245     *  the objective w.r.t. x */
246    virtual bool eval_grad_f(Index n, const Number* x, bool new_x,
247        Number* grad_f);
248
249    /** Returns the vector of constraint values in x*/
250    virtual bool eval_g(Index n, const Number* x, bool new_x,
251        Index m, Number* g);
252
253    /** Returns the jacobian of the
254     *  constraints. The vectors iRow and jCol only need to be set
255     *  once. The first call is used to set the structure only (iRow
256     *  and jCol will be non-NULL, and values will be NULL) For
257     *  subsequent calls, iRow and jCol will be NULL. */
258    virtual bool eval_jac_g(Index n, const Number* x, bool new_x,
259        Index m, Index nele_jac, Index* iRow,
260        Index *jCol, Number* values);
261
262    /** Return the hessian of the
263     *  lagrangian. The vectors iRow and jCol only need to be set once
264     *  (during the first call). The first call is used to set the
265     *  structure only (iRow and jCol will be non-NULL, and values
266     *  will be NULL) For subsequent calls, iRow and jCol will be
267     *  NULL. This matrix is symmetric - specify the lower diagonal
268     *  only */
269    virtual bool eval_h(Index n, const Number* x, bool new_x,
270        Number obj_factor, Index m, const Number* lambda,
271        bool new_lambda, Index nele_hess,
272        Index* iRow, Index* jCol, Number* values);
273    //@}
274
275    /** @name Solution Methods */
276    //@{
277    /** This method is called when the algorithm is complete so the TNLP can store/write the solution */
278    virtual void finalize_solution(SolverReturn status,
279        Index n, const Number* x, const Number* z_L, const Number* z_U,
280        Index m, const Number* g, const Number* lambda,
281        Number obj_value);
282    /** Intermediate Callback method for the user.  Providing dummy
283     *  default implementation.  For details see IntermediateCallBack
284     *  in IpNLP.hpp. */
285    virtual bool intermediate_callback(AlgorithmMode mode,
286        Index iter, Number obj_value,
287        Number inf_pr, Number inf_du,
288        Number mu, Number d_norm,
289        Number regularization_size,
290        Number alpha_du, Number alpha_pr,
291        Index ls_trials,
292        const IpoptData* ip_data,
293        IpoptCalculatedQuantities* ip_cq);
294    //@}
295
296    /** Method called to check wether a problem has still some variable not fixed. If there are no more
297        unfixed vars, checks wether the solution given by the bounds is feasible.*/
298    bool checkZeroDimension(ApplicationReturnStatus& optimization_status);
299
300    /** @name Methods for setting and getting the warm starter */
301    //@{
302    void SetWarmStarter(SmartPtr<IpoptInteriorWarmStarter> warm_starter)
303    {
304      curr_warm_starter_ = warm_starter;
305    }
306    SmartPtr<IpoptInteriorWarmStarter> GetWarmStarter()
307    {
308      return curr_warm_starter_;
309    }
310    //@}
311  protected:
312    /**@name Default Compiler Generated Methods
313     * (Hidden to avoid implicit creation/calling).
314     * These methods are not implemented and
315     * we do not want the compiler to implement
316     * them for us, so we declare them private
317     * and do not define them. This ensures that
318     * they will not be implicitly created/called. */
319    //@{
320    /** Default Constructor */
321    TMINLP2TNLP();
322
323    /** Copy Constructor */
324    TMINLP2TNLP(const TMINLP2TNLP&);
325
326    /** Overloaded Equals Operator */
327    void operator=(const TMINLP2TNLP&);
328    //@}
329
330    /** pointer to the tminlp that is being adapted */
331    SmartPtr<TMINLP> tminlp_;
332
333    /** @name Internal copies of data allowing caller to modify the MINLP */
334    //@{
335    /// Number of variables
336    Index n_;
337    /// Number of constraints
338    Index m_;
339    /// Number of non-zeroes in the lagrangian.
340    Index nnz_h_lag_;
341    /**index style (fortran or C)*/
342    TNLP::IndexStyleEnum index_style_;
343    /// Types of the variable (TMINLP::CONTINUOUS, TMINLP::INTEGER, TMINLP::BINARY).
344    TMINLP::VariableType* var_types_;
345    /// Current lower bounds on variables
346    Number* x_l_;
347    /// Current upper bounds on variables
348    Number* x_u_;
349    /// Original lower bounds on variables
350    Number* orig_x_l_;
351    /// Original upper bounds on variables
352    Number* orig_x_u_;
353    /// Lower bounds on constraints values
354    Number* g_l_; // These are not modified, but a copy is kept for consistency
355    /// Upper bounds on constraints values
356    Number* g_u_;
357    /// Initial primal point
358    Number* x_init_;
359    /** Initial values for all dual multipliers (constraints then lower bounds then upper bounds) */
360    Number * duals_init_;
361    /// User-provideed initial prmal point
362    Number* x_init_user_;
363    /// Optimal solution
364    Number* x_sol_;
365    /// Activities of constraint g( x_sol_)
366    Number * g_sol_;
367    /** Dual multipliers of constraints and bounds*/
368    Number* duals_sol_;
369
370    /** Return status of the optimization process*/
371    SolverReturn return_status_;
372    /** Value of the optimal solution found by Ipopt */
373    Number obj_value_;
374    //@}
375
376    /** @name Warmstart object and related data */
377    //@{
378    /** Pointer to object that holds warmstart information */
379    SmartPtr<IpoptInteriorWarmStarter> curr_warm_starter_;
380    /** Value for a lower bound that denotes -infinity */
381    Number nlp_lower_bound_inf_;
382    /** Value for a upper bound that denotes infinity */
383    Number nlp_upper_bound_inf_;
384    /** Option from Ipopt - we currently use it to see if we want to
385     *  use some clever warm start or just the last iterate from the
386     *  previous run */
387    bool warm_start_entire_iterate_;
388    /** Do we need a new warm starter object */
389    bool need_new_warm_starter_;
390    //@}
391
392
393    /** Private method that throws an exception if the variable bounds
394     * are not consistent with the variable type */
395    void throw_exception_on_bad_variable_bound(Index i);
396
397  };
398
399} // namespace Ipopt
400
401#endif
Note: See TracBrowser for help on using the repository browser.