【问题标题】:C++ boost graph : how to add_vertex via iterationC++ 提升图:如何通过迭代添加顶点
【发布时间】:2018-04-07 14:52:44
【问题描述】:

我有一个大的 .json 文件,其中顶点信息被解析并分配到内存中,大量使用了指针。为简化起见,假设我有一个顶点标签向量,例如:

vector<string> vertices = {'A', 'B', 'C'}; //assume it is much longer

如何通过迭代将此向量作为我的提升图的顶点传递,而不为每个顶点创建唯一的 vector_descriptor?

我想避免的:

using namespace boost;
struct Vertex {string label};
struct Edge {double weight};

typedef adjacency_list<vecS, vecS, bidirectionalS, Vertex, Edge> Graph;
typedef graph_traits < Graph >::vertex_descriptor vertex_t;
typedef graph_traits < Graph >::edge_descriptor edge_t;
Graph g;

// manual generation of each vertex
vertex_t a = add_vertex(g); g[a].label = 'A'; 
vertex_t b = add_vertex(g); g[b].label = 'B'; 
vertex_t c = add_vertex(g); g[c].label = 'C'; 

add_edge(a,b,g); // reference to vertices by vertex_descriptor
add_edge(a,c,g);

我想要什么:

using namespace boost;
typedef adjacency_list<vecS, vecS, bidirectionalS, Vertex, Edge> Graph;
Graph g;

vector<string> vertices = {'A', 'B', 'C'}; //assume it is much longer
for (i=0; i<vertices.size(); i++) { // iterating thru 'long' vector
    add_vertex(vertices.at(i), g); // no unique vertex descriptor per vertex
}

add_edge('A', 'B', g); // reference to vertex label
add_edge('A', 'C', g);

我尝试过的: 但是我对这种方法的麻烦是将向量转换为枚举类型。或者找到一种附加到枚举类型的方法,以对应于我想要的迭代,因为我的顶点数很大。

using namespace boost;
typedef adjacency_list<vecS, vecS, bidirectionalS, Vertex, Edge> Graph;
Graph g;

enum {A, B, C};
add_edge(A, B, g); // reference to vertex label
add_edge(A, C, g);

注意:非常感谢您的建议和解释,以适应您的解决方案。我是 C++ 初学者。

【问题讨论】:

    标签: c++ boost graph iteration


    【解决方案1】:

    一些建议:

    1. 使用向量存储vertex_t
    vector<string> vertices = {"A", "B", "C"}; //assume it is much longer
    vector<vertex_t> vtx;
    for (i=0; i<vertices.size(); i++) { // iterating thru 'long' vector
        vertex_t tmp = add_vertex(g);
        g[tmp].label = vertices.at(i);
        vtx.push_back(tmp); // no unique vertex descriptor per vertex
    }
    
    add_edge(vtx[0], vtx[1], g); // reference to vertices by vertex_descriptor
    add_edge(vtx[0], vtx[2], g);
    

    这是你想要的吗?

    1. 上面使用map或者unordered map进行转换
    vector<string> vertices = {"A", "B", "C"}; //assume it is much longer
    unordered_map<string, vertex_t> vtx;
    for (i=0; i<vertices.size(); i++) { // iterating thru 'long' vector
        vertex_t tmp = add_vertex(g);
        g[tmp].label = vertices.at(i);
        vtx.emplace(vertices.at(i), tmp); // no unique vertex descriptor per vertex
    }
    
    add_edge(vtx["A"], vtx["B"], g); // reference to vertices by vertex_descriptor
    add_edge(vtx["A"], vtx["C"], g);
    

    这是你想要的吗?

    使用unordered_map需要#include &lt;unordered_map&gt;

    【讨论】:

    • 是的,选项#2 效果很好!!谢谢! (唯一必要的编辑,代表我的错误,是 tmp.label = 应该是 g[tmp].label =
    猜你喜欢
    • 2020-04-11
    • 2011-03-07
    • 1970-01-01
    • 2018-02-01
    • 1970-01-01
    • 2017-07-29
    • 2017-09-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多