在无向图中的DFS搜索中记录前驱

时间:2017-11-21 17:38:17

标签: c++11 boost graph-theory depth-first-search boost-graph

我试图使用此线程中的代码:Boost DFS back_edge来记录无向图中的周期。为此,我需要在找到back_edge时为每个dfs树存储predecessors。由于这是一张无向图,我认为我们无法直接使用EventVisitor Concept中的on_back_edge()。所以我想在下面代码的void back_edge()方法中记录前辈。但我不知道如何做到这一点并返回循环顶点。

以下是我为记录前辈添加的代码和部分:

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

namespace {
using namespace boost;

  typedef adjacency_list<vecS, vecS, undirectedS, no_property, 
  property<edge_weight_t, int> > Graph;
  typedef graph_traits<Graph>::edge_descriptor Edge;
  typedef std::set<Edge> EdgeSet;
}

struct MyVisitorCycle : default_dfs_visitor {
MyVisitorCycle(EdgeSet &tree_edges, vector<vector<vertex_t> > &cycles1) :
        tree_edges(tree_edges), cycles(cycles1) {}

  void tree_edge(Edge e, const Graph& g) const {
    std::cerr << "tree_edge " << e << std::endl;
    tree_edges.insert(e);
  }
  void back_edge(Edge e, const Graph& g) const {
    if (tree_edges.find(e) == tree_edges.end())
        std::cerr << "back_edge " << e << std::endl;

    /// I added this part
    vertex_t s = vertex (0,g);
    std::vector <vertex_t> p(num_vertices (g));
    depth_first_search (g, s, visitor (boost::record_predecessors (&p[0], 
                                  on_tree_edge())));/// here has problem
    p.push_back (target (e,g)); /// close the cycle
    cycles.push_back (p);
  }

  private:
  EdgeSet& tree_edges;
  vector<vector <vertex_t> > &cycles;
};

int main() {
  Graph g;
  add_edge(0, 1, g);
  add_edge(1, 2, g);
  add_edge(2, 3, g);
  add_edge(3, 0, g);
  add_edge(1, 4, g);
  add_edge(4, 5, g);
  add_edge(5, 6, g);
  add_edge(6, 3, g);
  add_edge(2, 5, g);

  std::set<Edge> tree_edges;
  vector<vector <vertex_t> > cycles;
  MyVisitorCycle vis(tree_edges, cycles);

  depth_first_search(g, visitor(vis));
}

1 个答案:

答案 0 :(得分:0)

这是一篇快速的帖子,我稍后会再回过头来看看

<强> Live On Coliru

#include <iostream>
#include <boost/config.hpp>
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/depth_first_search.hpp>

namespace {
    using namespace boost;

    typedef adjacency_list<vecS, vecS, undirectedS, no_property, property<edge_weight_t, int> > Graph;
    typedef graph_traits<Graph>::edge_descriptor Edge;
    typedef std::set<Edge> EdgeSet;
}

struct MyVisitor : default_dfs_visitor {
    MyVisitor(EdgeSet& tree_edges) : tree_edges(tree_edges) {}

    void tree_edge(Edge e, const Graph& g) const {
        std::cerr << "tree_edge " << e << std::endl;
        tree_edges.insert(e);
    }
    void back_edge(Edge e, const Graph& g) const {
        if (tree_edges.find(e) == tree_edges.end())
            std::cerr << "back_edge " << e << std::endl;
    }

  private: 
    EdgeSet& tree_edges;
};

int main() {
    Graph g;
    add_edge(0, 1, g);
    add_edge(0, 2, g);

    std::set<Edge> tree_edges;
    MyVisitor vis(tree_edges);


    std::vector<Graph::vertex_descriptor> pred(num_vertices(g), Graph::null_vertex());

    depth_first_search(g, visitor(boost::make_dfs_visitor(
            boost::record_predecessors(pred.data(), boost::on_back_edge{})
        )));

    for (auto v : make_iterator_range(vertices(g))) {
        std::cout << "Predecessor for " << v << " is " << pred.at(v) << "\n";
    }
}

打印

Predecessor for 0 is 2
Predecessor for 1 is 18446744073709551615
Predecessor for 2 is 18446744073709551615