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

copying edges with adjacent vertices and their properties using BOOST

本文关键字:属性 顶点 复制 BOOST 使用      更新时间:2023-10-16

我正试图从一个图中复制一条边,并将其添加到另一个图(带有他的所有顶点和属性)中,我做了一些类似的东西:

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

我得到了这个错误:

segmentation error core dumped

完整的来源在这里http://pastebin.com/vzCDbTiB

样本输入:http://pastebin.com/g4cgaHJB

您想要插入边,以便自动调整顶点的数量,以适应边的源和目标。

然后,只需按束复制顶点属性,无需干涉成员特定的映射(当您想将特定属性传递给例如算法时,这些映射很有用)。

这是简化版本:

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

活样本:

在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.
}

打印

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