哪些VertexList类型对depth_first_search有效

时间:2019-03-26 22:31:21

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

在将adjacency_list中的boost :: vecS用于VertexList时,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;
}

1 个答案:

答案 0 :(得分:0)

首先,我爱您包括概念检查。今天学到的一个技巧。

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

https://www.boost.org/doc/libs/1_69_0/libs/graph/doc/depth_first_search.html (大胆的我)

  

IN vertex_index_map(VertexIndexMap i_map)

     

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

     

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

换句话说,您的图形为FINE。但是您必须提供一个顶点索引。

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