【问题标题】:Which VertexList types are valid for depth_first_search哪些 VertexList 类型对 depth_first_search 有效
【发布时间】:2019-03-26 22:31:20
【问题描述】:

当在 adjacency_list 中为 VertexList 使用 boost::vecS 时, boost::depth_first_search(Graph, Visitor) 编译并正常工作。将 VertexList 类型切换为 boost::listS 时,我收到编译器错误:

boost_1_65_0\boost\graph\detail\adjacency_list.hpp(2545):错误 C2182:“const_reference”:非法使用类型“void”

从这个错误中我可以看出 boost::listS 不是一个有效的类型,但是 BOOST CONCEPT 检查通过了。

如果 boost::listS 不是 depth_first_search 的有效类型,为什么?

以下是演示该问题的示例代码。从 vecS 切换到 listS 会产生上述错误。我正在使用 Visual Studio 2017 并提升 1.65.0

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <boost/graph/graph_concepts.hpp>


//typedef boost::adjacency_list<boost::listS, boost::listS, boost::bidirectionalS> MyGraph;
typedef boost::adjacency_list<boost::listS, boost::vecS, boost::bidirectionalS> MyGraph;
using VertexType = boost::graph_traits<MyGraph>::vertex_descriptor;

BOOST_CONCEPT_ASSERT((boost::VertexListGraphConcept<MyGraph>));
BOOST_CONCEPT_ASSERT((boost::IncidenceGraphConcept<MyGraph>));
class dfs_visitor : public boost::default_dfs_visitor
{

public:

  void discover_vertex(VertexType u,  const MyGraph& g) const
  {
  }

  void finish_vertex(VertexType u,  const MyGraph& g) const
  {
  }

};

BOOST_CONCEPT_ASSERT((boost::DFSVisitorConcept<dfs_visitor, MyGraph>));

int main()
{
  MyGraph g;
  dfs_visitor vis;
  boost::depth_first_search(g, boost::visitor(vis));
  return 0;
}

【问题讨论】:

标签: c++ c++14 depth-first-search boost-graph


【解决方案1】:

首先,我喜欢你包含了概念检查。今天学到的一个技巧。

真正的答案很简单:概念限制了图形类型。但是,其他参数添加了更多约束:

https://www.boost.org/doc/libs/1_69_0/libs/graph/doc/depth_first_search.html (粗体字)

输入vertex_index_map(VertexIndexMap i_map)

这会将每个顶点映射到 [0, num_vertices(g)) 范围内的整数。仅当使用默认颜色属性图时,才需要此参数。 VertexIndexMap 类型必须是 Readable Property Map 的模型。 map 的值类型必须是整数类型。 图的顶点描述符类型需要可用作地图的键类型

默认值:get(vertex_index, g)。注意:如果您使用此默认值,请确保您的图表具有内部 vertex_index 属性。例如,具有 VertexList=listS 的 adjacency_list 没有内部 vertex_index 属性。

换句话说,您的图表很好。但是你必须提供一个顶点索引。

Live On Wandbox

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <boost/graph/graph_concepts.hpp>
#include <numeric>

typedef boost::adjacency_list<boost::listS, boost::listS, boost::bidirectionalS> MyGraph;
using VertexType = boost::graph_traits<MyGraph>::vertex_descriptor;

BOOST_CONCEPT_ASSERT((boost::VertexListGraphConcept<MyGraph>));
BOOST_CONCEPT_ASSERT((boost::IncidenceGraphConcept<MyGraph>));

struct dfs_visitor : boost::default_dfs_visitor {
    void discover_vertex(VertexType, const MyGraph &) const {}
    void finish_vertex(VertexType, const MyGraph &) const {}
};

BOOST_CONCEPT_ASSERT((boost::DFSVisitorConcept<dfs_visitor, MyGraph>));

int main() {
    MyGraph g;
    dfs_visitor vis;
    std::map<MyGraph::vertex_descriptor, int> index;

    // fill index
    for (auto vd : boost::make_iterator_range(vertices(g))) {
        index.emplace(vd, index.size());
    }

    auto index_map = boost::make_assoc_property_map(index);
    boost::depth_first_search(g, boost::visitor(vis).vertex_index_map(index_map));
}

如果您仔细阅读,您还可以通过传递自定义颜色图来满足它。这有一个微小的优势,即不需要将所有元素初始化为默认初始化值:

Live On Wandbox

int main() {
    MyGraph g;
    dfs_visitor vis;
    std::map<MyGraph::vertex_descriptor, boost::default_color_type> colors;

    auto color_map = boost::make_assoc_property_map(colors);
    boost::depth_first_search(g, boost::visitor(vis).color_map(color_map));
}

【讨论】:

  • 非常感谢!这些示例很棒,可以很好地与我正在遍历的现有图表一起使用。
猜你喜欢
  • 1970-01-01
  • 2012-12-26
  • 1970-01-01
  • 1970-01-01
  • 2011-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-07
相关资源
最近更新 更多