简体   繁体   English

从文件构造一个Boost图(邻接表)

[英]Constructing a Boost graph from a file (Adjacency list)

I'm trying to get started with the very good Boost graph library. 我正在尝试从非常好的Boost图形库开始。

The first step is reading a graph from a file, where each line contains edges separated by spaces. 第一步是从文件中读取图形,其中每行包含以空格分隔的边。

I can't seem to get it done right. 我似乎无法正确完成它。 My current code looks like this: 我当前的代码如下所示:

..include stuff..
using namespace boost;

typedef boost::adjacency_list<listS, vecS, undirectedS> Graph;

Graph get_graph(char* str1){

  Graph g; 

  std::ifstream infile(str1);
  std::string line;
  int e1;
  int e2;

  //std::map<int,g> VertexList;

  while (std::getline(infile, line)){

    std::istringstream iss(line);

    //std::cout<<line<<"\n";

    std::vector<std::string> strs;
    split(strs, line, is_any_of(" "));


    //std::cout<<" Adding edge: " << strs[0]<< " to " << strs[1] << "\n";

    std::istringstream ss(strs[0].substr(0,5));
    ss >> e1;

    std::istringstream s2(strs[1].substr(0,5));
    s2 >> e2;


    //ADD e1 and e2 to a graph and connect them with an edge somehow!



    //    VertexList[123]=boost::add_vertex(g);

    //Graph::vertex_descriptor v2 = boost::add_vertex(g);

    //add individual vertices to the graph..
    //e1 = add_vertex(g);
    //e2 = add_vertex(g);

    //add the corresponding edge..


  }

  std::cout<<num_vertices(g)<<std::endl;



  return g;

}

int main(int argc, char *argv[]){ 

  Graph g = get_graph(argv[1]);


  //degree_vec(g);

  return 0;

}

File example: 文件示例:

214328887 34428380
17116707 28465635
380580781 18996905
221036078 153460275
107830991 17868918
151338729 222261763
19705747 34428380
222261763 88323281
19933035 149538028
158419434 17434613

Things I tried and kind of worked: 我尝试过的事情和某种可行的方法:

  • Using boost graph library: how to create a graph by reading edge lists from file , but it reads Edge lists, which do not help me as I can not call functions, bound to Adjacency lists (or can I?) 使用Boost图形库:如何通过从文件读取边缘列表来创建图形 ,但它读取边缘列表,这对我没有帮助,因为我无法调用绑定到邻接列表的函数(或者可以吗?)

  • Using add_edge(e1,e2,g) did not work, as in this case e1 and e2 can only be unsigned integers of length 1 (?), It threw some weird results if I used add_edge(123,32,g) for example. 使用add_edge(e1,e2,g)不起作用,因为在这种情况下, e1e2只能是长度为1(?)的无符号整数,例如add_edge(123,32,g)如果我使用add_edge(123,32,g) ,它将产生一些奇怪的结果。 (like when I counted vertices, there were 122, instead of 1) (例如当我计算顶点时,有122个,而不是1个)

  • Using vertex_descriptors , for eg Graph::vertex_descriptor e1 = boost::add_vertex(g); 使用vertex_descriptors ,例如Graph::vertex_descriptor e1 = boost::add_vertex(g); and then adding edges using these descriptors, but I can't seem to make it work (as I said, this is relatively new to me) 然后使用这些描述符添加边,但我似乎无法使其正常工作(正如我所说,这对我来说是相对较新的)

Using add_edge(e1,e2,g) 使用add_edge(e1,e2,g)

Sure it does! 当然可以! Your assumptions about how adjacency_list<..., vecS,... > should work are wrong. 您对adjacency_list<..., vecS,... >应该如何工作的假设是错误的。 The vertex-descriptor IS the vertex index in that case and vertices are random-access (due to vecS ). 在这种情况下,顶点描述符是顶点索引,并且顶点是随机访问的(由于vecS )。

If you want to make the numbers as read "just" an ID, make them a property of your vertex, instead of directly using them as the vertex index. 如果要使数字读为“仅” ID,请使其成为顶点的属性,而不是直接将其用作顶点索引。 Most likely you will want to use some node-based container selector for the vertex container (so instead of vecS eg listS ). 您最有可能希望为顶点容器使用一些基于节点的容器选择器(因此,而不是vecS例如listS )。 Next, you probably want an id or name property associated with each vertex. 接下来,您可能需要与每个顶点关联的idname属性。 May I suggest a bundled property: 我可以建议捆绑物业:

struct VertexProperty {
    int id;
};

typedef boost::adjacency_list<listS, vecS, undirectedS, VertexProperty> Graph;

std::istringstream iss(line);
if (iss >> e1 >> e2) {
    // find or insert v1 and v2, e.g. insert by:
    auto v1 = add_vertex(VertexProperty { e1 }, g);
    auto v2 = add_vertex(VertexProperty { e2 }, g);

    add_edge(v1, v2, g);
}

Notes: 笔记:

BONUS: labeled_graph demo labeled_graphlabeled_graph演示

As a bonus, here's an example using labeled_graph adaptor: 另外,这是使用labeled_graph适配器的示例:

Live On Coliru 生活在Coliru

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/labeled_graph.hpp>
#include <fstream>
#include <iostream>
#include <sstream>

using namespace boost;

typedef boost::adjacency_list<listS, vecS, undirectedS> AdjList;
typedef boost::labeled_graph<AdjList, size_t, mapS> Graph;

Graph get_graph(char* str1){

    Graph g; 

    std::ifstream infile(str1);
    std::string line;

    while (std::getline(infile, line)) {

        std::istringstream iss(line);

        size_t vid1, vid2;
        if (iss >> vid1 >> vid2) {
            auto v1 = add_vertex(vid1, g);
            auto v2 = add_vertex(vid2, g);

            add_edge(v1, v2, g);
        } else {
            std::cerr << "Skipped invalid line '" << line << "'\n";
        }

    }

    std::cout << num_vertices(g) << std::endl;
    return g;
}

int main(int argc, char *argv[]){ 
    if (argc<2) return 255;
    Graph g = get_graph(argv[1]);
}

Which prints (for the example input): 哪个打印(对于示例输入):

18

Which is correct since 222261763 and 34428380 occur twice in the input of 10 lines (10x2 - 2 == 18 vertices). 这是正确的,因为22226176334428380在10行输入中出现了两次(10x2-2 == 18个顶点)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM