【问题标题】:How to traverse an graph branch, from specific node with Boost.Graph?如何使用Boost.Graph从特定节点遍历图分支?
【发布时间】:2015-06-04 08:47:45
【问题描述】:

将不胜感激。
我有树形结构,并希望按出现的顺序打印节点,就层次结构而言。

例如我想遍历 N1 的所有子节点:

[N0, N1[N2, N3, N4[N5], N6]

我希望得到

N1 N2 N3 N4 N5

但是我收到了一些不同的东西,使用这个 sn-p :

    typedef boost::adjacency_list<boost::listS, boost::vecS, boost::undirectedS> MyGraph;
    typedef boost::graph_traits<MyGraph>::vertex_descriptor MyVertex;

        class MyVisitor : public boost::default_dfs_visitor
        {
        public:
          void discover_vertex(MyVertex v, const MyGraph& g) const
          {
            cerr << v << endl;
            return;
          }
        };

int _tmain(int argc, _TCHAR* argv[])
{    
     MyGraph g;

        boost::add_edge(0, 1, g);
        boost::add_edge(0, 2, g);
        boost::add_edge(0, 3, g);
        boost::add_edge(2, 4, g);

        MyVisitor vis;

        //2 - N2 node 
        boost::depth_first_search(g,  boost::visitor(vis).root_vertex(2) );
        return 0;

}

输出是:

2
0
1
3
4

但我希望(2 个和所有孩子)

2
4

请帮忙。

谢谢。

【问题讨论】:

  • 你收到的,究竟是什么?因为那个“sn-p”并没有做任何事情,真的
  • 咳咳——抱歉。固定的!完整的 sn-p 添加了输出样本。

标签: c++ boost graph


【解决方案1】:

您的图是无向的,这意味着也采用了后边 (0,2)。

尝试将undirectedS 更改为directedS

为避免报告从其他根发现的顶点,您可以调整访问者以检测第一个 root 何时为 done

Live On Coliru

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/graph/depth_first_search.hpp>
#include <boost/graph/visitors.hpp>
#include <iterator>

using Graph = boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS>;
using VertexPair = std::pair<Graph::vertex_descriptor, Graph::vertex_descriptor>;

struct Visitor : boost::default_dfs_visitor {
    using V = Graph::vertex_descriptor;

    void discover_vertex(V v, const Graph& /*g*/) {
        if (!root) {
            root = v;
        }
        if (!done) std::cerr << v << "\n";
    }

    void finish_vertex(V v, const Graph& /*g*/) {
        done |= (root == v);
    }
  private:
    bool done = false;
    boost::optional<V> root;
};

int main() {
    // [N0, N1[N2, N3, N4[N5], N6] :
    // VertexPair const data[] { {1, 2}, {1, 3}, {1, 4}, {4, 5}, };
    VertexPair const data[] { {0, 1}, {0, 2}, {0, 3}, {2, 4}, };
    Graph g(std::begin(data), std::end(data), 7);

    boost::depth_first_search(g, boost::visitor(Visitor()).root_vertex(2));
    //boost::write_graphviz(std::cout, g);
}

打印

2
4

更新

如果为了提高效率您想避免遍历树的其余部分,您可以使用depht_first_visit,它可以采用TerminatorFunc。在这里,我将其添加到同一访客:

Live On Coliru

// in Visitor:

    // the TerminatorFunc
    bool operator()(V, Graph const&) const { return done; }

// later:

    Visitor vis_termfuc; // combines visitor and terminator functions
    std::vector<boost::default_color_type> colormap(num_vertices(g));
    boost::depth_first_visit(g, 2, vis_termfuc, colormap.data(), vis_termfuc);

【讨论】:

  • 谢赫,谢谢你的提示。现在结果好多了。 2 4 0 1 3 只有我需要的是在4之后切断所有节点。
  • 是的,我认为您需要阻止访客访问它。让我看看
  • @user1503944 添加了一种更高效的方法,可以提前停止搜索Live On Coliru
  • 谢赫,看起来它对我有用!非常感谢 !因为我的 MSVC 编译器没有准备好 C++11,所以添加了一些修改。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-09-28
  • 2018-09-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多