简体   繁体   English

在Boost :: Graph中读取read_graphviz(),传递给构造函数

[英]read_graphviz() in Boost::Graph, pass to constructor

I have used a python library to generate the following GraphViz .dot file. 我使用python库生成以下GraphViz .dot文件。

http://pastebin.com/mL7ck9Zp http://pastebin.com/mL7ck9Zp

I want to now read it into C++'s Boost::Graph so I can use Boost::Graph's library algorithms on it. 我现在想把它读到C ++的Boost :: Graph中,这样我就可以使用Boost :: Graph的库算法了。

However, I need to do some preprocessing. 但是,我需要做一些预处理。 In particular, I want to create a bundled property with a string constructor and have read_graphviz() pass the string in the label field in the dot file into the string constructor. 特别是,我想用字符串构造函数创建一个捆绑属性,并让read_graphviz()将点文件中label字段中的字符串传递给字符串构造函数。

How do I go about doing this? 我该怎么做呢?

First thing to realize is that Boost documentation samples almost always refer to/are generated from the actual samples: libs/graph/example/read_graphviz.cpp 首先要意识到的是Boost文档样本几乎总是引用/从实际样本生成: libs / graph / example / read_graphviz.cpp

Second thing to realize is that BGL is highly generic. 要意识到的第二件事是BGL非常通用。 Highly. 高度。 And it achieves much of this genericity on the concepts of Boost Property Maps . 它在Boost Property Maps的概念上实现了很多这种通用

Finally, observe that parsing from "free-form" (at least dynamically/untyped text form) into some kind of generic MutableGraph model is pushing the limits. 最后,观察从“自由形式”(至少动态/非类型化的文本形式)解析为某种通用的MutableGraph模型正在推动极限。

This explains how you would have to read important parts of the documentation under the docs for property_map . 这解释了如何阅读property_map文档下的文档的重要部分。

Anyhow, since indeed the sample seems a bit dated, allow me to demonstrate: 无论如何,既然样本确实有点过时了,请允许我证明:

  1. Include the implementation of the parser into one translation unit: 将解析器的实现包含在一个翻译单元中:

     #include <libs/graph/src/read_graphviz_new.cpp> 

    This way BGL remains a header-only library. 这样BGL仍然是一个只有头的库。

  2. Prefer bundled properties these days: 如今更喜欢捆绑的属性:

     struct Vertex { std::string name, label, shape; }; struct Edge { std::string label; double weight; // perhaps you need this later as well, just an example }; typedef property<graph_name_t, std::string> graph_p; typedef adjacency_list<vecS, vecS, directedS, Vertex, Edge, graph_p> graph_t; 

    We will be filling label , shape , name for vertices and edges. 我们将填充顶点和边的labelshapename

  3. The dynamic property maps are where the magic happens: 动态属性映射是魔术发生的地方:

     dynamic_properties dp/*(ignore_other_properties)*/; 

    This class provides type-erased access to a variety of underlying property maps identified by (name, typeid(key_type)) . 此类提供对由(name, typeid(key_type))标识的各种底层属性映射的类型擦除访问。

    This means you can register the bundled properties, and map them to the graphviz attribute names: 这意味着您可以注册捆绑的属性,并将它们映射到graphviz属性名称:

     int main() { // Construct an empty graph and prepare the dynamic_property_maps. graph_t graph(0); dynamic_properties dp(ignore_other_properties); dp.property("node_id", get(&Vertex::name, graph)); dp.property("label", get(&Vertex::label, graph)); dp.property("shape", get(&Vertex::shape, graph)); dp.property("label", get(&Edge::label, graph)); 

    That's really all there is to it. 这就是它的全部内容。 (Read up on the magic of Bundled Properties , found via the page for the adjacency_list template ). (阅读通过adjacency_list模板页面找到的Bundled Properties魔力 )。

    Though we don't need it, let's throw the graph property in the mix too (as in the documentation sample): 虽然我们不需要它,但我们也将图形属性抛出混合(如文档示例中所示):

      // Use ref_property_map to turn a graph property into a property map boost::ref_property_map<graph_t *, std::string> gname(get_property(graph, graph_name)); dp.property("name", gname); 
  4. Now all that's left is reading the graph. 现在剩下的就是阅读图表了。

    Well. 好。 Okay then. 好吧。 And let's write it back out too, but with a new graph name, then: 让我们把它写回来,但是使用新的图形名称,然后:

     std::ifstream dot("input.dot"); if (read_graphviz(dot, graph, dp/*, "node_id"*/)) { std::cout << "Graph name: '" << get_property(graph, graph_name) << "'\\n"; get_property(graph, graph_name) = "Let's give it a name"; write_graphviz_dp(std::cout, graph, dp/*, "node_id"*/); } 
  5. Don't forget to link to Boost Regex 别忘了链接到Boost Regex

Full Demo 完整的演示

Live On Coliru 住在Coliru

#include <boost/graph/adjacency_list.hpp>
#include <boost/graph/graphviz.hpp>
#include <boost/property_map/dynamic_property_map.hpp>
#include <libs/graph/src/read_graphviz_new.cpp>
#include <boost/graph/graph_utility.hpp>

using namespace boost;

struct Vertex {
    std::string name, label, shape;
};

struct Edge {
    std::string label;
    double weight; // perhaps you need this later as well, just an example
};

typedef property<graph_name_t, std::string> graph_p;
typedef adjacency_list<vecS, vecS, directedS, Vertex, Edge, graph_p> graph_t;

int main() {
    // Construct an empty graph and prepare the dynamic_property_maps.
    graph_t graph(0);

    dynamic_properties dp/*(ignore_other_properties)*/;
    dp.property("node_id", get(&Vertex::name,  graph));
    dp.property("label",   get(&Vertex::label, graph));
    dp.property("shape",   get(&Vertex::shape, graph));
    dp.property("label",   get(&Edge::label,   graph));

    // Use ref_property_map to turn a graph property into a property map
    boost::ref_property_map<graph_t *, std::string> gname(get_property(graph, graph_name));
    dp.property("name",    gname);

    std::ifstream dot("input.dot");

    if (read_graphviz(dot, graph, dp/*, "node_id"*/)) {
        std::cout << "Graph name: '" << get_property(graph, graph_name) << "'\n";
        get_property(graph, graph_name) = "Let's give it a name";
        write_graphviz_dp(std::cout, graph, dp/*, "node_id"*/);
    }
}

Prints (note the empty name before, and the updated graph name attribute, after): 打印(注意之前的空名称和更新的图形名称属性,之后):

Graph name: ''
digraph G {
name="Let's give it a name";
n0 [label="A9\n", shape=box];
n1 [label="- [0.48%,19.42%]", shape=ellipse];
n11 [label="+ [0%,0%]", shape=ellipse];
n12 [label="- [0%,0.75%]", shape=ellipse];
n13 [label="+ [0.03%,1.33%]", shape=ellipse];
n14 [label="- [0%,0.75%]", shape=ellipse];
n15 [label="+ [0%,0%]", shape=ellipse];
n16 [label="+ [0%,0%]", shape=ellipse];
n17 [label="A14\n", shape=box];
n18 [label="+ [0.03%,2.51%]", shape=ellipse];
n19 [label="A15\n", shape=box];
n2 [label="A15\n", shape=box];
n20 [label="A6\n", shape=box];
n21 [label="A2\n", shape=box];
n22 [label="- [0%,1.11%]", shape=ellipse];
n23 [label="+ [0%,1%]", shape=ellipse];
n25 [label="- [0%,2.18%]", shape=ellipse];
n26 [label="+ [0%,1.79%]", shape=ellipse];
n27 [label="- [0%,1%]", shape=ellipse];
n28 [label="- [0%,0%]", shape=ellipse];
n29 [label="- [0%,0%]", shape=ellipse];
n3 [label="A11\n", shape=box];
n30 [label="- [0%,0%]", shape=ellipse];
n31 [label="- [0%,0%]", shape=ellipse];
n32 [label="- [0%,1%]", shape=ellipse];
n33 [label="A13\n", shape=box];
n34 [label="+ [0%,1%]", shape=ellipse];
n35 [label="- [0%,0%]", shape=ellipse];
n36 [label="- [0.01%,1.21%]", shape=ellipse];
n38 [label="A12\n", shape=box];
n39 [label="- [0%,1%]", shape=ellipse];
n4 [label="A4\n", shape=box];
n40 [label="+ [0%,1.17%]", shape=ellipse];
n42 [label="- [0%,0%]", shape=ellipse];
n43 [label="A12\n", shape=box];
n44 [label="+ [0%,1.11%]", shape=ellipse];
n45 [label="- [0%,1%]", shape=ellipse];
n47 [label="- [0%,0%]", shape=ellipse];
n49 [label="+ [0%,1.17%]", shape=ellipse];
n5 [label="+ [0%,0%]", shape=ellipse];
n52 [label="+ [0%,0.75%]", shape=ellipse];
n54 [label="A13\n", shape=box];
n55 [label="A14\n", shape=box];
n56 [label="- [0.03%,2.5%]", shape=ellipse];
n57 [label="+ [0.01%,2.27%]", shape=ellipse];
n59 [label="- [0%,0%]", shape=ellipse];
n6 [label="A7\n", shape=box];
n60 [label="+ [0%,1%]", shape=ellipse];
n63 [label="A15\n", shape=box];
n64 [label="+ [0.05%,1.34%]", shape=ellipse];
n65 [label="A15\n", shape=box];
n66 [label="- [0%,1%]", shape=ellipse];
n67 [label="+ [0.02%,2.44%]", shape=ellipse];
n7 [label="A14\n", shape=box];
n71 [label="+ [0.21%,3.83%]", shape=ellipse];
n8 [label="+ [0%,1.57%]", shape=ellipse];
n9 [label="- [0.01%,1.22%]", shape=ellipse];
n0->n1  [label=f];
n0->n2  [label=t];
n17->n18  [label="<=110"];
n17->n19  [label=">110"];
n19->n20  [label="<=8"];
n19->n49  [label=">8"];
n2->n3  [label="<=228"];
n2->n71  [label=">228"];
n20->n21  [label=aa];
n20->n25  [label=c];
n20->n26  [label=cc];
n20->n27  [label=d];
n20->n28  [label=e];
n20->n29  [label=ff];
n20->n30  [label=i];
n20->n31  [label=j];
n20->n32  [label=k];
n20->n33  [label=m];
n20->n38  [label=q];
n20->n42  [label=r];
n20->n43  [label=w];
n20->n47  [label=x];
n21->n22  [label="<=41"];
n21->n23  [label=">41"];
n3->n4  [label="<=3"];
n3->n63  [label=">3"];
n33->n34  [label=g];
n33->n35  [label=p];
n33->n36  [label=s];
n38->n39  [label=f];
n38->n40  [label=t];
n4->n5  [label=l];
n4->n6  [label=u];
n4->n54  [label=y];
n43->n44  [label=f];
n43->n45  [label=t];
n54->n55  [label=g];
n54->n59  [label=p];
n54->n60  [label=s];
n55->n56  [label="<=204"];
n55->n57  [label=">204"];
n6->n7  [label=bb];
n6->n11  [label=dd];
n6->n12  [label=ff];
n6->n13  [label=h];
n6->n14  [label=j];
n6->n15  [label=n];
n6->n16  [label=o];
n6->n17  [label=v];
n6->n52  [label=z];
n63->n64  [label="<=4"];
n63->n65  [label=">4"];
n65->n66  [label="<=5"];
n65->n67  [label=">5"];
n7->n8  [label="<=164"];
n7->n9  [label=">164"];
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM