boost graph之基础

结构

在这里插入图片描述

属性相关

put_get_helper<Reference, LvaluePropertyMap>
iterator_property_map<RandomAccessIterator, IndexMap, T, R>
safe_iterator_property_map<RandomAccessIterator, IndexMap, T, R>
associative_property_map<UniquePairAssociativeContainer>
const_associative_property_map<UniquePairAssociativeContainer>
static_property_map<ValueType>
ref_property_map<KeyType, ValueType>
typed_identity_property_map<T>

图获取属性

//boost/graph/detail/adjacency_list.hpp
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);
      }

通过get_dispatch作转发,调用具体的模板特例化实例
graph对于图这块专门定义了类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_selector,对于不同的图会特例化不同的边选择器

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>
      {};

  template <class GraphTag>
  struct edge_property_selector {
    typedef detail::dummy_edge_property_selector type;
  };

对于邻接表,特例化为

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

最终类型为
adj_list_edge_all_properties_map
对于边列表,特例化为

template <>
  struct edge_property_selector<edge_list_tag> {
    typedef edge_list_edge_property_selector type;
  };

  template <>
  struct edge_property_selector<edge_list_ra_tag> {
    typedef edge_list_ra_edge_property_selector type;
  };

对于图作为树,特例化为

template <>
  struct edge_property_selector<graph_as_tree_tag> {
    typedef detail::graph_as_tree_edge_property_selector type;
  };

标签图,特例化为

template <>
struct edge_property_selector<labeled_graph_class_tag> {
    typedef graph_detail::labeled_graph_edge_property_selector type;
};

子图,特例化为

template <>
struct edge_property_selector<subgraph_tag> {
    typedef detail::subgraph_property_generator type;
};

点属性

其依赖点属性选择器vertex_property_selector,对于不同的图会特例化不同的点选择器

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>
      {};

template <class GraphTag>
  struct vertex_property_selector {
    typedef detail::dummy_vertex_property_selector type;
  };

对于邻接表,特例化为

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

  struct vec_adj_list_vertex_property_selector {
    template <class Graph, class Property, class Tag>
    struct bind_: detail::vec_adj_list_choose_vertex_pa<Tag,Graph,Property> {};
  };
  template <>
  struct vertex_property_selector<vec_adj_list_tag> {
    typedef vec_adj_list_vertex_property_selector type;
  };

对于图作为树,特例化为

template <>
  struct vertex_property_selector<graph_as_tree_tag> {
    typedef detail::graph_as_tree_vertex_property_selector type;
  };

标签图,特例化为

template <>
struct vertex_property_selector<labeled_graph_class_tag> {
    typedef graph_detail::labeled_graph_vertex_property_selector type;
};

子图,特例化

template <>
struct vertex_property_selector<subgraph_tag> {
    typedef detail::subgraph_property_generator type;
};

邻接表

adjacency_list
adj_list_gen
config
vec_adj_list_impl
adj_list_impl
adj_list_helper
directed_edges_helper
directed_graph_helper
undirected_graph_helper
bidirectional_graph_helper
bidirectional_graph_helper_with_property

adj_list_gen中定义了config类,以及vec_adj_list_impl,adj_list_impl,其中vec_adj_list_impl和adj_list_impl是if条件类型来区分
同时也定义了DirectedHelper,这个是通过mpl::if_的条件选型来决定是基类是使用bidirectional_graph_helper_with_property,还是directed_graph_helper或者undirected_graph_helper
adj_list_impl不支持随机访问,vec_adj_list_impl支持随机访问

list_edge
edge_base

edge_base:只包含顶点,没有其它的信息
list_edge:除了包含顶点信息,还包含边的辅助信息
边存储结构包含下面几种

  • stored_edge_property
  • stored_ra_edge_iter
  • stored_edge_iter

其结构为

stored_edge_property<Vertex, Property>
# unique_ptr<Property> m_property
stored_edge<Vertex>
+ Vertex m_target
stored_edge_iter<Vertex, Iter, Property>
# Iter m_iter
stored_ra_edge_iter<Vertex, EdgeVec, Property>
# std::size_t m_i
# EdgeVec* m_vec

边描述符

邻接表的边通过adjacency_list_traits定义

edge_desc_impl
edge_base

邻接表的点adjacency_list_traits中定义,如果支持随机访问时,类型为size_t,否则类型为void*
点有不同的表示结构,依赖图的结构,是否支持双向,随机访问

  • bidir_rand_stored_vertex
  • rand_stored_vertex
  • bidir_seq_stored_vertex
  • seq_stored_vertex
    点的类结构为
bidir_rand_stored_vertex
+ OutEdgeList m_out_edges
+ InEdgeList m_in_edges;
+ VertexProperty m_property;
rand_stored_vertex
+ OutEdgeList m_out_edges
+ VertexProperty m_property
bidir_seq_stored_vertex
+ OutEdgeList m_out_edges
+ InEdgeList m_in_edges
+ VertexProperty m_property
seq_stored_vertex
+ OutEdgeList m_out_edges
+ VertexProperty m_property
stored_vertex

存储点列表的结构有两种,依赖是否支持随机访问

  • RandStoredVertexList
  • SeqStoredVertexList

RandStoredVertexList的定义为

typedef typename container_gen<VertexListS, stored_vertex>::type
          RandStoredVertexList;

SeqStoredVertexList的定义为

typedef typename container_gen<VertexListS, vertex_ptr>::type
          SeqStoredVertexList;

容器生成器

container_gen模板两个类型参数Selector和ValueType
Selector:表示所使用的容器类型,支持
● list
● vector
● map
● set
● multiset
● multimap
● hash_set
● hash_map
● hash_multiset
● hash_multimap
ValueType:表示容器中元素的类型
点的关连边表示所使用的就是container_gen,其值类型为StoredEdge,可能的值为
● stored_edge_property
● stored_ra_edge_iter
● stored_edge_iter

stored_edge
stored_edge_property
stored_edge_iter
stored_ra_edge_iter

点表示类型可以为
● stored_vertex
● vertex_ptr(void*)

stored_vertex
bidir_rand_stored_vertex
rand_stored_vertex
bidir_seq_stored_vertex
seq_stored_vertex

算法

基础

BFS

使用visitor模式,bfs visitor的必须支持以下方法
● initialize_vertex:算法开始时初始化点相关处理
● discover_vertex:发现点时处理
● examine_vertex:检查点处理
● examine_edge:检查边处理
● tree_edge:树边处理
● non_tree_edge:非树边处理
● gray_target:反向边处理
● black_target:前身边或者交叉边处理
● finish_vertex:点遍历完全时处理
bfs_visitor是bfs中其它visitor的代理,其模板类型参数表示代理的visitor类型

bfs_visitor<Visitors>
base_visitor<Visitor>
+operator()(T, Graph&)
null_visitor
dijkstra_visitor<Visitors>
+void edge_relaxed(Edge e, Graph& g)
+void edge_not_relaxed(Edge e, Graph& g)
astar_visitor
brandes_dijkstra_visitor
visitor_type
graph_copy_visitor
core_numbers_visitor
SAW_visitor
parallel_dijkstra_bfs_visitor
scc_discovery_visitor

DFS

dfs visitor的必须支持以下方法
● initialize_vertex
● start_vertex
● discover_vertex
● examine_edge
● tree_edge
● back_edge
● forward_or_cross_edge
● finish_vertex
● finish_edge

dfs_visitor<Visitors>
base_visitor<Visitor>
+operator()(T, Graph&)
null_visitor
topo_sort_visitor
biconnected_components_visitor
components_recorder
odd_components_counter
tarjan_scc_visitor
SAW_visitor
planar_dfs_visitor

最短路径

dijkstra

dijkstra_shortest_paths对于bgl_named_params会调用分发函数dijkstra_dispatch1

dijkstra_shortest_paths
    (const VertexListGraph& g,
     typename graph_traits<VertexListGraph>::vertex_descriptor s,
     const bgl_named_params<Param,Tag,Rest>& params)
-> 
dijkstra_dispatch1
      (const VertexListGraph& g,
       typename graph_traits<VertexListGraph>::vertex_descriptor s,
       DistanceMap distance, WeightMap weight, IndexMap index_map,
       const Params& params)
->
dijkstra_dispatch2
      (const VertexListGraph& g,
       typename graph_traits<VertexListGraph>::vertex_descriptor s,
       DistanceMap distance, WeightMap weight, IndexMap index_map,
       const Params& params)
->
dijkstra_shortest_paths
    (const VertexListGraph& g,
     typename graph_traits<VertexListGraph>::vertex_descriptor s,
     PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
     IndexMap index_map,
     Compare compare, Combine combine, DistInf inf, DistZero zero,
     DijkstraVisitor vis,
     const bgl_named_params<T, Tag, Base>&
     BOOST_GRAPH_ENABLE_IF_MODELS_PARM(VertexListGraph,vertex_list_graph_tag))
-> 
void
  dijkstra_shortest_paths
    (const VertexListGraph& g,
     SourceInputIter s_begin, SourceInputIter s_end,
     PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
     IndexMap index_map,
     Compare compare, Combine combine, DistInf inf, DistZero zero,
     DijkstraVisitor vis)
-> 
void
  dijkstra_shortest_paths
    (const VertexListGraph& g,
     SourceInputIter s_begin, SourceInputIter s_end,
     PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
     IndexMap index_map,
     Compare compare, Combine combine, DistInf inf, DistZero zero,
     DijkstraVisitor vis,
     const bgl_named_params<T, Tag, Base>&
     BOOST_GRAPH_ENABLE_IF_MODELS_PARM(VertexListGraph,vertex_list_graph_tag))
->
void
  dijkstra_shortest_paths
    (const VertexListGraph& g,
     SourceInputIter s_begin, SourceInputIter s_end,
     PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
     IndexMap index_map,
     Compare compare, Combine combine, DistInf inf, DistZero zero,
     DijkstraVisitor vis, ColorMap color)

dijkstra_visitor在bfs_visitor基础上新增了两个方法

  • edge_relaxed
  • edge_not_relaxed
template <class Edge, class Graph>
    void edge_relaxed(Edge e, Graph& g) {
      invoke_visitors(this->m_vis, e, g, on_edge_relaxed());
    }
    template <class Edge, class Graph>
    void edge_not_relaxed(Edge e, Graph& g) {
      invoke_visitors(this->m_vis, e, g, on_edge_not_relaxed());
    }

最后的dijkstra_shortest_paths方法主要做下面一些事

  • 初始化顶点,将所有点的距离设置为inf,前驱结点设置为自身,点的颜色设置为白色,表示没有访问,源点的距离设置为0
for (boost::tie(ui, ui_end) = vertices(g); ui != ui_end; ++ui) {
      vis.initialize_vertex(*ui, g);
      put(distance, *ui, inf);
      put(predecessor, *ui, *ui);
      put(color, *ui, Color::white());
    }
    for (SourceInputIter it = s_begin; it != s_end; ++it) {
      put(distance, *it, zero);
    }
  • 调用dijkstra_shortest_paths_no_init
dijkstra_shortest_paths_no_init
    (const Graph& g,
     SourceInputIter s_begin, SourceInputIter s_end,
     PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
     IndexMap index_map,
     Compare compare, Combine combine, DistZero zero,
     DijkstraVisitor vis, ColorMap color)

使用dijkstra_bfs_visitor的Visitor,调用breadth_first_visit

dijkstra_bfs_visitor的visitor的模板参数使用的是dijkstra_visitor<null_visitor>,实际是没有做任何处理,关键处理逻辑是放在
dijkstra_bfs_visitor中

A*

  • astar_search
    调用栈表示为
    astar_search有名参数版本->astar_search无名参数版本->astar_search_no_init
    astar_search_no_init会调用breadth_first_visit,同时使用astar_bfs_visitor
  • astar_search_tree
    调用栈表示为
    astar_search_tree有名参数版本->astar_search_tree无名参数版本->astar_search_no_init_tree
    astar_visitor是bfs_visitor的子类,增加了两个方法edge_relaxed和edge_not_relaxed
template <class Edge, class Graph>
    void edge_relaxed(Edge e, const Graph& g) {
      invoke_visitors(this->m_vis, e, g, on_edge_relaxed());
    }
    template <class Edge, class Graph>
    void edge_not_relaxed(Edge e, const Graph& g) {
      invoke_visitors(this->m_vis, e, g, on_edge_not_relaxed());
    }

astar_bfs_visitor实现了bfs_visitor要求的所有方法,在astar_search_no_init中作bfs搜索时依赖astar_bfs_visitor

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

kgduu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值