使用 boost 库从文件创建图形
create graphs from a file using boost library
我正在尝试编写一个程序,该程序可以使用 BOOST 库从文件中读取和创建图形。
首先,我从一些解释开始。
该文件将类似于:http://pastebin.com/g4cgaHJB
每次我找到像 (t # 1) 这样的线时,它的均值图的 id 为 1。
(v 0 12) 它的平均顶点 ID 为 0,标签为 12。
(e 1 3 52) 它在 id 为 1 的顶点和 id 为 3 的顶点之间带有标签 52 的平均边。
我从读取文件开始,每次找到 (t # ..) 我都会创建一个图形并将其放入图形向量中。
这是代码:
#include <iostream>
#include <vector>
#include <ctime>
#include <set>
#include <fstream>
#include <string>
#include <unordered_set>
#include <cstdlib>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/graph/adjacency_list.hpp>
using namespace std;
using namespace boost;
using namespace boost::algorithm;
/*********************************************/
//vertex
struct VertexProperties
{
int id;
int label;
VertexProperties(){}
VertexProperties(unsigned i, unsigned l) : id(i), label(l) {}
};
//edge
struct EdgeProperties
{
unsigned id;
unsigned label;
EdgeProperties(){}
EdgeProperties(unsigned i, unsigned l) : id(i), label(l) {}
};
//Graph
struct GraphProperties
{
unsigned id;
unsigned label;
GraphProperties() {}
GraphProperties(unsigned i, unsigned l) : id(i), label(l) {}
};
//adjency list
typedef boost::adjacency_list<
boost::vecS, boost::vecS, boost::directedS,
VertexProperties,
EdgeProperties,
GraphProperties
> Graph;
//descriptors
typedef boost::graph_traits<Graph>::vertex_descriptor vertex_t;
typedef std::pair<boost::graph_traits<Graph>::edge_descriptor, bool> edge_t;
//iterators
typedef graph_traits<Graph>::vertex_iterator vertex_iter;
typedef graph_traits<Graph>::edge_iterator edge_iter;
/****************************************************************************/
//le seuil int seuil;
std::vector<std::string> tokens;
/*
programme principal
*/
int main()
{
vector<Graph> dataG; // vector<graphes> * pointsdataG;
ifstream * file_reader= new ifstream("5.txt" ); //flux d'entrée pour opérer sur les fichiers.
while (!file_reader->eof())
{
string line;
file_reader->sync(); //Synchronise le tampon d'entree avec la source de donnees associee.
getline(*file_reader, line); //lire les caracteres a partir du flux d'entree (file_reader) et les place dans une chaine: (line)
if(line[0]=='t') // ligne de transaction(graphe)
{
split(tokens, line, is_any_of(" "));
int gid=atoi(tokens[2].c_str());
Graph g(GraphProperties(gid,gid));
cout<<gid<<endl;
dataG.push_back(g);
}
}
std::cout << "dataG contains:";
for (std::vector<Graph>::iterator it = dataG.begin() ; it != dataG.end(); ++it)
{
std::cout << ' ' << (*it)->label;
std::cout << '\n';
}
}
但是我对这条线有疑问
std::cout << ' ' << (*it)->id;
解决这个问题后我会在每次前进时放上代码:)
首先,您的 myvector
没有在任何地方定义或声明。
其次,您说 std::cout << ' ' << (*it)->id;
有问题的行在您的代码中不存在。
但是,问题很可能与您在代码中 实际遇到的问题相同。您正在遍历包含 adjacency_list
项的向量,然后尝试从图形对象中提取节点值。
您需要一个额外的内部循环,以从节点中提取值。
更新1
这可能是这样的:
std::cout << "dataG contains:";
for (auto gr : dataG)
{
for (size_t i = 0 ; i < num_vertices(gr) ; ++i) {
std::cout << ' ' << gr[i].id << std::endl;
}
}
update2
你的评论让我很困惑。如果您想做的是填充 adjacency_list,那么您可以这样做:
while (!file_reader->eof())
{
string line;
file_reader->sync();
getline(*file_reader, line);
std::stringstream ss(line);
char lineType;
ss >> lineType;
if(lineType =='t')
{
char dummy;
int gid;
ss >> dummy >> gid;
Graph g(GraphProperties(gid,gid));
dataG.push_back(g);
} else if (lineType == 'v') {
assert(!dataG.empty());
int vId, vLabel;
ss >> vId >> vLabel;
boost::add_vertex(VertexProperties(vId, vLabel), dataG[dataG.size()-1]);
} else if (lineType == 'e') {
assert(!dataG.empty());
int fromId, toId, vLabel;
ss >> fromId >> toId >> vLabel;
// Note that the EdgeProperty.id doesn't make sense with your input data
// as it only contains [vertexFrom vertexTo edgeData]
boost::add_edge(fromId, toId,
EdgeProperties(0, vLabel), dataG[dataG.size()-1]);
}
}
我相信您使用 'id' 对顶点来说是多余的,因为它们都会附加隐式 ID。但是,如果您仍然希望将其作为顶点 属性,那很好。但是,您对边缘执行相同的操作,但边缘条目数据没有 'id' 字段。
update3*
要访问和输出图形的内容:
typedef std::pair<edge_iter, edge_iter> edge_pair;
std::cout << "dataG contains:" << std::endl;
int c = 0;
for (auto gr : dataG)
{
++c;
std::cout << "Graph " << c << " contains " << num_vertices(gr) << " vertices, and " << num_edges(gr) << " edges" << std::endl;
std::cout << " Vertex list: " << std::endl;
for (size_t i = 0 ; i < num_vertices(gr) ; ++i) {
std::cout << " [" << i << "] ID: " << gr[i].id << ", Label: " << gr[i].label << std::endl;
}
std::cout << " Edge list: " << std::endl;
edge_pair ep;
for (ep = edges(gr); ep.first != ep.second; ++ep.first) {
vertex_t from = source(*ep.first, gr);
vertex_t to = target(*ep.first, gr);
edge_t edg = edge(from, to, gr);
std::cout << " [" << gr[from].id << "," << gr[to].id << "] ID: N/A, Label: " << gr[edg.first].label << std::endl;
}
std::cout << std::endl;
}
使用'5.txt'的输出:
dataG contains:
Graph 1 contains 3 vertices, and 3 edges
Vertex list:
[0] ID: 0, Label: 0
[1] ID: 1, Label: 3
[2] ID: 2, Label: 9
Edge list:
[0,1] ID: N/A, Label: 10
[0,2] ID: N/A, Label: 4
[2,1] ID: N/A, Label: 68
Graph 2 contains 6 vertices, and 3 edges
Vertex list:
[0] ID: 0, Label: 2
[1] ID: 1, Label: 11
[2] ID: 2, Label: 6
[3] ID: 3, Label: 10
[4] ID: 4, Label: 18
[5] ID: 5, Label: 14
Edge list:
[0,1] ID: N/A, Label: 15
[1,3] ID: N/A, Label: 20
[2,5] ID: N/A, Label: 19
Graph 3 contains 2 vertices, and 1 edges
Vertex list:
[0] ID: 0, Label: 6
[1] ID: 1, Label: 11
Edge list:
[0,1] ID: N/A, Label: 13
Graph 4 contains 4 vertices, and 3 edges
Vertex list:
[0] ID: 0, Label: 2
[1] ID: 1, Label: 11
[2] ID: 2, Label: 19
[3] ID: 3, Label: 2
Edge list:
[0,1] ID: N/A, Label: 15
[0,3] ID: N/A, Label: 19
[1,2] ID: N/A, Label: 11
Graph 5 contains 3 vertices, and 4 edges
Vertex list:
[0] ID: 0, Label: 1
[1] ID: 1, Label: 16
[2] ID: 2, Label: 14
Edge list:
[0,1] ID: N/A, Label: 8
[0,2] ID: N/A, Label: 19
[0,2] ID: N/A, Label: 19
[1,2] ID: N/A, Label: 5
我正在尝试编写一个程序,该程序可以使用 BOOST 库从文件中读取和创建图形。 首先,我从一些解释开始。 该文件将类似于:http://pastebin.com/g4cgaHJB 每次我找到像 (t # 1) 这样的线时,它的均值图的 id 为 1。 (v 0 12) 它的平均顶点 ID 为 0,标签为 12。 (e 1 3 52) 它在 id 为 1 的顶点和 id 为 3 的顶点之间带有标签 52 的平均边。
我从读取文件开始,每次找到 (t # ..) 我都会创建一个图形并将其放入图形向量中。 这是代码:
#include <iostream>
#include <vector>
#include <ctime>
#include <set>
#include <fstream>
#include <string>
#include <unordered_set>
#include <cstdlib>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <boost/graph/adjacency_list.hpp>
using namespace std;
using namespace boost;
using namespace boost::algorithm;
/*********************************************/
//vertex
struct VertexProperties
{
int id;
int label;
VertexProperties(){}
VertexProperties(unsigned i, unsigned l) : id(i), label(l) {}
};
//edge
struct EdgeProperties
{
unsigned id;
unsigned label;
EdgeProperties(){}
EdgeProperties(unsigned i, unsigned l) : id(i), label(l) {}
};
//Graph
struct GraphProperties
{
unsigned id;
unsigned label;
GraphProperties() {}
GraphProperties(unsigned i, unsigned l) : id(i), label(l) {}
};
//adjency list
typedef boost::adjacency_list<
boost::vecS, boost::vecS, boost::directedS,
VertexProperties,
EdgeProperties,
GraphProperties
> Graph;
//descriptors
typedef boost::graph_traits<Graph>::vertex_descriptor vertex_t;
typedef std::pair<boost::graph_traits<Graph>::edge_descriptor, bool> edge_t;
//iterators
typedef graph_traits<Graph>::vertex_iterator vertex_iter;
typedef graph_traits<Graph>::edge_iterator edge_iter;
/****************************************************************************/
//le seuil int seuil;
std::vector<std::string> tokens;
/*
programme principal
*/
int main()
{
vector<Graph> dataG; // vector<graphes> * pointsdataG;
ifstream * file_reader= new ifstream("5.txt" ); //flux d'entrée pour opérer sur les fichiers.
while (!file_reader->eof())
{
string line;
file_reader->sync(); //Synchronise le tampon d'entree avec la source de donnees associee.
getline(*file_reader, line); //lire les caracteres a partir du flux d'entree (file_reader) et les place dans une chaine: (line)
if(line[0]=='t') // ligne de transaction(graphe)
{
split(tokens, line, is_any_of(" "));
int gid=atoi(tokens[2].c_str());
Graph g(GraphProperties(gid,gid));
cout<<gid<<endl;
dataG.push_back(g);
}
}
std::cout << "dataG contains:";
for (std::vector<Graph>::iterator it = dataG.begin() ; it != dataG.end(); ++it)
{
std::cout << ' ' << (*it)->label;
std::cout << '\n';
}
}
但是我对这条线有疑问
std::cout << ' ' << (*it)->id;
解决这个问题后我会在每次前进时放上代码:)
首先,您的 myvector
没有在任何地方定义或声明。
其次,您说 std::cout << ' ' << (*it)->id;
有问题的行在您的代码中不存在。
但是,问题很可能与您在代码中 实际遇到的问题相同。您正在遍历包含 adjacency_list
项的向量,然后尝试从图形对象中提取节点值。
您需要一个额外的内部循环,以从节点中提取值。
更新1 这可能是这样的:
std::cout << "dataG contains:";
for (auto gr : dataG)
{
for (size_t i = 0 ; i < num_vertices(gr) ; ++i) {
std::cout << ' ' << gr[i].id << std::endl;
}
}
update2
你的评论让我很困惑。如果您想做的是填充 adjacency_list,那么您可以这样做:
while (!file_reader->eof())
{
string line;
file_reader->sync();
getline(*file_reader, line);
std::stringstream ss(line);
char lineType;
ss >> lineType;
if(lineType =='t')
{
char dummy;
int gid;
ss >> dummy >> gid;
Graph g(GraphProperties(gid,gid));
dataG.push_back(g);
} else if (lineType == 'v') {
assert(!dataG.empty());
int vId, vLabel;
ss >> vId >> vLabel;
boost::add_vertex(VertexProperties(vId, vLabel), dataG[dataG.size()-1]);
} else if (lineType == 'e') {
assert(!dataG.empty());
int fromId, toId, vLabel;
ss >> fromId >> toId >> vLabel;
// Note that the EdgeProperty.id doesn't make sense with your input data
// as it only contains [vertexFrom vertexTo edgeData]
boost::add_edge(fromId, toId,
EdgeProperties(0, vLabel), dataG[dataG.size()-1]);
}
}
我相信您使用 'id' 对顶点来说是多余的,因为它们都会附加隐式 ID。但是,如果您仍然希望将其作为顶点 属性,那很好。但是,您对边缘执行相同的操作,但边缘条目数据没有 'id' 字段。
update3*
要访问和输出图形的内容:
typedef std::pair<edge_iter, edge_iter> edge_pair;
std::cout << "dataG contains:" << std::endl;
int c = 0;
for (auto gr : dataG)
{
++c;
std::cout << "Graph " << c << " contains " << num_vertices(gr) << " vertices, and " << num_edges(gr) << " edges" << std::endl;
std::cout << " Vertex list: " << std::endl;
for (size_t i = 0 ; i < num_vertices(gr) ; ++i) {
std::cout << " [" << i << "] ID: " << gr[i].id << ", Label: " << gr[i].label << std::endl;
}
std::cout << " Edge list: " << std::endl;
edge_pair ep;
for (ep = edges(gr); ep.first != ep.second; ++ep.first) {
vertex_t from = source(*ep.first, gr);
vertex_t to = target(*ep.first, gr);
edge_t edg = edge(from, to, gr);
std::cout << " [" << gr[from].id << "," << gr[to].id << "] ID: N/A, Label: " << gr[edg.first].label << std::endl;
}
std::cout << std::endl;
}
使用'5.txt'的输出:
dataG contains:
Graph 1 contains 3 vertices, and 3 edges
Vertex list:
[0] ID: 0, Label: 0
[1] ID: 1, Label: 3
[2] ID: 2, Label: 9
Edge list:
[0,1] ID: N/A, Label: 10
[0,2] ID: N/A, Label: 4
[2,1] ID: N/A, Label: 68
Graph 2 contains 6 vertices, and 3 edges
Vertex list:
[0] ID: 0, Label: 2
[1] ID: 1, Label: 11
[2] ID: 2, Label: 6
[3] ID: 3, Label: 10
[4] ID: 4, Label: 18
[5] ID: 5, Label: 14
Edge list:
[0,1] ID: N/A, Label: 15
[1,3] ID: N/A, Label: 20
[2,5] ID: N/A, Label: 19
Graph 3 contains 2 vertices, and 1 edges
Vertex list:
[0] ID: 0, Label: 6
[1] ID: 1, Label: 11
Edge list:
[0,1] ID: N/A, Label: 13
Graph 4 contains 4 vertices, and 3 edges
Vertex list:
[0] ID: 0, Label: 2
[1] ID: 1, Label: 11
[2] ID: 2, Label: 19
[3] ID: 3, Label: 2
Edge list:
[0,1] ID: N/A, Label: 15
[0,3] ID: N/A, Label: 19
[1,2] ID: N/A, Label: 11
Graph 5 contains 3 vertices, and 4 edges
Vertex list:
[0] ID: 0, Label: 1
[1] ID: 1, Label: 16
[2] ID: 2, Label: 14
Edge list:
[0,1] ID: N/A, Label: 8
[0,2] ID: N/A, Label: 19
[0,2] ID: N/A, Label: 19
[1,2] ID: N/A, Label: 5