-1

I'm trying to make a programme that read graphs from .txt (something like http://pastebin.com/g4cgaHJB) file and then createand put them in a vector. (this part work perfectly)

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;
}

Idea: I'm trying to itereate over graphs, by starting from the first edge (and create a graph from it lets call it testg ), and testing if this graph is frequent (I will test subgraph-isomorphism between testg and every graph in dataG vector and then I will count how many time there is true if there is much time then 2 so testg is frequent), if testg is frequent so I will add to it another adjacent edge (and do the subgraph-isomorpshism test again), if testg is no more frequent I will remove the last added edge (backtrack) and change it by another one(and do the subgraph-isomorpshism test again). if there is no more edge to add, I will say that testg is closed. and put it in a vector lets call it closedG.

I started the idea by doing this:

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);
        }

But, it doesn't work! here is the errors:

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);
  • "But, it doesn't work!". Impressive. What do you suppose we do about this? We don't have the input, we don't have the failing code, we don't know the error. Does it actually print "it doesn't work" to the console? – sehe Mar 01 '15 at 15:01
  • sorry, errors added now. – KHALDOUN Mohsen Mar 01 '15 at 17:29

1 Answers1

2

You've falling victim to the most vexing parse:

Graph testg();

declares a function. Don't feel bad. It took me a while to see this. o.O

Just write

Graph testg;

or if you want something that almost always does what you mean:

Graph testg {};

Do feel bad about

  • using namespace there (especially since std and boost do introduce significant conflicts),
  • redundant includes
  • gratuitous use of new for the file stream...
  • bad use of eof() in a reading loop
  • repeated use of dataG[dataG.size() -1] where data.back() could be used
  • lack of error handling parsing input
  • narrowing from gid (int) to 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.
}
sehe
  • 374,641
  • 47
  • 450
  • 633
  • I tried this http://pastebin.com/J6mfCTem and it say `terminate called after throwing an instance of 'std::runtime_error' what(): Error parsing 't # 0' Abandon (core dumped) ` – KHALDOUN Mohsen Mar 01 '15 at 21:03
  • It seems like the error is self descriptive. It fails parsing the line that contains `t # 0` (and you forgot to initialize `start`) – sehe Mar 01 '15 at 21:06
  • Ah. I forgot to put breaks in the switch my bad. Please next time, at least try to add the input used... It's too hard to do any useful debugging on your behalf without it – sehe Mar 01 '15 at 21:12
  • sorry, I dont understand where to put breaks. PS: Here is the txt file http://pastebin.com/g4cgaHJB – KHALDOUN Mohsen Mar 01 '15 at 21:16
  • I've updated the code sample with the breaks... Also, I suggest to [read a book](http://stackoverflow.com/q/388242/85371) if you don't know where to put the breaks. C++ is not a forgiving language. [Accelerated C++](http://www.amazon.co.uk/Accelerated-Practical-Programming-Example-Series/dp/020170353X) is a nice book if you already know some programming language. It's hard to **not** bump into a PDF version of this on the web :( – sehe Mar 01 '15 at 21:19
  • Thanks a lot. the creation part work perfectly. Now I'm trying to work on the idea, I'm starting by adding the first edge to testg here is the code http://pastebin.com/xUgeQHX9 it work but it doesn't copy the edge properties id & label. How can I do that please! – KHALDOUN Mohsen Mar 01 '15 at 21:36
  • @KHALDOUNMohsen come on. You don't ever copy the properties, so obviously they're not copied. Also, this is **not** [how things work at SO](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work). I'll answer this as soon as you post another, properly formulated question. Just the copy loop with the `add_edge` and the question "how can I copy the properties" would do. – sehe Mar 02 '15 at 07:55
  • I tried `boost::add_edge(from, to, EdgeProperties((*ep).id, (*ep).label), testg);` and I got this error http://pastebin.com/FX6iEzbG – KHALDOUN Mohsen Mar 02 '15 at 08:42
  • Please. I don't think you got me. Accessing properties: http://stackoverflow.com/a/28746453/85371 (skip to the "Bundled" section). If you have a new question, just ask it. I am really not going to give the answer until you post a new question. (***Irony***: My original answer copied the EdgeProperties, but I removed it because you showed code that seemed to intentionally _not_ copy them. **Lesson:** just tell us what you want to achieve, instead of only showing the broken approach) – sehe Mar 02 '15 at 09:06
  • I want to copy the first edge with her properties from dataG.front() and add it to testg , I tried what I found in "Accessing bundled properties" section [here](http://www.boost.org/doc/libs/1_57_0/libs/graph/doc/bundles.html) but it isn't working for me.here is the code: `auto const& gr = dataG.front(); // no copy auto ep = edges(gr).first; // ep edge number vertex_t from = source(*ep, gr); vertex_t to = target(*ep, gr); boost::add_edge(from, to, EdgeProperties(gr[ep].id, gr[ep].label), testg);` – KHALDOUN Mohsen Mar 02 '15 at 09:35
  • done, http://stackoverflow.com/questions/28806771/boost-bundled-properties-copy-the-first-edge-from-graph-with-properties – KHALDOUN Mohsen Mar 02 '15 at 09:52