如何在graphviz中打印带有一个属性显示的boost图形?

9

当使用属性映射时,我可以看到这种情况的示例,但是在使用结构来处理顶点和边(我想这被称为“束”)时,则没有。

我已经将顶点和边定义为邻接表图中的如下形式。

struct Vertex
{
    string name;
    int some_int;
};

struct Edge
{
    double weight;
};

图表的构建如下所示:
typedef boost::adjacency_list<boost::listS, boost::vecS, boost::directedS, Vertex, Edge> boost_graph;

我想以Graphviz格式打印这些对象的图形,以便我可以将其视为图像。 但是,我不仅想要节点和边缘。 我还希望在图像中显示顶点上的属性name和边缘上的属性weight。 我该怎么做?


我认为你应该展示一个完整的样例。我看不出你是如何使用“defined”来构建一棵树的。也许,这是边缘的映射属性? - sehe
@sehe 谢谢。我已经将图的定义添加到问题中了。边和顶点是通过函数boost::add_edge和boost::add_vertex添加的。 - Jim
你是否在寻找点格式的定义?请访问http://www.graphviz.org/Gallery.php,点击任意示例并查看制作它们所需的代码 :-) - Martin Kristiansen
@MartinKristiansen 谢谢。实际上,Boost 应该有将输出打印到 graphviz 的功能,我想利用这个功能。 - Jim
3个回答

31
我刚偶然发现了这个问题。虽然它已经有了一个被接受的答案,但我想也加上我的版本。
你在图表中使用了bundled property。从捆绑属性获取属性映射的正确方法是使用boost::get。所以你可以这样做:
boost::write_graphviz(std::cout, your_graph,
    boost::make_label_writer(boost::get(&Vertex::name, your_graph)),
    boost::make_label_writer(boost::get(&Edge::weight, your_graph)),
    );

其中your_graph是您创建的图形对象。


2
我有同样的问题,但是我的顶点类不是公共属性,而是一个方法,比如说类Vertex{ public: int getID(); private: int m_iID;}; 在这种情况下,我该怎么做才能将ID放入graphviz文件中呢? - Jepessen

6

我第一次给出的信息有误,请看下面的正确答案。

#include <boost/graph/graphviz.hpp>

using namespace boost;

// Graph type
typedef adjacency_list<vecS, vecS, directedS, VertexProperties, EdgeProperty> Graph;
Graph g;
std::vector<std::string> NameVec; // for dot file names


// write the dot file
std::ofstream dotfile (strDotFile.c_str ());
write_graphviz (dotfile, g, make_label_writer(&NameVec[0]));

谢谢,但我没有看到名为WriteDOTFile的方法。它在哪里? - Jim
@MartinKristiansen 是的,但这并没有解释 .WriteDOTFile 函数在哪里?我不确定你的意思。 - Jim
1
谢谢更新。make_label_writer是否会从Vertex结构中提取字符串? - Jim
是的,您可以使用向量将图中每个节点的字符串名称加载进去。 - Dan
这是我以前使用过的一个例子 http://www.boost.org/doc/libs/1_48_0/libs/graph/doc/write-graphviz.html - Dan

0
使用`boost::dynamic_properties`(请参见此处)和`boost::write_graphviz_dp`(请参见此处),您可以输出具有自定义顶点和边`struct`中定义的属性的图形。要将属性注册到`boost::dynamic_properties`对象中,您必须使用保留的属性,例如`label`,`weight`等。
一个注意事项是BOOST库(我正在使用1.82.0版本)仅支持`"node_id"`作为节点ID的属性名称,而当前的GraphViz标准使用`"id"`代替。
#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
#include <fstream>

struct Vertex {
  int some_int;
  std::string name;
};

struct Edge {
  double weight;
};

using DirectedSimpleGraph =
    boost::adjacency_list<boost::listS, boost::vecS, boost::directedS, Vertex,
                          Edge>;
using VertexSpec = boost::graph_traits<DirectedSimpleGraph>::vertex_descriptor;
using EdgeSpec = boost::graph_traits<DirectedSimpleGraph>::edge_descriptor;

int main() {
  DirectedSimpleGraph graph;
  boost::dynamic_properties dp;

  // "node_id", "label", and "weight" are reserved keywords
  // of the GraphViz DOT Format
  dp.property("node_id", boost::get(&Vertex::some_int, graph));
  dp.property("label", boost::get(&Vertex::name, graph));
  dp.property("weight", boost::get(&Edge::weight, graph));

  // Create vertices with id and label
  VertexSpec v0 = boost::add_vertex(Vertex{0, "Zero"}, graph);
  VertexSpec v1 = boost::add_vertex(Vertex{1, "One"}, graph);
  VertexSpec v2 = boost::add_vertex(Vertex{2, "Two"}, graph);
  VertexSpec v3 = boost::add_vertex(Vertex{3, "Three"}, graph);

  // Create edges with weight
  boost::add_edge(v0, v1, Edge{1.0}, graph);
  boost::add_edge(v0, v2, Edge{2.0}, graph);
  boost::add_edge(v2, v3, Edge{3.0}, graph);

  // Write to file
  std::ofstream graph_file_out("./out.gv");
  boost::write_graphviz_dp(graph_file_out, graph, dp);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接