提升图BFS忽略零权重边

时间:2016-10-21 20:55:41

标签: c++ boost boost-graph

我在使用邻接列表有向图构建boost中的特定BFS时遇到了一些麻烦。理想情况下,我希望:

  1. 从源头开始
  2. 只有具有正边缘重量的交叉边缘。
  3. 记录遇到的顶点(到某个数组)。
  4. 从原始图表中删除节点,因为它们已用完。
  5. 意识到访问者可能无法一次完成所有这些事情,最好的方法是什么?

2 个答案:

答案 0 :(得分:3)

我建议使用filtered_graph adaptor一组动态的“已删除”(已过滤)顶点或边缘。

我认为在StackOverflow上使用这种方法some samples。由于缺乏示例代码,我会让您找到这些代码并了解您的情况。

答案 1 :(得分:3)

您可以使用boost::filtered_graph动态过滤不想跨越的边缘。为此,您必须首先编写一个边缘谓词来过滤掉空加权边。

以下是谓词的可能实现:

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必须是定义边缘权重的ReadablePropertyMap

假设您从图中看起来像这样:

// 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>;

您可以像这样实例化一个谓词:

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);

现在,我们创建过滤图来执行我们的BFS:

boost::filtered_graph<RawGraph, decltype(predicate)>(graph, predicate);

下一步是记录我们将在BFS期间发现哪些顶点,这非常简单,因为您只需要定义discover_vertex的{​​{1}}部分:

BFSVisitor

将所有部分组合在一起会让您看到像live demo这样的内容。