A Parametric Integer (linear) Programming problem. More...
#include <PIP_Problem.defs.hh>

Public Types | |
| enum | Control_Parameter_Name { CUTTING_STRATEGY, PIVOT_ROW_STRATEGY, CONTROL_PARAMETER_NAME_SIZE } |
Possible names for PIP_Problem control parameters. More... | |
| enum | Control_Parameter_Value { CUTTING_STRATEGY_FIRST, CUTTING_STRATEGY_DEEPEST, CUTTING_STRATEGY_ALL, PIVOT_ROW_STRATEGY_FIRST, PIVOT_ROW_STRATEGY_MAX_COLUMN, CONTROL_PARAMETER_VALUE_SIZE } |
Possible values for PIP_Problem control parameters. More... | |
| typedef Constraint_Sequence::const_iterator | const_iterator |
| A type alias for the read-only iterator on the constraints defining the feasible region. | |
Public Member Functions | |
| PIP_Problem (dimension_type dim=0) | |
| Builds a trivial PIP problem. | |
| template<typename In > | |
| PIP_Problem (dimension_type dim, In first, In last, const Variables_Set &p_vars) | |
Builds a PIP problem having space dimension dim from the sequence of constraints in the range ; those dimensions whose indices occur in p_vars are interpreted as parameters. | |
| PIP_Problem (const PIP_Problem &y) | |
| Ordinary copy-constructor. | |
| ~PIP_Problem () | |
| Destructor. | |
| PIP_Problem & | operator= (const PIP_Problem &y) |
| Assignment operator. | |
| dimension_type | space_dimension () const |
| Returns the space dimension of the PIP problem. | |
| const Variables_Set & | parameter_space_dimensions () const |
| Returns a set containing all the variables' indexes representing the parameters of the PIP problem. | |
| const_iterator | constraints_begin () const |
| Returns a read-only iterator to the first constraint defining the feasible region. | |
| const_iterator | constraints_end () const |
| Returns a past-the-end read-only iterator to the sequence of constraints defining the feasible region. | |
| void | clear () |
Resets *this to be equal to the trivial PIP problem. | |
| void | add_space_dimensions_and_embed (dimension_type m_vars, dimension_type m_params) |
Adds m_vars + m_params new space dimensions and embeds the old PIP problem in the new vector space. | |
| void | add_to_parameter_space_dimensions (const Variables_Set &p_vars) |
Sets the space dimensions whose indexes which are in set p_vars to be parameter space dimensions. | |
| void | add_constraint (const Constraint &c) |
Adds a copy of constraint c to the PIP problem. | |
| void | add_constraints (const Constraint_System &cs) |
Adds a copy of the constraints in cs to the PIP problem. | |
| bool | is_satisfiable () const |
Checks satisfiability of *this. | |
| PIP_Problem_Status | solve () const |
| Optimizes the PIP problem. | |
| PIP_Tree | solution () const |
Returns a feasible solution for *this, if it exists. | |
| PIP_Tree | optimizing_solution () const |
Returns an optimizing solution for *this, if it exists. | |
| bool | OK () const |
| Checks if all the invariants are satisfied. | |
| void | print_solution (std::ostream &s, unsigned indent=0) const |
Prints on s the solution computed for *this. | |
| void | ascii_dump () const |
Writes to std::cerr an ASCII representation of *this. | |
| void | ascii_dump (std::ostream &s) const |
Writes to s an ASCII representation of *this. | |
| void | print () const |
Prints *this to std::cerr using operator<<. | |
| bool | ascii_load (std::istream &s) |
Loads from s an ASCII representation (as produced by ascii_dump(std::ostream&) const) and sets *this accordingly. Returns true if successful, false otherwise. | |
| memory_size_type | total_memory_in_bytes () const |
Returns the total size in bytes of the memory occupied by *this. | |
| memory_size_type | external_memory_in_bytes () const |
Returns the size in bytes of the memory managed by *this. | |
| void | swap (PIP_Problem &y) |
Swaps *this with y. | |
| Control_Parameter_Value | get_control_parameter (Control_Parameter_Name name) const |
Returns the value of control parameter name. | |
| void | set_control_parameter (Control_Parameter_Value value) |
Sets control parameter value. | |
| void | set_big_parameter_dimension (dimension_type big_dim) |
Sets the dimension for the big parameter to big_dim. | |
| dimension_type | get_big_parameter_dimension () const |
| Returns the space dimension for the big parameter. | |
Static Public Member Functions | |
| static dimension_type | max_space_dimension () |
| Returns the maximum space dimension a PIP_Problem can handle. | |
Private Types | |
| enum | Status { UNSATISFIABLE, OPTIMIZED, PARTIALLY_SATISFIABLE } |
An enumerated type describing the internal status of the PIP problem. More... | |
| typedef std::vector< Constraint > | Constraint_Sequence |
| A type alias for a sequence of constraints. | |
Private Member Functions | |
| void | control_parameters_init () |
| Initializes the control parameters with default values. | |
| void | control_parameters_copy (const PIP_Problem &y) |
Copies the control parameters from problem object y. | |
Private Attributes | |
| dimension_type | external_space_dim |
| The dimension of the vector space. | |
| dimension_type | internal_space_dim |
The space dimension of the current (partial) solution of the PIP problem; it may be smaller than external_space_dim. | |
| Status | status |
| The internal state of the MIP problem. | |
| PIP_Tree_Node * | current_solution |
| The current solution decision tree. | |
| Constraint_Sequence | input_cs |
| The sequence of constraints describing the feasible region. | |
| dimension_type | first_pending_constraint |
| The first index of `input_cs' containing a pending constraint. | |
| Variables_Set | parameters |
| A set containing all the indices of space dimensions that are interpreted as problem parameters. | |
| Matrix | initial_context |
| The initial context. | |
| Control_Parameter_Value | control_parameters [CONTROL_PARAMETER_NAME_SIZE] |
| The control parameters for the problem object. | |
| dimension_type | big_parameter_dimension |
The dimension for the big parameter, or not_a_dimension() if not set. | |
Friends | |
| class | PIP_Solution_Node |
Related Functions | |
(Note that these are not member functions.) | |
| std::ostream & | operator<< (std::ostream &s, const PIP_Problem &p) |
| Output operator. | |
| void | swap (Parma_Polyhedra_Library::PIP_Problem &x, Parma_Polyhedra_Library::PIP_Problem &y) |
Specializes std::swap. | |
A Parametric Integer (linear) Programming problem.
An object of this class encodes a parametric integer (linear) programming problem. The PIP problem is specified by providing:
Note that all problem variables and problem parameters are assumed to take non-negative integer values, so that there is no need to specify non-negativity constraints.
The class provides support for the (incremental) solution of the PIP problem based on variations of the revised simplex method and on Gomory cut generation techniques.
The solution for a PIP problem is the lexicographic minimum of the integer points of the feasible region, expressed in terms of the parameters. As the problem to be solved only involves non-negative variables and parameters, the problem will always be either unfeasible or optimizable.
As the feasibility and the solution value of a PIP problem depend on the values of the parameters, the solution is a binary decision tree, dividing the context parameter set into subsets. The tree nodes are of two kinds:
It may happen that a decision node has no false child. This means that there is no solution if at least one of the corresponding constraints is not satisfied. Decision nodes having two or more linear tests on the parameters cannot have a false child. Decision nodes always have a true child.
Both kinds of tree nodes may also contain the definition of extra parameters which are artificially introduced by the solver to enforce an integral solution. Such artificial parameters are defined by the integer division of a linear expression on the parameters by an integer coefficient.
By exploiting the incremental nature of the solver, it is possible to reuse part of the computational work already done when solving variants of a given PIP_Problem: currently, incremental resolution supports the addition of space dimensions, the addition of parameters and the addition of constraints.
3*j >= -2*i+8 j <= 4*i - 4 i <= n j <= m
i and j are the problem variables and n and m are the problem parameters. This problem can be optimized; the resulting solution tree may be represented as follows:
if 7*n >= 10 then
if 7*m >= 12 then
{i = 2 ; j = 2}
else
Parameter P = (m) div 2
if 2*n + 3*m >= 8 then
{i = -m - P + 4 ; j = m}
else
_|_
else
_|_
7*n >= 10. If this constraint is satisfied by the values assigned to the problem parameters, then the (textually first) then branch is taken, reaching the true child of the root node (which in this case is another decision node); otherwise, the (textually last) else branch is taken, for which there is no corresponding false child.
notation, also called bottom, denotes the lexicographic minimum of an empty set of solutions, here meaning the corresponding subproblem is unfeasible. P in the (textually first) else branch above. These artificial parameters are only meaningful inside the subtree where they are defined and are used to define the parametric values of the problem variables in solution nodes (e.g., the {i,j} vector in the textually third then branch).m >= n n >= 5
{i = 2 ; j = 2}
Variable i(0); Variable j(1); Variable n(2); Variable m(3); Variables_Set params(n, m); Constraint_System cs; cs.insert(3*j >= -2*i+8); cs.insert(j <= 4*i - 4); cs.insert(j <= m); cs.insert(i <= n); PIP_Problem pip(cs.space_dimension(), cs.begin(), cs.end(), params);
cs.insert(m >= n); cs.insert(n >= 5);
PIP_Problem_Status status = pip.solve();
status indicates if the problem has been optimized or if it is unfeasible for any possible configuration of the parameter values. The resolution process is also started if an attempt is made to get its solution, as follows: const PIP_Tree_Node* node = pip.solution();
node.pip.print_solution(std::cout);
Variable::set_output_function):
if 7*C >= 10 then
if 7*D >= 12 then
{2 ; 2}
else
Parameter E = (D) div 2
if 2*C + 3*D >= 8 then
{-D - E + 4 ; D}
else
_|_
else
_|_
const PIP_Tree_Node* node = pip.solution();
node represents an unfeasible solution (i.e.,
), its value will be 0. For a non-null tree node, the virtual methods PIP_Tree_Node::as_decision() and PIP_Tree_Node::as_solution() can be used to check whether the node is a decision or a solution node: const PIP_Solution_Node* sol = node->as_solution(); if (sol != 0) { // The node is a solution node ... } else { // The node is a decision node const PIP_Decision_Node* dec = node->as_decision(); ... }
PIP_Decision_Node::child_node(bool), passing true (resp., false) as the input argument.dim+1, where the value of dim is computed as follows:dim is the space dimension of the PIP_Problem;dim computed for the parent node to the number of artificial parameters defined in the parent node.
(i.e., the problem is unfeasible for that parameter assignment).
.
variable with an expression of the form
, where the
variables are positive variables to be minimized.
variable vector.
variables will be expressed in the form:
. To get back the value of the expression of each
variable, just apply the formula:
.
variables is not in the
form, this means that the sign-unrestricted problem is unbounded.
vector, under the constraints:
is a parameter.
Variable x(0); Variable y(1); Variable p(2); Variable M(3); Variables_Set params(p, M); Constraint_System cs; cs.insert(M - y >= 2*M - 2*x - 4); cs.insert(M - y <= -M + x + p); PIP_Problem pip(cs.space_dimension(), cs.begin(), cs.end(), params); pip.set_big_parameter_dimension(3); // M is the big parameter
Parameter E = (C + 1) div 3
{D - E - 1 ; -C + D + E + 1}
.
variable with an expression of the form
, where the
variables are positive.
variable vector.
variables will be expressed in the form:
. To get back the value of the expression of each signed
variable, just apply the formula:
.
variables is not in the
form, this means that the sign-unrestricted problem is unbounded.
vector, where the
and
variables are sign-unrestricted, under the constraints:
is a parameter.
Variable x(0); Variable y(1); Variable p(2); Variable M(3); Variables_Set params(p, M); Constraint_System cs; cs.insert(y - M >= -2*x + 2*M - 4); cs.insert(2*y - 2*M <= x - M + 2*p); PIP_Problem pip(cs.space_dimension(), cs.begin(), cs.end(), params); pip.set_big_parameter_dimension(3); // M is the big parameter
Parameter E = (2*C + 3) div 5
{D - E - 1 ; D + 2*E - 2}
arbitrarily signed by replacing
with
, where both
and
are positive parameters. To represent a set of arbitrarily signed parameters, replace each parameter
with
, where
is the minimum negative value of all parameters.
, and the parameters
. You can minimize a linear cost function
by simply adding the constraint
to the constraint system. As lexicographic minimization ensures
is minimized in priority, and because
is forced by a constraint to be superior or equal to the cost function, optimal solutions of the problem necessarily ensure that the solution value of
is the optimal value of the cost function. Definition at line 488 of file PIP_Problem.defs.hh.
| typedef Constraint_Sequence::const_iterator Parma_Polyhedra_Library::PIP_Problem::const_iterator |
A type alias for the read-only iterator on the constraints defining the feasible region.
Definition at line 567 of file PIP_Problem.defs.hh.
typedef std::vector<Constraint> Parma_Polyhedra_Library::PIP_Problem::Constraint_Sequence [private] |
A type alias for a sequence of constraints.
Definition at line 560 of file PIP_Problem.defs.hh.
Possible names for PIP_Problem control parameters.
| CUTTING_STRATEGY |
Cutting strategy. |
| PIVOT_ROW_STRATEGY |
Pivot row strategy. |
| CONTROL_PARAMETER_NAME_SIZE |
Number of different enumeration values. |
Definition at line 703 of file PIP_Problem.defs.hh.
00703 { 00705 CUTTING_STRATEGY, 00707 PIVOT_ROW_STRATEGY, 00708 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00709 00710 #endif // PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00711 CONTROL_PARAMETER_NAME_SIZE 00712 };
Possible values for PIP_Problem control parameters.
Definition at line 715 of file PIP_Problem.defs.hh.
00715 { 00717 CUTTING_STRATEGY_FIRST, 00719 CUTTING_STRATEGY_DEEPEST, 00721 CUTTING_STRATEGY_ALL, 00722 00724 PIVOT_ROW_STRATEGY_FIRST, 00726 PIVOT_ROW_STRATEGY_MAX_COLUMN, 00727 00728 #ifdef PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00729 00730 #endif // PPL_DOXYGEN_INCLUDE_IMPLEMENTATION_DETAILS 00731 CONTROL_PARAMETER_VALUE_SIZE 00732 };
enum Parma_Polyhedra_Library::PIP_Problem::Status [private] |
An enumerated type describing the internal status of the PIP problem.
Definition at line 768 of file PIP_Problem.defs.hh.
00768 { 00770 UNSATISFIABLE, 00772 OPTIMIZED, 00778 PARTIALLY_SATISFIABLE 00779 };
| Parma_Polyhedra_Library::PIP_Problem::PIP_Problem | ( | dimension_type | dim = 0 |
) | [explicit] |
Builds a trivial PIP problem.
A trivial PIP problem requires to compute the lexicographic minimum on a vector space under no constraints and with no parameters: due to the implicit non-negativity constraints, the origin of the vector space is an optimal solution.
| dim | The dimension of the vector space enclosing *this (optional argument with default value ). |
| std::length_error | Thrown if dim exceeds max_space_dimension(). |
Definition at line 47 of file PIP_Problem.cc.
References control_parameters_init(), max_space_dimension(), and OK().
00048 : external_space_dim(dim), 00049 internal_space_dim(0), 00050 status(PARTIALLY_SATISFIABLE), 00051 current_solution(0), 00052 input_cs(), 00053 first_pending_constraint(0), 00054 parameters(), 00055 initial_context(), 00056 big_parameter_dimension(not_a_dimension()) { 00057 // Check for space dimension overflow. 00058 if (dim > max_space_dimension()) 00059 throw std::length_error("PPL::PIP_Problem::PIP_Problem(dim):\n" 00060 "dim exceeds the maximum allowed " 00061 "space dimension."); 00062 control_parameters_init(); 00063 PPL_ASSERT(OK()); 00064 }
| Parma_Polyhedra_Library::PIP_Problem::PIP_Problem | ( | dimension_type | dim, | |
| In | first, | |||
| In | last, | |||
| const Variables_Set & | p_vars | |||
| ) | [inline] |
Builds a PIP problem having space dimension dim from the sequence of constraints in the range
; those dimensions whose indices occur in p_vars are interpreted as parameters.
| dim | The dimension of the vector space (variables and parameters) enclosing *this. | |
| first | An input iterator to the start of the sequence of constraints. | |
| last | A past-the-end input iterator to the sequence of constraints. | |
| p_vars | The set of variables' indexes that are interpreted as parameters. |
| std::length_error | Thrown if dim exceeds max_space_dimension(). | |
| std::invalid_argument | Thrown if the space dimension of a constraint in the sequence (resp., the parameter variables) is strictly greater than dim. |
Definition at line 32 of file PIP_Problem.templates.hh.
References control_parameters_init(), external_space_dim, input_cs, max_space_dimension(), OK(), and Parma_Polyhedra_Library::Variables_Set::space_dimension().
00036 : external_space_dim(dim), 00037 internal_space_dim(0), 00038 status(PARTIALLY_SATISFIABLE), 00039 current_solution(0), 00040 input_cs(), 00041 first_pending_constraint(0), 00042 parameters(p_vars), 00043 initial_context(), 00044 big_parameter_dimension(not_a_dimension()) { 00045 // Check that integer Variables_Set does not exceed the space dimension 00046 // of the problem. 00047 if (p_vars.space_dimension() > external_space_dim) { 00048 std::ostringstream s; 00049 s << "PPL::PIP_Problem::PIP_Problem(dim, first, last, p_vars):\n" 00050 << "dim == " << external_space_dim 00051 << " and p_vars.space_dimension() == " 00052 << p_vars.space_dimension() 00053 << " are dimension incompatible."; 00054 throw std::invalid_argument(s.str()); 00055 } 00056 00057 // Check for space dimension overflow. 00058 if (dim > max_space_dimension()) 00059 throw std::length_error("PPL::PIP_Problem::" 00060 "PIP_Problem(dim, first, last, p_vars):\n" 00061 "dim exceeds the maximum allowed " 00062 "space dimension."); 00063 // Check the constraints. 00064 for (In i = first; i != last; ++i) { 00065 if (i->space_dimension() > dim) { 00066 std::ostringstream s; 00067 s << "PPL::PIP_Problem::" 00068 << "PIP_Problem(dim, first, last, p_vars):\n" 00069 << "range [first, last) contains a constraint having space " 00070 << "dimension == " << i->space_dimension() 00071 << " that exceeds this->space_dimension == " << dim << "."; 00072 throw std::invalid_argument(s.str()); 00073 } 00074 input_cs.push_back(*i); 00075 } 00076 control_parameters_init(); 00077 PPL_ASSERT(OK()); 00078 }
| Parma_Polyhedra_Library::PIP_Problem::PIP_Problem | ( | const PIP_Problem & | y | ) |
Ordinary copy-constructor.
Definition at line 66 of file PIP_Problem.cc.
References Parma_Polyhedra_Library::PIP_Tree_Node::clone(), control_parameters_copy(), current_solution, OK(), and Parma_Polyhedra_Library::PIP_Tree_Node::set_owner().
00067 : external_space_dim(y.external_space_dim), 00068 internal_space_dim(y.internal_space_dim), 00069 status(y.status), 00070 current_solution(0), 00071 input_cs(y.input_cs), 00072 first_pending_constraint(y.first_pending_constraint), 00073 parameters(y.parameters), 00074 initial_context(y.initial_context), 00075 big_parameter_dimension(y.big_parameter_dimension) { 00076 if (y.current_solution != 0) { 00077 current_solution = y.current_solution->clone(); 00078 current_solution->set_owner(this); 00079 } 00080 control_parameters_copy(y); 00081 PPL_ASSERT(OK()); 00082 }
| Parma_Polyhedra_Library::PIP_Problem::~PIP_Problem | ( | ) |
Destructor.
Definition at line 84 of file PIP_Problem.cc.
References current_solution.
00084 { 00085 delete current_solution; 00086 }
| void Parma_Polyhedra_Library::PIP_Problem::add_constraint | ( | const Constraint & | c | ) |
Adds a copy of constraint c to the PIP problem.
| std::invalid_argument | Thrown if the space dimension of c is strictly greater than the space dimension of *this. |
Definition at line 625 of file PIP_Problem.cc.
References external_space_dim, input_cs, PARTIALLY_SATISFIABLE, Parma_Polyhedra_Library::Constraint::space_dimension(), status, and UNSATISFIABLE.
Referenced by add_constraints().
00625 { 00626 if (c.space_dimension() > external_space_dim) { 00627 std::ostringstream s; 00628 s << "PPL::PIP_Problem::add_constraint(c):\n" 00629 << "dim == "<< external_space_dim << " and c.space_dimension() == " 00630 << c.space_dimension() << " are dimension incompatible."; 00631 throw std::invalid_argument(s.str()); 00632 } 00633 input_cs.push_back(c); 00634 // Update problem status. 00635 if (status != UNSATISFIABLE) 00636 status = PARTIALLY_SATISFIABLE; 00637 }
| void Parma_Polyhedra_Library::PIP_Problem::add_constraints | ( | const Constraint_System & | cs | ) |
Adds a copy of the constraints in cs to the PIP problem.
| std::invalid_argument | Thrown if the space dimension of constraint system cs is strictly greater than the space dimension of *this. |
Definition at line 640 of file PIP_Problem.cc.
References add_constraint(), Parma_Polyhedra_Library::Constraint_System::begin(), and Parma_Polyhedra_Library::Constraint_System::end().
00640 { 00641 for (Constraint_System::const_iterator ci = cs.begin(), 00642 ci_end = cs.end(); ci != ci_end; ++ci) 00643 add_constraint(*ci); 00644 }
| void Parma_Polyhedra_Library::PIP_Problem::add_space_dimensions_and_embed | ( | dimension_type | m_vars, | |
| dimension_type | m_params | |||
| ) |
Adds m_vars + m_params new space dimensions and embeds the old PIP problem in the new vector space.
| m_vars | The number of space dimensions to add that are interpreted as PIP problem variables (i.e., non parameters). These are added before adding the m_params parameters. | |
| m_params | The number of space dimensions to add that are interpreted as PIP problem parameters. These are added after having added the m_vars problem variables. |
| std::length_error | Thrown if adding m_vars + m_params new space dimensions would cause the vector space to exceed dimension max_space_dimension(). |
The new space dimensions will be those having the highest indexes in the new PIP problem; they are initially unconstrained.
Definition at line 565 of file PIP_Problem.cc.
References external_space_dim, Parma_Polyhedra_Library::Variables_Set::insert(), max_space_dimension(), OK(), parameters, PARTIALLY_SATISFIABLE, space_dimension(), status, and UNSATISFIABLE.
00566 { 00567 // Adding no space dims at all is a no-op: 00568 // this avoids invalidating problem status (if it was optimized). 00569 if (m_vars == 0 && m_params == 0) 00570 return; 00571 00572 // The space dimension of the resulting PIP problem should not 00573 // overflow the maximum allowed space dimension. 00574 dimension_type available = max_space_dimension() - space_dimension(); 00575 bool should_throw = (m_vars > available); 00576 if (!should_throw) { 00577 available -= m_vars; 00578 should_throw = (m_params > available); 00579 } 00580 if (should_throw) 00581 throw std::length_error("PPL::PIP_Problem::" 00582 "add_space_dimensions_and_embed(m_v, m_p):\n" 00583 "adding m_v+m_p new space dimensions exceeds " 00584 "the maximum allowed space dimension."); 00585 // First add PIP variables ... 00586 external_space_dim += m_vars; 00587 // ... then add PIP parameters. 00588 for (dimension_type i = m_params; i-- > 0; ) { 00589 parameters.insert(Variable(external_space_dim)); 00590 ++external_space_dim; 00591 } 00592 // Update problem status. 00593 if (status != UNSATISFIABLE) 00594 status = PARTIALLY_SATISFIABLE; 00595 PPL_ASSERT(OK()); 00596 }
| void Parma_Polyhedra_Library::PIP_Problem::add_to_parameter_space_dimensions | ( | const Variables_Set & | p_vars | ) |
Sets the space dimensions whose indexes which are in set p_vars to be parameter space dimensions.
| std::invalid_argument | Thrown if some index in p_vars does not correspond to a space dimension in *this. |
Definition at line 600 of file PIP_Problem.cc.
References external_space_dim, Parma_Polyhedra_Library::Variables_Set::insert(), internal_space_dim, parameters, PARTIALLY_SATISFIABLE, Parma_Polyhedra_Library::Variables_Set::space_dimension(), status, and UNSATISFIABLE.
00600 { 00601 if (p_vars.space_dimension() > external_space_dim) 00602 throw std::invalid_argument("PPL::PIP_Problem::" 00603 "add_to_parameter_space_dimension(p_vars):\n" 00604 "*this and p_vars are dimension " 00605 "incompatible."); 00606 const dimension_type original_size = parameters.size(); 00607 parameters.insert(p_vars.begin(), p_vars.end()); 00608 // Do not allow to turn variables into parameters. 00609 for (Variables_Set::const_iterator p = p_vars.begin(), 00610 end = p_vars.end(); p != end; ++p) { 00611 if (*p < internal_space_dim) { 00612 throw std::invalid_argument("PPL::PIP_Problem::" 00613 "add_to_parameter_space_dimension(p_vars):" 00614 "p_vars contain variable indices."); 00615 } 00616 } 00617 00618 // If a new parameter was inserted, set the internal status to 00619 // PARTIALLY_SATISFIABLE. 00620 if (parameters.size() != original_size && status != UNSATISFIABLE) 00621 status = PARTIALLY_SATISFIABLE; 00622 }
| void Parma_Polyhedra_Library::PIP_Problem::ascii_dump | ( | std::ostream & | s | ) | const |
Writes to s an ASCII representation of *this.
Definition at line 344 of file PIP_Problem.cc.
References Parma_Polyhedra_Library::PIP_Tree_Node::as_decision(), Parma_Polyhedra_Library::PIP_Tree_Node::as_solution(), Parma_Polyhedra_Library::PIP_Solution_Node::ascii_dump(), Parma_Polyhedra_Library::Matrix::ascii_dump(), Parma_Polyhedra_Library::Variables_Set::ascii_dump(), ascii_dump(), big_parameter_dimension, CONTROL_PARAMETER_NAME_SIZE, control_parameters, current_solution, CUTTING_STRATEGY_ALL, CUTTING_STRATEGY_DEEPEST, CUTTING_STRATEGY_FIRST, external_space_dim, first_pending_constraint, initial_context, input_cs, internal_space_dim, OPTIMIZED, parameters, PARTIALLY_SATISFIABLE, PIVOT_ROW_STRATEGY_FIRST, PIVOT_ROW_STRATEGY_MAX_COLUMN, status, and UNSATISFIABLE.
00344 { 00345 using namespace IO_Operators; 00346 s << "\nexternal_space_dim: " << external_space_dim << "\n"; 00347 s << "\ninternal_space_dim: " << internal_space_dim << "\n"; 00348 00349 const dimension_type input_cs_size = input_cs.size(); 00350 00351 s << "\ninput_cs( " << input_cs_size << " )\n"; 00352 for (dimension_type i = 0; i < input_cs_size; ++i) 00353 input_cs[i].ascii_dump(s); 00354 00355 s << "\nfirst_pending_constraint: " << first_pending_constraint << "\n"; 00356 00357 s << "\nstatus: "; 00358 switch (status) { 00359 case UNSATISFIABLE: 00360 s << "UNSATISFIABLE"; 00361 break; 00362 case OPTIMIZED: 00363 s << "OPTIMIZED"; 00364 break; 00365 case PARTIALLY_SATISFIABLE: 00366 s << "PARTIALLY_SATISFIABLE"; 00367 break; 00368 } 00369 s << "\n"; 00370 00371 s << "\nparameters"; 00372 parameters.ascii_dump(s); 00373 00374 s << "\ninitial_context\n"; 00375 initial_context.ascii_dump(s); 00376 00377 s << "\ncontrol_parameters\n"; 00378 for (dimension_type i = 0; i < CONTROL_PARAMETER_NAME_SIZE; ++i) { 00379 Control_Parameter_Value value = control_parameters[i]; 00380 switch (value) { 00381 case CUTTING_STRATEGY_FIRST: 00382 s << "CUTTING_STRATEGY_FIRST"; 00383 break; 00384 case CUTTING_STRATEGY_DEEPEST: 00385 s << "CUTTING_STRATEGY_DEEPEST"; 00386 break; 00387 case CUTTING_STRATEGY_ALL: 00388 s << "CUTTING_STRATEGY_ALL"; 00389 break; 00390 case PIVOT_ROW_STRATEGY_FIRST: 00391 s << "PIVOT_ROW_STRATEGY_FIRST"; 00392 break; 00393 case PIVOT_ROW_STRATEGY_MAX_COLUMN: 00394 s << "PIVOT_ROW_STRATEGY_MAX_COLUMN"; 00395 break; 00396 default: 00397 s << "Invalid control parameter value"; 00398 } 00399 s << "\n"; 00400 } 00401 00402 s << "\nbig_parameter_dimension: " << big_parameter_dimension << "\n"; 00403 00404 s << "\ncurrent_solution: "; 00405 if (current_solution == 0) 00406 s << "BOTTOM\n"; 00407 else if (const PIP_Decision_Node* dec = current_solution->as_decision()) { 00408 s << "DECISION\n"; 00409 dec->ascii_dump(s); 00410 } 00411 else { 00412 const PIP_Solution_Node* sol = current_solution->as_solution(); 00413 PPL_ASSERT(sol != 0); 00414 s << "SOLUTION\n"; 00415 sol->ascii_dump(s); 00416 } 00417 }
| void Parma_Polyhedra_Library::PIP_Problem::ascii_dump | ( | ) | const |
Writes to std::cerr an ASCII representation of *this.
Referenced by ascii_dump(), and OK().
| bool Parma_Polyhedra_Library::PIP_Problem::ascii_load | ( | std::istream & | s | ) |
Loads from s an ASCII representation (as produced by ascii_dump(std::ostream&) const) and sets *this accordingly. Returns true if successful, false otherwise.
Definition at line 422 of file PIP_Problem.cc.
References Parma_Polyhedra_Library::PIP_Solution_Node::ascii_load(), Parma_Polyhedra_Library::PIP_Decision_Node::ascii_load(), Parma_Polyhedra_Library::Constraint::ascii_load(), Parma_Polyhedra_Library::PIP_Solution_Node::set_owner(), Parma_Polyhedra_Library::PIP_Decision_Node::set_owner(), and Parma_Polyhedra_Library::Constraint::zero_dim_positivity().
00422 { 00423 std::string str; 00424 if (!(s >> str) || str != "external_space_dim:") 00425 return false; 00426 00427 if (!(s >> external_space_dim)) 00428 return false; 00429 00430 if (!(s >> str) || str != "internal_space_dim:") 00431 return false; 00432 00433 if (!(s >> internal_space_dim)) 00434 return false; 00435 00436 if (!(s >> str) || str != "input_cs(") 00437 return false; 00438 00439 dimension_type input_cs_size; 00440 00441 if (!(s >> input_cs_size)) 00442 return false; 00443 00444 if (!(s >> str) || str != ")") 00445 return false; 00446 00447 Constraint c(Constraint::zero_dim_positivity()); 00448 for (dimension_type i = 0; i < input_cs_size; ++i) { 00449 if (!c.ascii_load(s)) 00450 return false; 00451 input_cs.push_back(c); 00452 } 00453 00454 if (!(s >> str) || str != "first_pending_constraint:") 00455 return false; 00456 00457 if (!(s >> first_pending_constraint)) 00458 return false; 00459 00460 if (!(s >> str) || str != "status:") 00461 return false; 00462 00463 if (!(s >> str)) 00464 return false; 00465 00466 if (str == "UNSATISFIABLE") 00467 status = UNSATISFIABLE; 00468 else if (str == "OPTIMIZED") 00469 status = OPTIMIZED; 00470 else if (str == "PARTIALLY_SATISFIABLE") 00471 status = PARTIALLY_SATISFIABLE; 00472 else 00473 return false; 00474 00475 if (!(s >> str) || str != "parameters") 00476 return false; 00477 00478 if (!parameters.ascii_load(s)) 00479 return false; 00480 00481 if (!(s >> str) || str != "initial_context") 00482 return false; 00483 00484 if (!initial_context.ascii_load(s)) 00485 return false; 00486 00487 if (!(s >> str) || str != "control_parameters") 00488 return false; 00489 00490 for (dimension_type i = 0; i < CONTROL_PARAMETER_NAME_SIZE; ++i) { 00491 if (!(s >> str)) 00492 return false; 00493 Control_Parameter_Value value; 00494 if (str == "CUTTING_STRATEGY_FIRST") 00495 value = CUTTING_STRATEGY_FIRST; 00496 else if (str == "CUTTING_STRATEGY_DEEPEST") 00497 value = CUTTING_STRATEGY_DEEPEST; 00498 else if (str == "CUTTING_STRATEGY_ALL") 00499 value = CUTTING_STRATEGY_ALL; 00500 else if (str == "PIVOT_ROW_STRATEGY_FIRST") 00501 value = PIVOT_ROW_STRATEGY_FIRST; 00502 else if (str == "PIVOT_ROW_STRATEGY_MAX_COLUMN") 00503 value = PIVOT_ROW_STRATEGY_MAX_COLUMN; 00504 else 00505 return false; 00506 control_parameters[i] = value; 00507 } 00508 00509 if (!(s >> str) || str != "big_parameter_dimension:") 00510 return false; 00511 if (!(s >> big_parameter_dimension)) 00512 return false; 00513 00514 // Release current_solution tree (if any). 00515 delete current_solution; 00516 current_solution = 0; 00517 // Load current_solution (if any). 00518 if (!(s >> str) || str != "current_solution:") 00519 return false; 00520 if (!(s >> str)) 00521 return false; 00522 if (str == "BOTTOM") 00523 current_solution = 0; 00524 else if (str == "DECISION") { 00525 PIP_Decision_Node* dec = new PIP_Decision_Node(0, 0, 0); 00526 current_solution = dec; 00527 if (!dec->ascii_load(s)) 00528 return false; 00529 dec->set_owner(this); 00530 } 00531 else if (str == "SOLUTION") { 00532 PIP_Solution_Node* sol = new PIP_Solution_Node(0); 00533 current_solution = sol; 00534 if (!sol->ascii_load(s)) 00535 return false; 00536 sol->set_owner(this); 00537 } 00538 else 00539 // Unknown node kind. 00540 return false; 00541 00542 PPL_ASSERT(OK()); 00543 return true; 00544 }
| void Parma_Polyhedra_Library::PIP_Problem::clear | ( | ) |
Resets *this to be equal to the trivial PIP problem.
The space dimension is reset to
.
Definition at line 547 of file PIP_Problem.cc.
References big_parameter_dimension, Parma_Polyhedra_Library::Matrix::clear(), control_parameters_init(), current_solution, external_space_dim, first_pending_constraint, initial_context, input_cs, internal_space_dim, Parma_Polyhedra_Library::not_a_dimension(), parameters, PARTIALLY_SATISFIABLE, and status.
00547 { 00548 external_space_dim = 0; 00549 internal_space_dim = 0; 00550 status = PARTIALLY_SATISFIABLE; 00551 if (current_solution != 0) { 00552 delete current_solution; 00553 current_solution = 0; 00554 } 00555 input_cs.clear(); 00556 first_pending_constraint = 0; 00557 parameters.clear(); 00558 initial_context.clear(); 00559 control_parameters_init(); 00560 big_parameter_dimension = not_a_dimension(); 00561 }
| PIP_Problem::const_iterator Parma_Polyhedra_Library::PIP_Problem::constraints_begin | ( | ) | const [inline] |
Returns a read-only iterator to the first constraint defining the feasible region.
Definition at line 40 of file PIP_Problem.inlines.hh.
References input_cs.
Referenced by operator<<().
00040 { 00041 return input_cs.begin(); 00042 }
| PIP_Problem::const_iterator Parma_Polyhedra_Library::PIP_Problem::constraints_end | ( | ) | const [inline] |
Returns a past-the-end read-only iterator to the sequence of constraints defining the feasible region.
Definition at line 45 of file PIP_Problem.inlines.hh.
References input_cs.
Referenced by operator<<().
00045 { 00046 return input_cs.end(); 00047 }
| void Parma_Polyhedra_Library::PIP_Problem::control_parameters_copy | ( | const PIP_Problem & | y | ) | [private] |
Copies the control parameters from problem object y.
Definition at line 95 of file PIP_Problem.cc.
References CONTROL_PARAMETER_NAME_SIZE, and control_parameters.
Referenced by PIP_Problem().
00095 { 00096 for (dimension_type i = CONTROL_PARAMETER_NAME_SIZE; i-- > 0; ) 00097 control_parameters[i] = y.control_parameters[i]; 00098 }
| void Parma_Polyhedra_Library::PIP_Problem::control_parameters_init | ( | ) | [private] |
Initializes the control parameters with default values.
Definition at line 89 of file PIP_Problem.cc.
References control_parameters, CUTTING_STRATEGY, CUTTING_STRATEGY_FIRST, PIVOT_ROW_STRATEGY, and PIVOT_ROW_STRATEGY_FIRST.
Referenced by clear(), and PIP_Problem().
00089 { 00090 control_parameters[CUTTING_STRATEGY] = CUTTING_STRATEGY_FIRST; 00091 control_parameters[PIVOT_ROW_STRATEGY] = PIVOT_ROW_STRATEGY_FIRST; 00092 }
| PPL::memory_size_type Parma_Polyhedra_Library::PIP_Problem::external_memory_in_bytes | ( | ) | const |
Returns the size in bytes of the memory managed by *this.
Definition at line 689 of file PIP_Problem.cc.
References current_solution, Parma_Polyhedra_Library::Matrix::external_memory_in_bytes(), initial_context, input_cs, parameters, and Parma_Polyhedra_Library::PIP_Tree_Node::total_memory_in_bytes().
Referenced by total_memory_in_bytes().
00689 { 00690 memory_size_type n = initial_context.external_memory_in_bytes(); 00691 // Adding the external memory for `current_solution'. 00692 if (current_solution) 00693 n += current_solution->total_memory_in_bytes(); 00694 // Adding the external memory for `input_cs'. 00695 n += input_cs.capacity() * sizeof(Constraint); 00696 for (const_iterator i = input_cs.begin(), 00697 i_end = input_cs.end(); i != i_end; ++i) 00698 n += (i->external_memory_in_bytes()); 00699 // FIXME: Adding the external memory for `parameters'. 00700 n += parameters.size() * sizeof(dimension_type); 00701 00702 return n; 00703 }
| dimension_type Parma_Polyhedra_Library::PIP_Problem::get_big_parameter_dimension | ( | ) | const [inline] |
Returns the space dimension for the big parameter.
If a big parameter was not set, returns not_a_dimension().
Definition at line 83 of file PIP_Problem.inlines.hh.
References big_parameter_dimension.
Referenced by operator<<().
00083 { 00084 return big_parameter_dimension; 00085 }
| PIP_Problem::Control_Parameter_Value Parma_Polyhedra_Library::PIP_Problem::get_control_parameter | ( | Control_Parameter_Name | name | ) | const [inline] |
Returns the value of control parameter name.
Definition at line 77 of file PIP_Problem.inlines.hh.
References CONTROL_PARAMETER_NAME_SIZE, and control_parameters.
00077 { 00078 PPL_ASSERT(n >= 0 && n < CONTROL_PARAMETER_NAME_SIZE); 00079 return control_parameters[n]; 00080 }
| bool Parma_Polyhedra_Library::PIP_Problem::is_satisfiable | ( | ) | const |
Checks satisfiability of *this.
true if and only if the PIP problem is satisfiable. Definition at line 647 of file PIP_Problem.cc.
References OPTIMIZED, PARTIALLY_SATISFIABLE, solve(), and status.
00647 { 00648 if (status == PARTIALLY_SATISFIABLE) 00649 solve(); 00650 return status == OPTIMIZED; 00651 }
| dimension_type Parma_Polyhedra_Library::PIP_Problem::max_space_dimension | ( | ) | [inline, static] |
Returns the maximum space dimension a PIP_Problem can handle.
Definition at line 35 of file PIP_Problem.inlines.hh.
Referenced by add_space_dimensions_and_embed(), and PIP_Problem().
00035 { 00036 return Constraint::max_space_dimension(); 00037 }
| bool Parma_Polyhedra_Library::PIP_Problem::OK | ( | ) | const |
Checks if all the invariants are satisfied.
Definition at line 246 of file PIP_Problem.cc.
References ascii_dump(), big_parameter_dimension, Parma_Polyhedra_Library::PIP_Tree_Node::check_ownership(), control_parameters, current_solution, CUTTING_STRATEGY, CUTTING_STRATEGY_ALL, CUTTING_STRATEGY_DEEPEST, CUTTING_STRATEGY_FIRST, external_space_dim, initial_context, input_cs, internal_space_dim, Parma_Polyhedra_Library::not_a_dimension(), Parma_Polyhedra_Library::PIP_Tree_Node::OK(), Parma_Polyhedra_Library::Matrix::OK(), Parma_Polyhedra_Library::Variables_Set::OK(), parameters, PIVOT_ROW_STRATEGY, PIVOT_ROW_STRATEGY_FIRST, PIVOT_ROW_STRATEGY_MAX_COLUMN, and space_dimension().
Referenced by add_space_dimensions_and_embed(), PIP_Problem(), and solve().
00246 { 00247 #ifndef NDEBUG 00248 using std::endl; 00249 using std::cerr; 00250 #endif 00251 00252 if (external_space_dim < internal_space_dim) { 00253 #ifndef NDEBUG 00254 cerr << "The internal space dimension of the PIP_Problem is " 00255 << "greater than its external space dimension." 00256 << endl; 00257 ascii_dump(cerr); 00258 #endif 00259 return false; 00260 } 00261 00262 // Constraint system should be OK. 00263 const dimension_type input_cs_num_rows = input_cs.size(); 00264 for (dimension_type i = input_cs_num_rows; i-- > 0; ) 00265 if (!input_cs[i].OK()) 00266 return false; 00267 00268 // Constraint system should be space dimension compatible. 00269 for (dimension_type i = input_cs_num_rows; i-- > 0; ) { 00270 if (input_cs[i].space_dimension() > external_space_dim) { 00271 #ifndef NDEBUG 00272 cerr << "The space dimension of the PIP_Problem is smaller than " 00273 << "the space dimension of one of its constraints." 00274 << endl; 00275 ascii_dump(cerr); 00276 #endif 00277 return false; 00278 } 00279 } 00280 00281 // Test validity of control parameter values. 00282 Control_Parameter_Value strategy = control_parameters[CUTTING_STRATEGY]; 00283 if (strategy != CUTTING_STRATEGY_FIRST 00284 && strategy != CUTTING_STRATEGY_DEEPEST 00285 && strategy != CUTTING_STRATEGY_ALL) { 00286 #ifndef NDEBUG 00287 cerr << "Invalid value for the CUTTING_STRATEGY control parameter." 00288 << endl; 00289 ascii_dump(cerr); 00290 #endif 00291 return false; 00292 } 00293 00294 strategy = control_parameters[PIVOT_ROW_STRATEGY]; 00295 if (strategy < PIVOT_ROW_STRATEGY_FIRST 00296 || strategy > PIVOT_ROW_STRATEGY_MAX_COLUMN) { 00297 #ifndef NDEBUG 00298 cerr << "Invalid value for the PIVOT_ROW_STRATEGY control parameter." 00299 << endl; 00300 ascii_dump(cerr); 00301 #endif 00302 return false; 00303 } 00304 00305 if (big_parameter_dimension != not_a_dimension() 00306 && parameters.count(big_parameter_dimension) == 0) { 00307 #ifndef NDEBUG 00308 cerr << "The big parameter is set, but it is not a parameter." << endl; 00309 ascii_dump(cerr); 00310 #endif 00311 return false; 00312 } 00313 00314 if (!parameters.OK()) 00315 return false; 00316 if (!initial_context.OK()) 00317 return false; 00318 00319 if (current_solution) { 00320 // Check well formedness of the solution tree. 00321 if (!current_solution->OK()) { 00322 #ifndef NDEBUG 00323 cerr << "The computed solution tree is broken.\n"; 00324 ascii_dump(cerr); 00325 #endif 00326 return false; 00327 } 00328 // Check that all nodes in the solution tree belong to *this. 00329 if (!current_solution->check_ownership(this)) { 00330 #ifndef NDEBUG 00331 cerr << "There are nodes in the solution tree " 00332 << "that are not owned by *this.\n"; 00333 ascii_dump(cerr); 00334 #endif 00335 return false; 00336 } 00337 } 00338 00339 // All checks passed. 00340 return true; 00341 }
| PIP_Problem & Parma_Polyhedra_Library::PIP_Problem::operator= | ( | const PIP_Problem & | y | ) | [inline] |
Assignment operator.
Definition at line 70 of file PIP_Problem.inlines.hh.
References swap().
00070 { 00071 PIP_Problem tmp(y); 00072 swap(tmp); 00073 return *this; 00074 }
| PPL::PIP_Tree Parma_Polyhedra_Library::PIP_Problem::optimizing_solution | ( | ) | const |
Returns an optimizing solution for *this, if it exists.
A null pointer is returned for an unfeasible PIP problem.
Definition at line 239 of file PIP_Problem.cc.
References current_solution, PARTIALLY_SATISFIABLE, solve(), and status.
00239 { 00240 if (status == PARTIALLY_SATISFIABLE) 00241 solve(); 00242 return current_solution; 00243 }
| const Variables_Set & Parma_Polyhedra_Library::PIP_Problem::parameter_space_dimensions | ( | ) | const [inline] |
Returns a set containing all the variables' indexes representing the parameters of the PIP problem.
Definition at line 50 of file PIP_Problem.inlines.hh.
References parameters.
Referenced by operator<<(), Parma_Polyhedra_Library::PIP_Solution_Node::parametric_values(), Parma_Polyhedra_Library::PIP_Tree_Node::print(), and Parma_Polyhedra_Library::PIP_Solution_Node::update_solution().
00050 { 00051 return parameters; 00052 }
| void Parma_Polyhedra_Library::PIP_Problem::print | ( | ) | const |
Prints *this to std::cerr using operator<<.
| void Parma_Polyhedra_Library::PIP_Problem::print_solution | ( | std::ostream & | s, | |
| unsigned | indent = 0 | |||
| ) | const |
Prints on s the solution computed for *this.
| s | The output stream. | |
| indent | An indentation parameter (default value 0). |
| std::logic_error | Thrown if trying to print the solution when the PIP problem still has to be solved. |
Definition at line 711 of file PIP_Problem.cc.
References current_solution, Parma_Polyhedra_Library::PIP_Tree_Node::indent_and_print(), OPTIMIZED, PARTIALLY_SATISFIABLE, Parma_Polyhedra_Library::PIP_Tree_Node::print(), status, and UNSATISFIABLE.
00711 { 00712 switch (status) { 00713 00714 case UNSATISFIABLE: 00715 PPL_ASSERT(current_solution == 0); 00716 PIP_Tree_Node::indent_and_print(s, indent, "_|_\n"); 00717 break; 00718 00719 case OPTIMIZED: 00720 PPL_ASSERT(current_solution != 0); 00721 current_solution->print(s, indent); 00722 break; 00723 00724 case PARTIALLY_SATISFIABLE: 00725 throw std::logic_error("PIP_Problem::print_solution():\n" 00726 "the PIP problem has not been solved."); 00727 } 00728 }
| void Parma_Polyhedra_Library::PIP_Problem::set_big_parameter_dimension | ( | dimension_type | big_dim | ) |
Sets the dimension for the big parameter to big_dim.
Definition at line 675 of file PIP_Problem.cc.
References big_parameter_dimension, internal_space_dim, and parameters.
00675 { 00676 if (parameters.count(big_dim) == 0) 00677 throw std::invalid_argument("PPL::PIP_Problem::" 00678 "set_big_parameter_dimension(big_dim):\n" 00679 "dimension 'big_dim' is not a parameter."); 00680 if (big_dim < internal_space_dim) 00681 throw std::invalid_argument("PPL::PIP_Problem::" 00682 "set_big_parameter_dimension(big_dim):\n" 00683 "only newly-added parameters can be" 00684 "converted into the big parameter."); 00685 big_parameter_dimension = big_dim; 00686 }
| void Parma_Polyhedra_Library::PIP_Problem::set_control_parameter | ( | Control_Parameter_Value | value | ) |
Sets control parameter value.
Definition at line 654 of file PIP_Problem.cc.
References control_parameters, CUTTING_STRATEGY, CUTTING_STRATEGY_ALL, CUTTING_STRATEGY_DEEPEST, CUTTING_STRATEGY_FIRST, PIVOT_ROW_STRATEGY, PIVOT_ROW_STRATEGY_FIRST, and PIVOT_ROW_STRATEGY_MAX_COLUMN.
00654 { 00655 switch (value) { 00656 case CUTTING_STRATEGY_FIRST: 00657 // Intentionally fall through. 00658 case CUTTING_STRATEGY_DEEPEST: 00659 // Intentionally fall through. 00660 case CUTTING_STRATEGY_ALL: 00661 control_parameters[CUTTING_STRATEGY] = value; 00662 break; 00663 case PIVOT_ROW_STRATEGY_FIRST: 00664 // Intentionally fall through. 00665 case PIVOT_ROW_STRATEGY_MAX_COLUMN: 00666 control_parameters[PIVOT_ROW_STRATEGY] = value; 00667 break; 00668 default: 00669 throw std::invalid_argument("PPL::PIP_Problem::set_control_parameter(v)" 00670 ":\ninvalid value."); 00671 } 00672 }
| PPL::PIP_Tree Parma_Polyhedra_Library::PIP_Problem::solution | ( | ) | const |
Returns a feasible solution for *this, if it exists.
A null pointer is returned for an unfeasible PIP problem.
Definition at line 232 of file PIP_Problem.cc.
References current_solution, PARTIALLY_SATISFIABLE, solve(), and status.
00232 { 00233 if (status == PARTIALLY_SATISFIABLE) 00234 solve(); 00235 return current_solution; 00236 }
| PPL::PIP_Problem_Status Parma_Polyhedra_Library::PIP_Problem::solve | ( | ) | const |
Optimizes the PIP problem.
Definition at line 101 of file PIP_Problem.cc.
References Parma_Polyhedra_Library::Matrix::add_row(), Parma_Polyhedra_Library::Matrix::add_zero_columns(), Parma_Polyhedra_Library::Constraint::coefficient(), Parma_Polyhedra_Library::PIP_Tree_Node::compatibility_check(), current_solution, external_space_dim, first_pending_constraint, Parma_Polyhedra_Library::Constraint::inhomogeneous_term(), initial_context, input_cs, internal_space_dim, Parma_Polyhedra_Library::Constraint::is_equality(), Parma_Polyhedra_Library::Constraint::is_strict_inequality(), Parma_Polyhedra_Library::neg_assign(), Parma_Polyhedra_Library::Matrix::num_columns(), OK(), OPTIMIZED, Parma_Polyhedra_Library::OPTIMIZED_PIP_PROBLEM, parameters, PARTIALLY_SATISFIABLE, PIP_Solution_Node, Parma_Polyhedra_Library::PIP_Tree_Node::solve(), Parma_Polyhedra_Library::Constraint::space_dimension(), status, Parma_Polyhedra_Library::UNFEASIBLE_PIP_PROBLEM, UNSATISFIABLE, and Parma_Polyhedra_Library::PIP_Tree_Node::update_tableau().
Referenced by is_satisfiable(), optimizing_solution(), and solution().
00101 { 00102 switch (status) { 00103 00104 case UNSATISFIABLE: 00105 PPL_ASSERT(OK()); 00106 return UNFEASIBLE_PIP_PROBLEM; 00107 00108 case OPTIMIZED: 00109 PPL_ASSERT(OK()); 00110 return OPTIMIZED_PIP_PROBLEM; 00111 00112 case PARTIALLY_SATISFIABLE: 00113 { 00114 PIP_Problem& x = const_cast<PIP_Problem&>(*this); 00115 // Allocate PIP solution tree root, if needed. 00116 if (current_solution == 0) 00117 x.current_solution = new PIP_Solution_Node(this); 00118 00119 // Properly resize context matrix. 00120 const dimension_type new_num_cols = parameters.size() + 1; 00121 const dimension_type old_num_cols = initial_context.num_columns(); 00122 if (old_num_cols < new_num_cols) 00123 x.initial_context.add_zero_columns(new_num_cols - old_num_cols); 00124 00125 // Computed once for all (to be used inside loop). 00126 const Variables_Set::const_iterator param_begin = parameters.begin(); 00127 const Variables_Set::const_iterator param_end = parameters.end(); 00128 00129 // This flag will be set if we insert a pending constraint 00130 // in the initial context. 00131 bool check_feasible_context = false; 00132 00133 // Go through all pending constraints. 00134 for (Constraint_Sequence::const_iterator 00135 cs_i = input_cs.begin() + first_pending_constraint, 00136 cs_end = input_cs.end(); cs_i != cs_end; ++cs_i) { 00137 const Constraint& c = *cs_i; 00138 const dimension_type c_space_dim = c.space_dimension(); 00139 PPL_ASSERT(external_space_dim >= c_space_dim); 00140 00141 // Check if constraint has a non-zero variable coefficient. 00142 bool has_nonzero_variable_coefficient = false; 00143 for (dimension_type i = c_space_dim; i-- > 0; ) { 00144 if (c.coefficient(Variable(i)) != 0 00145 && parameters.count(i) == 0) { 00146 has_nonzero_variable_coefficient = true; 00147 break; 00148 } 00149 } 00150 // Constraints having a non-zero variable coefficient 00151 // should not be inserted in context. 00152 if (has_nonzero_variable_coefficient) 00153 continue; 00154 00155 check_feasible_context = true; 00156 00157 // Translate constraint into context row. 00158 Row row(new_num_cols, Row::Flags()); 00159 row[0] = c.inhomogeneous_term(); 00160 { 00161 dimension_type i = 1; 00162 for (Variables_Set::const_iterator 00163 pi = param_begin; pi != param_end; ++pi, ++i) { 00164 if (*pi < c_space_dim) 00165 row[i] = c.coefficient(Variable(*pi)); 00166 else 00167 break; 00168 } 00169 } 00170 // Adjust inhomogenous term if strict. 00171 if (c.is_strict_inequality()) 00172 --row[0]; 00173 00174 // Insert new row into initial context. 00175 x.initial_context.add_row(row); 00176 00177 // If it is an equality, also insert its negation. 00178 if (c.is_equality()) { 00179 for (dimension_type i = new_num_cols; i-- > 0; ) 00180 neg_assign(row[i], row[i]); 00181 00182 // Insert new row into initial context. 00183 x.initial_context.add_row(row); 00184 } 00185 } 00186 00187 if (check_feasible_context) { 00188 // Check for feasibility of initial context. 00189 Matrix ctx_copy(initial_context); 00190 if (!PIP_Solution_Node::compatibility_check(ctx_copy)) { 00191 // Problem found to be unfeasible. 00192 delete x.current_solution; 00193 x.current_solution = 0; 00194 x.status = UNSATISFIABLE; 00195 PPL_ASSERT(OK()); 00196 return UNFEASIBLE_PIP_PROBLEM; 00197 } 00198 } 00199 00200 // Update tableau and mark constraints as no longer pending. 00201 x.current_solution->update_tableau(*this, 00202 external_space_dim, 00203 first_pending_constraint, 00204 input_cs, 00205 parameters); 00206 x.internal_space_dim = external_space_dim; 00207 x.first_pending_constraint = input_cs.size(); 00208 00209 // Actually solve problem. 00210 x.current_solution = x.current_solution->solve(*this, 00211 check_feasible_context, 00212 initial_context, 00213 parameters, 00214 external_space_dim, 00215 /*indent_level=*/ 0); 00216 // Update problem status. 00217 x.status = (x.current_solution) ? OPTIMIZED : UNSATISFIABLE; 00218 00219 PPL_ASSERT(OK()); 00220 return (x.current_solution) 00221 ? OPTIMIZED_PIP_PROBLEM 00222 : UNFEASIBLE_PIP_PROBLEM; 00223 } // End of handler for PARTIALLY_SATISFIABLE case. 00224 00225 } // End of switch. 00226 00227 // We should not be here! 00228 throw std::runtime_error("PPL internal error"); 00229 }
| dimension_type Parma_Polyhedra_Library::PIP_Problem::space_dimension | ( | ) | const [inline] |
Returns the space dimension of the PIP problem.
Definition at line 30 of file PIP_Problem.inlines.hh.
References external_space_dim.
Referenced by add_space_dimensions_and_embed(), OK(), operator<<(), Parma_Polyhedra_Library::PIP_Solution_Node::parametric_values(), Parma_Polyhedra_Library::PIP_Tree_Node::print(), and Parma_Polyhedra_Library::PIP_Solution_Node::update_solution().
00030 { 00031 return external_space_dim; 00032 }
| void Parma_Polyhedra_Library::PIP_Problem::swap | ( | PIP_Problem & | y | ) | [inline] |
Swaps *this with y.
Definition at line 55 of file PIP_Problem.inlines.hh.
References big_parameter_dimension, CONTROL_PARAMETER_NAME_SIZE, control_parameters, current_solution, external_space_dim, first_pending_constraint, initial_context, input_cs, internal_space_dim, parameters, status, and Parma_Polyhedra_Library::swap().
Referenced by operator=(), and swap().
00055 { 00056 std::swap(external_space_dim, y.external_space_dim); 00057 std::swap(internal_space_dim, y.internal_space_dim); 00058 std::swap(status, y.status); 00059 std::swap(current_solution, y.current_solution); 00060 std::swap(input_cs, y.input_cs); 00061 std::swap(first_pending_constraint, y.first_pending_constraint); 00062 std::swap(parameters, y.parameters); 00063 std::swap(initial_context, y.initial_context); 00064 for (dimension_type i = CONTROL_PARAMETER_NAME_SIZE; i-- > 0; ) 00065 std::swap(control_parameters[i], y.control_parameters[i]); 00066 std::swap(big_parameter_dimension, y.big_parameter_dimension); 00067 }
| PPL::memory_size_type Parma_Polyhedra_Library::PIP_Problem::total_memory_in_bytes | ( | ) | const |
Returns the total size in bytes of the memory occupied by *this.
Definition at line 706 of file PIP_Problem.cc.
References external_memory_in_bytes().
00706 { 00707 return sizeof(*this) + external_memory_in_bytes(); 00708 }
| std::ostream & operator<< | ( | std::ostream & | s, | |
| const PIP_Problem & | pip | |||
| ) | [related] |
Output operator.
Definition at line 32 of file PIP_Problem.cc.
References constraints_begin(), constraints_end(), get_big_parameter_dimension(), Parma_Polyhedra_Library::not_a_dimension(), parameter_space_dimensions(), and space_dimension().
00032 { 00033 s << "Space dimension: " << pip.space_dimension(); 00034 s << "\nConstraints:"; 00035 for (PIP_Problem::const_iterator i = pip.constraints_begin(), 00036 i_end = pip.constraints_end(); i != i_end; ++i) 00037 s << "\n" << *i; 00038 s << "\nProblem parameters: " << pip.parameter_space_dimensions(); 00039 if (pip.get_big_parameter_dimension() == not_a_dimension()) 00040 s << "\nNo big-parameter set.\n"; 00041 else 00042 s << "\nBig-parameter: " << Variable(pip.get_big_parameter_dimension()); 00043 s << "\n"; 00044 return s; 00045 }
friend class PIP_Solution_Node [friend] |
Definition at line 816 of file PIP_Problem.defs.hh.
Referenced by solve().
| void swap | ( | Parma_Polyhedra_Library::PIP_Problem & | x, | |
| Parma_Polyhedra_Library::PIP_Problem & | y | |||
| ) | [related] |
Specializes std::swap.
Definition at line 93 of file PIP_Problem.inlines.hh.
References swap().
00094 { 00095 x.swap(y); 00096 }
The dimension for the big parameter, or not_a_dimension() if not set.
Definition at line 814 of file PIP_Problem.defs.hh.
Referenced by ascii_dump(), clear(), get_big_parameter_dimension(), OK(), set_big_parameter_dimension(), swap(), and Parma_Polyhedra_Library::PIP_Solution_Node::update_tableau().
Control_Parameter_Value Parma_Polyhedra_Library::PIP_Problem::control_parameters[CONTROL_PARAMETER_NAME_SIZE] [private] |
The control parameters for the problem object.
Definition at line 808 of file PIP_Problem.defs.hh.
Referenced by ascii_dump(), control_parameters_copy(), control_parameters_init(), get_control_parameter(), OK(), set_control_parameter(), Parma_Polyhedra_Library::PIP_Solution_Node::solve(), and swap().
The current solution decision tree.
Definition at line 785 of file PIP_Problem.defs.hh.
Referenced by ascii_dump(), clear(), external_memory_in_bytes(), OK(), optimizing_solution(), PIP_Problem(), print_solution(), solution(), solve(), swap(), and ~PIP_Problem().
The dimension of the vector space.
Definition at line 759 of file PIP_Problem.defs.hh.
Referenced by add_constraint(), add_space_dimensions_and_embed(), add_to_parameter_space_dimensions(), ascii_dump(), clear(), OK(), PIP_Problem(), solve(), space_dimension(), swap(), and Parma_Polyhedra_Library::PIP_Solution_Node::update_tableau().
The first index of `input_cs' containing a pending constraint.
Definition at line 791 of file PIP_Problem.defs.hh.
Referenced by ascii_dump(), clear(), solve(), and swap().
The initial context.
Contains problem constraints on parameters only
Definition at line 804 of file PIP_Problem.defs.hh.
Referenced by ascii_dump(), clear(), external_memory_in_bytes(), OK(), solve(), and swap().
The sequence of constraints describing the feasible region.
Definition at line 788 of file PIP_Problem.defs.hh.
Referenced by add_constraint(), ascii_dump(), clear(), constraints_begin(), constraints_end(), external_memory_in_bytes(), OK(), PIP_Problem(), solve(), and swap().
The space dimension of the current (partial) solution of the PIP problem; it may be smaller than external_space_dim.
Definition at line 765 of file PIP_Problem.defs.hh.
Referenced by add_to_parameter_space_dimensions(), ascii_dump(), clear(), OK(), set_big_parameter_dimension(), solve(), swap(), and Parma_Polyhedra_Library::PIP_Solution_Node::update_tableau().
A set containing all the indices of space dimensions that are interpreted as problem parameters.
Definition at line 797 of file PIP_Problem.defs.hh.
Referenced by add_space_dimensions_and_embed(), add_to_parameter_space_dimensions(), ascii_dump(), clear(), external_memory_in_bytes(), OK(), parameter_space_dimensions(), set_big_parameter_dimension(), solve(), and swap().
The internal state of the MIP problem.
Definition at line 782 of file PIP_Problem.defs.hh.
Referenced by add_constraint(), add_space_dimensions_and_embed(), add_to_parameter_space_dimensions(), ascii_dump(), clear(), is_satisfiable(), optimizing_solution(), print_solution(), solution(), solve(), and swap().
1.6.3