图表有两种类型的节点

时间:2017-08-03 12:25:31

标签: c++ boost graph boost-graph

我正在使用C ++和Boost Graph Library(BGL)编写程序。 我有两个名为“建筑物和合同”的课程。我需要制作一个代表它们之间连接关系的图表。因此,图应具有两种类型的顶点(B和C),被定向并包括边B-> B,C-> C和B-> C.

  1. 有可能吗?
  2. 如果是,请如何实施?
  3. 修改

    实际上,我试图避免不同类型节点之间的连接,所以我有两个单独的图。但是由于实际上实现了B和C之间的现有关系,它使我的模型变得更加复杂。边缘B1-> B2表明已经构建了B1来构建B2。 C1-> C2实际上是相同的,但就合同而言。 B-> C表示合同C可以在建筑物B中完成。

1 个答案:

答案 0 :(得分:1)

我已经发表评论询问目标:

  

如果你能够描述你想要解决的问题,我会很乐意展示(几种)方法。因为在这一点上,你根本不清楚你需要集成数据结构(我无法想到可以从B-B,C-C,B-C边缘获益的算法)。在我的脑海中,2个单独的图形,一个隐含的图形与它们相结合,或者一个图形与可选的过滤视图相结合。过滤可以通过某种(动态)类型切换来完成,也可以使用某种外部/侵入索引来完成。 – sehe 31 mins ago

无论如何,您可以使用boost::variant完全完成问题(即可能是X/Y problem个问题):

演示

<强> Live On Wandbox

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

打印

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

除了为以下图表生成graph.dot之外:

enter image description here

源.dot看起来像这样:

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/

在线渲染