[英]Boost graph BFS that ignores zero weight edges
I am having a bit of trouble constructing a specific BFS in boost from an adjacency list directed graph. 我在从邻接列表有向图的构建中构建特定的BFS时遇到了一些麻烦。 Ideally, I would like it to:
理想情况下,我希望:
Realizing that it may not be possible for a visitor to do all of these things at once, what is the best way to do this? 意识到访客可能无法一次完成所有这些操作,最好的方法是什么?
I'd suggest using a filtered_graph
adaptor with a dynamic set of "deleted" (filtered) vertices or edges. 我建议使用带有动态集合“已删除”(已过滤)顶点或边的
filtered_graph
适配器 。
I have some samples on StackOverflow using this approach I think. 我认为使用这种方法在StackOverflow上有一些示例 。 In absense of sample code on your side, I'll let you find those and see how you fare.
在您身边没有示例代码的情况下,我将让您找到这些示例并查看价格。
You can use a boost::filtered_graph
to dynamically filter the edges you don't want to cross. 您可以使用
boost::filtered_graph
动态过滤您不想交叉的边缘。 To this end you must first write an edge predicate to filter out null weighted edges. 为此,您必须首先编写一个边缘谓词以过滤掉空的加权边缘。
Here is a possible implementation of the predicate: 这是谓词的可能实现:
template <typename EdgeWeightMap>
struct non_null_weight_edge {
non_null_weight_edge() {}
non_null_weight_edge(EdgeWeightMap const& map) : weight_map(map) {}
template <typename Edge>
bool operator()(Edge const& e) const {
return (boost::get(weight_map, e) != 0);
}
private:
EdgeWeightMap weight_map;
};
EdgeWeightMap
must be a ReadablePropertyMap
defining the weights for the edges. EdgeWeightMap
必须是ReadablePropertyMap
用于定义边缘的权重。
Assuming you start with a graph looking like this: 假设您从一个如下图开始:
// Just for clarity's sake while printing graph
struct VertexProperty {
std::string name;
};
struct EdgeProperty {
int weight; // Required
// Add whatever you want...
};
using RawGraph = boost::adjacency_list<boost::vecS, boost::vecS, boost::undirectedS,
VertexProperty, EdgeProperty>;
You can instantiate a predicate like this: 您可以像这样实例化谓词:
RawGraph graph; // Populate it however you want...
auto weight_map = boost::get(graph, &EdgeProperty::weight);
auto predicate = non_null_weight_edge<decltype(weight_map)>(weight_map);
Now, we create the filtered graph to perform our BFS: 现在,我们创建过滤图以执行BFS:
boost::filtered_graph<RawGraph, decltype(predicate)>(graph, predicate);
The next step is to record which vertices we will discover during the BFS, this is really simple as you only have to define the discover_vertex
part of the BFSVisitor
: 下一步是记录我们将在BFS中发现哪些顶点,这非常简单,因为您只需要定义
BFSVisitor
的discover_vertex
部分:
template <typename VertexSet>
struct VertexDetectorVisitor : boost::default_bfs_visitor {
VertexDetectorVisitor(VertexSet& output_vec) :
visited(output_vec) {}
template <typename Vertex, typename Graph>
void discover_vertex(Vertex const& v, Graph const& g) {
visited.insert(v);
}
private:
VertexSet& visited;
};
Putting all the pieces together leads you to something running like this live demo . 将所有部分放在一起,您将获得像此实时演示一样运行的内容。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.