[英]Constructing a Boost graph from a file (Adjacency list)
我正在尝试从非常好的Boost图形库开始。
第一步是从文件中读取图形,其中每行包含以空格分隔的边。
我似乎无法正确完成它。 我当前的代码如下所示:
..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;
}
文件示例:
214328887 34428380
17116707 28465635
380580781 18996905
221036078 153460275
107830991 17868918
151338729 222261763
19705747 34428380
222261763 88323281
19933035 149538028
158419434 17434613
我尝试过的事情和某种可行的方法:
使用Boost图形库:如何通过从文件读取边缘列表来创建图形 ,但它读取边缘列表,这对我没有帮助,因为我无法调用绑定到邻接列表的函数(或者可以吗?)
使用add_edge(e1,e2,g)
不起作用,因为在这种情况下, e1
和e2
只能是长度为1(?)的无符号整数,例如add_edge(123,32,g)
如果我使用add_edge(123,32,g)
,它将产生一些奇怪的结果。 (例如当我计算顶点时,有122个,而不是1个)
使用vertex_descriptors
,例如Graph::vertex_descriptor e1 = boost::add_vertex(g);
然后使用这些描述符添加边,但我似乎无法使其正常工作(正如我所说,这对我来说是相对较新的)
使用add_edge(e1,e2,g)
当然可以! 您对adjacency_list<..., vecS,... >
应该如何工作的假设是错误的。 在这种情况下,顶点描述符是顶点索引,并且顶点是随机访问的(由于vecS
)。
如果要使数字读为“仅” ID,请使其成为顶点的属性,而不是直接将其用作顶点索引。 您最有可能希望为顶点容器使用一些基于节点的容器选择器(因此,而不是vecS
例如listS
)。 接下来,您可能需要与每个顶点关联的id
或name
属性。 我可以建议捆绑物业:
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);
}
笔记:
e1
会使您感到困惑) labeled_graph
: labeled_graph
演示 另外,这是使用labeled_graph
适配器的示例:
#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]);
}
哪个打印(对于示例输入):
18
这是正确的,因为222261763
和34428380
在10行输入中出现了两次(10x2-2 == 18个顶点)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.