简体   繁体   English

使用BOOST复制具有相邻顶点的边及其属性

[英]copying edges with adjacent vertices and their properties using BOOST

I'm trying to copy an edge from a graph and add it to another (with all his vertices and properties), I make something like: 我正在尝试从图形中复制一条边并将其添加到另一条边(具有其所有的顶点和属性)中,我所做的事情如下:

if (!dataG.empty()) 
    {
        auto const& gr = dataG.front(); // firslt graph in G_list


        auto ep = edges(gr).first;  //first edge in gr

            vertex_t from = source(*ep, gr);
        vertex_t to   = target(*ep, gr);
        boost::property_map<Graph, int VertexProperties::*>::type idmap    = boost::get(&VertexProperties::id, testg);
        boost::property_map<Graph, int VertexProperties::*>::type labelmap = boost::get(&VertexProperties::label, testg);
        idmap[from]    = gr[from].id;
        labelmap[from] = gr[from].label;
        boost::add_vertex(VertexProperties(idmap[from], labelmap[from]), testg);
        idmap[to]    = gr[to].id;
        labelmap[to] = gr[to].label;
        boost::add_vertex(VertexProperties(idmap[to], labelmap[to]), testg);


        boost::add_edge(from, to, gr[*ep], testg);    
    }

and I got this error: 我得到这个错误:

segmentation error core dumped

The full source is here http://pastebin.com/vzCDbTiB 完整的来源在这里http://pastebin.com/vzCDbTiB

Sample input: http://pastebin.com/g4cgaHJB 输入样例: http : //pastebin.com/g4cgaHJB

You want to insert the edge so the number of vertices gets automatically adjusted to accommodate the source and target for the edge. 您要插入边,以便自动调整顶点数量以适应边的源和目标。

Then, just copy the vertex properties by their bundles, no need to meddle with the member-specific maps (these are useful when you want to pass specific properties to eg algorithms). 然后,仅按其束复制顶点属性,而无需插入成员特定的映射(当您要将特定的属性传递给算法时,这些功能将非常有用)。

Here's the simplified version: 这是简化版:

    auto const& gr = dataG.front(); // firslt graph in G_list
    auto ep = edges(gr).first; // first edge in gr

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

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

    testg[source(copied_edge, testg)] = gr[from];
    testg[target(copied_edge, testg)] = gr[to];

Live sample: 现场样本:

Live On Coliru 生活在Coliru

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

/*********************************************/
// 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_t;
typedef std::pair<boost::graph_traits<Graph>::edge_descriptor, bool> edge_t;
// iterators
typedef boost::graph_traits<Graph>::vertex_iterator vertex_iter;
typedef boost::graph_traits<Graph>::edge_iterator edge_iter;

int main()
{
    clock_t start = std::clock();
    std::vector<Graph> dataG;

    std::ifstream file_reader("5.txt"); // flux d'entrée pour opérer sur les fichiers.
    // ifstream * file_reader= new ifstream("60.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
        }
    }

    Graph testg;
    if (!dataG.empty()) {
        auto const& gr = dataG.front(); // firslt graph in G_list
        auto ep = edges(gr).first; // first edge in gr

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

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

        testg[source(copied_edge, testg)] = gr[from];
        testg[target(copied_edge, testg)] = gr[to];
    }

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

    // int c = 0; //compteur de dataG

    //++c;
    std::cout << "Graph  contains " << num_vertices(testg) << " vertices, and " << num_edges(testg) << " edges" << std::endl;
    // Vertex list
    std::cout << "  Vertex list: " << std::endl;
    for (size_t i = 0; i < num_vertices(testg); ++i) // size_t vertice number in the graph
    {
        std::cout << "   v[" << i << "]   ID: " << testg[i].id << ", Label: " << testg[i].label << std::endl;
    }
    // Edge list
    std::cout << "  Edge list: " << std::endl;
    edge_pair ep;
    for (ep = edges(testg); ep.first != ep.second; ++ep.first) // ep edge number
    {
        vertex_t from = source(*ep.first, testg);
        vertex_t to = target(*ep.first, testg);
        edge_t edg = edge(from, to, testg);
        std::cout << "   e[" << testg[from].id << "," << testg[to].id << "]   ID: " << testg[edg.first].id
                  << " ,  Label: " << testg[edg.first].label << std::endl;
    }
    std::cout << std::endl;

    std::cout << "TIME: " << (std::clock() - start) / (double)CLOCKS_PER_SEC << "s" << std::endl; // fin du programme.
}

Prints 版画

INPUT
Graph  contains 2 vertices, and 1 edges
  Vertex list: 
   v[0]   ID: 0, Label: 0
   v[1]   ID: 1, Label: 3
  Edge list: 
   e[0,1]   ID: 10 ,  Label: 10

TIME: 0s

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM