summaryrefslogtreecommitdiff
path: root/newstructure/thirdparty/linux/include/coin/BonCutStrengthener.hpp
blob: 7e2b92f5b5f1ea3a12952ebd2be9729102c50fa8 (plain)
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
// Copyright (C) 2007 International Business Machines and others.
// All Rights Reserved.
// This code is published under the Eclipse Public License.
//
// $Id: BonCutStrengthener.hpp 2106 2015-01-20 10:33:55Z stefan $
//
// Author:   Andreas Waechter                 IBM    2007-03-29

#ifndef __BONCUTSTRENGTHENER_HPP__
#define __BONCUTSTRENGTHENER_HPP__

#include "BonTMINLP.hpp"
#include "CoinPackedVector.hpp"
#include "BonTNLPSolver.hpp"

namespace Bonmin
{
  enum CutStrengtheningType{
    CS_None=0,
    CS_StrengthenedGlobal=1,
    CS_UnstrengthenedGlobal_StrengthenedLocal=2,
    CS_StrengthenedGlobal_StrengthenedLocal=3
  };

  enum DisjunctiveCutType{
    DC_None=0,
    DC_MostFractional=1
  };

  /** Class for strengthening OA cuts, and generating additional ones.
   */
  class CutStrengthener: public Ipopt::ReferencedObject
  {
    /** Class implementing the TNLP for strengthening one cut.  We
     *  assume that the cut has a lower bound. */
    class StrengtheningTNLP: public Ipopt::TNLP {
    public:
      /** Contructor */
      StrengtheningTNLP(Ipopt::SmartPtr<TMINLP> tminlp,
			const CoinPackedVector& cut,
			bool lower_bound,
			Ipopt::Index n,
			const Ipopt::Number* starting_point,
			const double* x_l_orig,
			const double* x_u_orig,
			Ipopt::Index constr_index,
			Ipopt::Index nvar_constr /** Ipopt::Number of variables in constraint */,
			const Ipopt::Index* jCol);

      /** Destructor */
      ~StrengtheningTNLP();

      /**@name Overloaded from TNLP */
      //@{
      /** Method to return some info about the nlp */
      virtual bool get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g,
				Ipopt::Index& nnz_h_lag, Ipopt::TNLP::IndexStyleEnum& index_style);

      /** Method to return the bounds for my problem */
      virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u,
				   Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u);

      /** Method to return the starting point for the algorithm */
      virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number* x,
				      bool init_z, Ipopt::Number* z_L, Ipopt::Number* z_U,
				      Ipopt::Index m, bool init_lambda,
				      Ipopt::Number* lambda);

      /** Method to return the objective value */
      virtual bool eval_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, Ipopt::Number& obj_value);

      /** Method to return the gradient of the objective */
      virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x, Ipopt::Number* grad_f);

      /** Method to return the constraint residuals */
      virtual bool eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x, Ipopt::Index m, Ipopt::Number* g);

      /** Method to return:
       *   1) The structure of the jacobian (if "values" is NULL)
       *   2) The values of the jacobian (if "values" is not NULL)
       */
      virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x,
			      Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow, Ipopt::Index *jCol,
			      Ipopt::Number* values);

      /** Method to return:
       *   1) The structure of the hessian of the lagrangian (if "values" is NULL)
       *   2) The values of the hessian of the lagrangian (if "values" is not NULL)
       */
      virtual bool eval_h(Ipopt::Index n, const Ipopt::Number* x, bool new_x,
			  Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number* lambda,
			  bool new_lambda, Ipopt::Index nele_hess, Ipopt::Index* iRow,
			  Ipopt::Index* jCol, Ipopt::Number* values);

      //@}
      /** @name Solution Methods */
      //@{
      /** This method is called when the algorithm is complete so the TNLP can store/write the solution */
      virtual void finalize_solution(Ipopt::SolverReturn status,
				     Ipopt::Index n, const Ipopt::Number* x, const Ipopt::Number* z_L, const Ipopt::Number* z_U,
				     Ipopt::Index m, const Ipopt::Number* g, const Ipopt::Number* lambda,
				     Ipopt::Number obj_value,
				     const Ipopt::IpoptData* ip_data,
				     Ipopt::IpoptCalculatedQuantities* ip_cq);
      //@}

      /** Method for asking for the strengthened bound. */
      Ipopt::Number StrengthenedBound() const;
      
    private:
      /**@name Methods to block default compiler methods. */
      //@{
      StrengtheningTNLP();
      StrengtheningTNLP(const StrengtheningTNLP&);
      StrengtheningTNLP& operator=(const StrengtheningTNLP&);
      //@}

      /** TMINLP (with current bounds) for which the cut it to be
       *  generated */
      const Ipopt::SmartPtr<TMINLP> tminlp_;

      /** Gradient of the (linear) objective function */
      Ipopt::Number* obj_grad_;

      /** Dimension of original problem */
      const Ipopt::Index n_orig_;

      /** Ipopt::Number of constraints in original problem */
      Ipopt::Index m_orig_;

      /** Starting point */
      Ipopt::Number* starting_point_;

      /** Full dimentional x which is used to call the TMINLP
       *  evaluation routines */
      Ipopt::Number* x_full_;

      /** Lower bounds for constraint variables */
      Ipopt::Number* x_l_;

      /** Upper bounds for constraint variables */
      Ipopt::Number* x_u_;

      /** Ipopt::Index of the constraint */
      const Ipopt::Index constr_index_;

      /** Ipopt::Number of variables appearing in the constraint */
      const Ipopt::Index nvar_constr_;

      /** List of variables appearing on the constraints */
      Ipopt::Index* var_indices_;

      /** Flag indicating if the cut has a lower or upper bound */
      bool lower_bound_;

      /** Flag indicating if we TNLP has been solved successfully */
      bool have_final_bound_;

      /** Final strengthened bound */
      Ipopt::Number strengthened_bound_;

      /** space for original gradient if objective function is handled */
      Ipopt::Number* grad_f_;

      /** Auxilliary method for updating the full x variable */
      void update_x_full(const Ipopt::Number *x);
    };

  public:
    /** @name Constructor/Destructor */
    //@{
    /** Constructor.  It is given a TNLP solver to solve the internal
     *  NLPs. */
    CutStrengthener(Ipopt::SmartPtr<TNLPSolver> tnlp_solver,
		    Ipopt::SmartPtr<Ipopt::OptionsList> options);

    /** Destructor */
    virtual ~CutStrengthener();
    //@}

    /** Method for generating and strenghtening all desired cuts */
    bool ComputeCuts(OsiCuts &cs,
		     TMINLP* tminlp,
		     TMINLP2TNLP* problem,
		     const int gindex, CoinPackedVector& cut,
		     double& cut_lb, double& cut_ub,
		     const double g_val, const double g_lb,
		     const double g_ub,
		     int n, const double* x,
		     double infty);

  private:
    /**@name Default Compiler Generated Methods
     * (Hidden to avoid implicit creation/calling).
     * These methods are not implemented and 
     * we do not want the compiler to implement
     * them for us, so we declare them private
     * and do not define them. This ensures that
     * they will not be implicitly created/called. */
    //@{
    /** Default Constructor */
    CutStrengthener();

    /** Copy Constructor */
    CutStrengthener(const CutStrengthener&);

    /** Overloaded Equals Operator */
    void operator=(const CutStrengthener&);
    //@}

    /** Method for strengthening one cut. */
    bool StrengthenCut(Ipopt::SmartPtr<TMINLP> tminlp /** current TMINLP */,
		       int constr_index /** Ipopt::Index number of the constraint to be strengthened, -1 means objective function */,
		       const CoinPackedVector& row /** Cut to be strengthened */,
		       int n /** Ipopt::Number of variables */,
		       const double* x /** solution from node */,
		       const double* x_l /** Lower bounds for x in which should be valid. */,
		       const double* x_u /** Upper bounds for x in which should be valid. */,
		       double& lb,
		       double& ub);

    /** Method for generating one type of cut (strengthened or disjunctive) */
    bool HandleOneCut(bool is_tight, TMINLP* tminlp,
		      TMINLP2TNLP* problem,
		      const double* minlp_lb,
		      const double* minlp_ub,
		      const int gindex, CoinPackedVector& cut,
		      double& cut_lb, double& cut_ub,
		      int n, const double* x,
		      double infty);

    /** Object for solving the TNLPs */
    Ipopt::SmartPtr<TNLPSolver> tnlp_solver_;

    /** Type of OA cut strengthener */
    int cut_strengthening_type_;
    /** What kind of disjuntion should be done */
    int disjunctive_cut_type_;
    /** verbosity level for OA-related output */
    int oa_log_level_;
  };

} // namespace Ipopt
#endif