00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #ifndef __TMINLP_HPP__
00015 #define __TMINLP_HPP__
00016
00017 #include "IpUtils.hpp"
00018 #include "IpReferenced.hpp"
00019 #include "IpException.hpp"
00020 #include "IpAlgTypes.hpp"
00021 #include "CoinPackedMatrix.hpp"
00022 #include "OsiCuts.hpp"
00023 #include "IpTNLP.hpp"
00024 #include "CoinError.hpp"
00025 #include "CoinHelperFunctions.hpp"
00026
00027 namespace Bonmin
00028 {
00029 DECLARE_STD_EXCEPTION(TMINLP_INVALID);
00030 DECLARE_STD_EXCEPTION(TMINLP_INVALID_VARIABLE_BOUNDS);
00031
00059 class TMINLP : public Ipopt::ReferencedObject
00060 {
00061 public:
00062 friend class TMINLP2TNLP;
00064 enum SolverReturn{
00065 SUCCESS,
00066 INFEASIBLE,
00067 CONTINUOUS_UNBOUNDED,
00068 LIMIT_EXCEEDED,
00069 MINLP_ERROR};
00071 struct SosInfo
00072 {
00074 int num;
00076 char * types;
00078 int * priorities;
00079
00083 int numNz;
00085 int * starts;
00087 int * indices;
00089 double * weights;
00092 SosInfo();
00094 SosInfo(const SosInfo & source);
00095
00096
00098 ~SosInfo()
00099 {
00100 gutsOfDestructor();
00101 }
00102
00103
00105 void gutsOfDestructor();
00106
00107 };
00108
00110 struct BranchingInfo
00111 {
00113 int size;
00115 int * priorities;
00117 int * branchingDirections;
00119 double * upPsCosts;
00121 double * downPsCosts;
00122 BranchingInfo():
00123 size(0),
00124 priorities(NULL),
00125 branchingDirections(NULL),
00126 upPsCosts(NULL),
00127 downPsCosts(NULL)
00128 {}
00129 BranchingInfo(const BranchingInfo &other)
00130 {
00131 gutsOfDestructor();
00132 size = other.size;
00133 priorities = CoinCopyOfArray(other.priorities, size);
00134 branchingDirections = CoinCopyOfArray(other.branchingDirections, size);
00135 upPsCosts = CoinCopyOfArray(other.upPsCosts, size);
00136 downPsCosts = CoinCopyOfArray(other.downPsCosts, size);
00137 }
00138 void gutsOfDestructor()
00139 {
00140 if (priorities != NULL) delete [] priorities;
00141 priorities = NULL;
00142 if (branchingDirections != NULL) delete [] branchingDirections;
00143 branchingDirections = NULL;
00144 if (upPsCosts != NULL) delete [] upPsCosts;
00145 upPsCosts = NULL;
00146 if (downPsCosts != NULL) delete [] downPsCosts;
00147 downPsCosts = NULL;
00148 }
00149 ~BranchingInfo()
00150 {
00151 gutsOfDestructor();
00152 }
00153 };
00154
00156 class PerturbInfo
00157 {
00158 public:
00160 PerturbInfo() :
00161 perturb_radius_(NULL)
00162 {}
00163
00165 ~PerturbInfo()
00166 {
00167 delete [] perturb_radius_;
00168 }
00169
00171 void SetPerturbationArray(Ipopt::Index numvars, const double* perturb_radius);
00172
00175 const double* GetPerturbationArray() const {
00176 return perturb_radius_;
00177 }
00178
00179 private:
00181 PerturbInfo(const PerturbInfo & source);
00182
00187 double* perturb_radius_;
00188 };
00189
00191 enum VariableType
00192 {
00193 CONTINUOUS,
00194 BINARY,
00195 INTEGER
00196 };
00197
00200 TMINLP();
00201
00203 virtual ~TMINLP();
00205
00211 virtual bool get_nlp_info(Ipopt::Index& n, Ipopt::Index& m, Ipopt::Index& nnz_jac_g,
00212 Ipopt::Index& nnz_h_lag, Ipopt::TNLP::IndexStyleEnum& index_style)=0;
00213
00221 virtual bool get_scaling_parameters(Ipopt::Number& obj_scaling,
00222 bool& use_x_scaling, Ipopt::Index n,
00223 Ipopt::Number* x_scaling,
00224 bool& use_g_scaling, Ipopt::Index m,
00225 Ipopt::Number* g_scaling)
00226 {
00227 return false;
00228 }
00229
00230
00233 virtual bool get_variables_types(Ipopt::Index n, VariableType* var_types)=0;
00234
00237 virtual bool get_variables_linearity(Ipopt::Index n,
00238 Ipopt::TNLP::LinearityType* var_types) = 0;
00239
00242 virtual bool get_constraints_linearity(Ipopt::Index m,
00243 Ipopt::TNLP::LinearityType* const_types) = 0;
00244
00253 virtual bool get_bounds_info(Ipopt::Index n, Ipopt::Number* x_l, Ipopt::Number* x_u,
00254 Ipopt::Index m, Ipopt::Number* g_l, Ipopt::Number* g_u)=0;
00255
00263 virtual bool get_starting_point(Ipopt::Index n, bool init_x, Ipopt::Number* x,
00264 bool init_z, Ipopt::Number* z_L, Ipopt::Number* z_U,
00265 Ipopt::Index m, bool init_lambda,
00266 Ipopt::Number* lambda)=0;
00267
00269 virtual bool eval_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x,
00270 Ipopt::Number& obj_value)=0;
00271
00274 virtual bool eval_grad_f(Ipopt::Index n, const Ipopt::Number* x, bool new_x,
00275 Ipopt::Number* grad_f)=0;
00276
00278 virtual bool eval_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x,
00279 Ipopt::Index m, Ipopt::Number* g)=0;
00280
00286 virtual bool eval_jac_g(Ipopt::Index n, const Ipopt::Number* x, bool new_x,
00287 Ipopt::Index m, Ipopt::Index nele_jac, Ipopt::Index* iRow,
00288 Ipopt::Index *jCol, Ipopt::Number* values)=0;
00289
00297 virtual bool eval_h(Ipopt::Index n, const Ipopt::Number* x, bool new_x,
00298 Ipopt::Number obj_factor, Ipopt::Index m, const Ipopt::Number* lambda,
00299 bool new_lambda, Ipopt::Index nele_hess,
00300 Ipopt::Index* iRow, Ipopt::Index* jCol, Ipopt::Number* values)=0;
00303 virtual bool eval_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x,
00304 Ipopt::Index i, Ipopt::Number& gi)
00305 {
00306 std::cerr << "Method eval_gi not overloaded from TMINLP\n";
00307 throw -1;
00308 }
00312 virtual bool eval_grad_gi(Ipopt::Index n, const Ipopt::Number* x, bool new_x,
00313 Ipopt::Index i, Ipopt::Index& nele_grad_gi, Ipopt::Index* jCol,
00314 Ipopt::Number* values)
00315 {
00316 std::cerr << "Method eval_grad_gi not overloaded from TMINLP\n";
00317 throw -1;
00318 }
00320
00324 virtual void finalize_solution(TMINLP::SolverReturn status,
00325 Ipopt::Index n, const Ipopt::Number* x, Ipopt::Number obj_value) =0;
00327
00328 virtual const BranchingInfo * branchingInfo() const = 0;
00329
00330 virtual const SosInfo * sosConstraints() const = 0;
00331
00332 virtual const PerturbInfo* perturbInfo() const
00333 {
00334 return NULL;
00335 }
00336
00338 virtual bool hasUpperBoundingObjective(){
00339 return false;}
00340
00343 virtual bool eval_upper_bound_f(Ipopt::Index n, const Ipopt::Number* x,
00344 Ipopt::Number& obj_value){ return false; }
00345
00347 enum Convexity {
00348 Convex,
00349 NonConvex,
00350 SimpleConcave};
00351
00354 struct MarkedNonConvex {
00356 MarkedNonConvex():
00357 cIdx(-1), cRelaxIdx(-1){}
00359 int cIdx;
00361 int cRelaxIdx;};
00365 struct SimpleConcaveConstraint{
00367 SimpleConcaveConstraint():
00368 xIdx(-1), yIdx(-1), cIdx(-1){}
00370 int xIdx;
00372 int yIdx;
00374 int cIdx;};
00376 virtual bool get_constraint_convexities(int m, TMINLP::Convexity * constraints_convexities)const {
00377 CoinFillN(constraints_convexities, m, TMINLP::Convex);
00378 return true;}
00380 virtual bool get_number_nonconvex(int & number_non_conv, int & number_concave) const{
00381 number_non_conv = 0;
00382 number_concave = 0;
00383 return true;}
00385 virtual bool get_constraint_convexities(int number_non_conv, MarkedNonConvex * non_convs) const{
00386 assert(number_non_conv == 0);
00387 return true;}
00389 virtual bool get_simple_concave_constraints(int number_concave, SimpleConcaveConstraint * simple_concave) const{
00390 assert(number_concave == 0);
00391 return true;}
00392
00394 virtual bool hasLinearObjective(){return false;}
00395
00397 bool hasGeneralInteger();
00398 protected:
00402 TMINLP(const TMINLP&);
00403
00405 void operator=(const TMINLP&);
00407
00408 private:
00409 };
00410
00411 }
00412
00413 #endif
00414