subgraph.hpp

来自「CGAL is a collaborative effort of severa」· HPP 代码 · 共 862 行 · 第 1/2 页

HPP
862
字号
//=======================================================================// Copyright 2001 University of Notre Dame.// Authors: Jeremy G. Siek and Lie-Quan Lee//// This file is part of the Boost Graph Library//// You should have received a copy of the License Agreement for the// Boost Graph Library along with the software; see the file LICENSE.// If not, contact Office of Research, University of Notre Dame, Notre// Dame, IN 46556.//// Permission to modify the code and to distribute modified code is// granted, provided the text of this NOTICE is retained, a notice that// the code was modified is included with the above COPYRIGHT NOTICE and// with the COPYRIGHT NOTICE in the LICENSE file, and that the LICENSE// file is distributed with the modified code.//// LICENSOR MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED.// By way of example, but not limitation, Licensor MAKES NO// REPRESENTATIONS OR WARRANTIES OF MERCHANTABILITY OR FITNESS FOR ANY// PARTICULAR PURPOSE OR THAT THE USE OF THE LICENSED SOFTWARE COMPONENTS// OR DOCUMENTATION WILL NOT INFRINGE ANY PATENTS, COPYRIGHTS, TRADEMARKS// OR OTHER RIGHTS.//=======================================================================#ifndef BOOST_SUBGRAPH_HPP#define BOOST_SUBGRAPH_HPP// UNDER CONSTRUCTION#include <boost/config.hpp>#include <list>#include <vector>#include <map>#include <cassert>#include <boost/graph/graph_traits.hpp>#include <boost/graph/properties.hpp>#include <boost/iterator/indirect_iterator.hpp>#include <boost/static_assert.hpp>#include <boost/type_traits/is_same.hpp>namespace boost {  struct subgraph_tag { };  // Invariants of an induced subgraph:  //   - If vertex u is in subgraph g, then u must be in g.parent().  //   - If edge e is in subgraph g, then e must be in g.parent().  //   - If edge e=(u,v) is in the root graph, then edge e  //     is also in any subgraph that contains both vertex u and v.  // The Graph template parameter must have a vertex_index  // and edge_index internal property. It is assumed that  // the vertex indices are assigned automatically by the  // graph during a call to add_vertex(). It is not  // assumed that the edge vertices are assigned automatically,  // they are explicitly assigned here.  template <typename Graph>  class subgraph {    typedef graph_traits<Graph> Traits;    typedef std::list<subgraph<Graph>*> ChildrenList;  public:    // Graph requirements    typedef typename Traits::vertex_descriptor         vertex_descriptor;    typedef typename Traits::edge_descriptor           edge_descriptor;    typedef typename Traits::directed_category         directed_category;    typedef typename Traits::edge_parallel_category    edge_parallel_category;    typedef typename Traits::traversal_category        traversal_category;    static vertex_descriptor null_vertex()    {      return Traits::null_vertex();    }    // IncidenceGraph requirements    typedef typename Traits::out_edge_iterator         out_edge_iterator;    typedef typename Traits::degree_size_type          degree_size_type;    // AdjacencyGraph requirements    typedef typename Traits::adjacency_iterator        adjacency_iterator;    // VertexListGraph requirements    typedef typename Traits::vertex_iterator           vertex_iterator;    typedef typename Traits::vertices_size_type        vertices_size_type;    // EdgeListGraph requirements    typedef typename Traits::edge_iterator             edge_iterator;    typedef typename Traits::edges_size_type           edges_size_type;    typedef typename Traits::in_edge_iterator          in_edge_iterator;    typedef typename Graph::edge_property_type         edge_property_type;    typedef typename Graph::vertex_property_type       vertex_property_type;    typedef subgraph_tag                               graph_tag;    typedef Graph                                      graph_type;    typedef typename Graph::graph_property_type        graph_property_type;    // Constructors    // Create the main graph, the root of the subgraph tree    subgraph()      : m_parent(0), m_edge_counter(0)    { }    subgraph(const graph_property_type& p)      : m_graph(p), m_parent(0), m_edge_counter(0)    { }    subgraph(vertices_size_type n,             const graph_property_type& p = graph_property_type())      : m_graph(n, p), m_parent(0), m_edge_counter(0), m_global_vertex(n)    {      typename Graph::vertex_iterator v, v_end;      vertices_size_type i = 0;      for (tie(v, v_end) = vertices(m_graph); v != v_end; ++v)        m_global_vertex[i++] = *v;    }    // copy constructor    subgraph(const subgraph& x)      : m_graph(x.m_graph), m_parent(x.m_parent),      m_edge_counter(x.m_edge_counter),      m_global_vertex(x.m_global_vertex),      m_global_edge(x.m_global_edge)    {      // Do a deep copy      for (typename ChildrenList::const_iterator i = x.m_children.begin();           i != x.m_children.end(); ++i)        m_children.push_back(new subgraph<Graph>( **i ));    }    ~subgraph() {      for (typename ChildrenList::iterator i = m_children.begin();           i != m_children.end(); ++i)        delete *i;    }    // Create a subgraph    subgraph<Graph>& create_subgraph() {      m_children.push_back(new subgraph<Graph>());      m_children.back()->m_parent = this;      return *m_children.back();    }    // Create a subgraph with the specified vertex set.    template <typename VertexIterator>    subgraph<Graph>& create_subgraph(VertexIterator first,                                     VertexIterator last)    {      m_children.push_back(new subgraph<Graph>());      m_children.back()->m_parent = this;      for (; first != last; ++first)        add_vertex(*first, *m_children.back());      return *m_children.back();    }    // local <-> global descriptor conversion functions    vertex_descriptor local_to_global(vertex_descriptor u_local) const    {      return m_global_vertex[u_local];    }    vertex_descriptor global_to_local(vertex_descriptor u_global) const    {      vertex_descriptor u_local; bool in_subgraph;      tie(u_local, in_subgraph) = this->find_vertex(u_global);      assert(in_subgraph == true);      return u_local;    }    edge_descriptor local_to_global(edge_descriptor e_local) const    {      return m_global_edge[get(get(edge_index, m_graph), e_local)];    }    edge_descriptor global_to_local(edge_descriptor e_global) const    {      return        (*m_local_edge.find(get(get(edge_index, root().m_graph), e_global))).second;    }    // Is vertex u (of the root graph) contained in this subgraph?    // If so, return the matching local vertex.    std::pair<vertex_descriptor, bool>    find_vertex(vertex_descriptor u_global) const    {      typename std::map<vertex_descriptor, vertex_descriptor>::const_iterator        i = m_local_vertex.find(u_global);      bool valid = i != m_local_vertex.end();      return std::make_pair((valid ? (*i).second : null_vertex()), valid);    }    // Return the parent graph.    subgraph& parent() { return *m_parent; }    const subgraph& parent() const { return *m_parent; }    bool is_root() const { return m_parent == 0; }    // Return the root graph of the subgraph tree.    subgraph& root() {      if (this->is_root())        return *this;      else        return m_parent->root();    }    const subgraph& root() const {      if (this->is_root())        return *this;      else        return m_parent->root();    }    // Return the children subgraphs of this graph/subgraph.    // Use a list of pointers because the VC++ std::list doesn't like    // storing incomplete type.    typedef indirect_iterator<        typename ChildrenList::const_iterator      , subgraph<Graph>      , std::bidirectional_iterator_tag    >    children_iterator;    typedef indirect_iterator<        typename ChildrenList::const_iterator      , subgraph<Graph> const      , std::bidirectional_iterator_tag    >    const_children_iterator;    std::pair<const_children_iterator, const_children_iterator>    children() const    {      return std::make_pair(const_children_iterator(m_children.begin()),                            const_children_iterator(m_children.end()));    }    std::pair<children_iterator, children_iterator>    children()    {      return std::make_pair(children_iterator(m_children.begin()),                            children_iterator(m_children.end()));    }    std::size_t num_children() const { return m_children.size(); }    //  private:    typedef typename property_map<Graph, edge_index_t>::type EdgeIndexMap;    typedef typename property_traits<EdgeIndexMap>::value_type edge_index_type;    BOOST_STATIC_ASSERT((!is_same<edge_index_type,                         boost::detail::error_property_not_found>::value));    Graph m_graph;    subgraph<Graph>* m_parent;    edge_index_type m_edge_counter; // for generating unique edge indices    ChildrenList m_children;    std::vector<vertex_descriptor> m_global_vertex; // local -> global    std::map<vertex_descriptor, vertex_descriptor> m_local_vertex;  // global -> local    std::vector<edge_descriptor> m_global_edge;              // local -> global    std::map<edge_index_type, edge_descriptor> m_local_edge; // global -> local    edge_descriptor    local_add_edge(vertex_descriptor u_local, vertex_descriptor v_local,                   edge_descriptor e_global)    {      edge_descriptor e_local;      bool inserted;      tie(e_local, inserted) = add_edge(u_local, v_local, m_graph);      put(edge_index, m_graph, e_local, m_edge_counter++);      m_global_edge.push_back(e_global);      m_local_edge[get(get(edge_index, this->root()), e_global)] = e_local;      return e_local;    }  };  //===========================================================================  // Functions special to the Subgraph Class  template <typename G>  typename subgraph<G>::vertex_descriptor  add_vertex(typename subgraph<G>::vertex_descriptor u_global,             subgraph<G>& g)  {    assert(!g.is_root());    typename subgraph<G>::vertex_descriptor u_local, v_global, uu_global;    typename subgraph<G>::edge_descriptor e_global;    u_local = add_vertex(g.m_graph);    g.m_global_vertex.push_back(u_global);    g.m_local_vertex[u_global] = u_local;    subgraph<G>& r = g.root();    // remember edge global and local maps    {      typename subgraph<G>::out_edge_iterator ei, ei_end;      for (tie(ei, ei_end) = out_edges(u_global, r);           ei != ei_end; ++ei) {        e_global = *ei;        v_global = target(e_global, r);        if (g.find_vertex(v_global).second == true)          g.local_add_edge(u_local, g.global_to_local(v_global), e_global);      }    }    if (is_directed(g)) { // not necessary for undirected graph      typename subgraph<G>::vertex_iterator vi, vi_end;      typename subgraph<G>::out_edge_iterator ei, ei_end;      for (tie(vi, vi_end) = vertices(r); vi != vi_end; ++vi) {        v_global = *vi;        if (g.find_vertex(v_global).second)          for (tie(ei, ei_end) = out_edges(*vi, r); ei != ei_end; ++ei) {            e_global = *ei;            uu_global = target(e_global, r);            if (uu_global == u_global && g.find_vertex(v_global).second)              g.local_add_edge(g.global_to_local(v_global), u_local, e_global);          }      }    }    return u_local;  }  //===========================================================================  // Functions required by the IncidenceGraph concept  template <typename G>  std::pair<typename graph_traits<G>::out_edge_iterator,            typename graph_traits<G>::out_edge_iterator>  out_edges(typename graph_traits<G>::vertex_descriptor u_local,            const subgraph<G>& g)    { return out_edges(u_local, g.m_graph); }  template <typename G>  typename graph_traits<G>::degree_size_type  out_degree(typename graph_traits<G>::vertex_descriptor u_local,             const subgraph<G>& g)    { return out_degree(u_local, g.m_graph); }  template <typename G>  typename graph_traits<G>::vertex_descriptor  source(typename graph_traits<G>::edge_descriptor e_local,         const subgraph<G>& g)    { return source(e_local, g.m_graph); }  template <typename G>  typename graph_traits<G>::vertex_descriptor  target(typename graph_traits<G>::edge_descriptor e_local,         const subgraph<G>& g)    { return target(e_local, g.m_graph); }  //===========================================================================  // Functions required by the BidirectionalGraph concept  template <typename G>  std::pair<typename graph_traits<G>::in_edge_iterator,            typename graph_traits<G>::in_edge_iterator>  in_edges(typename graph_traits<G>::vertex_descriptor u_local,            const subgraph<G>& g)    { return in_edges(u_local, g.m_graph); }  template <typename G>  typename graph_traits<G>::degree_size_type  in_degree(typename graph_traits<G>::vertex_descriptor u_local,             const subgraph<G>& g)    { return in_degree(u_local, g.m_graph); }  template <typename G>  typename graph_traits<G>::degree_size_type  degree(typename graph_traits<G>::vertex_descriptor u_local,             const subgraph<G>& g)    { return degree(u_local, g.m_graph); }  //===========================================================================  // Functions required by the AdjacencyGraph concept  template <typename G>  std::pair<typename subgraph<G>::adjacency_iterator,            typename subgraph<G>::adjacency_iterator>  adjacent_vertices(typename subgraph<G>::vertex_descriptor u_local,                    const subgraph<G>& g)    { return adjacent_vertices(u_local, g.m_graph); }  //===========================================================================  // Functions required by the VertexListGraph concept  template <typename G>  std::pair<typename subgraph<G>::vertex_iterator,            typename subgraph<G>::vertex_iterator>  vertices(const subgraph<G>& g)    { return vertices(g.m_graph); }  template <typename G>  typename subgraph<G>::vertices_size_type  num_vertices(const subgraph<G>& g)    { return num_vertices(g.m_graph); }  //===========================================================================  // Functions required by the EdgeListGraph concept  template <typename G>  std::pair<typename subgraph<G>::edge_iterator,            typename subgraph<G>::edge_iterator>  edges(const subgraph<G>& g)    { return edges(g.m_graph); }  template <typename G>  typename subgraph<G>::edges_size_type  num_edges(const subgraph<G>& g)    { return num_edges(g.m_graph); }  //===========================================================================  // Functions required by the AdjacencyMatrix concept  template <typename G>  std::pair<typename subgraph<G>::edge_descriptor, bool>  edge(typename subgraph<G>::vertex_descriptor u_local,       typename subgraph<G>::vertex_descriptor v_local,       const subgraph<G>& g)  {    return edge(u_local, v_local, g.m_graph);  }  //===========================================================================  // Functions required by the MutableGraph concept  namespace detail {    template <typename Vertex, typename Edge, typename Graph>    void add_edge_recur_down    (Vertex u_global, Vertex v_global, Edge e_global, subgraph<Graph>& g);

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?