/* A collection of useful convex polyhedra algorithms: inline functions.
Copyright (C) 2001-2004 Roberto Bagnara <bagnara@cs.unipr.it>
This file is part of the Parma Polyhedra Library (PPL).
The PPL is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the
Free Software Foundation; either version 2 of the License, or (at your
option) any later version.
The PPL is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
USA.
For the most up-to-date information see the Parma Polyhedra Library
site: http://www.cs.unipr.it/ppl/ . */
#ifndef PPL_algorithms_hh
#define PPL_algorithms_hh 1
#include "NNC_Polyhedron.defs.hh"
#include "Polyhedra_PowerSet.defs.hh"
#include "Constraint.defs.hh"
#include "LinExpression.defs.hh"
#include "ConSys.defs.hh"
#include <utility>
#include <cassert>
namespace Parma_Polyhedra_Library {
//! Partitions \p q with respect to \p p.
/*! \relates Polyhedra_PowerSet
Let \p p and \p q be two polyhedra.
The function returns an object <CODE>r</CODE> of type
<CODE>std::pair\<PH, Polyhedra_PowerSet\<NNC_Polyhedron\> \></CODE>
such that
- <CODE>r.first</CODE> is the intersection of \p p and \p q;
- <CODE>r.second</CODE> has the property that all its elements are
not empty, pairwise disjoint, and disjoint from \p p;
- the union of <CODE>r.first</CODE> with all the elements of
<CODE>r.second</CODE> gives \p q (i.e., <CODE>r</CODE> is the
representation of a partition of \p q).
\if Include_Implementation_Details
See
<A HREF="http://www.cs.unipr.it/ppl/Documentation/bibliography#Srivastava93">
this paper</A> for more information about the implementation.
\endif
*/
template <typename PH>
std::pair<PH, Polyhedra_PowerSet<NNC_Polyhedron> >
linear_partition(const PH& p, const PH& q);
namespace {
template <typename PH>
void
linear_partition_aux(const Constraint& c,
PH& qq,
Polyhedra_PowerSet<NNC_Polyhedron>& r) {
LinExpression le(c);
Constraint neg_c = c.is_strict_inequality() ? (le <= 0) : (le < 0);
NNC_Polyhedron qqq(qq);
if (qqq.add_constraint_and_minimize(neg_c))
r.add_disjunct(qqq);
qq.add_constraint(c);
}
} // namespace
/*! \relates Polyhedra_PowerSet */
template <typename PH>
std::pair<PH, Polyhedra_PowerSet<NNC_Polyhedron> >
linear_partition(const PH& p, const PH& q) {
Polyhedra_PowerSet<NNC_Polyhedron> r(p.space_dimension(),
Polyhedron::EMPTY);
PH qq = q;
const ConSys& pcs = p.constraints();
for (ConSys::const_iterator i = pcs.begin(),
pcs_end = pcs.end(); i != pcs_end; ++i) {
const Constraint c = *i;
if (c.is_equality()) {
LinExpression le(c);
linear_partition_aux(le <= 0, qq, r);
linear_partition_aux(le >= 0, qq, r);
}
else
linear_partition_aux(c, qq, r);
}
return std::pair<PH, Polyhedra_PowerSet<NNC_Polyhedron> >(qq, r);
}
//! If the poly-hull between \p p and \p q is exact it is assigned to \p p.
/*! \relates Polyhedron */
template <typename PH>
bool
poly_hull_assign_if_exact(PH& p, const PH& q);
/*! \relates Polyhedron */
template <typename PH>
bool
poly_hull_assign_if_exact(PH& p, const PH& q) {
PH phull = p;
NNC_Polyhedron nnc_p(p);
phull.poly_hull_assign(q);
std::pair<PH, Polyhedra_PowerSet<NNC_Polyhedron> >
partition = linear_partition(q, phull);
const Polyhedra_PowerSet<NNC_Polyhedron>& s = partition.second;
typedef Polyhedra_PowerSet<NNC_Polyhedron>::const_iterator iter;
for (iter i = s.begin(), s_end = s.end(); i != s_end; ++i)
// The polyhedral hull is exact if and only if all the elements
// of the partition of the polyhedral hull of `p' and `q' with
// respect to `q' are included in `p'
if (!nnc_p.contains(i->element()))
return false;
p = phull;
return true;
}
template <typename PH>
bool
check_containment(const PH& ph, const Polyhedra_PowerSet<PH>& ps);
template <typename PH>
bool
check_containment(const PH& ph, const Polyhedra_PowerSet<PH>& ps) {
Polyhedra_PowerSet<NNC_Polyhedron> tmp(ph.space_dimension(),
Polyhedron::EMPTY);
tmp.add_disjunct(NNC_Polyhedron(ph));
for (typename Polyhedra_PowerSet<PH>::const_iterator i = ps.begin(),
ps_end = ps.end(); i != ps_end; ++i) {
const NNC_Polyhedron pi(i->element());
for (typename Polyhedra_PowerSet<NNC_Polyhedron>::iterator j = tmp.begin(),
jn = j; j != tmp.end(); j = jn) {
++jn;
const NNC_Polyhedron& pj = j->element();
if (pi.contains(pj))
tmp.erase(j);
}
if (tmp.empty())
return true;
else {
Polyhedra_PowerSet<NNC_Polyhedron> new_disjuncts(ph.space_dimension(),
Polyhedron::EMPTY);
for (Polyhedra_PowerSet<NNC_Polyhedron>::iterator j = tmp.begin(),
jn = j; j != tmp.end(); j = jn) {
++jn;
const NNC_Polyhedron& pj = j->element();
if (!pj.is_disjoint_from(pi)) {
std::pair<NNC_Polyhedron, Polyhedra_PowerSet<NNC_Polyhedron> >
partition = linear_partition(pi, pj);
tmp.erase(j);
new_disjuncts.add_disjunct(partition.first);
new_disjuncts.upper_bound_assign(partition.second);
}
}
tmp.upper_bound_assign(new_disjuncts);
}
}
return false;
}
} // namespace Parma_Polyhedra_Library
#endif // !defined(PPL_algorithms_hh)
syntax highlighted by Code2HTML, v. 0.9.1