【问题标题】:create graphs from a file using boost library使用 boost 库从文件创建图形
【发布时间】:2015-02-28 09:22:07
【问题描述】:

我正在尝试编写一个程序,该程序可以使用 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;

解决这个问题后,我每次前进都会放代码:)

【问题讨论】:

    标签: c++ boost graph io


    【解决方案1】:

    首先,您的myvector 没有在任何地方定义或声明。

    其次,你说你对std::cout &lt;&lt; ' ' &lt;&lt; (*it)-&gt;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;
        }
      }
    

    更新2

    你的 cmets 把我弄糊涂了。如果您想做的是填充 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
    

    【讨论】:

    • 代码已修改。请问如何制作额外的内循环!我也试过这个循环,但它不起作用std::cout &lt;&lt; "dataG contains:"; for( auto gr : dataG ) std::cout &lt;&lt; gr-&gt;id &lt;&lt; ' ' ;
    • 我没有使用过 boost 图形库,但是在快速查看文档之后,您也许可以只用for (size_t i = 0 ; i &lt; num_vertices(gr) ; ++i) { std::cout &lt;&lt; gr[i].id &lt;&lt; std::end;} 遍历顶点我已将此添加到答案中清晰度。
    • 我应该注意,您可能不会从输出中获得太多信息,因为我看不到如何从您提供的代码中正确填充节点。
    • 其实我想把图放到dataG中,并通过写id来确保,那么为什么要使用num_vertices呢?
    • 这将为社区节省大量时间@swalog :) +1 努力,但实际上,我们应该尽量少做一个个人帮助台。教一个人如何钓鱼等。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-04-29
    • 2013-09-19
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多