结构
属性相关
图获取属性
//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;
};
邻接表
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支持随机访问
边
edge_base:只包含顶点,没有其它的信息
list_edge:除了包含顶点信息,还包含边的辅助信息
边存储结构包含下面几种
- stored_edge_property
- stored_ra_edge_iter
- stored_edge_iter
其结构为
边描述符
邻接表的边通过adjacency_list_traits定义
点
邻接表的点adjacency_list_traits中定义,如果支持随机访问时,类型为size_t,否则类型为void*
点有不同的表示结构,依赖图的结构,是否支持双向,随机访问
- bidir_rand_stored_vertex
- rand_stored_vertex
- bidir_seq_stored_vertex
- seq_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_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类型
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
:其模板参数缺省值为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_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
调用顺序为
A*
- astar_search
调用栈表示为
- astar_search_tree
调用栈表示为
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_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
:模板参数表示父结点的mapCostMap
:模板参数表示从起点到终点的成本的mapDistanceMap
:模板参数表示从起点到其它点的距离的mapWeightMap
:模板参数表示边的权重的mapColorMap
:模板参数表示点的状态BianaryFunction
:模板参数用于计算从起点到当前点的成本与从当前点到目标点成本的叠加BinaryPredicate
:模板参数用于比较距离,看是否有松弛操作
bellman_ford
BellmanFordVisitor需要有以下方法
- examine_edge
- edge_relaxed
- edge_not_relaxed
- edge_minimized
- edge_not_minimized
bellman_visitor默认的访问器
其定义为
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
内部调用顺序为
floyd_warshall
其没有使用Visitor
最小生成树
prim
其distance_combine合并策略为
template <class U, class V>
struct _project2nd
{
V operator()(U, V v)
{
return v;
}
};
compare策略使用的是std::less<W> compare