关于 c :Graph 有两种类型的节点

Graph with two types of nodes

我正在使用 C 和 Boost 图形库 (BGL) 编写程序。
我有两个名为 Buildings 和 Contracts 的类。我需要制作一个图表来表示它们之间的连接关系。所以图应该有两种类型的顶点(B和C),有方向的并包括边B->B、C->C和B->C。

  • 是否可以?
  • 如果是,如何实施?
  • 编辑

    实际上,我试图避免不同类型节点之间的连接,所以我有两个单独的图表。但是由于 B 和 C 之间实际上存在关系的实现,它使我的模型变得更加复杂。边缘 B1->B2 表明,必须已经构建 B1 才能构建 B2。 C1->C2 实际上是相同的,但在合同方面。 B->C表明,合同C可以在B楼完成。


    我已经留言询问目标:

    I'd be happy to show (several) approaches iff you would be able to describe the problem you're trying to solve. Because at this point it's not at all clear what you'd require the integrated datastructure for (I'm unable to think of algorithms that would benefit from having both the B-B, C-C, B-C edges.). Off the top of my mind 2 separate graphs, an implicit graph that conjoins them, or a single graph with optionally filtered views would do. Filtering could be done by some kind of (dynamic) type switch OR it could be done using some kind of external/intrusive index. a€" sehe 31 mins ago

    不管怎样,你可以使用 boost::variant 来做问题所要求的(也就是说,可能是一个 X/Y 问题的问题):

    演示

    Live On Wandbox

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    #include <boost/graph/adj_list_serialize.hpp>
    #include <boost/property_map/function_property_map.hpp>
    #include <boost/property_map/transform_value_property_map.hpp>
    #include <boost/graph/graphviz.hpp>
    #include <boost/graph/graph_utility.hpp>
    #include <boost/variant.hpp>
    #include <fstream>
    using namespace boost;

    namespace Nodes {
        struct Building { std::string id; };
        struct Contract { std::string id; };

        static inline std::ostream& operator<<(std::ostream& os, Building const& b) { return os <<"Building" << b.id; }
        static inline std::ostream& operator<<(std::ostream& os, Contract const& b) { return os <<"Contract" << b.id; }

        std::string id_of(Building const& b) { return b.id; }
        std::string id_of(Contract const& c) { return c.id; }
        std::string shape_of(Building const& b) { return"circle"; }
        std::string shape_of(Contract const& c) { return"diamond"; }
    }

    using Nodes::Building;
    using Nodes::Contract;
    using Vertex = boost::variant<Building, Contract>;

    std::string id_of(Vertex const& v) {
        return boost::apply_visitor([](auto const& node) { return id_of(node); }, v);
    }
    std::string shape_of(Vertex const& v) {
        return boost::apply_visitor([](auto const& node) { return shape_of(node); }, v);
    }

    typedef adjacency_list<vecS, vecS, directedS, Vertex> Graph;

    int main() {
        Graph g;
        auto office1    = add_vertex(Building{"office1" }, g);
        auto office2    = add_vertex(Building{"office2" }, g);
        auto warehouse1 = add_vertex(Building{"warehouse1" }, g);
        auto contract1  = add_vertex(Contract{"contract1" }, g);
        auto contract2  = add_vertex(Contract{"contract2" }, g);

        add_edge(office1, office2, g);
        add_edge(warehouse1, contract1, g);
        add_edge(contract2, contract1, g);

        {
            std::ofstream dot_file("graph.dot");
            dynamic_properties dp;

            dp.property("node_id", boost::make_transform_value_property_map(&::id_of, boost::get(boost::vertex_bundle, g)));
            dp.property("shape", boost::make_transform_value_property_map(&::shape_of, boost::get(boost::vertex_bundle, g)));
            dp.property("label", boost::make_transform_value_property_map(
                [](Vertex const& v) { return boost::lexical_cast<std::string>(v); },
                boost::get(boost::vertex_bundle, g)));

            write_graphviz_dp(dot_file, g, dp);
        }

        print_graph(g);
    }

    印刷品

    1
    2
    3
    4
    5
    0 --> 1
    1 -->
    2 --> 3
    3 -->
    4 --> 3

    以及为下图生成 graph.dot

    enter

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    digraph G {
    office1 [label="Building office1", shape=circle];
    office2 [label="Building office2", shape=circle];
    warehouse1 [label="Building warehouse1", shape=circle];
    contract1 [label="Contract contract1", shape=diamond];
    contract2 [label="Contract contract2", shape=diamond];
    office1->office2 ;
    warehouse1->contract1 ;
    contract2->contract1 ;
    }

    我使用 https://dreampuf.github.io/GraphvizOnline/

    在线渲染它