如何使用所有自定义属性将一个 boost 图复制到另一个(深层复制)?

问题描述 投票:0回答:1

我有一个带有自定义属性的增强图。我想复印一份。我按照以下方式尝试了,但出现了很多编译错误。

这就是我所做的:

using BGType = boost::adjacency_list<boost::vecS, boost::vecS, boost::bidirectionalS,
                                     // Vertex Properties...
                                     vertexProps,
                                     // Edge Propereties...
                                     edgeProps,
                                     // Graph Properties
                                     graphProps>;

vertexProps.h

class vertexProps {
   public:
    explicit vertexProps(const std::string *moduleName = nullptr, const std::string *name = nullptr,
                            long refPtr = 0 )
     : _refPtr(refPtr),
    {
        _moduleName = moduleName ? *moduleName : "";
        _name = name ? *name : "";
    };


struct CustomVertexCopy {
    void operator()(const vertexProps& source_vertex, vertexProps& target_vertex) const {
        target_vertex._refPtr = source_vertex._refPtr;
        target_vertex._moduleName = source_vertex._moduleName;
        target_vertex._name = source_vertex._name;
}

edgeProps.h

class edgeProps {
   public:
    explicit edgeProps(std::string name = "")
        : _name(name){};
    std::string _name;
};

struct CustomEdgeCopy {
    void operator()(const edgeProps& source_edge, edgeProps& target_edge) const {
        target_edge._name = source_edge._name;
    }
};

一些函数.cpp

OnClick(BGType* bGraph)
{
   // some code
  BGType* oldBg = new BGType;
  boost::copy_graph(bGraph, oldBg, boost::vertex_copy(CustomVertexCopy()));
  boost::copy_graph(bGraph, oldBg, boost::edge_copy(CustomEdgeCopy()));
  // some code
}

我哪里错了?

我还有一个疑问。
如果 grpah 很大,这种深度复制会影响性能吗? 如果是的话,有什么办法可以避免吗?

c++ c++11 graph boost-graph
1个回答
0
投票

命名参数是链接的,因此您可以在一个地方传递任意数量的参数:

boost::copy_graph(                         //
    g1, g2,                                //
    boost::vertex_copy(CustomVertexCopy{}) //
        .edge_copy(CustomEdgeCopy{}));

请注意,

.edge_copy
链接在
vertex_copy()
命名参数对象上。

然后,仍然无法编译,因为自定义复制器应该采用描述符,而不是捆绑引用:

struct CustomVertexCopy {
    BGType const& g1;
    BGType&       g2;

    void operator()(BGType::vertex_descriptor v1, BGType::vertex_descriptor v2) const {
        vertexProps const& p1 = g1[v1];
        vertexProps&       p2 = g2[v2];

        p2._refPtr     = p1._refPtr;
        p2._moduleName = p1._moduleName;
        p2._name       = p1._name;
    }
};

现在一切正常了:

住在Coliru

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/copy.hpp>
#include <boost/graph/graphviz.hpp>

class vertexProps {
  public:
    explicit vertexProps(std::string const* mn = nullptr, std::string const* n = nullptr, long refPtr = 0)
        : _refPtr(refPtr) {
        _moduleName = mn ? *mn : "";
        _name       = n ? *n : "";
    }

    std::string _moduleName;
    std::string _name;
    long        _refPtr;
};

class edgeProps {
   public:
     explicit edgeProps(std::string name = "") : _name(name){};
     std::string _name;
};

struct graphProps {};

using BGType = boost::adjacency_list<                //
    boost::vecS, boost::vecS, boost::bidirectionalS, //
    vertexProps, edgeProps, graphProps>;

struct CustomVertexCopy {
    BGType const& g1;
    BGType&       g2;

    void operator()(BGType::vertex_descriptor v1, BGType::vertex_descriptor v2) const {
        vertexProps const& p1 = g1[v1];
        vertexProps&       p2 = g2[v2];

        p2._refPtr     = p1._refPtr;
        p2._moduleName = p1._moduleName;
        p2._name       = p1._name;
    }
};

struct CustomEdgeCopy {
    BGType const& g1;
    BGType&       g2;

    void operator()(BGType::edge_descriptor e1, BGType::edge_descriptor e2) const {
        g2[e2]._name = g1[e1]._name;
    }
};

int main() {
    BGType g1(3);
    std::string const names[] {"Hello", "world", "Goodbye", "moon", "Greetings", "Cosmos"};
    g1[0] = vertexProps{names + 0, names + 1, 111};
    g1[1] = vertexProps{names + 2, names + 3, 222};
    g1[2] = vertexProps{names + 4, names + 5, 333};
    add_edge(0, 1, edgeProps{"one"}, g1);
    add_edge(2, 0, edgeProps{"two"}, g1);

    BGType g2;

    boost::copy_graph(                               //
        g1, g2,                                      //
        boost::vertex_copy(CustomVertexCopy{g1, g2}) //
            .edge_copy(CustomEdgeCopy{g1, g2}));

    boost::dynamic_properties dp;
    dp.property("node_id",    get(boost::vertex_index,       g2));
    dp.property("moduleName", get(&vertexProps::_moduleName, g2));
    dp.property("name",       get(&vertexProps::_name,       g2));
    dp.property("ref",        get(&vertexProps::_refPtr,     g2));
    dp.property("name",       get(&edgeProps::_name,         g2));
    write_graphviz_dp(std::cout, g2, dp);
}

打印

digraph G {
0 [moduleName=Hello, name=world, ref=111];
1 [moduleName=Goodbye, name=moon, ref=222];
2 [moduleName=Greetings, name=Cosmos, ref=333];
0->1  [name=one];
2->0  [name=two];
}

奖金

简化!只需使属性可复制,就可以了,代码行数减少了 20 行,大约减少了 30% 的错误/悲观空间:

住在Coliru

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/copy.hpp>
#include <boost/graph/graphviz.hpp>

class vertexProps {
  public:
    vertexProps(vertexProps const&) = default;
    vertexProps& operator=(vertexProps const&) = default;

    explicit vertexProps(std::string const* mn = nullptr, std::string const* n = nullptr, long refPtr = 0)
        : _refPtr(refPtr) {
        _moduleName = mn ? *mn : "";
        _name       = n ? *n : "";
    }

    std::string _moduleName;
    std::string _name;
    long        _refPtr;
};

class edgeProps {
   public:
     edgeProps(edgeProps const&)            = default;
     edgeProps& operator=(edgeProps const&) = default;
     explicit edgeProps(std::string name = "") : _name(name){};

     std::string _name;
};

struct graphProps {};

using BGType = boost::adjacency_list<                //
    boost::vecS, boost::vecS, boost::bidirectionalS, //
    vertexProps, edgeProps, graphProps>;

int main() {
    BGType g1(3);
    std::string const names[] {"Hello", "world", "Goodbye", "moon", "Greetings", "Cosmos"};
    g1[0] = vertexProps{names + 0, names + 1, 111};
    g1[1] = vertexProps{names + 2, names + 3, 222};
    g1[2] = vertexProps{names + 4, names + 5, 333};
    add_edge(0, 1, edgeProps{"one"}, g1);
    add_edge(2, 0, edgeProps{"two"}, g1);

    BGType g2;

    boost::copy_graph(g1, g2);

    boost::dynamic_properties dp;
    dp.property("node_id",    get(boost::vertex_index,       g2));
    dp.property("moduleName", get(&vertexProps::_moduleName, g2));
    dp.property("name",       get(&vertexProps::_name,       g2));
    dp.property("ref",        get(&vertexProps::_refPtr,     g2));
    dp.property("name",       get(&edgeProps::_name,         g2));
    write_graphviz_dp(std::cout, g2, dp);
}

仍在打印

digraph G {
0 [moduleName=Hello, name=world, ref=111];
1 [moduleName=Goodbye, name=moon, ref=222];
2 [moduleName=Greetings, name=Cosmos, ref=333];
0->1  [name=one];
2->0  [name=two];
}
© www.soinside.com 2019 - 2024. All rights reserved.