1 /* PIP_Tree_Node class declaration. 2 Copyright (C) 2001-2010 Roberto Bagnara <bagnara@cs.unipr.it> 3 Copyright (C) 2010-2016 BUGSENG srl (http://bugseng.com) 4 5 This file is part of the Parma Polyhedra Library (PPL). 6 7 The PPL is free software; you can redistribute it and/or modify it 8 under the terms of the GNU General Public License as published by the 9 Free Software Foundation; either version 3 of the License, or (at your 10 option) any later version. 11 12 The PPL is distributed in the hope that it will be useful, but WITHOUT 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 for more details. 16 17 You should have received a copy of the GNU General Public License 18 along with this program; if not, write to the Free Software Foundation, 19 Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1307, USA. 20 21 For the most up-to-date information see the Parma Polyhedra Library 22 site: http://bugseng.com/products/ppl/ . */ 23 24 #ifndef PPL_PIP_Tree_defs_hh 25 #define PPL_PIP_Tree_defs_hh 1 26 27 #include "PIP_Tree_types.hh" 28 #include "Variable_defs.hh" 29 #include "Linear_Expression_types.hh" 30 #include "Constraint_System_defs.hh" 31 #include "Constraint_System_inlines.hh" 32 #include "Constraint_defs.hh" 33 #include "Variables_Set_defs.hh" 34 #include "globals_defs.hh" 35 #include "PIP_Problem_defs.hh" 36 37 #include "Matrix_defs.hh" 38 #include "Dense_Row_defs.hh" 39 #include "Sparse_Row_defs.hh" 40 41 namespace Parma_Polyhedra_Library { 42 43 //! A node of the PIP solution tree. 44 /*! 45 This is the base class for the nodes of the binary trees representing 46 the solutions of PIP problems. From this one, two classes are derived: 47 - PIP_Decision_Node, for the internal nodes of the tree; 48 - PIP_Solution_Node, for the leaves of the tree. 49 */ 50 class PIP_Tree_Node { 51 protected: 52 //! Constructor: builds a node owned by \p *owner. 53 explicit PIP_Tree_Node(const PIP_Problem* owner); 54 55 //! Copy constructor. 56 PIP_Tree_Node(const PIP_Tree_Node& y); 57 58 //! Returns a pointer to the PIP_Problem owning object. 59 const PIP_Problem* get_owner() const; 60 61 //! Sets the pointer to the PIP_Problem owning object. 62 virtual void set_owner(const PIP_Problem* owner) = 0; 63 64 /*! \brief 65 Returns \c true if and only if all the nodes in the subtree 66 rooted in \p *this are owned by \p *owner. 67 */ 68 virtual bool check_ownership(const PIP_Problem* owner) const = 0; 69 70 public: 71 #if PPL_USE_SPARSE_MATRIX 72 typedef Sparse_Row Row; 73 #else 74 typedef Dense_Row Row; 75 #endif 76 77 //! Returns a pointer to a dynamically-allocated copy of \p *this. 78 virtual PIP_Tree_Node* clone() const = 0; 79 80 //! Destructor. 81 virtual ~PIP_Tree_Node(); 82 83 //! Returns \c true if and only if \p *this is well formed. 84 virtual bool OK() const = 0; 85 86 //! Returns \p this if \p *this is a solution node, 0 otherwise. 87 virtual const PIP_Solution_Node* as_solution() const = 0; 88 89 //! Returns \p this if \p *this is a decision node, 0 otherwise. 90 virtual const PIP_Decision_Node* as_decision() const = 0; 91 92 /*! \brief 93 Returns the system of parameter constraints controlling \p *this. 94 95 The indices in the constraints are the same as the original variables and 96 parameters. Coefficients in indices corresponding to variables always are 97 zero. 98 */ 99 const Constraint_System& constraints() const; 100 101 class Artificial_Parameter; 102 103 //! A type alias for a sequence of Artificial_Parameter's. 104 typedef std::vector<Artificial_Parameter> Artificial_Parameter_Sequence; 105 106 //! Returns a const_iterator to the beginning of local artificial parameters. 107 Artificial_Parameter_Sequence::const_iterator art_parameter_begin() const; 108 109 //! Returns a const_iterator to the end of local artificial parameters. 110 Artificial_Parameter_Sequence::const_iterator art_parameter_end() const; 111 112 //! Returns the number of local artificial parameters. 113 dimension_type art_parameter_count() const; 114 115 //! Prints on \p s the tree rooted in \p *this. 116 /*! 117 \param s 118 The output stream. 119 120 \param indent 121 The amount of indentation. 122 */ 123 void print(std::ostream& s, int indent = 0) const; 124 125 //! Dumps to \p s an ASCII representation of \p *this. 126 void ascii_dump(std::ostream& s) const; 127 128 /*! \brief 129 Loads from \p s an ASCII representation (as produced by 130 ascii_dump(std::ostream&) const) and sets \p *this accordingly. 131 Returns <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise. 132 */ 133 bool ascii_load(std::istream& s); 134 135 //! Returns the total size in bytes of the memory occupied by \p *this. 136 virtual memory_size_type total_memory_in_bytes() const = 0; 137 //! Returns the size in bytes of the memory managed by \p *this. 138 virtual memory_size_type external_memory_in_bytes() const = 0; 139 140 protected: 141 //! A type alias for a sequence of constraints. 142 typedef std::vector<Constraint> Constraint_Sequence; 143 144 // Only PIP_Problem and PIP_Decision_Node are allowed to use the 145 // constructor and methods. 146 friend class PIP_Problem; 147 friend class PIP_Decision_Node; 148 friend class PIP_Solution_Node; 149 150 //! A pointer to the PIP_Problem object owning this node. 151 const PIP_Problem* owner_; 152 153 //! A pointer to the parent of \p *this, null if \p *this is the root. 154 const PIP_Decision_Node* parent_; 155 156 //! The local system of parameter constraints. 157 Constraint_System constraints_; 158 159 //! The local sequence of expressions for local artificial parameters. 160 Artificial_Parameter_Sequence artificial_parameters; 161 162 //! Returns a pointer to this node's parent. 163 const PIP_Decision_Node* parent() const; 164 165 //! Set this node's parent to \p *p. 166 void set_parent(const PIP_Decision_Node* p); 167 168 /*! \brief 169 Populates the parametric simplex tableau using external data. 170 171 \param pip 172 The PIP_Problem object containing this node. 173 174 \param external_space_dim 175 The number of all problem variables and problem parameters 176 (excluding artificial parameters). 177 178 \param first_pending_constraint 179 The first element in \p input_cs to be added to the tableau, 180 which already contains the previous elements. 181 182 \param input_cs 183 All the constraints of the PIP problem. 184 185 \param parameters 186 The set of indices of the problem parameters. 187 */ 188 virtual void update_tableau(const PIP_Problem& pip, 189 dimension_type external_space_dim, 190 dimension_type first_pending_constraint, 191 const Constraint_Sequence& input_cs, 192 const Variables_Set& parameters) = 0; 193 194 /*! \brief 195 Executes a parametric simplex on the tableau, under specified context. 196 197 \return 198 The root of the PIP tree solution, or 0 if unfeasible. 199 200 \param pip 201 The PIP_Problem object containing this node. 202 203 \param check_feasible_context 204 Whether the resolution process should (re-)check feasibility of 205 context (since the initial context may have been modified). 206 207 \param context 208 The context, being a set of constraints on the parameters. 209 210 \param params 211 The local parameter set, including parent's artificial parameters. 212 213 \param space_dim 214 The space dimension of parent, including artificial parameters. 215 216 \param indent_level 217 The indentation level (for debugging output only). 218 */ 219 virtual PIP_Tree_Node* solve(const PIP_Problem& pip, 220 bool check_feasible_context, 221 const Matrix<Row>& context, 222 const Variables_Set& params, 223 dimension_type space_dim, 224 int indent_level) = 0; 225 226 //! Inserts a new parametric constraint in internal row format. 227 void add_constraint(const Row& row, const Variables_Set& parameters); 228 229 //! Merges parent's artificial parameters into \p *this. 230 void parent_merge(); 231 232 //! Prints on \p s the tree rooted in \p *this. 233 /*! 234 \param s 235 The output stream. 236 237 \param indent 238 The amount of indentation. 239 240 \param pip_dim_is_param 241 A vector of Boolean flags telling which PIP problem dimensions are 242 problem parameters. The size of the vector is equal to the PIP 243 problem internal space dimension (i.e., no artificial parameters). 244 245 \param first_art_dim 246 The first space dimension corresponding to an artificial parameter 247 that was created in this node (if any). 248 */ 249 virtual void print_tree(std::ostream& s, 250 int indent, 251 const std::vector<bool>& pip_dim_is_param, 252 dimension_type first_art_dim) const = 0; 253 254 //! A helper function used when printing PIP trees. 255 static void 256 indent_and_print(std::ostream& s, int indent, const char* str); 257 258 /*! \brief 259 Checks whether a context matrix is satisfiable. 260 261 The satisfiability check is implemented by the revised dual simplex 262 algorithm on the context matrix. The algorithm ensures the feasible 263 solution is integer by applying a cut generation method when 264 intermediate non-integer solutions are found. 265 */ 266 static bool compatibility_check(Matrix<Row>& s); 267 268 /*! \brief 269 Helper method: checks for satisfiability of the restricted context 270 obtained by adding \p row to \p context. 271 */ 272 static bool compatibility_check(const Matrix<Row>& context, const Row& row); 273 274 }; // class PIP_Tree_Node 275 276 277 /*! \brief 278 Artificial parameters in PIP solution trees. 279 280 These parameters are built from a linear expression combining other 281 parameters (constant term included) divided by a positive integer 282 denominator. Coefficients at variables indices corresponding to 283 PIP problem variables are always zero. 284 */ 285 class PIP_Tree_Node::Artificial_Parameter 286 : public Linear_Expression { 287 public: 288 //! Default constructor: builds a zero artificial parameter. 289 Artificial_Parameter(); 290 291 //! Constructor. 292 /*! 293 Builds artificial parameter \f$\frac{\mathtt{expr}}{\mathtt{d}}\f$. 294 295 \param expr 296 The expression that, after normalization, will form the numerator of 297 the artificial parameter. 298 299 \param d 300 The integer constant that, after normalization, will form the 301 denominator of the artificial parameter. 302 303 \exception std::invalid_argument 304 Thrown if \p d is zero. 305 306 Normalization will ensure that the denominator is positive. 307 */ 308 Artificial_Parameter(const Linear_Expression& expr, 309 Coefficient_traits::const_reference d); 310 311 //! Copy constructor. 312 Artificial_Parameter(const Artificial_Parameter& y); 313 314 //! Returns the normalized (i.e., positive) denominator. 315 Coefficient_traits::const_reference denominator() const; 316 317 //! Swaps \p *this with \p y. 318 void m_swap(Artificial_Parameter& y); 319 320 //! Returns \c true if and only if \p *this and \p y are equal. 321 /*! 322 Note that two artificial parameters having different space dimensions 323 are considered to be different. 324 */ 325 bool operator==(const Artificial_Parameter& y) const; 326 //! Returns \c true if and only if \p *this and \p y are different. 327 bool operator!=(const Artificial_Parameter& y) const; 328 329 PPL_OUTPUT_DECLARATIONS 330 331 /*! \brief 332 Loads from \p s an ASCII representation (as produced by 333 ascii_dump(std::ostream&) const) and sets \p *this accordingly. 334 Returns <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise. 335 */ 336 bool ascii_load(std::istream& s); 337 338 //! Returns the total size in bytes of the memory occupied by \p *this. 339 memory_size_type total_memory_in_bytes() const; 340 //! Returns the size in bytes of the memory managed by \p *this. 341 memory_size_type external_memory_in_bytes() const; 342 343 //! Returns \c true if and only if the parameter is well-formed. 344 bool OK() const; 345 346 private: 347 //! The normalized (i.e., positive) denominator. 348 Coefficient denom; 349 }; // class PIP_Tree_Node::Artificial_Parameter 350 351 352 //! Swaps \p x with \p y. 353 /*! \relates PIP_Tree_Node::Artificial_Parameter */ 354 void 355 swap(PIP_Tree_Node::Artificial_Parameter& x, 356 PIP_Tree_Node::Artificial_Parameter& y); 357 358 359 //! A tree node representing part of the space of solutions. 360 class PIP_Solution_Node : public PIP_Tree_Node { 361 public: 362 363 //! Constructor: builds a solution node owned by \p *owner. 364 explicit PIP_Solution_Node(const PIP_Problem* owner); 365 366 //! Returns a pointer to a dynamically-allocated copy of \p *this. 367 virtual PIP_Tree_Node* clone() const; 368 369 //! Destructor. 370 virtual ~PIP_Solution_Node(); 371 372 //! Returns \c true if and only if \p *this is well formed. 373 virtual bool OK() const; 374 375 //! Returns \p this. 376 virtual const PIP_Solution_Node* as_solution() const; 377 378 //! Returns 0, since \p this is not a decision node. 379 virtual const PIP_Decision_Node* as_decision() const; 380 381 /*! \brief 382 Returns a parametric expression for the values of problem variable \p var. 383 384 The returned linear expression may involve problem parameters 385 as well as artificial parameters. 386 387 \param var 388 The problem variable which is queried about. 389 390 \exception std::invalid_argument 391 Thrown if \p var is dimension-incompatible with the PIP_Problem 392 owning this solution node, or if \p var is a problem parameter. 393 */ 394 const Linear_Expression& parametric_values(Variable var) const; 395 396 //! Dumps to \p os an ASCII representation of \p *this. 397 void ascii_dump(std::ostream& os) const; 398 399 /*! \brief 400 Loads from \p is an ASCII representation (as produced by 401 ascii_dump(std::ostream&) const) and sets \p *this accordingly. 402 Returns <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise. 403 */ 404 bool ascii_load(std::istream& is); 405 406 //! Returns the total size in bytes of the memory occupied by \p *this. 407 virtual memory_size_type total_memory_in_bytes() const; 408 //! Returns the size in bytes of the memory managed by \p *this. 409 virtual memory_size_type external_memory_in_bytes() const; 410 411 private: 412 //! The type for parametric simplex tableau. 413 struct Tableau { 414 //! The matrix of simplex coefficients. 415 Matrix<Row> s; 416 //! The matrix of parameter coefficients. 417 Matrix<Row> t; 418 //! A common denominator for all matrix elements 419 Coefficient denom; 420 421 //! Default constructor. 422 Tableau(); 423 //! Copy constructor. 424 Tableau(const Tableau& y); 425 //! Destructor. 426 ~Tableau(); 427 428 //! Tests whether the matrix is integer, i.e., the denominator is 1. 429 bool is_integer() const; 430 431 //! Multiplies all coefficients and denominator with ratio. 432 void scale(Coefficient_traits::const_reference ratio); 433 434 //! Normalizes the modulo of coefficients so that they are mutually prime. 435 /*! 436 Computes the Greatest Common Divisor (GCD) among the elements of 437 the matrices and normalizes them and the denominator by the GCD itself. 438 */ 439 void normalize(); 440 441 /*! \brief 442 Compares two pivot row and column pairs before pivoting. 443 444 The algorithm searches the first (ie, leftmost) column \f$k\f$ in 445 parameter matrix for which the \f$c=s_{*j}\frac{t_{ik}}{s_{ij}}\f$ 446 and \f$c'=s_{*j'}\frac{t_{i'k}}{s_{i'j'}}\f$ columns are different, 447 where \f$s_{*j}\f$ denotes the \f$j\f$<sup>th</sup> column from the 448 \f$s\f$ matrix and \f$s_{*j'}\f$ is the \f$j'\f$<sup>th</sup> column 449 of \f$s\f$. 450 451 \f$c\f$ is the computed column that would be subtracted to column 452 \f$k\f$ in parameter matrix if pivoting is done using the \f$(i,j)\f$ 453 row and column pair. 454 \f$c'\f$ is the computed column that would be subtracted to column 455 \f$k\f$ in parameter matrix if pivoting is done using the 456 \f$(i',j')\f$ row and column pair. 457 458 The test is true if the computed \f$-c\f$ column is lexicographically 459 bigger than the \f$-c'\f$ column. Due to the column ordering in the 460 parameter matrix of the tableau, leftmost search will enforce solution 461 increase with respect to the following priority order: 462 - the constant term 463 - the coefficients for the original parameters 464 - the coefficients for the oldest artificial parameters. 465 466 \return 467 \c true if pivot row and column pair \f$(i,j)\f$ is more 468 suitable for pivoting than the \f$(i',j')\f$ pair 469 470 \param mapping 471 The PIP_Solution_Node::mapping vector for the tableau. 472 473 \param basis 474 The PIP_Solution_Node::basis vector for the tableau. 475 476 \param row_0 477 The row number for the first pivot row and column pair to be compared. 478 479 \param col_0 480 The column number for the first pivot row and column pair to be 481 compared. 482 483 \param row_1 484 The row number for the second pivot row and column pair to be compared. 485 486 \param col_1 487 The column number for the second pivot row and column pair to be 488 compared. 489 */ 490 bool is_better_pivot(const std::vector<dimension_type>& mapping, 491 const std::vector<bool>& basis, 492 const dimension_type row_0, 493 const dimension_type col_0, 494 const dimension_type row_1, 495 const dimension_type col_1) const; 496 497 //! Returns the value of the denominator. 498 Coefficient_traits::const_reference denominator() const; 499 500 //! Dumps to \p os an ASCII representation of \p *this. 501 void ascii_dump(std::ostream& os) const; 502 503 /*! \brief 504 Loads from \p is an ASCII representation (as produced by 505 ascii_dump(std::ostream&) const) and sets \p *this accordingly. 506 Returns \c true if successful, \c false otherwise. 507 */ 508 bool ascii_load(std::istream& is); 509 510 //! Returns the size in bytes of the memory managed by \p *this. 511 /*! 512 \note 513 No need for a \c total_memory_in_bytes() method, since 514 class Tableau is a private inner class of PIP_Solution_Node. 515 */ 516 memory_size_type external_memory_in_bytes() const; 517 518 //! Returns \c true if and only if \p *this is well formed. 519 bool OK() const; 520 }; // struct Tableau 521 522 //! The parametric simplex tableau. 523 Tableau tableau; 524 525 /*! \brief 526 A boolean vector for identifying the basic variables. 527 528 Variable identifiers are numbered from 0 to <CODE>n+m-1</CODE>, where \p n 529 is the number of columns in the simplex tableau corresponding to variables, 530 and \p m is the number of rows. 531 532 Indices from 0 to <CODE>n-1</CODE> correspond to the original variables. 533 534 Indices from \p n to <CODE>n+m-1</CODE> correspond to the slack variables 535 associated to the internal constraints, which do not strictly correspond 536 to original constraints, since these may have been transformed to fit the 537 standard form of the dual simplex. 538 539 The value for <CODE>basis[i]</CODE> is: 540 - \b true if variable \p i is basic, 541 - \b false if variable \p i is nonbasic. 542 */ 543 std::vector<bool> basis; 544 545 /*! \brief 546 A mapping between the tableau rows/columns and the original variables. 547 548 The value of <CODE>mapping[i]</CODE> depends of the value of <CODE>basis[i]</CODE>. 549 550 - If <CODE>basis[i]</CODE> is \b true, <CODE>mapping[i]</CODE> encodes the column 551 index of variable \p i in the \p s matrix of the tableau. 552 - If <CODE>basis[i]</CODE> is \b false, <CODE>mapping[i]</CODE> encodes the row 553 index of variable \p i in the tableau. 554 */ 555 std::vector<dimension_type> mapping; 556 557 /*! \brief 558 The variable identifiers associated to the rows of the simplex tableau. 559 */ 560 std::vector<dimension_type> var_row; 561 562 /*! \brief 563 The variable identifiers associated to the columns of the simplex tableau. 564 */ 565 std::vector<dimension_type> var_column; 566 567 /*! \brief 568 The variable number of the special inequality used for modeling 569 equality constraints. 570 571 The subset of equality constraints in a specific problem can be expressed 572 as: \f$f_i(x,p) = 0 ; 1 \leq i \leq n\f$. As the dual simplex standard form 573 requires constraints to be inequalities, the following constraints can be 574 modeled as follows: 575 576 - \f$f_i(x,p) \geq 0 ; 1 \leq i \leq n\f$ 577 578 - \f$\sum\limits_{i=1}^n f_i(x,p) \leq 0\f$ 579 580 The \p special_equality_row value stores the variable number of the 581 specific constraint which is used to model the latter sum of 582 constraints. If no such constraint exists, the value is set to \p 0. 583 */ 584 dimension_type special_equality_row; 585 586 /*! \brief 587 The column index in the parametric part of the simplex tableau 588 corresponding to the big parameter; \c not_a_dimension() if not set. 589 */ 590 dimension_type big_dimension; 591 592 //! The possible values for the sign of a parametric linear expression. 593 enum Row_Sign { 594 //! Not computed yet (default). 595 UNKNOWN, 596 //! All row coefficients are zero. 597 ZERO, 598 //! All nonzero row coefficients are positive. 599 POSITIVE, 600 //! All nonzero row coefficients are negative. 601 NEGATIVE, 602 //! The row contains both positive and negative coefficients. 603 MIXED 604 }; 605 606 //! A cache for computed sign values of constraint parametric RHS. 607 std::vector<Row_Sign> sign; 608 609 //! Parametric values for the solution. 610 std::vector<Linear_Expression> solution; 611 612 //! An indicator for solution validity. 613 bool solution_valid; 614 615 //! Returns the sign of row \p x. 616 static Row_Sign row_sign(const Row& x, 617 dimension_type big_dimension); 618 619 protected: 620 //! Copy constructor. 621 PIP_Solution_Node(const PIP_Solution_Node& y); 622 623 //! A tag type to select the alternative copy constructor. 624 struct No_Constraints {}; 625 626 //! Alternative copy constructor. 627 /*! 628 This constructor differs from the default copy constructor in that 629 it will not copy the constraint system, nor the artificial parameters. 630 */ 631 PIP_Solution_Node(const PIP_Solution_Node& y, No_Constraints); 632 633 // PIP_Problem::ascii load() method needs access set_owner(). 634 friend bool PIP_Problem::ascii_load(std::istream& s); 635 636 //! Sets the pointer to the PIP_Problem owning object. 637 virtual void set_owner(const PIP_Problem* owner); 638 639 /*! \brief 640 Returns \c true if and only if all the nodes in the subtree 641 rooted in \p *this is owned by \p *pip. 642 */ 643 virtual bool check_ownership(const PIP_Problem* owner) const; 644 645 //! Implements pure virtual method PIP_Tree_Node::update_tableau. 646 virtual void update_tableau(const PIP_Problem& pip, 647 dimension_type external_space_dim, 648 dimension_type first_pending_constraint, 649 const Constraint_Sequence& input_cs, 650 const Variables_Set& parameters); 651 652 /*! \brief 653 Update the solution values. 654 655 \param pip_dim_is_param 656 A vector of Boolean flags telling which PIP problem dimensions are 657 problem parameters. The size of the vector is equal to the PIP 658 problem internal space dimension (i.e., no artificial parameters). 659 */ 660 void update_solution(const std::vector<bool>& pip_dim_is_param) const; 661 662 //! Helper method. 663 void update_solution() const; 664 665 //! Implements pure virtual method PIP_Tree_Node::solve. 666 virtual PIP_Tree_Node* solve(const PIP_Problem& pip, 667 bool check_feasible_context, 668 const Matrix<Row>& context, 669 const Variables_Set& params, 670 dimension_type space_dim, 671 int indent_level); 672 673 /*! \brief 674 Generate a Gomory cut using non-integer tableau row \p index. 675 676 \param index 677 Row index in simplex tableau from which the cut is generated. 678 679 \param parameters 680 A std::set of the current parameter dimensions (including artificials); 681 to be updated if a new artificial parameter is to be created. 682 683 \param context 684 A set of linear inequalities on the parameters, in matrix form; to be 685 updated if a new artificial parameter is to be created. 686 687 \param space_dimension 688 The current space dimension, including variables and all parameters; to 689 be updated if an extra parameter is to be created. 690 691 \param indent_level 692 The indentation level (for debugging output only). 693 */ 694 void generate_cut(dimension_type index, Variables_Set& parameters, 695 Matrix<Row>& context, dimension_type& space_dimension, 696 int indent_level); 697 698 //! Prints on \p s the tree rooted in \p *this. 699 virtual void print_tree(std::ostream& s, int indent, 700 const std::vector<bool>& pip_dim_is_param, 701 dimension_type first_art_dim) const; 702 703 }; // class PIP_Solution_Node 704 705 706 //! A tree node representing a decision in the space of solutions. 707 class PIP_Decision_Node : public PIP_Tree_Node { 708 public: 709 //! Returns a pointer to a dynamically-allocated copy of \p *this. 710 virtual PIP_Tree_Node* clone() const; 711 712 //! Destructor. 713 virtual ~PIP_Decision_Node(); 714 715 //! Returns \c true if and only if \p *this is well formed. 716 virtual bool OK() const; 717 718 //! Returns \p this. 719 virtual const PIP_Decision_Node* as_decision() const; 720 721 //! Returns 0, since \p this is not a solution node. 722 virtual const PIP_Solution_Node* as_solution() const; 723 724 //! Returns a const pointer to the \p b (true or false) branch of \p *this. 725 const PIP_Tree_Node* child_node(bool b) const; 726 727 //! Returns a pointer to the \p b (true or false) branch of \p *this. 728 PIP_Tree_Node* child_node(bool b); 729 730 //! Dumps to \p s an ASCII representation of \p *this. 731 void ascii_dump(std::ostream& s) const; 732 733 /*! \brief 734 Loads from \p s an ASCII representation (as produced by 735 ascii_dump(std::ostream&) const) and sets \p *this accordingly. 736 Returns <CODE>true</CODE> if successful, <CODE>false</CODE> otherwise. 737 */ 738 bool ascii_load(std::istream& s); 739 740 //! Returns the total size in bytes of the memory occupied by \p *this. 741 virtual memory_size_type total_memory_in_bytes() const; 742 //! Returns the size in bytes of the memory managed by \p *this. 743 virtual memory_size_type external_memory_in_bytes() const; 744 745 private: 746 // PIP_Solution_Node is allowed to use the constructor and methods. 747 friend class PIP_Solution_Node; 748 749 // PIP_Problem ascii load method needs access to private constructors. 750 friend bool PIP_Problem::ascii_load(std::istream& s); 751 752 //! Pointer to the "false" child of \p *this. 753 PIP_Tree_Node* false_child; 754 755 //! Pointer to the "true" child of \p *this. 756 PIP_Tree_Node* true_child; 757 758 /*! \brief 759 Builds a decision node having \p fcp and \p tcp as child. 760 761 The decision node will encode the structure 762 "if \c cs then \p tcp else \p fcp", 763 where the system of constraints \c cs is initially empty. 764 765 \param owner 766 Pointer to the owning PIP_Problem object; it may be null if and 767 only if both children are null. 768 769 \param fcp 770 Pointer to "false" child; it may be null. 771 772 \param tcp 773 Pointer to "true" child; it may be null. 774 775 \note 776 If any of \p fcp or \p tcp is not null, then \p owner is required 777 to be not null and equal to the owner of its non-null children; 778 otherwise the behavior is undefined. 779 */ 780 explicit PIP_Decision_Node(const PIP_Problem* owner, 781 PIP_Tree_Node* fcp, 782 PIP_Tree_Node* tcp); 783 784 //! Sets the pointer to the PIP_Problem owning object. 785 virtual void set_owner(const PIP_Problem* owner); 786 787 /*! \brief 788 Returns \c true if and only if all the nodes in the subtree 789 rooted in \p *this is owned by \p *pip. 790 */ 791 virtual bool check_ownership(const PIP_Problem* owner) const; 792 793 protected: 794 //! Copy constructor. 795 PIP_Decision_Node(const PIP_Decision_Node& y); 796 797 //! Implements pure virtual method PIP_Tree_Node::update_tableau. 798 virtual void update_tableau(const PIP_Problem& pip, 799 dimension_type external_space_dim, 800 dimension_type first_pending_constraint, 801 const Constraint_Sequence& input_cs, 802 const Variables_Set& parameters); 803 804 //! Implements pure virtual method PIP_Tree_Node::solve. 805 virtual PIP_Tree_Node* solve(const PIP_Problem& pip, 806 bool check_feasible_context, 807 const Matrix<Row>& context, 808 const Variables_Set& params, 809 dimension_type space_dim, 810 int indent_level); 811 812 //! Prints on \p s the tree rooted in \p *this. 813 virtual void print_tree(std::ostream& s, int indent, 814 const std::vector<bool>& pip_dim_is_param, 815 dimension_type first_art_dim) const; 816 817 }; // class PIP_Decision_Node 818 819 namespace IO_Operators { 820 821 //! Output operator: prints the solution tree rooted in \p x. 822 /*! \relates Parma_Polyhedra_Library::PIP_Tree_Node */ 823 std::ostream& operator<<(std::ostream& os, const PIP_Tree_Node& x); 824 825 //! Output operator. 826 /*! \relates Parma_Polyhedra_Library::PIP_Tree_Node::Artificial_Parameter */ 827 std::ostream& operator<<(std::ostream& os, 828 const PIP_Tree_Node::Artificial_Parameter& x); 829 830 } // namespace IO_Operators 831 832 } // namespace Parma_Polyhedra_Library 833 834 #include "PIP_Tree_inlines.hh" 835 836 #endif // !defined(PPL_PIP_Tree_defs_hh) 837