如何反转 Graphviz(点语言)图中每条边的方向?

Woo*_*III 8 dot graphviz

我有一个用 Graphvizdot语言指定的有向图,例如

digraph G { A -> B [label="foo"]; A -> B [label="bar"]; B -> A; C; }
Run Code Online (Sandbox Code Playgroud)

我想自动将其处理成一个边缘反转的图形,即

digraph G { B -> A [label="foo"]; B -> A [label="bar"]; A -> B; C; }
Run Code Online (Sandbox Code Playgroud)

我想使用一个健壮的解决方案(即理解图形的解决方案,因此可能不使用sed)来保留任何现有的边缘标签和其他属性。请注意,我不仅仅是在谈论dot用箭头向后渲染我的图形;我真的需要一个边缘反转的图。(在这种情况下,我打算反转边缘, apply prune,然后再次反转边缘。)

如何反转 Graphviz(dot-language)图中每条边的方向?

Sté*_*ane 8

最简单的方法是包含一个图形级别的dir语句,您可以在其中反转箭头的方向。默认情况下,方向为forward。如果您在图表顶部反转它,那么无需更改任何其他线条,图表就会以您想要的方式显示。

你现在拥有的是:

digraph G
{
    edge [dir="forward"]; /* implied */
    A -> B [label="foo"];
    A -> B [label="bar"];
    B -> A;
    C;
}
Run Code Online (Sandbox Code Playgroud)

你想要的是这个:

digraph G
{
    edge [dir="back"]; /* note the change to this line */
    A -> B [label="foo"];
    A -> B [label="bar"];
    B -> A;
    C;
}
Run Code Online (Sandbox Code Playgroud)

  • 我认为你必须在边上设置属性,而不是整个图。像这样:`edge [dir="back"];` (7认同)

Woo*_*III 2

到目前为止我想出的最好的是

BEG_G {
    graph_t g = graph($.name + " reversed", "D");
    int edge_id = 0;
}

N {
    clone(g, $);
}

E {
    node_t newHead = clone(g, $.head);
    node_t newTail = clone(g, $.tail);
    edge_t newEdge = edge_sg(g, newHead, newTail, edge_id);
    copyA($, newEdge);
    edge_id++;
}

END_G {
    $O = g;
}
Run Code Online (Sandbox Code Playgroud)

然后我用 调用它gvpr

这确实为所有生成的边添加了“关键”属性,但我不确定如何避免这种情况并仍然保留同一对节点之间的多个边。

当我这样做时echo 'digraph G { A -> B [label="foo"]; A -> B [label="bar"]; B -> A; C; }' | gvpr -f reverseAllEdges.gvpr,我得到:

digraph "G reversed" {
    A -> B [key=2];
    B -> A [key=0, label=foo];
    B -> A [key=1, label=bar];
    C;
}
Run Code Online (Sandbox Code Playgroud)

我不知道这会被证明有多强大,但看起来很有希望。