00001
00002
00003
00004
00005
00006
00007 #ifndef CUTS_H
00008 #define CUTS_H
00009
00010 #include "standard.h"
00011 #include "opt.h"
00012 #include "MINLPData.h"
00013
00017 class IntervalGradientCut {
00018 public:
00019 class ConstraintInfo {
00020 public:
00022 double c;
00024 Pointer<UserVector<double> > b_x;
00025 Pointer<UserVector<double> > b_w;
00026 Pointer<UserVector<double> > b_z;
00027
00028 ConstraintInfo(const Pointer<UserVector<double> >& b_x_, const Pointer<UserVector<double> >& b_w_, const Pointer<UserVector<double> >& b_z_, double c_)
00029 : b_x(b_x_), b_w(b_w_), b_z(b_z_), c(c_)
00030 { }
00031 };
00032
00035 list<ConstraintInfo> coninfos;
00038 int coninfos_size;
00039
00042 dvector ref_x;
00045 dvector w_z_up;
00048 ivector indices;
00049
00050 IntervalGradientCut(const dvector& ref_x_, const dvector& w_z_up_, const ivector& indices_)
00051 : ref_x(ref_x_), w_z_up(w_z_up_), indices(indices_), coninfos_size(0)
00052 { }
00053 };
00054
00055
00056 class SimpleCut {
00057 friend ostream& operator<<(ostream& out, const SimpleCut& cut);
00058 public:
00059 Pointer<UserVector<double> > coeff;
00060 double constant;
00061
00062 SimpleCut()
00063 : constant(0.)
00064 { }
00065
00066 SimpleCut(const Pointer<UserVector<double> >& coeff_, double constant_)
00067 : coeff(coeff_), constant(constant_)
00068 { }
00069
00070 bool feasible(const dvector& x, double tol) const {
00071 return 2*(*coeff*x)+constant<tol;
00072 }
00073
00076 void scale(double max_coeff=100.);
00077 };
00078
00079 class LinearizationCut : public SimpleCut {
00080 public:
00081 LinearizationCut()
00082 : objcon_nr(-2), derived_from_lower_part(true)
00083 { }
00084
00085 LinearizationCut(const Pointer<UserVector<double> >& coeff_, double constant_)
00086 : SimpleCut(coeff_, constant_), objcon_nr(-2), derived_from_lower_part(true)
00087 { }
00088
00089 LinearizationCut(const Pointer<UserVector<double> >& coeff_, double constant_, int objcon_nr_, bool derived_from_lower_part_, const dvector& x_, double t_)
00090 : SimpleCut(coeff_, constant_), objcon_nr(objcon_nr_), derived_from_lower_part(derived_from_lower_part_), x(x_), t_value(t_)
00091 { }
00092
00095 int objcon_nr;
00098 bool derived_from_lower_part;
00101 dvector x;
00104 double t_value;
00105
00106 };
00107
00108
00111 class IntervalGradientCutGenerator {
00112 private:
00115 Pointer<MinlpProblem> prob;
00116
00117 vector<Pointer<SparsityInfo> > sparsity;
00118
00119 public:
00120 IntervalGradientCutGenerator(Pointer<MinlpProblem> prob_=NULL)
00121 : prob(prob_)
00122 { prob->get_sparsity(sparsity); }
00123
00124 void set_problem(Pointer<MinlpProblem> prob_) { prob=prob_; prob->get_sparsity(sparsity); }
00125
00132 Pointer<IntervalGradientCut> get_cuts(const dvector& x, int k, const dvector& low, const dvector& up);
00133
00134 Pointer<IntervalGradientCut> update_cuts(Pointer<IntervalGradientCut> cut, int k, const dvector& low, const dvector& up) {
00135 return get_cuts(cut->ref_x, k, low, up);
00136 }
00137 };
00138
00139 class CutPool;
00140 class MinlpNode;
00141
00144 template <class CutType> class Cut {
00145 friend class CutPool;
00146
00147
00148 class NodeInfo {
00149 public:
00152 int inactive_time;
00153
00154 NodeInfo()
00155 : inactive_time(0)
00156 { }
00157
00158 NodeInfo(const NodeInfo& cni)
00159 : inactive_time(cni.inactive_time)
00160 { }
00161 };
00162
00163 private:
00166 Pointer<CutType> cut;
00167
00170 map<Pointer<MinlpNode>, NodeInfo> nodes;
00171
00174 bool global;
00177 int inactive_time_global;
00178
00181 bool tagged;
00182
00183 public:
00184 Cut(Pointer<CutType> cut_, Pointer<MinlpNode> node=NULL)
00185 : cut(cut_), global(false), tagged(false), inactive_time_global(0)
00186 { if (node) add_node(node);
00187 else global=true;
00188 }
00189
00190 Cut(const Cut<CutType>& cut_)
00191 : cut(cut_.cut), nodes(cut_.nodes), global(cut_.global), tagged(cut_.tagged), inactive_time_global(cut_.inactive_time_global)
00192 { }
00193
00194 virtual ~Cut();
00195
00196 bool valid(const Pointer<MinlpNode>& node=NULL) const {
00197 return global || (node && nodes.count(node));
00198 }
00199
00200 void add_node(Pointer<MinlpNode> node) {
00201 nodes.insert(pair<Pointer<MinlpNode>, NodeInfo>(node, NodeInfo()));
00202 }
00203
00207 void duplicate_nodeinfo(Pointer<MinlpNode> oldnode, Pointer<MinlpNode> newnode);
00208
00212 bool remove_node(Pointer<MinlpNode> node);
00213
00221 pair<bool, bool> set_inactivetime(Pointer<MinlpNode> node, bool increase, int limit);
00222
00223 const CutType& get_cut() const { return *cut; }
00224 };
00225
00235 class CutPool {
00236 private:
00240 list<Cut<SimpleCut> > simplecuts;
00241
00244 list<Cut<LinearizationCut> > linearizationcuts;
00245
00248 list<Cut<IntervalGradientCut> > intgradcuts;
00249
00252 int cuts_size;
00253
00254 int inactivetime_limit_global;
00255 int inactivetime_limit_local;
00256
00257 public:
00258 typedef enum { SIMPLE, LINEARIZATION, INTERVALGRADIENT } CutType;
00259
00265 class CutInfo {
00266 friend class CutPool;
00267 public:
00270 list<Cut<SimpleCut> >::iterator it_simplecuts;
00271
00274 list<Cut<IntervalGradientCut> >::iterator it_intgradcuts;
00275
00278 list<Cut<LinearizationCut> >::iterator it_linearizationcuts;
00279
00282 CutType type;
00283
00284 int block_nr;
00287 bool inactive;
00290 bool removed;
00291
00294 list<const MIPSolver::RowItem*> rowitems;
00295
00298 list<const MIPSolver::ColItem*> colitems;
00299
00300 CutInfo(list<Cut<SimpleCut> >::iterator& it, int bnr)
00301 : it_simplecuts(it), type(SIMPLE), block_nr(bnr), inactive(false), removed(false)
00302 { }
00303
00304 CutInfo(list<Cut<LinearizationCut> >::iterator& it, int bnr)
00305 : it_linearizationcuts(it), type(LINEARIZATION), block_nr(bnr), inactive(false), removed(false)
00306 { }
00307
00308 CutInfo(list<Cut<IntervalGradientCut> >::iterator& it_intgradcuts_, int bnr)
00309 : it_intgradcuts(it_intgradcuts_), type(INTERVALGRADIENT), block_nr(bnr), inactive(false), removed(false)
00310 { }
00311
00312 pair<bool, bool> set_inactivetime(Pointer<MinlpNode> node, int limit);
00313 };
00314
00315 CutPool(int inactivetime_limit_global_=10, int inactivetime_limit_local_=3)
00316 : inactivetime_limit_global(inactivetime_limit_global_), inactivetime_limit_local(inactivetime_limit_local_), cuts_size(0)
00317 { }
00318
00321 CutPool(const CutPool& cutpool, Pointer<MinlpNode> node=NULL);
00322
00329 CutInfo add_cut(Pointer<SimpleCut>, Pointer<MinlpNode> node, int blocknr=-1);
00330
00337 CutInfo add_cut(Pointer<IntervalGradientCut> intgradcut, Pointer<MinlpNode> node, int blocknr);
00338
00341 CutInfo add_cut(Pointer<LinearizationCut> linearizationcut, Pointer<MinlpNode> node, int blocknr);
00342
00347 void integrate(const CutPool& cutpool, Pointer<MinlpNode> node=NULL);
00348
00349 void duplicate_nodeinfo(Pointer<MinlpNode> oldnode, Pointer<MinlpNode> newnode);
00350
00351 void remove_node(Pointer<MinlpNode> node);
00352
00358 void update_nodeinfo(list<CutInfo>& cutinfos, int block_nr, Pointer<MinlpNode> node);
00359
00365 void get_cuts(list<CutInfo>& cutinfos, int blocknr, Pointer<MinlpNode> node=NULL);
00366
00369 void update_cuts(Pointer<MinlpNode> node, int blocknr, const dvector& low, const dvector& up, IntervalGradientCutGenerator& generator, LinearizedConCutGenerator& linconcutgen);
00370
00374 bool feasible(Pointer<MinlpNode> node, const dvector& x, double tol=1E-4) const;
00375
00379 int nr_local_cuts(Pointer<MinlpNode> node) const;
00383 int nr_global_cuts() const;
00386 int nr_all_cuts() const { return cuts_size; }
00387 };
00388
00389 class LinearizedConCutGenerator {
00390 private:
00391 Pointer<MinlpProblem> prob;
00392
00393 Pointer<MINLPData> minlpdata;
00394
00395 Pointer<Reformulation> reform;
00396
00397 static const double tol;
00398
00399 public:
00402 double max_violation;
00403
00404 LinearizedConCutGenerator(Pointer<MinlpProblem> prob_, Pointer<MINLPData> minlpdata_=NULL, Pointer<Reformulation> reform_=NULL);
00405
00412 LinearizationCut get_cut(const dvector& x, int c, int block_nr, double val=INFINITY);
00413
00414 int get_cuts(list<pair<LinearizationCut, pair<int, bool> > >& cuts, const MINLPData::ObjCon& objcon, int objcon_nr, const dvector& x, const dvector& lower, const dvector& upper, bool violated_polyest_only=false);
00415 int get_cuts(list<pair<LinearizationCut, pair<int, bool> > >& cuts, const MINLPData::Constraint& objcon, int objcon_nr, const dvector& x, const dvector& lower, const dvector& upper, bool violated_polyest_only=false);
00423 int get_cuts(list<pair<LinearizationCut, pair<int, bool> > >& cuts, const dvector& x, const dvector& lower, const dvector& upper, bool violated_polyest_only=false);
00424
00429 Pointer<LinearizationCut> update_cut(LinearizationCut& cut, unsigned int block_nr, const dvector& lower, const dvector& upper);
00430
00431 void set_problem(Pointer<MinlpProblem> prob_) { prob=prob_; }
00432 void set_reform(Pointer<Reformulation> reform_);
00433 void set_MINLPData(Pointer<MINLPData> minlpdata_) { minlpdata=minlpdata_; }
00434
00435 };
00436
00437 class LinearRelax;
00438
00439 #endif