]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/boost/boost/graph/tiernan_all_cycles.hpp
update source to Ceph Pacific 16.2.2
[ceph.git] / ceph / src / boost / boost / graph / tiernan_all_cycles.hpp
index d4527d5523766ab9c96a5d9b724543cda3fa5e5b..c24c87553f058afbc225772b89a69a16a4f339d1 100644 (file)
 #include <boost/concept/assert.hpp>
 
 #include <boost/concept/detail/concept_def.hpp>
-namespace boost {
-    namespace concepts {
-        BOOST_concept(CycleVisitor,(Visitor)(Path)(Graph))
-        {
-            BOOST_CONCEPT_USAGE(CycleVisitor)
-            {
-                vis.cycle(p, g);
-            }
-        private:
-            Visitor vis;
-            Graph g;
-            Path p;
-        };
-    } /* namespace concepts */
+namespace boost
+{
+namespace concepts
+{
+    BOOST_concept(CycleVisitor, (Visitor)(Path)(Graph))
+    {
+        BOOST_CONCEPT_USAGE(CycleVisitor) { vis.cycle(p, g); }
+
+    private:
+        Visitor vis;
+        Graph g;
+        Path p;
+    };
+} /* namespace concepts */
 using concepts::CycleVisitorConcept;
 } /* namespace boost */
 #include <boost/concept/detail/concept_undef.hpp>
 
-
 namespace boost
 {
 
@@ -43,43 +42,35 @@ namespace boost
 //
 //     @article{362819,
 //         author = {James C. Tiernan},
-//         title = {An efficient search algorithm to find the elementary circuits of a graph},
-//         journal = {Commun. ACM},
-//         volume = {13},
-//         number = {12},
-//         year = {1970},
-//         issn = {0001-0782},
-//         pages = {722--726},
-//         doi = {http://doi.acm.org/10.1145/362814.362819},
+//         title = {An efficient search algorithm to find the elementary
+//         circuits of a graph}, journal = {Commun. ACM}, volume = {13}, number
+//         = {12}, year = {1970}, issn = {0001-0782}, pages = {722--726}, doi =
+//         {http://doi.acm.org/10.1145/362814.362819},
 //             publisher = {ACM Press},
 //             address = {New York, NY, USA},
 //         }
 //
-// It should be pointed out that the author does not provide a complete analysis for
-// either time or space. This is in part, due to the fact that it's a fairly input
-// sensitive problem related to the density and construction of the graph, not just
-// its size.
+// It should be pointed out that the author does not provide a complete analysis
+// for either time or space. This is in part, due to the fact that it's a fairly
+// input sensitive problem related to the density and construction of the graph,
+// not just its size.
 //
-// I've also taken some liberties with the interpretation of the algorithm - I've
-// basically modernized it to use real data structures (no more arrays and matrices).
-// Oh... and there's explicit control structures - not just gotos.
+// I've also taken some liberties with the interpretation of the algorithm -
+// I've basically modernized it to use real data structures (no more arrays and
+// matrices). Oh... and there's explicit control structures - not just gotos.
 //
 // The problem is definitely NP-complete, an unbounded implementation of this
 // will probably run for quite a while on a large graph. The conclusions
 // of this paper also reference a Paton algorithm for undirected graphs as being
-// much more efficient (apparently based on spanning trees). Although not implemented,
-// it can be found here:
+// much more efficient (apparently based on spanning trees). Although not
+// implemented, it can be found here:
 //
 //     @article{363232,
 //         author = {Keith Paton},
-//         title = {An algorithm for finding a fundamental set of cycles of a graph},
-//         journal = {Commun. ACM},
-//         volume = {12},
-//         number = {9},
-//         year = {1969},
-//         issn = {0001-0782},
-//         pages = {514--518},
-//         doi = {http://doi.acm.org/10.1145/363219.363232},
+//         title = {An algorithm for finding a fundamental set of cycles of a
+//         graph}, journal = {Commun. ACM}, volume = {12}, number = {9}, year =
+//         {1969}, issn = {0001-0782}, pages = {514--518}, doi =
+//         {http://doi.acm.org/10.1145/363219.363232},
 //             publisher = {ACM Press},
 //             address = {New York, NY, USA},
 //         }
@@ -90,9 +81,10 @@ namespace boost
  */
 struct cycle_visitor
 {
-    template <typename Path, typename Graph>
+    template < typename Path, typename Graph >
     inline void cycle(const Path& p, const Graph& g)
-    { }
+    {
+    }
 };
 
 /**
@@ -102,69 +94,66 @@ struct cycle_visitor
 struct min_max_cycle_visitor
 {
     min_max_cycle_visitor(std::size_t& min_, std::size_t& max_)
-        : minimum(min_), maximum(max_)
-    { }
+    : minimum(min_), maximum(max_)
+    {
+    }
 
-    template <typename Path, typename Graph>
+    template < typename Path, typename Graph >
     inline void cycle(const Path& p, const Graph& g)
     {
         BOOST_USING_STD_MIN();
         BOOST_USING_STD_MAX();
         std::size_t len = p.size();
-        minimum = min BOOST_PREVENT_MACRO_SUBSTITUTION (minimum, len);
-        maximum = max BOOST_PREVENT_MACRO_SUBSTITUTION (maximum, len);
+        minimum = min BOOST_PREVENT_MACRO_SUBSTITUTION(minimum, len);
+        maximum = max BOOST_PREVENT_MACRO_SUBSTITUTION(maximum, len);
     }
     std::size_t& minimum;
     std::size_t& maximum;
 };
 
-inline min_max_cycle_visitor
-find_min_max_cycle(std::size_t& min_, std::size_t& max_)
-{ return min_max_cycle_visitor(min_, max_); }
+inline min_max_cycle_visitor find_min_max_cycle(
+    std::size_t& min_, std::size_t& max_)
+{
+    return min_max_cycle_visitor(min_, max_);
+}
 
 namespace detail
 {
-    template <typename Graph, typename Path>
-    inline bool
-    is_vertex_in_path(const Graph&,
-                        typename graph_traits<Graph>::vertex_descriptor v,
-                        const Path& p)
+    template < typename Graph, typename Path >
+    inline bool is_vertex_in_path(const Graph&,
+        typename graph_traits< Graph >::vertex_descriptor v, const Path& p)
     {
         return (std::find(p.begin(), p.end(), v) != p.end());
     }
 
-    template <typename Graph, typename ClosedMatrix>
-    inline bool
-    is_path_closed(const Graph& g,
-                    typename graph_traits<Graph>::vertex_descriptor u,
-                    typename graph_traits<Graph>::vertex_descriptor v,
-                    const ClosedMatrix& closed)
+    template < typename Graph, typename ClosedMatrix >
+    inline bool is_path_closed(const Graph& g,
+        typename graph_traits< Graph >::vertex_descriptor u,
+        typename graph_traits< Graph >::vertex_descriptor v,
+        const ClosedMatrix& closed)
     {
         // the path from u to v is closed if v can be found in the list
         // of closed vertices associated with u.
         typedef typename ClosedMatrix::const_reference Row;
         Row r = closed[get(vertex_index, g, u)];
-        if(find(r.begin(), r.end(), v) != r.end()) {
+        if (find(r.begin(), r.end(), v) != r.end())
+        {
             return true;
         }
         return false;
     }
 
-    template <typename Graph, typename Path, typename ClosedMatrix>
-    inline bool
-    can_extend_path(const Graph& g,
-                    typename graph_traits<Graph>::edge_descriptor e,
-                    const Path& p,
-                    const ClosedMatrix& m)
+    template < typename Graph, typename Path, typename ClosedMatrix >
+    inline bool can_extend_path(const Graph& g,
+        typename graph_traits< Graph >::edge_descriptor e, const Path& p,
+        const ClosedMatrix& m)
     {
-        BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept<Graph> ));
-        BOOST_CONCEPT_ASSERT(( VertexIndexGraphConcept<Graph> ));
-        typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+        BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >));
+        BOOST_CONCEPT_ASSERT((VertexIndexGraphConcept< Graph >));
+        typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
 
         // get the vertices in question
-        Vertex
-            u = source(e, g),
-            v = target(e, g);
+        Vertex u = source(e, g), v = target(e, g);
 
         // conditions for allowing a traversal along this edge are:
         // 1. the index of v must be greater than that at which the
@@ -172,61 +161,59 @@ namespace detail
         // 2. the vertex v cannot already be in the path
         // 3. the vertex v cannot be closed to the vertex u
 
-        bool indices = get(vertex_index, g, p.front()) < get(vertex_index, g, v);
+        bool indices
+            = get(vertex_index, g, p.front()) < get(vertex_index, g, v);
         bool path = !is_vertex_in_path(g, v, p);
         bool closed = !is_path_closed(g, u, v, m);
         return indices && path && closed;
     }
 
-    template <typename Graph, typename Path>
-    inline bool
-    can_wrap_path(const Graph& g, const Path& p)
+    template < typename Graph, typename Path >
+    inline bool can_wrap_path(const Graph& g, const Path& p)
     {
-        BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept<Graph> ));
-        typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
-        typedef typename graph_traits<Graph>::out_edge_iterator OutIterator;
+        BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >));
+        typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+        typedef typename graph_traits< Graph >::out_edge_iterator OutIterator;
 
         // iterate over the out-edges of the back, looking for the
         // front of the path. also, we can't travel along the same
         // edge that we did on the way here, but we don't quite have the
         // stringent requirements that we do in can_extend_path().
-        Vertex
-            u = p.back(),
-            v = p.front();
+        Vertex u = p.back(), v = p.front();
         OutIterator i, end;
-        for(boost::tie(i, end) = out_edges(u, g); i != end; ++i) {
-            if((target(*i, g) == v)) {
+        for (boost::tie(i, end) = out_edges(u, g); i != end; ++i)
+        {
+            if ((target(*i, g) == v))
+            {
                 return true;
             }
         }
         return false;
     }
 
-    template <typename Graph,
-        typename Path,
-        typename ClosedMatrix>
-    inline typename graph_traits<Graph>::vertex_descriptor
-    extend_path(const Graph& g,
-                Path& p,
-                ClosedMatrix& closed)
+    template < typename Graph, typename Path, typename ClosedMatrix >
+    inline typename graph_traits< Graph >::vertex_descriptor extend_path(
+        const Graph& g, Path& p, ClosedMatrix& closed)
     {
-        BOOST_CONCEPT_ASSERT(( IncidenceGraphConcept<Graph> ));
-        typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
-        typedef typename graph_traits<Graph>::out_edge_iterator OutIterator;
+        BOOST_CONCEPT_ASSERT((IncidenceGraphConcept< Graph >));
+        typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+        typedef typename graph_traits< Graph >::out_edge_iterator OutIterator;
 
         // get the current vertex
         Vertex u = p.back();
-        Vertex ret = graph_traits<Graph>::null_vertex();
+        Vertex ret = graph_traits< Graph >::null_vertex();
 
         // AdjacencyIterator i, end;
         OutIterator i, end;
-        for(boost::tie(i, end) = out_edges(u, g); i != end; ++i) {
+        for (boost::tie(i, end) = out_edges(u, g); i != end; ++i)
+        {
             Vertex v = target(*i, g);
 
             // if we can actually extend along this edge,
             // then that's what we want to do
-            if(can_extend_path(g, *i, p, closed)) {
-                p.push_back(v);         // add the vertex to the path
+            if (can_extend_path(g, *i, p, closed))
+            {
+                p.push_back(v); // add the vertex to the path
                 ret = v;
                 break;
             }
@@ -234,17 +221,17 @@ namespace detail
         return ret;
     }
 
-    template <typename Graph, typename Path, typename ClosedMatrix>
-    inline bool
-    exhaust_paths(const Graph& g, Path& p, ClosedMatrix& closed)
+    template < typename Graph, typename Path, typename ClosedMatrix >
+    inline bool exhaust_paths(const Graph& g, Path& p, ClosedMatrix& closed)
     {
-        BOOST_CONCEPT_ASSERT(( GraphConcept<Graph> ));
-        typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
+        BOOST_CONCEPT_ASSERT((GraphConcept< Graph >));
+        typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
 
         // if there's more than one vertex in the path, this closes
         // of some possible routes and returns true. otherwise, if there's
         // only one vertex left, the vertex has been used up
-        if(p.size() > 1) {
+        if (p.size() > 1)
+        {
             // get the last and second to last vertices, popping the last
             // vertex off the path
             Vertex last, prev;
@@ -259,49 +246,50 @@ namespace detail
             closed[get(vertex_index, g, prev)].push_back(last);
             return true;
         }
-        else {
+        else
+        {
             return false;
         }
     }
 
-    template <typename Graph, typename Visitor>
-    inline void
-    all_cycles_from_vertex(const Graph& g,
-                            typename graph_traits<Graph>::vertex_descriptor v,
-                            Visitor vis,
-                            std::size_t minlen,
-                            std::size_t maxlen)
+    template < typename Graph, typename Visitor >
+    inline void all_cycles_from_vertex(const Graph& g,
+        typename graph_traits< Graph >::vertex_descriptor v, Visitor vis,
+        std::size_t minlen, std::size_t maxlen)
     {
-        BOOST_CONCEPT_ASSERT(( VertexListGraphConcept<Graph> ));
-        typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
-        typedef std::vector<Vertex> Path;
-        BOOST_CONCEPT_ASSERT(( CycleVisitorConcept<Visitor,Path,Graph> ));
-        typedef std::vector<Vertex> VertexList;
-        typedef std::vector<VertexList> ClosedMatrix;
+        BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
+        typedef typename graph_traits< Graph >::vertex_descriptor Vertex;
+        typedef std::vector< Vertex > Path;
+        BOOST_CONCEPT_ASSERT((CycleVisitorConcept< Visitor, Path, Graph >));
+        typedef std::vector< Vertex > VertexList;
+        typedef std::vector< VertexList > ClosedMatrix;
 
         Path p;
         ClosedMatrix closed(num_vertices(g), VertexList());
-        Vertex null = graph_traits<Graph>::null_vertex();
+        Vertex null = graph_traits< Graph >::null_vertex();
 
         // each path investigation starts at the ith vertex
         p.push_back(v);
 
-        while(1) {
+        while (1)
+        {
             // extend the path until we've reached the end or the
             // maxlen-sized cycle
             Vertex j = null;
-            while(((j = detail::extend_path(g, p, closed)) != null)
-                    && (p.size() < maxlen))
+            while (((j = detail::extend_path(g, p, closed)) != null)
+                && (p.size() < maxlen))
                 ; // empty loop
 
             // if we're done extending the path and there's an edge
             // connecting the back to the front, then we should have
             // a cycle.
-            if(detail::can_wrap_path(g, p) && p.size() >= minlen) {
+            if (detail::can_wrap_path(g, p) && p.size() >= minlen)
+            {
                 vis.cycle(p, g);
             }
 
-            if(!detail::exhaust_paths(g, p, closed)) {
+            if (!detail::exhaust_paths(g, p, closed))
+            {
                 break;
             }
         }
@@ -309,67 +297,75 @@ namespace detail
 
     // Select the minimum allowable length of a cycle based on the directedness
     // of the graph - 2 for directed, 3 for undirected.
-    template <typename D> struct min_cycles { enum { value = 2 }; };
-    template <> struct min_cycles<undirected_tag> { enum { value = 3 }; };
+    template < typename D > struct min_cycles
+    {
+        enum
+        {
+            value = 2
+        };
+    };
+    template <> struct min_cycles< undirected_tag >
+    {
+        enum
+        {
+            value = 3
+        };
+    };
 } /* namespace detail */
 
-template <typename Graph, typename Visitor>
-inline void
-tiernan_all_cycles(const Graph& g,
-                    Visitor vis,
-                    std::size_t minlen,
-                    std::size_t maxlen)
+template < typename Graph, typename Visitor >
+inline void tiernan_all_cycles(
+    const Graph& g, Visitor vis, std::size_t minlen, std::size_t maxlen)
 {
-    BOOST_CONCEPT_ASSERT(( VertexListGraphConcept<Graph> ));
-    typedef typename graph_traits<Graph>::vertex_iterator VertexIterator;
+    BOOST_CONCEPT_ASSERT((VertexListGraphConcept< Graph >));
+    typedef typename graph_traits< Graph >::vertex_iterator VertexIterator;
 
     VertexIterator i, end;
-    for(boost::tie(i, end) = vertices(g); i != end; ++i) {
+    for (boost::tie(i, end) = vertices(g); i != end; ++i)
+    {
         detail::all_cycles_from_vertex(g, *i, vis, minlen, maxlen);
     }
 }
 
-template <typename Graph, typename Visitor>
-inline void
-tiernan_all_cycles(const Graph& g, Visitor vis, std::size_t maxlen)
+template < typename Graph, typename Visitor >
+inline void tiernan_all_cycles(const Graph& g, Visitor vis, std::size_t maxlen)
 {
-    typedef typename graph_traits<Graph>::directed_category Dir;
-    tiernan_all_cycles(g, vis, detail::min_cycles<Dir>::value, maxlen);
+    typedef typename graph_traits< Graph >::directed_category Dir;
+    tiernan_all_cycles(g, vis, detail::min_cycles< Dir >::value, maxlen);
 }
 
-template <typename Graph, typename Visitor>
-inline void
-tiernan_all_cycles(const Graph& g, Visitor vis)
+template < typename Graph, typename Visitor >
+inline void tiernan_all_cycles(const Graph& g, Visitor vis)
 {
-    typedef typename graph_traits<Graph>::directed_category Dir;
-    tiernan_all_cycles(g, vis, detail::min_cycles<Dir>::value,
-                       (std::numeric_limits<std::size_t>::max)());
+    typedef typename graph_traits< Graph >::directed_category Dir;
+    tiernan_all_cycles(g, vis, detail::min_cycles< Dir >::value,
+        (std::numeric_limits< std::size_t >::max)());
 }
 
-template <typename Graph>
-inline std::pair<std::size_t, std::size_t>
-tiernan_girth_and_circumference(const Graph& g)
+template < typename Graph >
+inline std::pair< std::size_t, std::size_t > tiernan_girth_and_circumference(
+    const Graph& g)
 {
-    std::size_t
-        min_ = (std::numeric_limits<std::size_t>::max)(),
-        max_ = 0;
+    std::size_t min_ = (std::numeric_limits< std::size_t >::max)(), max_ = 0;
     tiernan_all_cycles(g, find_min_max_cycle(min_, max_));
 
     // if this is the case, the graph is acyclic...
-    if(max_ == 0) max_ = min_;
+    if (max_ == 0)
+        max_ = min_;
 
     return std::make_pair(min_, max_);
 }
 
-template <typename Graph>
-inline std::size_t
-tiernan_girth(const Graph& g)
-{ return tiernan_girth_and_circumference(g).first; }
+template < typename Graph > inline std::size_t tiernan_girth(const Graph& g)
+{
+    return tiernan_girth_and_circumference(g).first;
+}
 
-template <typename Graph>
-inline std::size_t
-tiernan_circumference(const Graph& g)
-{ return tiernan_girth_and_circumference(g).second; }
+template < typename Graph >
+inline std::size_t tiernan_circumference(const Graph& g)
+{
+    return tiernan_girth_and_circumference(g).second;
+}
 
 } /* namespace boost */