结构
属性相关
图获取属性
//boost/graph/detail/adjacency_list.hpp
template <class Config, class Base, class Property>inlinetypename boost::property_map<typename Config::graph_type, Property>::typeget(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>inlinetypename boost::property_map<typename Config::graph_type,Property>::typeget_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;};
对于边列表,特例化为
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;
};
邻接表
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
边
edge_base:只包含顶点,没有其它的信息
list_edge:除了包含顶点信息,还包含边的辅助信息
边描述符
邻接表的边通过adjacency_list_traits定义
点
邻接表的点adjacency_list_traits中定义,如果支持随机访问时,类型为size_t,否则类型为void*
容器生成器
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_vertex
● vertex_ptr(void*)
算法
基础
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类型
DFS
dfs visitor的必须支持以下方法
● initialize_vertex
● start_vertex
● discover_vertex
● examine_edge
● tree_edge
● back_edge
● forward_or_cross_edge
● finish_vertex
● finish_edge
最短路径
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))
->
voiddijkstra_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)
->
voiddijkstra_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))
->
voiddijkstra_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中