00001
00002
00003
00004
00005
00006
00007 #ifndef LINRELAX_H
00008 #define LINRELAX_H
00009
00010 #include "standard.h"
00011 #include "problem.h"
00012 #include "cuts.h"
00013 #include "boxfind.h"
00014
00015 class MinlpNode;
00016 class LinearRelaxSolver;
00017 class LinearRelaxSolverGeneral;
00018 class LinearRelaxSolverMIP;
00019
00043 class LinearRelax {
00044 friend class LinearRelaxSolverGeneral;
00045 friend class LinearRelaxSolverMIP;
00046 friend ostream& operator<<(ostream& out, LinearRelax& linrelax);
00047 public:
00050 class LinConstraint {
00051 friend ostream& operator<<(ostream& out, const LinConstraint& lincon);
00052 public:
00053 vector<Pointer<UserVector<double> > > b;
00054 double c;
00057 bool eq;
00058 Pointer<char> name;
00059
00060 LinConstraint(vector<Pointer<UserVector<double> > >& b_, double c_, bool eq_, Pointer<char> name_=NULL)
00061 : b(b_), c(c_), eq(eq_), name(name_)
00062 { }
00063
00064 LinConstraint(Pointer<UserVector<double> > b_, double c_, bool eq_, Pointer<char> name_=NULL)
00065 : b(1, b_), c(c_), eq(eq_), name(name_)
00066 { }
00067
00068 LinConstraint(const LinConstraint& lincon)
00069 : b(lincon.b), c(lincon.c), eq(lincon.eq), name(lincon.name)
00070 { }
00071 };
00072
00073 private:
00076 Pointer<Param> param;
00077
00080 int max_cutsnr;
00081
00084 int inactivetime_limit_global;
00085 int inactivetime_limit_local;
00086
00087 vector<Pointer<CutPool> > cutpool;
00088
00091 Pointer<CutPool> cutpoolcoupling;
00092
00095 dvector lower, upper;
00096
00099 vector<int> i_discr;
00100
00101 Pointer<LinearRelaxSolver> solver;
00102
00106 MinlpNode* solver_node;
00107
00111 list<LinConstraint>::iterator levelcut_pos;
00112
00122 bool box_reduce(pair<double,double>& newbox, const pair<double,double>& oldbox, int k, int i, bool discrete=false, bool unknown_only=false);
00123
00124 public:
00127 Pointer<SepQcFunc> obj;
00131 vector<list<LinConstraint> > block_con;
00134 list<LinConstraint> couple_con;
00138 int core_size() const;
00139
00140 set<pair<int, int> > boxreduce_reduced_integer;
00141
00144 LinearRelax(Pointer<Param> param_);
00145
00151 LinearRelax(const LinearRelax& linrelax, int k, Pointer<MinlpNode> node=NULL, Pointer<SepQcFunc> alt_obj=NULL);
00152
00155 void init(Pointer<MinlpProblem> convex_prob, const vector<int>& i_discr, Pointer<dvector> feas_point=NULL, bool is_feas=true);
00156
00159 void add_level_cut(double level);
00162 void update_level_cut(double newlevel);
00163
00167 void add_cut(const Pointer<SimpleCut>& cut, int k, const Pointer<MinlpNode>& node=NULL);
00168
00171 void add_cut(const Pointer<SimpleCut>& cut, const Pointer<MinlpNode>& node=NULL) {
00172 add_cut(cut, -1, node);
00173 }
00174
00175 void add_cut(const Pointer<LinearizationCut>& cut, int k, const Pointer<MinlpNode>& node=NULL);
00176
00180 void add_cut(Pointer<IntervalGradientCut> intgradcut, int k, Pointer<MinlpNode> node=NULL);
00181
00185 void integrate(LinearRelax& linrelax, int k, Pointer<MinlpNode> node=NULL);
00186
00189 void get_cuts(list<CutPool::CutInfo>& cutinfos, Pointer<MinlpNode> node=NULL);
00190
00191 void update_cuts(Pointer<MinlpNode> node, int k, IntervalGradientCutGenerator& generator, LinearizedConCutGenerator& linconcutgen);
00192
00195 double get_upper_bound();
00196
00197 bool cutlimit_reached() const { return nr_all_cuts()>=max_cutsnr; }
00198
00201 int nr_local_cuts(Pointer<MinlpNode> node) const;
00204 int nr_global_cuts() const;
00207 int nr_all_cuts() const;
00208
00211 void remove_node(Pointer<MinlpNode> node);
00212
00213 void duplicate_nodeinfo(Pointer<MinlpNode> oldnode, Pointer<MinlpNode> newnode);
00214
00217 void clear_solver();
00221 bool feasible(Pointer<MinlpNode> node, double tol=1E-4);
00222
00226 bool point_feasible(Pointer<MinlpNode> node, const dvector& x, double tol=1E-4) const;
00227
00235 int solve(dvector& sol_point, double& value, Pointer<MinlpNode> node, dvector* dual_point=NULL, double tol=1E-4);
00236
00245 double box_reduce(Pointer<MinlpNode> node, int k, const vector<bool>& discr, bool unknown_only=false, set<pair<int, IntervalReduction::which_bound_type> >* changed_var=NULL, double min_impr=0.01);
00253 double box_reduce(Pointer<MinlpNode> node, const vector<bool>& discr, bool unknown_only=false, set<pair<int, IntervalReduction::which_bound_type> >* changed_var=NULL, double min_impr=0.01);
00254 double box_reduce(dvector& newlow, dvector& newup, const vector<bool>& discr, bool unknown_only=false, set<pair<int, IntervalReduction::which_bound_type> >* changed_var=NULL, double min_impr=0.01);
00255
00256 void set_box(const dvector& lower_, const dvector& upper_) {
00257 lower=lower_;
00258 upper=upper_;
00259 }
00260
00261 int generate_cuts(Pointer<MinlpNode> node);
00262 };
00263
00268 class LinearRelaxSolver : public Solver {
00269 protected:
00270 LinearRelax& linrelax;
00271
00272 public:
00273 list<CutPool::CutInfo> cutinfos;
00274
00277 dvector duals;
00278
00279 LinearRelaxSolver(LinearRelax& linrelax_);
00280
00281 virtual ~LinearRelaxSolver();
00282
00285 virtual void init()=0;
00286
00289 virtual void reset()=0;
00290
00293 virtual void construct(Pointer<MinlpNode> node=NULL)=0;
00294
00297
00298
00299 virtual void add_cut(const CutPool::CutInfo& cutinfo)=0;
00300
00301 virtual void set_objective(Pointer<SepQcFunc> obj)=0;
00302
00303 virtual void update_levelcut(double newlevel)=0;
00304
00307 virtual bool feasible()=0;
00308
00309 virtual int solve(Pointer<MinlpNode> node)=0;
00310
00313 virtual void remove_cuts()=0;
00314
00315 int solve();
00316
00317 using Solver::solve;
00318
00319 virtual int generate_cuts(list<Pointer<SimpleCut> >& cuts)=0;
00320 };
00321
00324 class LinearRelaxSolverGeneral : public LinearRelaxSolver {
00325 private:
00334 Pointer<MinlpProblem> prob;
00335
00339 int cutstart;
00342 int levelcut_pos;
00343
00344 public:
00345 LinearRelaxSolverGeneral(LinearRelax& linrelax_)
00346 : LinearRelaxSolver(linrelax_), cutstart(0), levelcut_pos(-1)
00347 { tol=1E-4;
00348 init();
00349 }
00350
00351 void init();
00352
00353 void reset();
00354
00355 void construct(Pointer<MinlpNode> node=NULL);
00356
00357 void add_cut(const CutPool::CutInfo& cutinfo);
00358
00359 void set_objective(Pointer<SepQcFunc> obj);
00360
00361 void update_levelcut(double newlevel);
00362
00363 bool feasible();
00364
00365 int solve(Pointer<MinlpNode> node=NULL);
00366
00367 using LinearRelaxSolver::solve;
00368
00369 void remove_cuts();
00370
00371 int generate_cuts(list<Pointer<SimpleCut> >& cuts) { return 0; }
00372 };
00373
00374 class LinearRelaxSolverMIP : public LinearRelaxSolver {
00375 private:
00378 MipProblem mip;
00379
00380 Pointer<MIPSolver> solver;
00381
00382 int levelcut_pos;
00383
00386 int intervalgradcutvars_start;
00387
00388 void add_intervalgradientcut(CutPool::CutInfo& cutinfo);
00389
00390 public:
00391 LinearRelaxSolverMIP(LinearRelax& linrelax_);
00392 void init();
00393
00394 void reset();
00395
00396 void construct(Pointer<MinlpNode> node=NULL);
00397
00398 void add_cut(const CutPool::CutInfo& cutinfo);
00399
00400 void set_objective(Pointer<SepQcFunc> obj);
00401
00402 void update_levelcut(double newlevel);
00403
00404 bool feasible();
00405
00406 int solve(Pointer<MinlpNode> node=NULL);
00407
00408 using LinearRelaxSolver::solve;
00409
00410 void remove_cuts();
00411
00412 int generate_cuts(list<Pointer<SimpleCut> >& cuts);
00413 };
00414
00415 #endif