复制边 BOOST 图 C++

Copying edges BOOST graph c++

我正在尝试制作一个程序,从 .txt(类似于 http://pastebin.com/g4cgaHJB)文件中读取图形,然后创建并将它们放入向量中。 (这部分工作完美)

here ise the code:
#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();//Synchronize input buffer

        getline(*file_reader, line);//getline reads characters from an input stream and places them into a string
        std::stringstream ss(line); //use a string buffer that contains a sequence of characters.
        char lineType;
        ss >> lineType;
        if(lineType =='t')
        {
          char diez;
          int gid;
          ss >> diez >> gid;
          Graph g(GraphProperties(gid,gid));
          dataG.push_back(g);
        }  else if (lineType == 'v') 
        {
          assert(!dataG.empty());//evaluate the parameter. If this parameter is false it causes an assertion failure that terminates the program.
          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(vLabel, vLabel), dataG[dataG.size()-1]);
        }
      }


        cout<<"fin."<<endl; // fin du programme.

       return 0;
}

想法:我正在尝试迭代图,方法是从第一条边开始(并从中创建一个图,我们称之为 testg ),并测试该图是否频繁(我将测试之间的子图同构testg 和 dataG 向量中的每个图然后我会计算有多少次是真的如果有很多时间然后 2 所以 testg 很频繁),如果 testg 很频繁所以我会添加另一个相邻的边(并做子图 -再次同构测试),如果 testg 不再频繁,我将删除最后添加的边(回溯)并将其更改为另一个边(并再次进行子图同构测试)。如果没有更多的边缘可以添加,我会说 testg 已关闭。并将其放入一个向量中,我们称它为 closedG。

我是这样开始这个想法的:

auto gr=dataG.at(0);
        Graph testg();             
        edge_pair ep;

        for (ep = edges(gr); ep.first != ep.second; ++ep.first) //ep edge number 
        {
          vertex_t from = source(*ep.first, gr);
          vertex_t to = target(*ep.first, gr);
          edge_t edg = edge(from, to, gr);
          boost::add_edge(from, to,testg);
        }

但是,这是行不通的! 这是错误:

In function 'int main()'
:workshop.cpp:123:42: error: no matching function for call to 'add_edge(vertex_t&, vertex_t&, Graph (&)())'boost:
:add_edge(from, to, testg);
workshop.cpp:123:42: note: candidates are
:In file included from ./boost/graph/adjacency_list.hpp:246:0,from workshop.cpp:12
:./boost/graph/detail/adjacency_list.hpp:707:5: note: template<class Config> std::pair<typename boost::directed_graph_helper<Config>::edge_descriptor, bool> boost::add_edge(typename Config::vertex_descriptor, typename Config::vertex_descriptor, const typename Config::edge_property_type&, boost::directed_graph_helper<Config>&)add_edge(typename Config:
:vertex_descriptor u,
./boost/graph/detail/adjacency_list.hpp:707:5: note:   template argument deduction/substitution failed
:workshop.cpp:123:42: note:   candidate expects 4 arguments, 3 providedboost:
:add_edge(from, to, testg);
In file included from ./boost/graph/adjacency_list.hpp:246:0,from workshop.cpp:12
:./boost/graph/detail/adjacency_list.hpp:727:5: note: template<class Config> std::pair<typename Config::edge_descriptor, bool> boost::add_edge(typename Config::vertex_descriptor, typename Config::vertex_descriptor, boost::directed_graph_helper<Config>&)add_edge(typename Config:
:vertex_descriptor u,
./boost/graph/detail/adjacency_list.hpp:727:5: note:   template argument deduction/substitution failed
:workshop.cpp:123:42: note:   mismatched types 'boost::directed_graph_helper<Config>' and 'Graph() {aka boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, VertexProperties, EdgeProperties, GraphProperties>()}'boost:
:add_edge(from, to, testg);
In file included from ./boost/graph/adjacency_list.hpp:246:0,from workshop.cpp:12
:./boost/graph/detail/adjacency_list.hpp:1045:5: note: template<class Config> std::pair<typename Config::edge_descriptor, bool> boost::add_edge(typename Config::vertex_descriptor, typename Config::vertex_descriptor, const typename Config::edge_property_type&, boost::undirected_graph_helper<C>&)add_edge(typename Config:
:vertex_descriptor u,
./boost/graph/detail/adjacency_list.hpp:1045:5: note:   template argument deduction/substitution failed
:workshop.cpp:123:42: note:   candidate expects 4 arguments, 3 providedboost:
:add_edge(from, to, testg);
In file included from ./boost/graph/adjacency_list.hpp:246:0,from workshop.cpp:12
:./boost/graph/detail/adjacency_list.hpp:1075:5: note: template<class Config> std::pair<typename Config::edge_descriptor, bool> boost::add_edge(typename Config::vertex_descriptor, typename Config::vertex_descriptor, boost::undirected_graph_helper<C>&)add_edge(typename Config:
:vertex_descriptor u,
./boost/graph/detail/adjacency_list.hpp:1075:5: note:   template argument deduction/substitution failed
:workshop.cpp:123:42: note:   mismatched types 'boost::undirected_graph_helper<C>' and 'Graph() {aka boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, VertexProperties, EdgeProperties, GraphProperties>()}'boost:
:add_edge(from, to, testg);
In file included from ./boost/graph/adjacency_list.hpp:246:0,from workshop.cpp:12
:./boost/graph/detail/adjacency_list.hpp:1473:5: note: template<class Config> std::pair<typename Config::edge_descriptor, bool> boost::add_edge(typename Config::vertex_descriptor, typename Config::vertex_descriptor, const typename Config::edge_property_type&, boost::bidirectional_graph_helper_with_property<Config>&)add_edge(typename Config:
:vertex_descriptor u,
./boost/graph/detail/adjacency_list.hpp:1473:5: note:   template argument deduction/substitution failed
:workshop.cpp:123:42: note:   candidate expects 4 arguments, 3 providedboost:
:add_edge(from, to, testg);
In file included from ./boost/graph/adjacency_list.hpp:246:0,from workshop.cpp:12
:./boost/graph/detail/adjacency_list.hpp:1503:5: note: template<class Config> std::pair<typename Config::edge_descriptor, bool> boost::add_edge(typename Config::vertex_descriptor, typename Config::vertex_descriptor, boost::bidirectional_graph_helper_with_property<Config>&)add_edge(typename Config:
:vertex_descriptor u,
./boost/graph/detail/adjacency_list.hpp:1503:5: note:   template argument deduction/substitution failed
:workshop.cpp:123:42: note:   mismatched types 'boost::bidirectional_graph_helper_with_property<Config>' and 'Graph() {aka boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, VertexProperties, EdgeProperties, GraphProperties>()}'boost:
:add_edge(from, to, testg);
In file included from ./boost/graph/adjacency_list.hpp:246:0,from workshop.cpp:12
:./boost/graph/detail/adjacency_list.hpp:2217:5: note: template<class Graph, class Config, class Base> std::pair<typename Config::edge_descriptor, bool> boost::add_edge(typename Config::vertex_descriptor, typename Config::vertex_descriptor,const typename Config::edge_property_type&, boost::vec_adj_list_impl<G, C, B>&)add_edge(typename Config:
:vertex_descriptor u,
./boost/graph/detail/adjacency_list.hpp:2217:5: note:   template argument deduction/substitution failed
:workshop.cpp:123:42: note:   candidate expects 4 arguments, 3 providedboost:
:add_edge(from, to, testg);
In file included from ./boost/graph/adjacency_list.hpp:246:0,from workshop.cpp:12
:./boost/graph/detail/adjacency_list.hpp:2231:5: note: template<class Graph, class Config, class Base> std::pair<typename Config::edge_descriptor, bool> boost::add_edge(typename Config::vertex_descriptor, typename Config::vertex_descriptor,boost::vec_adj_list_impl<G, C, B>&)add_edge(typename Config:
:vertex_descriptor u,
./boost/graph/detail/adjacency_list.hpp:2231:5: note:   template argument deduction/substitution failed
:workshop.cpp:123:42: note:   mismatched types 'boost::vec_adj_list_impl<G, C, B>' and 'Graph() {aka boost::adjacency_list<boost::vecS, boost::vecS, boost::directedS, VertexProperties, EdgeProperties, GraphProperties>()}'boost::add_edge(from, to, testg);

您已成为 most vexing parse 的受害者:

Graph testg();

声明一个函数。不要难过。我花了一段时间才看到这个。 o.O

随便写

Graph testg;

或者如果您想要几乎总是按您的意思行事的东西:

Graph testg {};

确实对

感到难过
  • using namespace 那里(特别是因为 stdboost do 引入了重大冲突),
  • 冗余包括
  • 无偿使用 new 文件流...
  • 在阅读循环中 eof() 的错误使用
  • 重复使用 dataG[dataG.size() -1],其中可以使用 data.back()
  • 缺少解析输入的错误处理
  • gid (int) 缩小到 unsigned int

Live On Coliru

#include <boost/graph/adjacency_list.hpp>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>

using namespace boost;

/*********************************************/
// vertex
struct VertexProperties {
    int id;
    int label;
    VertexProperties(unsigned i=0, unsigned l=0) : id(i), label(l) {}
};

// edge
struct EdgeProperties {
    unsigned id;
    unsigned label;
    EdgeProperties(unsigned i=0, unsigned l=0) : id(i), label(l) {}
};

// Graph
struct GraphProperties {
    unsigned id;
    unsigned label;
    GraphProperties(unsigned i=0, unsigned l=0) : 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_descriptor;
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;

int main() {
    std::vector<Graph> dataG;

    std::ifstream file_reader("5.txt"); // flux d'entrée pour opérer sur les fichiers.

    std::string line;
    while (std::getline(file_reader, line)) { // getline reads characters from an input stream and places them into a string

        char lineType;

        std::stringstream ss(line);  // use a string buffer that contains a sequence of characters.
        if (ss >> lineType) switch (lineType) {
            case 't':
                {
                    char diez;
                    unsigned gid;
                    if (ss >> diez >> gid) {
                        dataG.emplace_back(GraphProperties { gid, gid });
                    }
                    else throw std::runtime_error("Error parsing '" + line + "'");
                }
                break;
            case 'v':
                {
                    assert(!dataG.empty());

                    int vId, vLabel;
                    if (ss >> vId >> vLabel) {
                        boost::add_vertex(VertexProperties(vId, vLabel), dataG.back());
                    }
                    else throw std::runtime_error("Error parsing '" + line + "'");
                }
                break;
            case 'e':
                {
                    assert(!dataG.empty());

                    int fromId, toId, vLabel;
                    if (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(vLabel, vLabel), dataG.back());
                    }
                    else throw std::runtime_error("Error parsing '" + line + "'");
                }
                break;
        } else
        {
            // ignoring empty line
        }
    }

    if (!dataG.empty()) {
        auto const& gr = dataG.front(); // no copy
        Graph testg;

        for (auto ep = edges(gr); ep.first != ep.second; ++ep.first) // ep edge number
        {
            vertex_descriptor from = source(*ep.first, gr);
            vertex_descriptor to   = target(*ep.first, gr);

            boost::add_edge(from, to, testg);
        }
    }
    std::cout << "fin." << std::endl; // fin du programme.
}