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
00163 class MinlpBCP : public RelaxationSolver {
00164 friend class ColumnGenerator;
00165 friend class MinlpNode;
00166 private:
00167 Pointer<dvector> sol_C;
00168 bool sol_C_is_solution;
00169
00173 bool prob_is_convex;
00174
00177 Pointer<MinlpProblem> quad_prob;
00178
00181 vector<Pointer<MinlpProblem> > block_prob;
00184 vector<Pointer<MinlpProblem> > block_convex_prob;
00185
00188 vector<list<ExtremePoint> > ExtremePoints;
00189
00190 vector<Pointer<MinlpProblem> > block_sub_convex_prob;
00191
00192 Pointer<MinlpProblem> sub_convex_prob;
00193
00196 vector<Pointer<MinlpProblem> > lag_problem;
00197
00198 Pointer<ColumnGenerator> colgen;
00199
00201 multimap<double, Pointer<MinlpNode> > bb_tree;
00202
00206 Pointer<MinlpNode> current_node;
00207
00209 double gap_tol;
00210
00212 double bound_impr_tol;
00213
00217 double start_bb();
00218
00221 bool intgrad_cuts;
00222 IntervalGradientCutGenerator intgrad_cutgen;
00223
00224 LinearizedConCutGenerator linconcutgen;
00225
00228 bool mip_cuts;
00229
00230 bool add_sol_candidate(const dvector& x);
00231
00236 int find_sol_candidates(Pointer<MinlpNode> node);
00237
00238 int preswitching(Pointer<MinlpNode> node);
00239
00240 Pointer<LagHeu> lagheu;
00241
00243 void init();
00244
00246 void init_block_problems();
00247
00248 void clean_sub_problems();
00249
00255 pair<list<ExtremePoint>::iterator, bool> add_ExtremePoint(const dvector &w, int k, Pointer<MinlpNode> = NULL);
00256
00259 int init_ExtremePoints(Pointer<MinlpNode> node);
00260
00261 int primal_init_ExtremePoints(const dvector& x, Pointer<MinlpNode> node);
00262
00263
00264 int dual_init_ExtremePoints(Pointer<MinlpNode> node);
00265
00268 void prune_ExtremePoints(multimap<double, Pointer<MinlpNode> >& bb_tree);
00269
00270 void project_ExtremePoints(dvector& x, Pointer<MinlpNode> node);
00271
00272
00273
00274 typedef enum { RMP_bound, NLP_bound, LP_bound, LP_RMP_bound, stop_bound } t_bound_type;
00275 t_bound_type pre_bound_type;
00276 t_bound_type maj_bound_type;
00279 t_bound_type bound_type;
00280
00281 enum { BranchCut } lagsolve_type;
00282
00283 enum { BinSubdiv, CostSubdivLag, CostSubdivNewton, BisectSubdiv, RMPSubdiv, ViolSubdiv } subdiv_type;
00284
00285 int subdiv_discrete_emphasis;
00286
00287 enum { Bound, UnfixedDiscrete } nodeselect_type;
00288 int alternate_bounds;
00289
00290 int upper_bound_effort_level;
00291
00294 int pre_bb_max_iter;
00295
00298 bool lag_cuts;
00299
00302 int max_outerapprox_iter;
00303 int max_outerapprox_root_iter;
00304
00307 int bound_failed;
00308 int bound_computed;
00309 double bound_time;
00310 double init_RMP_time;
00311
00314 int lagprob_solves;
00315
00316 double find_solcand_time;
00317 int nr_solcand_found;
00318
00319 double subdiv_time;
00320
00321 int update_ExtremePoints_count;
00322
00323 Pointer<Timer> timer;
00324 double max_time;
00325
00326 bool is_maxcut;
00327
00328 Pointer<IntervalReduction> intervalreduction;
00329
00332 bool boxreduce(Pointer<MinlpNode> node, int index, IntervalReduction::which_bound_type which_bound);
00333
00336 bool feasibility_check(Pointer<MinlpNode> node);
00337
00338 multimap<double, Pointer<MinlpNode> >::iterator select_node();
00339 multimap<double, Pointer<MinlpNode> >::iterator select_node_bestbound();
00340 multimap<double, Pointer<MinlpNode> >::iterator select_node_worstbound();
00341 multimap<double, Pointer<MinlpNode> >::iterator select_node_unfixeddiscrete_bestbound();
00342 multimap<double, Pointer<MinlpNode> >::iterator select_node_unfixeddiscrete_worstbound();
00343
00344
00345
00350 int set_low_bound(Pointer<MinlpNode> node);
00351
00355 pair<bool, double> improve_bound(Pointer<MinlpNode> node);
00356
00357 int set_NLP_bound(Pointer<MinlpNode> node, bool improve=false);
00358 int set_RMP_bound(Pointer<MinlpNode> node);
00359 int set_LP_bound(Pointer<MinlpNode> node);
00360 int set_LP_RMP_bound(Pointer<MinlpNode> node);
00361 int improve_LP_bound(Pointer<MinlpNode> node, bool is_root=false);
00362
00369 int update_subdiv_bound(int k, int i, Pointer<MinlpNode> node);
00370
00371
00372
00379 int subdivide(list<Pointer<MinlpNode> >& nodes, Pointer<MinlpNode> node);
00380
00382 int bin_subdiv(list<Pointer<MinlpNode> >& nodes, int& subdiv_var, Pointer<MinlpNode> node);
00383
00385 void cost_subdiv(list<Pointer<MinlpNode> >& nodes, int& subdiv_var, Pointer<MinlpNode> node);
00386
00388
00389
00391 void bisect_subdiv(list<Pointer<MinlpNode> >& nodes, int& subdiv_var, Pointer<MinlpNode> node);
00392
00394 void viol_subdiv(list<Pointer<MinlpNode> >& nodes, int& subdiv_var, Pointer<MinlpNode> node);
00395
00397 void rect_subdiv(list<Pointer<MinlpNode> >& nodes, Pointer<MinlpNode> node, int k, int i, double cut);
00398
00401 int nr_subdiv_contvar;
00404 int nr_subdiv_bisect;
00405
00406
00407
00410 void init_lag_problems(Pointer<MinlpNode> node);
00411
00415 void update_lag_problems(const dvector& dual_point);
00416 void update_lag_problem(int k, const dvector& a);
00417
00418 typedef struct LagSolveStatus_s {
00419 set<SolCandidate> solset;
00420 int ret;
00421 int iter;
00422 double lowbound;
00423 double value;
00424 int new_points;
00425 } LagSolveStatus;
00426
00435 void solve_lag_problem(LagSolveStatus& status, int k, Pointer<MinlpNode> node, Pointer<SepQcFunc> temp_cut=NULL);
00436
00437
00438
00441 double conv_rate_cntrl_stopping_rho;
00444 int conv_rate_cntrl_minor_iter;
00447 double conv_rate_cntrl_last_major_val;
00450 double conv_rate_cntrl_last_val;
00453 double conv_rate_cntrl_first_major_val;
00456 double conv_rate_cntrl_max_rel_improvement;
00459 int conv_rate_cntrl_improve_iter;
00460
00466 int conv_rate_check(double val);
00467
00468
00469
00470 int mem_limit;
00471 void mem_check();
00472
00473 public:
00474 MinlpBCP(Pointer<MinlpProblem> orig_prob_, Pointer<MinlpProblem> split_prob_, Pointer<LinearRelax> linear_relax_,
00475 bool is_gams_prob=false, double closeval_tol_=0., Pointer<dvector> diam_=NULL, Pointer<Param> param_=NULL,
00476 Pointer<ostream> out_solver_p_=out_out_p, Pointer<ostream> out_solver_log_p_=out_log_p);
00477
00478 virtual ~MinlpBCP();
00479
00480 void set_quad_relax(Pointer<MinlpProblem> quad_prob_);
00481
00482 void set_convex_prob(Pointer<MinlpProblem> convex_prob_, const Pointer<dvector>& sol_C_=NULL, bool sol_C_is_solution_=false);
00483
00484 void set_reform(Pointer<Reformulation> reform_, Pointer<dvector> sol_C_, bool sol_C_is_solution_);
00485
00486 void set_reform(Pointer<Reformulation> reform_);
00487
00488 void set_linear_relax(Pointer<LinearRelax> linrelax_);
00489
00490 void set_problem_is_convex(bool prob_is_convex_) { prob_is_convex=prob_is_convex_; }
00491
00492 void set_MINLPData(Pointer<MINLPData> minlpdata_);
00493
00494 void set_timer(Pointer<Timer> timer_);
00495
00498 int solve();
00499
00500 int solve(dvector& start);
00501
00502 };
00503
00504 #endif