我试图让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"];
}
我通过运行
打印它boost::write_graphviz(myfile, G, boost::default_writer(), make_edge_writer(w_map));
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"];
}
然后运行graphviz,我得到相同的图形减去多余的顶点!这基本上意味着graphviz不需要事先知道顶点,对吧?
那么,有人知道如何让write_graphviz
预先不写顶点索引吗?我不想删除那些顶点,因为在实际例子中,剩余顶点可能在图形内部,然后我的顶点数字不对应于我的输入..
此外,这真的不是什么大问题,但它一直在困扰我,我想知道是否有人知道该怎么做。我尝试从boost::default_writer()
更改为我自己的代码(没有做任何事情),但似乎没有任何区别。
答案 0 :(得分:5)
三部分答案
您想过滤掉节点
PropertyWriter
我建议第一个(因为"表达你的意图")或后者(因为"关注点分离")。
Graphviz不需要预先知道顶点,除非它们需要一些非默认属性。
0 [label="Node 0"];
1 [shape="Mrect"];
0 -- 1; // works
但是
0 [label="Node 0"] -- 1 [shape="Mrect"]; // doesn't work
实际上
0 [label="Node 0"];
0 -- 1 [label="oops"]; // oops
设置" 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_;
};
您可以使用gvpr
对输出进行后处理:
gvpr -c 'N[$.degree==0]{$.style="invis"}' test.dot | dot -Tpng > test.png
或者,要真正删除空间使用情况:
gvpr -c 'N[$.degree==0]{delete(0,$);}' test.dot | dot -Tpng > test.png
出于某种原因,我似乎需要重复这一点(我确定前往 gvpr
documentation 可以解决这个问题):
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