00001
00002
00003
00004
00005
00006
00007 #ifndef BCP_H
00008 #define BCP_H
00009
00010 #include "standard.h"
00011 #include "problem.h"
00012 #include "func.h"
00013 #include "opt.h"
00014 #include "relaxopt.h"
00015 #include "cuts.h"
00016 #include "boxfind.h"
00017
00018 class ExtremePoint : public dvector {
00019 public:
00020 SparseVector<double> rmpcolumn;
00021 double rmpobjcoeff;
00022 const MIPSolver::ColItem* rmpcolitem;
00023
00024 ExtremePoint(const dvector& point)
00025 : dvector(point), rmpcolitem(NULL)
00026 { }
00027
00028 ExtremePoint(const dvector& point, Pointer<LinearRelax> linear_relax, int k)
00029 : dvector(point), rmpcolitem(NULL)
00030 { set_rmpdata(linear_relax, k);
00031 }
00032
00033 void set_rmpdata(Pointer<LinearRelax> linear_relax, int k);
00034 };
00035
00036 #include "node.h"
00037
00038 class ColumnGenerator;
00039 class LagHeu;
00040
00158 class MinlpBCP : public RelaxationSolver {
00159 friend class ColumnGenerator;
00160 friend class MinlpNode;
00161 private:
00162 Pointer<dvector> sol_C;
00163 bool sol_C_is_solution;
00164
00168 bool prob_is_convex;
00169
00172 Pointer<MinlpProblem> quad_prob;
00173
00176 vector<Pointer<MinlpProblem> > block_prob;
00179 vector<Pointer<MinlpProblem> > block_convex_prob;
00180
00183 vector<list<ExtremePoint> > ExtremePoints;
00184
00185 vector<Pointer<MinlpProblem> > block_sub_convex_prob;
00186
00187 Pointer<MinlpProblem> sub_convex_prob;
00188
00191 vector<Pointer<MinlpProblem> > lag_problem;
00192
00193 Pointer<ColumnGenerator> colgen;
00194
00196 multimap<double, Pointer<MinlpNode> > bb_tree;
00197
00201 Pointer<MinlpNode> current_node;
00202
00204 double gap_tol;
00205
00207 double bound_impr_tol;
00208
00212 double start_bb();
00213
00216 bool intgrad_cuts;
00217 IntervalGradientCutGenerator intgrad_cutgen;
00218
00219 LinearizedConCutGenerator linconcutgen;
00220
00223 bool mip_cuts;
00224
00225 bool add_sol_candidate(const dvector& x);
00226
00231 int find_sol_candidates(Pointer<MinlpNode> node);
00232
00233 int preswitching(Pointer<MinlpNode> node);
00234
00235 Pointer<LagHeu> lagheu;
00236
00238 void init();
00239
00241 void init_block_problems();
00242
00243 void clean_sub_problems();
00244
00250 pair<list<ExtremePoint>::iterator, bool> add_ExtremePoint(const dvector &w, int k, Pointer<MinlpNode> = NULL);
00251
00254 int init_ExtremePoints(Pointer<MinlpNode> node);
00255
00256 int primal_init_ExtremePoints(const dvector& x, Pointer<MinlpNode> node);
00257
00258
00259 int dual_init_ExtremePoints(Pointer<MinlpNode> node);
00260
00263 void prune_ExtremePoints(multimap<double, Pointer<MinlpNode> >& bb_tree);
00264
00265 void project_ExtremePoints(dvector& x, Pointer<MinlpNode> node);
00266
00267
00268
00269 typedef enum { RMP_bound, NLP_bound, LP_bound, LP_RMP_bound, stop_bound } t_bound_type;
00270 t_bound_type pre_bound_type;
00271 t_bound_type maj_bound_type;
00274 t_bound_type bound_type;
00275
00276 enum { BranchCut } lagsolve_type;
00277
00278 enum { BinSubdiv, CostSubdivLag, CostSubdivNewton, BisectSubdiv, RMPSubdiv, ViolSubdiv } subdiv_type;
00279
00280 int subdiv_discrete_emphasis;
00281
00282 enum { BestBound, UnfixedDiscrete } nodeselect_type;
00283
00284 int upper_bound_effort_level;
00285
00288 int pre_bb_max_iter;
00289
00292 bool lag_cuts;
00293
00296 int bound_failed;
00297 int bound_computed;
00298 double bound_time;
00299 double init_RMP_time;
00300
00303 int lagprob_solves;
00304
00305 double find_solcand_time;
00306 int nr_solcand_found;
00307
00308 double subdiv_time;
00309
00310 int update_ExtremePoints_count;
00311
00312 Pointer<Timer> timer;
00313 double max_time;
00314
00315 bool is_maxcut;
00316
00317 Pointer<IntervalReduction> intervalreduction;
00318
00321 bool boxreduce(Pointer<MinlpNode> node, int index, IntervalReduction::which_bound_type which_bound);
00322
00325 bool feasibility_check(Pointer<MinlpNode> node);
00326
00327 multimap<double, Pointer<MinlpNode> >::iterator select_node();
00328
00329
00330
00335 int set_low_bound(Pointer<MinlpNode> node);
00336
00340 pair<bool, double> improve_bound(Pointer<MinlpNode> node);
00341
00342 int set_NLP_bound(Pointer<MinlpNode> node, bool improve=false);
00343 int set_RMP_bound(Pointer<MinlpNode> node);
00344 int set_LP_bound(Pointer<MinlpNode> node);
00345 int set_LP_RMP_bound(Pointer<MinlpNode> node);
00346 int improve_LP_bound(Pointer<MinlpNode> node);
00347
00354 int update_subdiv_bound(int k, int i, Pointer<MinlpNode> node);
00355
00356
00357
00364 int subdivide(list<Pointer<MinlpNode> >& nodes, Pointer<MinlpNode> node);
00365
00367 int bin_subdiv(list<Pointer<MinlpNode> >& nodes, int& subdiv_var, Pointer<MinlpNode> node);
00368
00370 void cost_subdiv(list<Pointer<MinlpNode> >& nodes, int& subdiv_var, Pointer<MinlpNode> node);
00371
00373
00374
00376 void bisect_subdiv(list<Pointer<MinlpNode> >& nodes, int& subdiv_var, Pointer<MinlpNode> node);
00377
00379 void viol_subdiv(list<Pointer<MinlpNode> >& nodes, int& subdiv_var, Pointer<MinlpNode> node);
00380
00382 void rect_subdiv(list<Pointer<MinlpNode> >& nodes, Pointer<MinlpNode> node, int k, int i, double cut);
00383
00386 int nr_subdiv_contvar;
00389 int nr_subdiv_bisect;
00390
00391
00392
00395 void init_lag_problems(Pointer<MinlpNode> node);
00396
00400 void update_lag_problems(const dvector& dual_point);
00401 void update_lag_problem(int k, const dvector& a);
00402
00403 typedef struct LagSolveStatus_s {
00404 set<SolCandidate> solset;
00405 int ret;
00406 int iter;
00407 double lowbound;
00408 double value;
00409 int new_points;
00410 } LagSolveStatus;
00411
00420 void solve_lag_problem(LagSolveStatus& status, int k, Pointer<MinlpNode> node, Pointer<SepQcFunc> temp_cut=NULL);
00421
00422
00423
00426 double conv_rate_cntrl_stopping_rho;
00429 int conv_rate_cntrl_minor_iter;
00432 double conv_rate_cntrl_last_major_val;
00435 double conv_rate_cntrl_last_val;
00438 double conv_rate_cntrl_first_major_val;
00441 double conv_rate_cntrl_max_rel_improvement;
00444 int conv_rate_cntrl_improve_iter;
00445
00451 int conv_rate_check(double val);
00452
00453
00454
00455 int mem_limit;
00456 void mem_check();
00457
00458 public:
00459 MinlpBCP(Pointer<MinlpProblem> orig_prob_, Pointer<MinlpProblem> split_prob_, Pointer<LinearRelax> linear_relax_,
00460 bool is_gams_prob=false, double closeval_tol_=0., Pointer<dvector> diam_=NULL, Pointer<Param> param_=NULL,
00461 Pointer<ostream> out_solver_p_=out_out_p, Pointer<ostream> out_solver_log_p_=out_log_p);
00462
00463 virtual ~MinlpBCP();
00464
00465 void set_quad_relax(Pointer<MinlpProblem> quad_prob_);
00466
00467 void set_convex_prob(Pointer<MinlpProblem> convex_prob_, const Pointer<dvector>& sol_C_=NULL, bool sol_C_is_solution_=false);
00468
00469 void set_reform(Pointer<Reformulation> reform_, Pointer<dvector> sol_C_, bool sol_C_is_solution_);
00470
00471 void set_reform(Pointer<Reformulation> reform_);
00472
00473 void set_linear_relax(Pointer<LinearRelax> linrelax_);
00474
00475 void set_problem_is_convex(bool prob_is_convex_) { prob_is_convex=prob_is_convex_; }
00476
00477 void set_MINLPData(Pointer<MINLPData> minlpdata_);
00478
00479 void set_timer(Pointer<Timer> timer_);
00480
00483 int solve();
00484
00485 int solve(dvector& start);
00486
00487 };
00488
00489 #endif