我可以让boost :: write_graphviz只写边缘吗?

adi*_*c21 3 c++ boost graph

我试图让BGL输出一个只有边缘的文件,因为我正在做一个最大连通分量,我不想删除顶点,但如果没有边缘我也不想绘制它们.

我的点文件现在是:

graph G {
0;
1;
2;
3;
4;
5;
6;
7;
8;
9;
10;
11;
12;
0--1 [label="-3"];
0--5 [label="-2"];
2--3 [label="-8"];
3--8 [label="-4"];
4--5 [label="-1"];
4--6 [label="-6"];
4--7 [label="-5"];
4--8 [label="-10"];
8--9 [label="-9"];
}
Run Code Online (Sandbox Code Playgroud)

我通过跑步打印出来

boost::write_graphviz(myfile, G, boost::default_writer(), make_edge_writer(w_map));
Run Code Online (Sandbox Code Playgroud)

make_edge_writer(w_map)确保我拿到打印出来的重量(忽略负号,我实际上做了最大生成树,但我的玩具例子有正沿).

现在,graphviz分别在我的正确图形中绘制了9个顶点,加上顶点{10,11,12).如果我手动编辑我的点文件为:

graph G {
0--1 [label="-3"];
0--5 [label="-2"];
2--3 [label="-8"];
3--8 [label="-4"];
4--5 [label="-1"];
4--6 [label="-6"];
4--7 [label="-5"];
4--8 [label="-10"];
8--9 [label="-9"];
}
Run Code Online (Sandbox Code Playgroud)

然后运行graphviz,我得到相同的图形减去剩余的顶点!这基本上意味着graphviz不需要事先知道顶点,对吧?

所以,任何人都知道如何write_graphviz预先不写顶点索引?我不想删除那些顶点,因为在实际例子中,剩余顶点可能在图形内部,然后我的顶点数字将不对应于我的输入..

此外,这真的不是什么大问题,但它一直在困扰我,我想知道是否有人知道如何做到这一点.我尝试改变boost::default_writer()自己的代码(没有做任何事情),但似乎没有任何区别.

seh*_*ehe 5

三部分答案

  • 在Graphviz中预定义顶点可能很有用

您想要过滤掉节点

  • 你可以调整一下 PropertyWriter
  • 您可以调整图形渲染器

我建议第一个(因为"表达你的意图")或后者(因为"关注点分离").

在Graphviz中预定义顶点可能很有用

Graphviz不需要事先知道顶点,除非它们需要一些非默认属性.

 0 [label="Node 0"];
 1 [shape="Mrect"];

 0 -- 1; // works
Run Code Online (Sandbox Code Playgroud)

 0 [label="Node 0"] -- 1 [shape="Mrect"]; // doesn't work
Run Code Online (Sandbox Code Playgroud)

事实上

 0 [label="Node 0"];
 0 -- 1 [label="oops"]; // oops
Run Code Online (Sandbox Code Playgroud)

设置边缘上的"oops"标签,而不是id为1的顶点.


调整 PropertyWriter

你真正想要做的是过滤出具有零相邻顶点的顶点,我想说.如果您坚持不这样做,则可以为EdgePropertyWriter 传递自定义PropertyWriter实现.我认为这可能适合你

  template <class Name>
  class my_vertex_writer {
  public:
    my_vertex_writer(Graph& g) : g_(g) {}

    template <class Vertex>
    void operator()(std::ostream& out, const Vertex& v) const {
         // pseudo-code!
         if (0 == boost::size(in_edges(v, g_)))
            out << "[style=\"invis\"]";
    }
  private:
    Graph& g_;
  };
Run Code Online (Sandbox Code Playgroud)

调整渲染器

您可以使用gvpr后处理输出:

gvpr -c 'N[$.degree==0]{$.style="invis"}' test.dot | dot -Tpng > test.png
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

或者,要真正删除空间使用情况:

gvpr -c 'N[$.degree==0]{delete(0,$);}' test.dot | dot -Tpng > test.png
Run Code Online (Sandbox Code Playgroud)

出于某种原因,我似乎需要重复这一点(我确信gvpr文件之旅可以解决这个问题):

cat test.dot | 
    gvpr -c 'N[$.degree==0]{delete(0,$)}' |
    gvpr -c 'N[$.degree==0]{delete(0,$)}' |
    gvpr -c 'N[$.degree==0]{delete(0,$)}' |
    dot -Tpng > test.png
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述