【问题标题】:Boost BGL Transitive reduction提升 BGL 传递减少
【发布时间】:2015-03-22 19:35:12
【问题描述】:

我尝试使用boost的transitive_reduction,但是不知道怎么用。

我有一个用 : 定义的图表:

typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, IQsNode*> Graph;
typedef Graph::vertex_descriptor Vertex;

我想调用方法:

Graph TC;
boost::transitive_reduction(_fullGraph, TC,g_to_tr_map_stor,g_to_tc_map_stor);

我不知道“g_to_tr_map_stor”和“g_to_tc_map_stor”必须使用的类型。

根据我阅读的信息,它必须是顶点的地图
为整数。我尝试了多种地图但没有成功。

一些想法?

谢谢

【问题讨论】:

    标签: c++ boost graph-theory boost-graph transitive-closure


    【解决方案1】:

    据我的文档告诉我,这不是公共 API。这意味着您可以找到内部使用它的地方,并将其用作如何使用它的示例。

    有趣的是,事实并非如此。这可能会让人认为文档滞后/被遗忘

    CAVEAT 使用未记录的 API 表面可能会在升级时破坏您的代码,恕不另行通知。

    这是我能想到的满足界面的最简单的方法:

    Graph const g = make_random();
    
    Graph tr;
    std::map<Graph::vertex_descriptor, Graph::vertex_descriptor> g_to_tr;
    std::vector<size_t> id_map(num_vertices(g));
    std::iota(id_map.begin(), id_map.end(), 0u);
    
    transitive_reduction(g, tr, make_assoc_property_map(g_to_tr), id_map.data());
    

    因此,它使用std::map 作为g_to_tr 顶点关联映射传递。我们传递和顶点 id-map,它只是增加每个顶点的 id。

    如果打印结果:

    print_graph(g);
    std::cout << "----------------------------\n";
    for (auto& e : g_to_tr)
        std::cout << "Mapped " << e.first << " to " << e.second << "\n";
    std::cout << "----------------------------\n";
    print_graph(tr);
    

    你可能会知道它的作用。

    Live On Coliru

    #include <boost/graph/adjacency_list.hpp>
    #include <boost/graph/transitive_reduction.hpp>
    #include <iostream>
    
    #include <boost/graph/graph_utility.hpp> // dumping graphs
    #include <boost/graph/graphviz.hpp>      // generating pictures
    
    using namespace boost;
    
    struct IQsNode { };
    typedef boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS, IQsNode*> Graph;
    
    Graph make_random();
    
    int main() {
        Graph const g = make_random();
    
        Graph tr;
        std::map<Graph::vertex_descriptor, Graph::vertex_descriptor> g_to_tr;
        std::vector<size_t> id_map(num_vertices(g));
        std::iota(id_map.begin(), id_map.end(), 0u);
    
        transitive_reduction(g, tr, make_assoc_property_map(g_to_tr), id_map.data());
    
        print_graph(g);
        std::cout << "----------------------------\n";
        for (auto& e : g_to_tr)
            std::cout << "Mapped " << e.first << " to " << e.second << "\n";
        std::cout << "----------------------------\n";
        print_graph(tr);
    
        // generating graphviz files
        { std::ofstream dot("g.dot");  write_graphviz(dot, g); }
        { std::ofstream dot("tr.dot"); write_graphviz(dot, tr); }
    }
    
    // generating test data
    #include <boost/graph/random.hpp>
    #include <random>
    Graph make_random() {
        Graph g;
        std::mt19937 prng (std::random_device{}());
        generate_random_graph(g, 10, 5, prng);
    
        return g;
    }
    

    这里是转载的[维基百科样本]:

    Graph make_wikipedia() {
        Graph g;
        enum {a,b,c,d,e};
        add_edge(a,b,g);
        add_edge(a,c,g);
        add_edge(a,d,g);
        add_edge(a,e,g);
        add_edge(b,d,g);
        add_edge(c,d,g);
        add_edge(c,e,g);
        add_edge(d,e,g);
        return g;
    }
    

    这里是 4 个随机生成的图及其传递缩减的动画:

    【讨论】:

    • 感谢您的完整回答。它可以工作,但在主图中我有一个指向类“IQsNode *”的指针,在结果图 TC 中,指针无效“0xcdcdcdcd”。之后我必须手动设置还是有办法告诉 boost 自动填充它?
    • 您可以使用映射来传输它,例如live: for (auto&amp; e : g_to_tr) tr[e.second] = g[e.first];(内存泄漏是设计使然:))
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多