1

After reading a graph from a txt file:

t # 0
v 0 5
v 1 9
v 2 8
v 3 7
e 0 1 4
e 1 2 68
e 3 2 18

I'm triying to test if two edges are neighbours. here is the function:

bool edgesneighbors(Graph g, edge_iter ep1,edge_iter ep2)
{
vertex_t fromep1 = source(*ep1, g);
vertex_t toep1 = target(*ep1, g);
vertex_t fromep2 = source(*ep2, g);
vertex_t toep2 = target(*ep2, g);
cout<<g[fromep1].id<<"--"<<g[toep1].id<<endl;cout<<g[fromep2].id<<"--"<<g[toep2].id<<endl;
if(graphconnexe(g)){return((fromep1==fromep2)||(fromep1==toep2)||(toep1==toep2)||(fromep2==toep1));}
else {return false;}                              
}

and here is the part of the program where I do the test. I want to test all the edges two by two.

if (!dataG.empty()) 
{
edge_pair ep;edge_iter e1,e2;
for (ep = edges(dataG[0]); ep.first != ep.second; ++ep.first) //ep edge number
    {
        e1=ep.first;
        e2=ep.second;
    }
    cout<<"edgesneighbors"<<edgesneighbors(dataG[0],e1,e2)<<endl;                                       
}

But when I run it I got a "core dumped" error, and I think it comes from

e2=ep.second

How can I solve this?

for more information here is the full source code: http://pastebin.com/3HrmJppv

I want to know if there is any predefined functions in BOOST to work with edges/vertices adjacency ?

1 Answers1

0

1. don't work on a copy

bool edgesneighbors(Graph g, edge_iter ep1, edge_iter ep2) 

This takes g by value, making a copy. Of course, ep1 and ep2 are not valid iterators into the copy

Take it by reference:

bool edgesneighbors(Graph const& g, edge_iter ep1, edge_iter ep2) {

2. don't use the end iterator

You used ep.second, which is the end iterator. That's invalid. Instead:

if (!dataG.empty()) {
    edge_pair ep = edges(dataG[0]);

    if (size(ep) >= 2) {
         Graph::edge_descriptor e1 = ep.first++;
         Graph::edge_descriptor e2 = ep.first++;

         cout << "edgesneighbors" << edgesneighbors(dataG[0], e1, e2) << endl;
    }
}

3. prefer writing the intention of the code

Until your profiling tells you you have performance bottlenecks in this function:

template <typename Graph, typename E = typename boost::graph_traits<Graph>::edge_descriptor>
bool edgesneighbors(Graph const& g, E e1, E e2) {

    std::set<vertex_t> vertex_set { 
        source(e1, g), target(e1, g),
        source(e2, g), target(e2, g),
    };

    return graphconnexe(g) && vertex_set.size() < 4;
}

So there is less need to "trust" that all these conditions were spelled correctly.

DEMO

Live On Coliru

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/vf2_sub_graph_iso.hpp>
#include <boost/algorithm/string/split.hpp>
#include <boost/algorithm/string/classification.hpp>
#include <fstream>
#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <ctime>
#include <queue> // std::queue
// for mmap:
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
using namespace std;
using namespace boost;

//==========STRUCTURES==========
// 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::undirectedS, 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;
typedef std::pair<edge_iter, edge_iter> edge_pair;

//==========READ ALL THE FILE AND RETURN A STRING==========
void handle_error(const char *msg) {
    perror(msg);
    exit(255);
}
//===============================
const char *readfromfile2(const char *fname, size_t &length) {
    int fd = open(fname, O_RDONLY);
    if (fd == -1)
        handle_error("open");

    // obtain file size
    struct stat sb;
    if (fstat(fd, &sb) == -1)
        handle_error("fstat");

    length = sb.st_size;

    const char *addr = static_cast<const char *>(mmap(NULL, length, PROT_READ, MAP_PRIVATE, fd, 0u));
    if (addr == MAP_FAILED)
        handle_error("mmap");

    // TODO close fd at some point in time, call munmap(...)
    return addr;
}

//==========SPLIT THE STRING BY NEWLINE (\n) ==========
vector<string> splitstringtolines(string const &str) {
    vector<string> split_vector;
    split(split_vector, str, is_any_of("\n"));

    return split_vector;
}

//==============================================================
string getpos(int pos, string yy) {
    size_t i = pos;
    string str;
    for (; yy[i] != ' ' && i < yy.length(); i++)
        str += yy[i];
    return str;
}
//==============================================================
std::vector<Graph> creategraphs(std::vector<string> const &fichlines) {
    std::vector<Graph> dataG;
    int compide = 0; // compteur de id edge
    for (string yy : fichlines) {
        switch (yy[0]) {
        case 't': {
            string str2 = getpos(4, yy);
            unsigned gid = atoi(str2.c_str());
            dataG.emplace_back(GraphProperties(gid, gid));
            compide = 0;
        } break;
        case 'v': {
            assert(!dataG.empty()); // assert will terminate the program  if its argument turns out to be false
            // cout<<yy<<endl;
            int vId, vLabel;
            string vvv = getpos(2, yy);
            vId = atoi(vvv.c_str());
            string vvvv = getpos((int)vvv.length() + 3, yy);
            // cout<<vvvv<<endl;
            vLabel = atoi(vvvv.c_str());
            boost::add_vertex(VertexProperties(vId, vLabel), dataG.back());
        }

        break;

        case 'e': { // cout<<yy<<endl;
            assert(!dataG.empty()); // assert will terminate the program  if its argument turns out to be false

            int fromId, toId, eLabel;
            string eee = getpos(2, yy);
            // cout<<eee<<endl;
            fromId = atoi(eee.c_str());
            string eee2 = getpos((int)eee.length() + 3, yy);
            // cout<<eee2<<endl;
            toId = atoi(eee2.c_str());
            int c = (int)eee.length() + (int)eee2.length() + 4;
            //    cout<<c<<endl;
            string eee3 = getpos(c, yy);
            //  cout<<eee3<<endl;
            eLabel = atoi(eee3.c_str());
            boost::add_edge(fromId, toId, EdgeProperties(compide, eLabel), dataG.back());
            compide++;
        } break;
        }
    }

    return dataG;
}
//==================================================================================
bool graphconnexe(Graph const &g) { return num_edges(g) >= num_vertices(g) - 1; }
//============================================================================
void printgraph(Graph const &gr) {
    typedef std::pair<edge_iter, edge_iter> edge_pair;

    std::cout << " contains " << num_vertices(gr) << " vertices, and " << num_edges(gr) << " edges " << std::endl;
    if (graphconnexe(gr)) {

        // Vertex list
        if (num_vertices(gr) != 0) {
            std::cout << "  Vertex list: " << std::endl;
            for (size_t i = 0; i < num_vertices(gr); ++i) // size_t vertice number in the graph
            {
                std::cout << "   v[" << i << "]   ID: " << gr[i].id << ", Label: " << gr[i].label << std::endl;
            }
        }
        // Edge list
        if (num_edges(gr) != 0) {
            std::cout << "  Edge list: " << std::endl;
            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);
                std::cout << "   e(" << gr[from].id << "," << gr[to].id << ")   ID: " << gr[edg.first].id
                          << " ,  Label: " << gr[edg.first].label << std::endl;
            }
        }
        std::cout << "\n\n" << std::endl;
    } else {
        cout << "Please check this graph connectivity." << endl;
    }
}
//==================================================================================
struct my_callback {
    template <typename CorrespondenceMap1To2, typename CorrespondenceMap2To1>
    bool operator()(CorrespondenceMap1To2 f, CorrespondenceMap2To1 g) const {
        return false;
    }
};
//==================================================================================
/*bool graphexistance( std::vector<Graph> const& v, Graph item)
{
   return std::find(v.begin(), v.end(), item)!=v.end();
}*/

//=========================================================
bool gUe(Graph &g, edge_iter ep, Graph t) {

    vertex_t from = source(*ep, t);
    vertex_t to = target(*ep, t);

    Graph::edge_descriptor copied_edge = boost::add_edge(from, to, t[*ep], g).first;

    g[source(copied_edge, g)] = t[from];
    g[target(copied_edge, g)] = t[to];

    if (graphconnexe(g) && graphconnexe(t)) {
        return vf2_subgraph_iso(g, t, my_callback());
    } else {
        return false;
    }
}
//==========================================
bool verticeexist(Graph &g, int vId, int vlabel) {
    int cpt = 0;
    if (num_edges(g) != 0) {
        for (size_t i = 0; i < num_vertices(g); ++i) // size_t vertice number in the graph
        {
            if ((g[i].id == vId) && (g[i].label == vlabel)) {
                cpt++;
            }
        }
    }
    return cpt != 0;
}
//========================================
bool edgeexist(Graph g, int fromid, int toid, unsigned elabel) {
    int bn = 0;
    if (graphconnexe(g)) {
        if (num_edges(g) != 0) {
            edge_pair ep;
            for (ep = edges(g); ep.first != ep.second; ++ep.first) // ep edge number
            {
                vertex_t from = source(*ep.first, g);
                vertex_t to = target(*ep.first, g);
                edge_t edg = edge(from, to, g);

                if ((g[from].id == fromid) && (g[to].id == toid) && (g[edg.first].label == elabel)) {
                    bn++;
                }
            }
        }
    }

    return (bn != 0);
}

// =========================================

bool vareneighbors(Graph g, int a, int b) {
    int bn = 0;
    if (graphconnexe(g)) {

        if (num_edges(g) != 0) {
            edge_pair ep;
            for (ep = edges(g); ep.first != ep.second; ++ep.first) // ep edge number
            {
                vertex_t from = source(*ep.first, g);
                vertex_t to = target(*ep.first, g);

                if (((g[from].id == a) || (g[to].id == a)) && ((g[from].id == b) || (g[to].id == b))) {
                    bn++;
                }
            }
        }
    }

    return (bn != 0);
}
//==========================================
    template <typename Graph, typename E = typename boost::graph_traits<Graph>::edge_descriptor>
    bool edgesneighbors(Graph const& g, E e1, E e2) {

        std::set<vertex_t> vertex_set { 
            source(e1, g), target(e1, g),
            source(e2, g), target(e2, g),
        };

        return graphconnexe(g) && vertex_set.size() < 4;
    }
//==========================================
void emptygraphaddedge(Graph &g, int fromId, int toId, int eLabel) {
    if (num_edges(g) == 0) {
        boost::add_edge(fromId, toId, EdgeProperties(num_edges(g) + 1, eLabel), g);
    }
}

//==========================================
int main() {
    clock_t start = std::clock();
    size_t length;

    std::vector<Graph> dataG = creategraphs(splitstringtolines(readfromfile2("testgUe.txt", length)));

    typedef std::pair<edge_iter, edge_iter> edge_pair;

    if (!dataG.empty()) {
        edge_pair ep = edges(dataG[0]);

        if (size(ep) >= 2) {
             Graph::edge_descriptor e1 = *ep.first++;
             Graph::edge_descriptor e2 = *ep.first++;

             cout << "edgesneighbors" << edgesneighbors(dataG[0], e1, e2) << endl;
        }
    }

    // end and time
    cout << "FILE Contains " << dataG.size() << " graphs.\nTIME: " << (std::clock() - start) / (double)CLOCKS_PER_SEC
         << "s" << endl; // fin du programme.
}

Output:

edgesneighbors1
FILE Contains 1 graphs.
TIME: 0s
sehe
  • 374,641
  • 47
  • 450
  • 633
  • when I run this I got `cc1plus: out of memory allocating 1677721600 bytes after a total of 5996544 bytes` – KHALDOUN Mohsen Mar 15 '15 at 09:41
  • Clearly your machine has low capacities or you should upgrade the compiler. Did you try with your original function taking `g` by reference? – sehe Mar 15 '15 at 09:53
  • Yes, but the problem persist. even with swap as mentioned [here](http://www.cyberciti.biz/faq/linux-add-a-swap-file-howto/) I'm using UBUNTU 14.04 lts 32bits. – KHALDOUN Mohsen Mar 15 '15 at 11:29
  • Let me get this straight. Again I spend time on a question of yours, which clearly demonstrates you don't know what you want to do (sequentially traversing edges from an adjacency list and saying something about the neighbourship of the adjacent pairs is pretty useless!). Then, everything gets dismissed because "magic failure X". Not even a vote. No information. Tell me why I bother. – sehe Mar 15 '15 at 15:20
  • Two edges can be from the same graph but they are not adjacent. I tried to verify your aswer but I got `cc1plus: out of memory allocating 1677721600 bytes after a total of 5996544 bytes` – KHALDOUN Mohsen Mar 15 '15 at 15:52
  • You said that before. Repeating it does not make it more informative. (PS. I took "I want to test all the edges two by two." in combination with the test program loop to mean that you indeed wanted tro test all the edges two by two in sequential order) – sehe Mar 15 '15 at 15:53