boost.graph之属性

相关宏

BOOST_INSTALL_PROPERTY

#define BOOST_INSTALL_PROPERTY(KIND, NAME) \
  template <> struct property_kind<KIND##_##NAME##_t> { \
    typedef KIND##_property_tag type; \
  }

最终形式为

template <> 
struct property_kind<KIND_NAME_t> 
{
	typedef KIND_property_tag type;
}

是property_kind的模板特例化,看是点属性还是边属性

BOOST_DEF_PROPERTY

#define BOOST_DEF_PROPERTY(KIND, NAME) \
  enum KIND##_##NAME##_t { KIND##_##NAME }; \
  BOOST_INSTALL_PROPERTY(KIND, NAME)

最终形式为

enum KIND_NAME_T {KIND_NAME};
template <> 
struct property_kind<KIND_NAME_t> 
{
	typedef KIND_property_tag type;
}

定义边或者点的枚举,同时确定是边属性还是点属性

支持的点边属性

BOOST_INSTALL_PROPERTY(vertex, all);
  BOOST_INSTALL_PROPERTY(edge, all);
  BOOST_INSTALL_PROPERTY(graph, all);
  BOOST_DEF_PROPERTY(vertex, index);
  BOOST_DEF_PROPERTY(vertex, index1);
  BOOST_DEF_PROPERTY(vertex, index2);
  BOOST_DEF_PROPERTY(vertex, root);
  BOOST_DEF_PROPERTY(edge, index);
  BOOST_DEF_PROPERTY(edge, name);
  BOOST_DEF_PROPERTY(edge, weight);
  BOOST_DEF_PROPERTY(edge, weight2);
  BOOST_DEF_PROPERTY(edge, color);
  BOOST_DEF_PROPERTY(vertex, name);
  BOOST_DEF_PROPERTY(graph, name);
  BOOST_DEF_PROPERTY(vertex, distance);
  BOOST_DEF_PROPERTY(vertex, distance2);
  BOOST_DEF_PROPERTY(vertex, color);
  BOOST_DEF_PROPERTY(vertex, degree);
  BOOST_DEF_PROPERTY(vertex, in_degree);
  BOOST_DEF_PROPERTY(vertex, out_degree);
  BOOST_DEF_PROPERTY(vertex, current_degree);
  BOOST_DEF_PROPERTY(vertex, priority);
  BOOST_DEF_PROPERTY(vertex, discover_time);
  BOOST_DEF_PROPERTY(vertex, finish_time);
  BOOST_DEF_PROPERTY(vertex, predecessor);
  BOOST_DEF_PROPERTY(vertex, rank);
  BOOST_DEF_PROPERTY(vertex, centrality);
  BOOST_DEF_PROPERTY(vertex, lowpoint);
  BOOST_DEF_PROPERTY(vertex, potential);
  BOOST_DEF_PROPERTY(vertex, update);
  BOOST_DEF_PROPERTY(vertex, underlying);
  BOOST_DEF_PROPERTY(edge, reverse);
  BOOST_DEF_PROPERTY(edge, capacity);
  BOOST_DEF_PROPERTY(edge, flow);
  BOOST_DEF_PROPERTY(edge, residual_capacity);
  BOOST_DEF_PROPERTY(edge, centrality);
  BOOST_DEF_PROPERTY(edge, discover_time);
  BOOST_DEF_PROPERTY(edge, update);
  BOOST_DEF_PROPERTY(edge, finished);
  BOOST_DEF_PROPERTY(edge, underlying);
  BOOST_DEF_PROPERTY(graph, visitor);

  // These tags are used for property bundles
  // These three are defined in boost/pending/property.hpp
  BOOST_INSTALL_PROPERTY(graph, bundle);
  BOOST_INSTALL_PROPERTY(vertex, bundle);
  BOOST_INSTALL_PROPERTY(edge, bundle);

  // These tags are used to denote the owners and local descriptors
  // for the vertices and edges of a distributed graph.
  BOOST_DEF_PROPERTY(vertex, global);
  BOOST_DEF_PROPERTY(vertex, owner);
  BOOST_DEF_PROPERTY(vertex, local);
  BOOST_DEF_PROPERTY(edge, global);
  BOOST_DEF_PROPERTY(edge, owner);
  BOOST_DEF_PROPERTY(edge, local);
  BOOST_DEF_PROPERTY(vertex, local_index);
  BOOST_DEF_PROPERTY(edge, local_index);

获取属性类型

property_kind_from_graph,其定义为

template <typename G, typename Tag>
    struct property_kind_from_graph: property_kind<Tag> {};

使用

get分发

通过判断属性是边属性还是点属性分发到具体的函数

template <class Config, class Base, class Property>
    inline
    typename boost::property_map<typename Config::graph_type, Property>::type
    get(Property p, adj_list_helper<Config, Base>& g) {
      typedef typename detail::property_kind_from_graph<adj_list_helper<Config, Base>, Property>::type Kind;
      return detail::get_dispatch(g, p, Kind());
    }

如果是边属性,分发到

template <class Config, class Base, class Property>
      inline
      typename boost::property_map<typename Config::graph_type,
        Property>::type
      get_dispatch(adj_list_helper<Config,Base>&, Property p,
                   boost::edge_property_tag) {
        typedef typename Config::graph_type Graph;
        typedef typename boost::property_map<Graph, Property>::type PA;
        return PA(p);
      }

如果是点属性,分发到

template <class Config, class Base, class Property>
      inline
      typename boost::property_map<typename Config::graph_type,
        Property>::type
      get_dispatch(adj_list_helper<Config,Base>& g, Property p,
                   boost::vertex_property_tag) {
        typedef typename Config::graph_type Graph;
        typedef typename boost::property_map<Graph, Property>::type PA;
        return PA(&static_cast<Graph&>(g), p);
      }

property_map

根据属性看继承edge_property_map还是vertex_property_map

template <class Graph, class Property, class Enable = void>
  struct property_map:
    mpl::if_<
      is_same<typename detail::property_kind_from_graph<Graph, Property>::type, edge_property_tag>,
      detail::edge_property_map<Graph, Property>,
      detail::vertex_property_map<Graph, Property> >::type
  {};

edge_property_map

边属性映射

template <class Graph, class PropertyTag>
    struct edge_property_map
      : edge_property_selector<
          typename graph_tag_or_void<Graph>::type
        >::type::template bind_<
                            Graph,
                            typename edge_property_type<Graph>::type,
                            PropertyTag>
      {};

其依赖于图的类型graph_tag_or_void,参考boost.graph之graph_tag
依赖关系为

edge_property_map<Graph, PropertyTag>
edge_property_selector<GraphTag>

以邻接表adjacency_list为例

edge_property_map<Graph, PropertyTag>
adj_list_edge_property_selector::bind_<Graph, Property,Tag>
adj_list_choose_edge_pmap<Tag, Graph, Property>
adj_list_any_edge_pmap::bind_<Graph, Property, Tag>
adj_list_all_edge_pmap::bind_<Graph, Property, Tag>
adj_list_edge_all_properties_map<Directed, Property, PropRef, PropPtr, Vertex>
adj_list_edge_property_map<Directed, Value, Ref, Vertex, Property, Tag>

以图tag是adj_list_tag为例,其内部定义的type为adj_list_edge_property_selector

template <>
  struct edge_property_selector<adj_list_tag> {
    typedef detail::adj_list_edge_property_selector type;
  };

adj_list_edge_property_selector的定义为,其内部定义了模板类bind_,继承adj_list_choose_edge_pmap

struct adj_list_edge_property_selector {
      template <class Graph, class Property, class Tag>
      struct bind_: adj_list_choose_edge_pmap<Tag, Graph, Property> {};
    };

adj_list_choose_edge_pmap定义为类模板,其继承adj_list_any_edge_pmap的类模板bind_

template <class Tag, class Graph, class Property>
    struct adj_list_choose_edge_pmap
      : adj_list_choose_edge_pmap_helper<Tag>::type::template bind_<Graph, Property, Tag>
      {};

template <class Tag>
    struct adj_list_choose_edge_pmap_helper {
      typedef adj_list_any_edge_pmap type;
    };

adj_list_any_edge_pmap 定义为

struct adj_list_any_edge_pmap {
      template <class Graph, class Property, class Tag>
      struct bind_ {
        typedef typename property_value<Property,Tag>::type value_type;
        typedef value_type& reference;
        typedef const value_type& const_reference;

        typedef adj_list_edge_property_map
           <typename Graph::directed_category, value_type, reference,
            typename Graph::vertex_descriptor,Property,Tag> type;
        typedef adj_list_edge_property_map
           <typename Graph::directed_category, value_type, const_reference,
            typename Graph::vertex_descriptor,const Property, Tag> const_type;
      };
    };

所以get_dispatch中的PAadj_list_edge_property_map,其定义为

template <class Directed, class Value, class Ref, class Vertex,
              class Property, class Tag>
    struct adj_list_edge_property_map
      : public put_get_helper<
          Ref,
          adj_list_edge_property_map<Directed, Value, Ref, Vertex, Property,
            Tag>
        >
    {
      Tag tag;
      explicit adj_list_edge_property_map(Tag tag = Tag()): tag(tag) {}

      typedef Value value_type;
      typedef Ref reference;
      typedef detail::edge_desc_impl<Directed, Vertex> key_type;
      typedef boost::lvalue_property_map_tag category;
      inline Ref operator[](key_type e) const {
        Property& p = *(Property*)e.get_property();
        return get_property_value(p, tag);
      }
      inline Ref operator()(key_type e) const {
        return this->operator[](e);
      }
    };

vertex_property_map

点属性映射

template <class Graph, class PropertyTag>
    struct vertex_property_map
      : vertex_property_selector<
          typename graph_tag_or_void<Graph>::type
        >::type::template bind_<
                            Graph,
                            typename vertex_property_type<Graph>::type,
                            PropertyTag>
      {};

adj_list_tag依赖关系为

vertex_property_selector<adj_list_tag>
adj_list_vertex_property_selector::bind_<Graph, Property, Tag>
adj_list_choose_vertex_pa<Tag, Graph, Property>
adj_list_all_vertex_pa::bind_<Tag, Graph, Property>
adj_list_any_vertex_pa::bind_<Tag, Graph, Property>
adj_list_vertex_property_selector
adj_list_vertex_all_properties_map<Graph,Property, Property&>
adj_list_vertex_property_map<Graph, value_type, reference, Tag>

vec_adj_list_tag依赖关系为

vertex_property_selector<vec_adj_list_tag>
vec_adj_list_vertex_property_selector::bind_<Graph, Property, Tag>
vec_adj_list_choose_vertex_pa<Tag,Graph,Property>
vec_adj_list_id_vertex_pa::bind_<Tag, Graph,Property>
vec_adj_list_all_vertex_pa::bind_<Tag, Graph,Property>
vec_adj_list_any_vertex_pa::bind_<Tag, Graph,Property>
vec_adj_list_vertex_property_selector
vec_adj_list_vertex_id_map<Property, Vertex>
vec_adj_list_vertex_all_properties_map<Graph, Graph*, Property, Property&>
vec_adj_list_vertex_property_map<Graph, Graph*, value_type, reference, Tag>

对于tag为vertex_all_t使用的property_map为vec_adj_list_vertex_all_properties_map
对于tag为vertex_index_t,使用的property_map为vec_adj_list_vertex_id_map
其它tag,使用的是vec_adj_list_vertex_property_map

adj_list_tag

以图tag是adj_list_tag为例,其内部定义的type为adj_list_vertex_property_selector

template <>
  struct vertex_property_selector<adj_list_tag> {
    typedef adj_list_vertex_property_selector type;
  };

adj_list_vertex_property_selector 的定义为,其内部定义了模板类bind_,继承adj_list_choose_vertex_pa

struct adj_list_vertex_property_selector {
    template <class Graph, class Property, class Tag>
    struct bind_
      : detail::adj_list_choose_vertex_pa<Tag,Graph,Property>
    {};
  };

adj_list_choose_vertex_pa的定义为

template <class Tag, class Graph, class Property>
    struct adj_list_choose_vertex_pa
      : boost::mpl::if_<
          boost::is_same<Tag, vertex_all_t>,
          adj_list_all_vertex_pa,
          adj_list_any_vertex_pa>::type
        ::template bind_<Tag, Graph, Property>
    {};

其依赖Tag取adj_list_all_vertex_pa还是adj_list_any_vertex_pa,以adj_list_any_vertex_pa为例

struct adj_list_any_vertex_pa {
      template <class Tag, class Graph, class Property>
      struct bind_ {
        typedef typename property_value<Property, Tag>::type value_type;
        typedef value_type& reference;
        typedef const value_type& const_reference;

        typedef adj_list_vertex_property_map
          <Graph, value_type, reference, Tag> type;
        typedef adj_list_vertex_property_map
          <Graph, value_type, const_reference, Tag> const_type;
      };
    };

所以get_dispatch中的PAadj_list_vertex_property_map,其定义为

template <class Graph, class ValueType, class Reference, class Tag>
    struct adj_list_vertex_property_map
      : public boost::put_get_helper<
          Reference,
          adj_list_vertex_property_map<Graph, ValueType, Reference, Tag>
        >
    {
      typedef typename Graph::stored_vertex StoredVertex;
      typedef ValueType value_type;
      typedef Reference reference;
      typedef typename Graph::vertex_descriptor key_type;
      typedef boost::lvalue_property_map_tag category;
      inline adj_list_vertex_property_map(const Graph* = 0, Tag tag = Tag()): m_tag(tag) { }
      inline Reference operator[](key_type v) const {
        StoredVertex* sv = (StoredVertex*)v;
        return get_property_value(sv->m_property, m_tag);
      }
      inline Reference operator()(key_type v) const {
        return this->operator[](v);
      }
      Tag m_tag;
    };

vec_adj_list_tag

对于tag类型为vertex_index_t,vec_adj_list_vertex_id_map是直接返回点描述符

template <class Property, class Vertex>
    struct vec_adj_list_vertex_id_map
      : public boost::put_get_helper<
          Vertex, vec_adj_list_vertex_id_map<Property, Vertex>
        >
    {
      typedef Vertex value_type;
      typedef Vertex key_type;
      typedef Vertex reference;
      typedef boost::readable_property_map_tag category;
      inline vec_adj_list_vertex_id_map() { }
      template <class Graph>
      inline vec_adj_list_vertex_id_map(const Graph&, vertex_index_t) { }
      inline value_type operator[](key_type v) const { return v; }
      inline value_type operator()(key_type v) const { return v; }
    };
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

kgduu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值