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

bfs_visitor的类定义为

template <class Visitors = null_visitor>
  class bfs_visitor {
  public:
    bfs_visitor() { }
    bfs_visitor(Visitors vis) : m_vis(vis) { }

    template <class Vertex, class Graph>
    graph::bfs_visitor_event_not_overridden
    initialize_vertex(Vertex u, Graph& g)
    {
      invoke_visitors(m_vis, u, g, ::boost::on_initialize_vertex());
      return graph::bfs_visitor_event_not_overridden();
    }

    template <class Vertex, class Graph>
    graph::bfs_visitor_event_not_overridden
    discover_vertex(Vertex u, Graph& g)
    {
      invoke_visitors(m_vis, u, g, ::boost::on_discover_vertex());
      return graph::bfs_visitor_event_not_overridden();
    }

    template <class Vertex, class Graph>
    graph::bfs_visitor_event_not_overridden
    examine_vertex(Vertex u, Graph& g)
    {
      invoke_visitors(m_vis, u, g, ::boost::on_examine_vertex());
      return graph::bfs_visitor_event_not_overridden();
    }

    template <class Edge, class Graph>
    graph::bfs_visitor_event_not_overridden
    examine_edge(Edge e, Graph& g)
    {
      invoke_visitors(m_vis, e, g, ::boost::on_examine_edge());
      return graph::bfs_visitor_event_not_overridden();
    }

    template <class Edge, class Graph>
    graph::bfs_visitor_event_not_overridden
    tree_edge(Edge e, Graph& g)
    {
      invoke_visitors(m_vis, e, g, ::boost::on_tree_edge());
      return graph::bfs_visitor_event_not_overridden();
    }

    template <class Edge, class Graph>
    graph::bfs_visitor_event_not_overridden
    non_tree_edge(Edge e, Graph& g)
    {
      invoke_visitors(m_vis, e, g, ::boost::on_non_tree_edge());
      return graph::bfs_visitor_event_not_overridden();
    }

    template <class Edge, class Graph>
    graph::bfs_visitor_event_not_overridden
    gray_target(Edge e, Graph& g)
    {
      invoke_visitors(m_vis, e, g, ::boost::on_gray_target());
      return graph::bfs_visitor_event_not_overridden();
    }

    template <class Edge, class Graph>
    graph::bfs_visitor_event_not_overridden
    black_target(Edge e, Graph& g)
    {
      invoke_visitors(m_vis, e, g, ::boost::on_black_target());
      return graph::bfs_visitor_event_not_overridden();
    }

    template <class Vertex, class Graph>
    graph::bfs_visitor_event_not_overridden
    finish_vertex(Vertex u, Graph& g)
    {
      invoke_visitors(m_vis, u, g, ::boost::on_finish_vertex());
      return graph::bfs_visitor_event_not_overridden();
    }

    BOOST_GRAPH_EVENT_STUB(on_initialize_vertex,bfs)
    BOOST_GRAPH_EVENT_STUB(on_discover_vertex,bfs)
    BOOST_GRAPH_EVENT_STUB(on_examine_vertex,bfs)
    BOOST_GRAPH_EVENT_STUB(on_examine_edge,bfs)
    BOOST_GRAPH_EVENT_STUB(on_tree_edge,bfs)
    BOOST_GRAPH_EVENT_STUB(on_non_tree_edge,bfs)
    BOOST_GRAPH_EVENT_STUB(on_gray_target,bfs)
    BOOST_GRAPH_EVENT_STUB(on_black_target,bfs)
    BOOST_GRAPH_EVENT_STUB(on_finish_vertex,bfs)

  protected:
    Visitors m_vis;
  };

bfs_visitor的工厂方法为

 template <class Visitors>
  bfs_visitor<Visitors>
  make_bfs_visitor(Visitors vis) {
    return bfs_visitor<Visitors>(vis);
  }

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<OutputIterator>
biconnected_components_visitor
components_recorder
odd_components_counter
tarjan_scc_visitor
SAW_visitor
planar_dfs_visitor

有两种实现方式,一种是栈实现,一种是递归实现
dfs_visitor:其模板参数缺省值为null_visitor
其定义为

template <class Visitors = null_visitor>
  class dfs_visitor {
  public:
    dfs_visitor() { }
    dfs_visitor(Visitors vis) : m_vis(vis) { }

    template <class Vertex, class Graph>
    void initialize_vertex(Vertex u, const Graph& g) {
      invoke_visitors(m_vis, u, g, ::boost::on_initialize_vertex());
    }
    template <class Vertex, class Graph>
    void start_vertex(Vertex u, const Graph& g) {
      invoke_visitors(m_vis, u, g, ::boost::on_start_vertex());
    }
    template <class Vertex, class Graph>
    void discover_vertex(Vertex u, const Graph& g) {
      invoke_visitors(m_vis, u, g, ::boost::on_discover_vertex());
    }
    template <class Edge, class Graph>
    void examine_edge(Edge u, const Graph& g) {
      invoke_visitors(m_vis, u, g, ::boost::on_examine_edge());
    }
    template <class Edge, class Graph>
    void tree_edge(Edge u, const Graph& g) {
      invoke_visitors(m_vis, u, g, ::boost::on_tree_edge());
    }
    template <class Edge, class Graph>
    void back_edge(Edge u, const Graph& g) {
      invoke_visitors(m_vis, u, g, ::boost::on_back_edge());
    }
    template <class Edge, class Graph>
    void forward_or_cross_edge(Edge u, const Graph& g) {
      invoke_visitors(m_vis, u, g, ::boost::on_forward_or_cross_edge());
    }
    template <class Edge, class Graph>
    void finish_edge(Edge u, const Graph& g) {
      invoke_visitors(m_vis, u, g, ::boost::on_finish_edge());
    }
    template <class Vertex, class Graph>
    void finish_vertex(Vertex u, const Graph& g) {
      invoke_visitors(m_vis, u, g, ::boost::on_finish_vertex());
    }

    BOOST_GRAPH_EVENT_STUB(on_initialize_vertex,dfs)
    BOOST_GRAPH_EVENT_STUB(on_start_vertex,dfs)
    BOOST_GRAPH_EVENT_STUB(on_discover_vertex,dfs)
    BOOST_GRAPH_EVENT_STUB(on_examine_edge,dfs)
    BOOST_GRAPH_EVENT_STUB(on_tree_edge,dfs)
    BOOST_GRAPH_EVENT_STUB(on_back_edge,dfs)
    BOOST_GRAPH_EVENT_STUB(on_forward_or_cross_edge,dfs)
    BOOST_GRAPH_EVENT_STUB(on_finish_edge,dfs)
    BOOST_GRAPH_EVENT_STUB(on_finish_vertex,dfs)

  protected:
    Visitors m_vis;
  };

工厂方法为

template <class Visitors>
  dfs_visitor<Visitors>
  make_dfs_visitor(Visitors vis) {
    return dfs_visitor<Visitors>(vis);
  }

最短路径

dijkstra

dijkstra_shortest_paths调用顺序为

dijkstra_shortest_paths
(const VertexListGraph& g,
typename graph_traits::vertex_descriptor s,
const bgl_named_params& params)
dijkstra_shortest_paths
(const VertexListGraph& g,
typename graph_traits::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&
BOOST_GRAPH_ENABLE_IF_MODELS_PARM(VertexListGraph,vertex_list_graph_tag))
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)
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&
BOOST_GRAPH_ENABLE_IF_MODELS_PARM(VertexListGraph,vertex_list_graph_tag))
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_dispatch1
dijkstra_dispatch2

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

  • edge_relaxed
  • edge_not_relaxed
    dijkstra_visitor的定义为
template <class Visitors = null_visitor>
  class dijkstra_visitor : public bfs_visitor<Visitors> {
  public:
    dijkstra_visitor() { }
    dijkstra_visitor(Visitors vis)
      : bfs_visitor<Visitors>(vis) { }

    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());
    }
  private:
    template <class Edge, class Graph>
    void tree_edge(Edge u, Graph& g) { }
  };

其工厂方法为

template <class Visitors>
  dijkstra_visitor<Visitors>
  make_dijkstra_visitor(Visitors vis) {
    return dijkstra_visitor<Visitors>(vis);
  }

最后的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中,dijkstra_bfs_visitor定义为

template <class UniformCostVisitor, class UpdatableQueue,
      class WeightMap, class PredecessorMap, class DistanceMap,
      class BinaryFunction, class BinaryPredicate>
    struct dijkstra_bfs_visitor
    {
      typedef typename property_traits<DistanceMap>::value_type D;
      typedef typename property_traits<WeightMap>::value_type W;

      dijkstra_bfs_visitor(UniformCostVisitor vis, UpdatableQueue& Q,
                           WeightMap w, PredecessorMap p, DistanceMap d,
                           BinaryFunction combine, BinaryPredicate compare,
                           D zero)
        : m_vis(vis), m_Q(Q), m_weight(w), m_predecessor(p), m_distance(d),
          m_combine(combine), m_compare(compare), m_zero(zero)  { }

      template <class Edge, class Graph>
      void tree_edge(Edge e, Graph& g) {
        bool decreased = relax(e, g, m_weight, m_predecessor, m_distance,
                               m_combine, m_compare);
        if (decreased)
          m_vis.edge_relaxed(e, g);
        else
          m_vis.edge_not_relaxed(e, g);
      }
      template <class Edge, class Graph>
      void gray_target(Edge e, Graph& g) {
        D old_distance = get(m_distance, target(e, g));

        bool decreased = relax(e, g, m_weight, m_predecessor, m_distance,
                               m_combine, m_compare);
        if (decreased) {
          dijkstra_queue_update(m_Q, target(e, g), old_distance);
          m_vis.edge_relaxed(e, g);
        } else
          m_vis.edge_not_relaxed(e, g);
      }

      template <class Vertex, class Graph>
      void initialize_vertex(Vertex u, Graph& g)
        { m_vis.initialize_vertex(u, g); }
      template <class Edge, class Graph>
      void non_tree_edge(Edge, Graph&) { }
      template <class Vertex, class Graph>
      void discover_vertex(Vertex u, Graph& g) { m_vis.discover_vertex(u, g); }
      template <class Vertex, class Graph>
      void examine_vertex(Vertex u, Graph& g) { m_vis.examine_vertex(u, g); }
      template <class Edge, class Graph>
      void examine_edge(Edge e, Graph& g) {
        
        if (m_compare(m_combine(m_zero, get(m_weight, e)), m_zero)) 
            boost::throw_exception(negative_edge());
        // End of test for negative-weight edges.

        m_vis.examine_edge(e, g);

      }
      template <class Edge, class Graph>
      void black_target(Edge, Graph&) { }
      template <class Vertex, class Graph>
      void finish_vertex(Vertex u, Graph& g) { m_vis.finish_vertex(u, g); }

      UniformCostVisitor m_vis;
      UpdatableQueue& m_Q;
      WeightMap m_weight;
      PredecessorMap m_predecessor;
      DistanceMap m_distance;
      BinaryFunction m_combine;
      BinaryPredicate m_compare;
      D m_zero;
    };

dijkstra_shortest_paths_no_color_map调用顺序为

dijkstra_shortest_paths_no_color_map(
const Graph& graph,
typename graph_traits::vertex_descriptor start_vertex,
const bgl_named_params& params)
void dijkstra_shortest_paths_no_color_map(
const Graph& graph,
typename graph_traits::vertex_descriptor start_vertex,
PredecessorMap predecessor_map,
DistanceMap distance_map,
WeightMap weight_map,
VertexIndexMap index_map,
DistanceCompare distance_compare,
DistanceWeightCombine distance_weight_combine,
DistanceInfinity distance_infinity,
DistanceZero distance_zero,
DijkstraVisitor visitor)
dijkstra_no_color_map_dispatch1
dijkstra_no_color_map_dispatch2
dijkstra_shortest_paths_no_color_map_no_init

A*

  • astar_search
    调用栈表示为
astar_search(const VertexListGraph& g,
typename graph_traits::vertex_descriptor s,
AStarHeuristic h, const bgl_named_params& params)
astar_search(const VertexListGraph& g,
typename graph_traits::vertex_descriptor s,
AStarHeuristic h, AStarVisitor vis, PredecessorMap predecessor,
CostMap cost, DistanceMap distance, WeightMap weight,
VertexIndexMap index_ap, ColorMap color, CompareFunction compare,
CombindFunction combine, CostInf inf, CostZero zero)
astar_search_no_init
breadth_first_visit
  • astar_search_tree
    调用栈表示为
astar_search_tree(const VertexListGraph& g,
typename graph_traits::vertex_descriptor s,
AStarHeuristic h, const bgl_named_params& params)
astar_search_tree(const VertexListGraph& g,
typename graph_traits::vertex_descriptor s,
AStarHeuristic h, AStarVisitor vis, PredecessorMap predecessor,
CostMap cost, DistanceMap distance, WeightMap weight,
VertexIndexMap index_ap, ColorMap color, CompareFunction compare,
CombindFunction combine, CostInf inf, CostZero zero)
astar_search_no_init_tree
astar_visitor

astar_visitor是bfs_visitor的子类,增加了两个方法edge_relaxed和edge_not_relaxed,其
定义为

template <class Visitors = null_visitor>
  class astar_visitor : public bfs_visitor<Visitors> {
  public:
    astar_visitor() {}
    astar_visitor(Visitors vis)
      : bfs_visitor<Visitors>(vis) {}

    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());
    }
  private:
    template <class Edge, class Graph>
    void tree_edge(Edge e, const Graph& g) {}
    template <class Edge, class Graph>
    void non_tree_edge(Edge e, const Graph& g) {}
  };

astar_visitor的工厂方法为

  template <class Visitors>
  astar_visitor<Visitors>
  make_astar_visitor(Visitors vis) {
    return astar_visitor<Visitors>(vis);
  }

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

template <class AStarHeuristic, class UniformCostVisitor,
              class UpdatableQueue, class PredecessorMap,
              class CostMap, class DistanceMap, class WeightMap,
              class ColorMap, class BinaryFunction,
              class BinaryPredicate>
    struct astar_bfs_visitor
    {

      typedef typename property_traits<CostMap>::value_type C;
      typedef typename property_traits<ColorMap>::value_type ColorValue;
      typedef color_traits<ColorValue> Color;
      typedef typename property_traits<DistanceMap>::value_type distance_type;

      astar_bfs_visitor(AStarHeuristic h, UniformCostVisitor vis,
                        UpdatableQueue& Q, PredecessorMap p,
                        CostMap c, DistanceMap d, WeightMap w,
                        ColorMap col, BinaryFunction combine,
                        BinaryPredicate compare, C zero)
        : m_h(h), m_vis(vis), m_Q(Q), m_predecessor(p), m_cost(c),
          m_distance(d), m_weight(w), m_color(col),
          m_combine(combine), m_compare(compare), m_zero(zero) {}


      template <class Vertex, class Graph>
      void initialize_vertex(Vertex u, const Graph& g) {
        m_vis.initialize_vertex(u, g);
      }
      template <class Vertex, class Graph>
      void discover_vertex(Vertex u, const Graph& g) {
        m_vis.discover_vertex(u, g);
      }
      template <class Vertex, class Graph>
      void examine_vertex(Vertex u, const Graph& g) {
        m_vis.examine_vertex(u, g);
      }
      template <class Vertex, class Graph>
      void finish_vertex(Vertex u, const Graph& g) {
        m_vis.finish_vertex(u, g);
      }
      template <class Edge, class Graph>
      void examine_edge(Edge e, const Graph& g) {
        if (m_compare(get(m_weight, e), m_zero))
          BOOST_THROW_EXCEPTION(negative_edge());
        m_vis.examine_edge(e, g);
      }
      template <class Edge, class Graph>
      void non_tree_edge(Edge, const Graph&) {}



      template <class Edge, class Graph>
      void tree_edge(Edge e, const Graph& g) {
        using boost::get;
        bool m_decreased =
          relax(e, g, m_weight, m_predecessor, m_distance,
                m_combine, m_compare);

        if(m_decreased) {
          m_vis.edge_relaxed(e, g);
          put(m_cost, target(e, g),
              m_combine(get(m_distance, target(e, g)),
                        m_h(target(e, g))));
        } else
          m_vis.edge_not_relaxed(e, g);
      }


      template <class Edge, class Graph>
      void gray_target(Edge e, const Graph& g) {
        using boost::get;
        bool m_decreased =
          relax(e, g, m_weight, m_predecessor, m_distance,
                m_combine, m_compare);

        if(m_decreased) {
          put(m_cost, target(e, g),
              m_combine(get(m_distance, target(e, g)),
                        m_h(target(e, g))));
          m_Q.update(target(e, g));
          m_vis.edge_relaxed(e, g);
        } else
          m_vis.edge_not_relaxed(e, g);
      }


      template <class Edge, class Graph>
      void black_target(Edge e, const Graph& g) {
        using boost::get;
        bool m_decreased =
          relax(e, g, m_weight, m_predecessor, m_distance,
                m_combine, m_compare);

        if(m_decreased) {
          m_vis.edge_relaxed(e, g);
          put(m_cost, target(e, g),
              m_combine(get(m_distance, target(e, g)),
                        m_h(target(e, g))));
          m_Q.push(target(e, g));
          put(m_color, target(e, g), Color::gray());
          m_vis.black_target(e, g);
        } else
          m_vis.edge_not_relaxed(e, g);
      }



      AStarHeuristic m_h;
      UniformCostVisitor m_vis;
      UpdatableQueue& m_Q;
      PredecessorMap m_predecessor;
      CostMap m_cost;
      DistanceMap m_distance;
      WeightMap m_weight;
      ColorMap m_color;
      BinaryFunction m_combine;
      BinaryPredicate m_compare;
      C m_zero;

    };
astar_bfs_visitor<
AStarHeuristic,
UniformCostVisitor,
UpdatableQueue,
PredecessorMap,
CostMap,
DistanceMap,
WeightMap,
ColorMap,
BianaryFunction,
BinaryPredicate>
astar_visitor<Visitors>
astar_heuristic<Graph, CostType>

astar_heuristic:函数对象,其定义为

  template <class Graph, class CostType>
  class astar_heuristic : public std::unary_function<
    typename graph_traits<Graph>::vertex_descriptor, CostType>
  {
  public:
    typedef typename graph_traits<Graph>::vertex_descriptor Vertex;
    astar_heuristic() {}
    CostType operator()(Vertex u) { return static_cast<CostType>(0); }
  };

astar_bfs_visitor:astar visitor的类模板

  • AStarHeuristic:为启发函数对象模板参数,为astar_heuristic的子类,计算当前点到目标点的成本
  • UniformCostVisitor:模板参数为astar_visitor或者子类
  • UpdatableQueue:模板参数为队列,默认使用的是d_ary_heap_indirect
  • PredecessorMap:模板参数表示父结点的map
  • CostMap:模板参数表示从起点到终点的成本的map
  • DistanceMap:模板参数表示从起点到其它点的距离的map
  • WeightMap:模板参数表示边的权重的map
  • ColorMap:模板参数表示点的状态
  • BianaryFunction:模板参数用于计算从起点到当前点的成本与从当前点到目标点成本的叠加
  • BinaryPredicate:模板参数用于比较距离,看是否有松弛操作

bellman_ford

BellmanFordVisitor需要有以下方法

  • examine_edge
  • edge_relaxed
  • edge_not_relaxed
  • edge_minimized
  • edge_not_minimized

bellman_visitor默认的访问器

bellman_visitor<Visitors>
# Visitors m_vis

其定义为

template <class Visitors = null_visitor>
  class bellman_visitor {
  public:
    bellman_visitor() { }
    bellman_visitor(Visitors vis) : m_vis(vis) { }

    template <class Edge, class Graph>
    void examine_edge(Edge u, Graph& g) {
      invoke_visitors(m_vis, u, g, on_examine_edge());
    }
    template <class Edge, class Graph>
    void edge_relaxed(Edge u, Graph& g) {
      invoke_visitors(m_vis, u, g, on_edge_relaxed());      
    }
    template <class Edge, class Graph>
    void edge_not_relaxed(Edge u, Graph& g) {
      invoke_visitors(m_vis, u, g, on_edge_not_relaxed());
    }
    template <class Edge, class Graph>
    void edge_minimized(Edge u, Graph& g) {
      invoke_visitors(m_vis, u, g, on_edge_minimized());
    }
    template <class Edge, class Graph>
    void edge_not_minimized(Edge u, Graph& g) {
      invoke_visitors(m_vis, u, g, on_edge_not_minimized());
    }
  protected:
    Visitors m_vis;
  };

其创建工厂为

template <class Visitors>
  bellman_visitor<Visitors>
  make_bellman_visitor(Visitors vis) {
    return bellman_visitor<Visitors>(vis);
  }

bellman_ford_shortest_paths内部调用顺序为

bellman_ford_shortest_paths(EdgeListGraph& g, Size N)
bellman_ford_shortest_paths
(VertexAndEdgeListGraph& g,
const bgl_named_params& params)
bellman_ford_shortest_paths
(EdgeListGraph& g, Size N,
const bgl_named_params& params)
bellman_dispatch
bellman_dispatch2
bellman_ford_shortest_paths(EdgeListGraph& g, Size N,
WeightMap weight,
PredecessorMap pred,
DistanceMap distance,
BinaryFunction combine,
BinaryPredicate compare,
BellmanFordVisitor v)

floyd_warshall

其没有使用Visitor

floyd_warshall_all_pairs_shortest_paths(
const VertexAndEdgeListGraph& g, DistanceMatrix& d,
const bgl_named_params& params)
floyd_warshall_all_pairs_shortest_paths(
const VertexAndEdgeListGraph& g, DistanceMatrix& d)
floyd_warshall_initialized_all_pairs_shortest_paths(
const VertexListGraph& g, DistanceMatrix& d,
const bgl_named_params& params)
floyd_warshall_initialized_all_pairs_shortest_paths(
const VertexListGraph& g, DistanceMatrix& d)
floyd_warshall_dispatch(const VertexListGraph& g,
DistanceMatrix& d, const BinaryPredicate &compare,
const BinaryFunction &combine, const Infinity& inf,
const Zero& zero)
floyd_warshall_noninit_dispatch
floyd_warshall_init_dispatch
floyd_warshall_all_pairs_shortest_paths
floyd_warshall_initialized_all_pairs_shortest_paths

最小生成树

prim

prim_mininum_spanning_tree(const VertexListGraph& g,
PredecessorMap p_map, const bgl_named_params& params)
prim_mininum_spanning_tree(const VertexListGraph& g,
PredecessorMap p_map)
prim_mininum_spanning_tree(const VertexListGraph& g,
typename graph_traits::vertex_descriptor s,
PredecessorMap predecessor, DistanceMap distance, WeightMap weight,
IndexMap index_map, DijkstraVisitor vis)
prim_mst_impl
dijkstra_shortest_paths

其distance_combine合并策略为

template <class U, class V>
struct _project2nd
{
	V operator()(U, V v)
	{
		return v;
	}
};

compare策略使用的是std::less<W> compare

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

kgduu

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

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

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

打赏作者

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

抵扣说明:

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

余额充值