c++11 - 通过删除叶子来制作 boost 图的子图

标签 c++11 boost boost-graph

我有一个 vecS 类型的 BGL 图。我想通过删除叶子来制作它的新图表。我需要它主要是为了可视化,因为有很多叶子我不需要可视化。根据这篇文章c++ remove vertex from a graphBGL page从 vecS 邻接表中删除顶点并不安全。那么,对于我有 vecS 图的情况,解决方案是什么?我如何制作一个没有叶子的新图。

    /// vertex properties
struct VertexData
{
    std::string label;
    int num;
    bool is_leaf=false;
};

/// edges properties
struct EdgeData
{
    std::string edge_name;
    double edge_confidence;
};

/// define the boost-graph
typedef boost::adjacency_list<boost::vecS, boost::vecS,
        boost::bidirectionalS,
        boost::property<boost::vertex_index_t , size_t , VertexData>,
        boost::property<boost::edge_weight_t, double, EdgeData> > Graph;

感谢您的回答。

PS。是否可以使用谓词filtered_graph

最佳答案

有点令人惊讶的是,您有一个 bool 标志来指示什么是叶子。从图的本质来看,假设叶子是出度为 0 的任何顶点似乎是合乎逻辑的。

无论如何:

Live On Coliru

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/filtered_graph.hpp>
#include <boost/graph/graph_utility.hpp>

/// vertex properties
struct VertexData {
    std::string label;
    int num;
    bool is_leaf=false;
};

/// edges properties
struct EdgeData {
    std::string edge_name;
    double edge_confidence;
};

/// define the boost-graph
typedef boost::adjacency_list<boost::vecS, boost::vecS,
        boost::bidirectionalS,
        boost::property<boost::vertex_index_t, size_t, VertexData>,
        boost::property<boost::edge_weight_t, double, EdgeData> > Graph;

using Predicate = std::function<bool(Graph::vertex_descriptor)>;
using Filtered  = boost::filtered_graph<Graph, boost::keep_all, Predicate>;

Graph make_graph();

int main() {
    Graph g = make_graph();
    auto const labels = get(&VertexData::label, g);

    std::cout << "\n---Main graph:\n";
    print_graph(g, labels);

    // manual markings
    {
        auto manual_is_leaf = [&g](Graph::vertex_descriptor vd) { return !g[vd].is_leaf; };
        Filtered manual(g, boost::keep_all{}, manual_is_leaf);

        {

            std::cout << "\n---Filtered, no leafs:\n";
            print_graph(manual, labels);
        }

        {
            std::cout << "\n---Filtered, manual leafs:\n";
            g[2].is_leaf = true; // only "three"

            print_graph(manual, labels);
        }
    }

    // automatic, dynamic markings
    {
        // note that for bidirectional/undirected out_degree might not make
        // sense, but neither does the notion of a leaf! 
        auto by_degree = [&g](Graph::vertex_descriptor vd) { return boost::out_degree(vd, g); };
        Filtered automatic(g, boost::keep_all{}, by_degree);

        {
            std::cout << "\n---Filtered by actual out_degree:\n";
            print_graph(automatic, labels);
        }

        {
            // make `five` and `six` appear:
            add_edge(5, 4, 100, g); // six -> five

            std::cout << "\n---After adding an edge:\n";
            print_graph(automatic, labels);
        }
    }
}

Graph make_graph() {
    Graph g;

    auto v1 = add_vertex({ 1, {"one",   100, false} }, g);
    auto v2 = add_vertex({ 2, {"two",   200, false} }, g);
    auto v3 = add_vertex({ 3, {"three", 300, false} }, g);
    auto v4 = add_vertex({ 4, {"four",  400, false} }, g);
    auto v5 = add_vertex({ 5, {"five",  500, false} }, g);
    auto v6 = add_vertex({ 6, {"six",   600, false} }, g);

    add_edge(v1, v2, 0.5, g);
    add_edge(v2, v3, 0.5, g);
    add_edge(v3, v4, 0.5, g);
    add_edge(v3, v5, 0.5, g);
    add_edge(v3, v6, 0.5, g);
    add_edge(v2, v4, 0.5, g);
    add_edge(v3, v5, 0.5, g);
    add_edge(v4, v6, 0.5, g);

    return g;
}

打印

---Main graph:
one --> two 
two --> three four 
three --> four five six five 
four --> six 
five --> 
six --> 

---Filtered, no leafs:
one --> two 
two --> three four 
three --> four five six five 
four --> six 
five --> 
six --> 

---Filtered, manual leafs:
one --> two 
two --> four 
four --> six 
five --> 
six --> 

---Filtered by actual out_degree:
one --> two 
two --> three four 
three --> four 
four --> 

---After adding an edge:
one --> two 
two --> three four 
three --> four six 
four --> six 
six --> 

NOTE

Replace boost::out_degree with boost::degree if you want to be more "true" to the nature of bidirectional/undirected graphs (see the comment). In that case you will see all vertices in the automatic section, because all vertices are connected with some edge.

关于c++11 - 通过删除叶子来制作 boost 图的子图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47060794/

相关文章:

c++ - 发布安全、宽松的内存模型和 memcpy

c++ - C++中的虚拟继承和统一初始化

c++ - enable_shared_from_this 和堆栈上的对象

c++ - 将 listS 用于顶点和边列表时无法调用 boost::clear_vertex

c++ - in_degree 函数的问题

c++ - 在 C++ 中实现和使用节点图的方法?

c++ - GLM 无法使用 g++/C++11 进行编译

c++ - 头尾打印比检查结束或开始更有效吗?

c++ - 没有规则使目标 '/usr/lib/x86_64-linux-gnu/libboost_filesystem.so`

c++ - STL端口错误: '__cxa_demangle' is not a member of 'abi' for boost library