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
00108 double violation;
00109
00110 };
00111
00112
00115 class IntervalGradientCutGenerator {
00116 private:
00119 Pointer<MinlpProblem> prob;
00120
00121 vector<Pointer<SparsityInfo> > sparsity;
00122
00123 public:
00124 double min_violation;
00125
00126 IntervalGradientCutGenerator(Pointer<MinlpProblem> prob_=NULL)
00127 : prob(prob_), min_violation(1E-4)
00128 { prob->get_sparsity(sparsity); }
00129
00130 void set_problem(Pointer<MinlpProblem> prob_) { prob=prob_; prob->get_sparsity(sparsity); }
00131
00138 Pointer<IntervalGradientCut> get_cuts(const dvector& x, int k, const dvector& low, const dvector& up);
00139
00140 Pointer<IntervalGradientCut> update_cuts(Pointer<IntervalGradientCut> cut, int k, const dvector& low, const dvector& up) {
00141 return get_cuts(cut->ref_x, k, low, up);
00142 }
00143 };
00144
00145 class CutPool;
00146 class MinlpNode;
00147
00150 template <class CutType> class Cut {
00151 friend class CutPool;
00152
00153
00154 class NodeInfo {
00155 public:
00158 int inactive_time;
00159
00160 NodeInfo()
00161 : inactive_time(0)
00162 { }
00163
00164 NodeInfo(const NodeInfo& cni)
00165 : inactive_time(cni.inactive_time)
00166 { }
00167 };
00168
00169 private:
00172 Pointer<CutType> cut;
00173
00176 map<Pointer<MinlpNode>, NodeInfo> nodes;
00177
00180 bool global;
00183 int inactive_time_global;
00184
00187 bool tagged;
00188
00189 public:
00190 Cut(Pointer<CutType> cut_, Pointer<MinlpNode> node=NULL)
00191 : cut(cut_), global(false), tagged(false), inactive_time_global(0)
00192 { if (node) add_node(node);
00193 else global=true;
00194 }
00195
00196 Cut(const Cut<CutType>& cut_)
00197 : cut(cut_.cut), nodes(cut_.nodes), global(cut_.global), tagged(cut_.tagged), inactive_time_global(cut_.inactive_time_global)
00198 { }
00199
00200 virtual ~Cut();
00201
00202 bool valid(const Pointer<MinlpNode>& node=NULL) const {
00203 return global || (node && nodes.count(node));
00204 }
00205
00206 void add_node(Pointer<MinlpNode> node) {
00207 nodes.insert(pair<Pointer<MinlpNode>, NodeInfo>(node, NodeInfo()));
00208 }
00209
00213 void duplicate_nodeinfo(Pointer<MinlpNode> oldnode, Pointer<MinlpNode> newnode);
00214
00218 bool remove_node(Pointer<MinlpNode> node);
00219
00227 pair<bool, bool> set_inactivetime(Pointer<MinlpNode> node, bool increase, int limit);
00228
00229 const CutType& get_cut() const { return *cut; }
00230 };
00231
00241 class CutPool {
00242 private:
00246 list<Cut<SimpleCut> > simplecuts;
00247
00250 list<Cut<LinearizationCut> > linearizationcuts;
00251
00254 list<Cut<IntervalGradientCut> > intgradcuts;
00255
00258 int cuts_size;
00259
00260 int inactivetime_limit_global;
00261 int inactivetime_limit_local;
00262
00263 public:
00264 typedef enum { SIMPLE, LINEARIZATION, INTERVALGRADIENT } CutType;
00265
00271 class CutInfo {
00272 friend class CutPool;
00273 public:
00276 list<Cut<SimpleCut> >::iterator it_simplecuts;
00277
00280 list<Cut<IntervalGradientCut> >::iterator it_intgradcuts;
00281
00284 list<Cut<LinearizationCut> >::iterator it_linearizationcuts;
00285
00288 CutType type;
00289
00290 int block_nr;
00293 bool inactive;
00296 bool removed;
00297
00300 list<const MIPSolver::RowItem*> rowitems;
00301
00304 list<const MIPSolver::ColItem*> colitems;
00305
00306 CutInfo(list<Cut<SimpleCut> >::iterator& it, int bnr)
00307 : it_simplecuts(it), type(SIMPLE), block_nr(bnr), inactive(false), removed(false)
00308 { }
00309
00310 CutInfo(list<Cut<LinearizationCut> >::iterator& it, int bnr)
00311 : it_linearizationcuts(it), type(LINEARIZATION), block_nr(bnr), inactive(false), removed(false)
00312 { }
00313
00314 CutInfo(list<Cut<IntervalGradientCut> >::iterator& it_intgradcuts_, int bnr)
00315 : it_intgradcuts(it_intgradcuts_), type(INTERVALGRADIENT), block_nr(bnr), inactive(false), removed(false)
00316 { }
00317
00318 pair<bool, bool> set_inactivetime(Pointer<MinlpNode> node, int limit);
00319 };
00320
00321 CutPool(int inactivetime_limit_global_=10, int inactivetime_limit_local_=3)
00322 : inactivetime_limit_global(inactivetime_limit_global_), inactivetime_limit_local(inactivetime_limit_local_), cuts_size(0)
00323 { }
00324
00327 CutPool(const CutPool& cutpool, Pointer<MinlpNode> node=NULL);
00328
00335 CutInfo add_cut(Pointer<SimpleCut>, Pointer<MinlpNode> node, int blocknr=-1);
00336
00343 CutInfo add_cut(Pointer<IntervalGradientCut> intgradcut, Pointer<MinlpNode> node, int blocknr);
00344
00347 CutInfo add_cut(Pointer<LinearizationCut> linearizationcut, Pointer<MinlpNode> node, int blocknr);
00348
00353 void integrate(const CutPool& cutpool, Pointer<MinlpNode> node=NULL);
00354
00355 void duplicate_nodeinfo(Pointer<MinlpNode> oldnode, Pointer<MinlpNode> newnode);
00356
00357 void remove_node(Pointer<MinlpNode> node);
00358
00364 void update_nodeinfo(list<CutInfo>& cutinfos, int block_nr, Pointer<MinlpNode> node);
00365
00371 void get_cuts(list<CutInfo>& cutinfos, int blocknr, Pointer<MinlpNode> node=NULL);
00372
00375 void update_cuts(Pointer<MinlpNode> node, int blocknr, const dvector& low, const dvector& up, IntervalGradientCutGenerator& generator, LinearizedConCutGenerator& linconcutgen);
00376
00380 bool feasible(Pointer<MinlpNode> node, const dvector& x, double tol=1E-4) const;
00381
00385 int nr_local_cuts(Pointer<MinlpNode> node) const;
00389 int nr_global_cuts() const;
00392 int nr_all_cuts() const { return cuts_size; }
00393 };
00394
00395 class LinearizedConCutGenerator {
00396 private:
00397 Pointer<MinlpProblem> prob;
00398
00399 Pointer<MINLPData> minlpdata;
00400
00401 Pointer<Reformulation> reform;
00402
00403 static const double tol;
00404
00405 public:
00409 int max_cuts;
00412 double min_violation;
00413
00416 double max_violation;
00417
00418 LinearizedConCutGenerator(Pointer<MinlpProblem> prob_, Pointer<MINLPData> minlpdata_=NULL, Pointer<Reformulation> reform_=NULL);
00419
00426 LinearizationCut get_cut(const dvector& x, int c, int block_nr, double val=INFINITY);
00427
00428 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);
00429 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);
00437 int get_cuts(list<pair<LinearizationCut, pair<int, bool> > >& cuts, const dvector& x, const dvector& lower, const dvector& upper, bool violated_polyest_only=false);
00438
00443 Pointer<LinearizationCut> update_cut(LinearizationCut& cut, unsigned int block_nr, const dvector& lower, const dvector& upper);
00444
00445 void set_problem(Pointer<MinlpProblem> prob_) { prob=prob_; }
00446 void set_reform(Pointer<Reformulation> reform_);
00447 void set_MINLPData(Pointer<MINLPData> minlpdata_) { minlpdata=minlpdata_; }
00448
00449 };
00450
00451 class LinearRelax;
00452
00453 #endif