00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #ifndef PPL_MIP_Problem_defs_hh
00025 #define PPL_MIP_Problem_defs_hh 1
00026
00027 #include "MIP_Problem.types.hh"
00028 #include "globals.types.hh"
00029 #include "Row.defs.hh"
00030 #include "Matrix.defs.hh"
00031 #include "Linear_Expression.defs.hh"
00032 #include "Constraint.types.hh"
00033 #include "Constraint_System.types.hh"
00034 #include "Generator.defs.hh"
00035 #include "Variables_Set.defs.hh"
00036 #include <vector>
00037 #include <deque>
00038 #include <iosfwd>
00039
00040 namespace Parma_Polyhedra_Library {
00041
00042 namespace IO_Operators {
00043
00045
00046 std::ostream&
00047 operator<<(std::ostream& s, const MIP_Problem& lp);
00048
00049 }
00050
00051 }
00052
00054
00080 class Parma_Polyhedra_Library::MIP_Problem {
00081 public:
00083
00095 explicit MIP_Problem(dimension_type dim = 0);
00096
00133 template <typename In>
00134 MIP_Problem(dimension_type dim,
00135 In first, In last,
00136 const Variables_Set& int_vars,
00137 const Linear_Expression& obj = Linear_Expression::zero(),
00138 Optimization_Mode mode = MAXIMIZATION);
00139
00171 template <typename In>
00172 MIP_Problem(dimension_type dim,
00173 In first, In last,
00174 const Linear_Expression& obj = Linear_Expression::zero(),
00175 Optimization_Mode mode = MAXIMIZATION);
00176
00202 MIP_Problem(dimension_type dim,
00203 const Constraint_System& cs,
00204 const Linear_Expression& obj = Linear_Expression::zero(),
00205 Optimization_Mode mode = MAXIMIZATION);
00206
00208 MIP_Problem(const MIP_Problem& y);
00209
00211 ~MIP_Problem();
00212
00214 MIP_Problem& operator=(const MIP_Problem& y);
00215
00217 static dimension_type max_space_dimension();
00218
00220 dimension_type space_dimension() const;
00221
00226 const Variables_Set& integer_space_dimensions() const;
00227
00228 private:
00230 typedef std::vector<Constraint> Constraint_Sequence;
00231
00232 public:
00237 typedef Constraint_Sequence::const_iterator const_iterator;
00238
00243 const_iterator constraints_begin() const;
00244
00249 const_iterator constraints_end() const;
00250
00252 const Linear_Expression& objective_function() const;
00253
00255 Optimization_Mode optimization_mode() const;
00256
00258
00261 void clear();
00262
00277 void add_space_dimensions_and_embed(dimension_type m);
00278
00287 void add_to_integer_space_dimensions(const Variables_Set& i_vars);
00288
00296 void add_constraint(const Constraint& c);
00297
00306 void add_constraints(const Constraint_System& cs);
00307
00309
00314 void set_objective_function(const Linear_Expression& obj);
00315
00317 void set_optimization_mode(Optimization_Mode mode);
00318
00320
00324 bool is_satisfiable() const;
00325
00327
00332 MIP_Problem_Status solve() const;
00333
00351 void evaluate_objective_function(const Generator& evaluating_point,
00352 Coefficient& num,
00353 Coefficient& den) const;
00354
00356
00360 const Generator& feasible_point() const;
00361
00363
00368 const Generator& optimizing_point() const;
00369
00378 void optimal_value(Coefficient& num, Coefficient& den) const;
00379
00381 bool OK() const;
00382
00383 PPL_OUTPUT_DECLARATIONS
00384
00390 bool ascii_load(std::istream& s);
00391
00393 memory_size_type total_memory_in_bytes() const;
00394
00396 memory_size_type external_memory_in_bytes() const;
00397
00399 void swap(MIP_Problem& y);
00400
00402 enum Control_Parameter_Name {
00404 PRICING
00405 };
00406
00408 enum Control_Parameter_Value {
00410 PRICING_STEEPEST_EDGE_FLOAT,
00412 PRICING_STEEPEST_EDGE_EXACT,
00414 PRICING_TEXTBOOK
00415 };
00416
00418 Control_Parameter_Value
00419 get_control_parameter(Control_Parameter_Name name) const;
00420
00422 void set_control_parameter(Control_Parameter_Value value);
00423
00424 private:
00426 dimension_type external_space_dim;
00427
00432 dimension_type internal_space_dim;
00433
00435 Matrix tableau;
00436
00438 Row working_cost;
00439
00441
00448 std::vector<std::pair<dimension_type, dimension_type> > mapping;
00449
00451 std::vector<dimension_type> base;
00452
00454 enum Status {
00456 UNSATISFIABLE,
00458 SATISFIABLE,
00460 UNBOUNDED,
00462 OPTIMIZED,
00468 PARTIALLY_SATISFIABLE
00469 };
00470
00472 Status status;
00473
00474
00475
00476
00477
00479 Control_Parameter_Value pricing;
00480
00486 bool initialized;
00487
00489 Constraint_Sequence input_cs;
00490
00492 dimension_type first_pending_constraint;
00493
00495 Linear_Expression input_obj_function;
00496
00498 Optimization_Mode opt_mode;
00499
00501 Generator last_generator;
00502
00507 Variables_Set i_variables;
00508
00510 struct RAII_Temporary_Real_Relaxation {
00511 MIP_Problem& lp;
00512 Variables_Set i_vars;
00513
00514 RAII_Temporary_Real_Relaxation(MIP_Problem& mip)
00515 : lp(mip), i_vars() {
00516
00517 std::swap(i_vars, lp.i_variables);
00518 }
00519
00520 ~RAII_Temporary_Real_Relaxation() {
00521
00522 std::swap(i_vars, lp.i_variables);
00523 }
00524 };
00525 friend class RAII_Temporary_Real_Relaxation;
00526
00528
00533 bool process_pending_constraints();
00534
00539 void second_phase();
00540
00554 MIP_Problem_Status
00555 compute_tableau(std::vector<dimension_type>& worked_out_row);
00556
00608 bool parse_constraints(dimension_type& additional_tableau_rows,
00609 dimension_type& additional_slack_variables,
00610 std::deque<bool>& is_tableau_constraint,
00611 std::deque<bool>& is_satisfied_inequality,
00612 std::deque<bool>& is_nonnegative_variable,
00613 std::deque<bool>& is_remergeable_variable) const;
00614
00625 dimension_type
00626 get_exiting_base_index(dimension_type entering_var_index) const;
00627
00629
00643 static void linear_combine(Row& x, const Row& y, const dimension_type k);
00644
00654 void pivot(dimension_type entering_var_index,
00655 dimension_type exiting_base_index);
00656
00666 dimension_type textbook_entering_index() const;
00667
00693 dimension_type steepest_edge_exact_entering_index() const;
00694
00706 dimension_type steepest_edge_float_entering_index() const;
00707
00716 bool compute_simplex_using_exact_pricing();
00717
00727 bool compute_simplex_using_steepest_edge_float();
00728
00745 void erase_artificials(dimension_type begin_artificials,
00746 dimension_type end_artificials);
00747
00748 bool is_in_base(dimension_type var_index,
00749 dimension_type& row_index) const;
00750
00755 void compute_generator() const;
00756
00769 dimension_type merge_split_variable(dimension_type var_index);
00770
00772 static bool is_satisfied(const Constraint& c, const Generator& g);
00773
00775 static bool is_saturated(const Constraint& c, const Generator& g);
00776
00796 static MIP_Problem_Status solve_mip(bool& have_incumbent_solution,
00797 mpq_class& incumbent_solution_value,
00798 Generator& incumbent_solution_point,
00799 MIP_Problem& mip,
00800 const Variables_Set& i_vars);
00801
00805 bool is_lp_satisfiable() const;
00806
00820 static bool is_mip_satisfiable(MIP_Problem& lp,
00821 const Variables_Set& i_vars,
00822 Generator& p);
00823
00838 static bool choose_branching_variable(const MIP_Problem& lp,
00839 const Variables_Set& i_vars,
00840 dimension_type& branching_index);
00841 };
00842
00843 namespace std {
00844
00846
00847 void swap(Parma_Polyhedra_Library::MIP_Problem& x,
00848 Parma_Polyhedra_Library::MIP_Problem& y);
00849
00850 }
00851
00852 #include "MIP_Problem.inlines.hh"
00853 #include "MIP_Problem.templates.hh"
00854
00855 #endif // !defined(PPL_MIP_Problem_defs_hh)