【问题标题】:How can I reverse the direction of every edge in a Graphviz (dot language) graph?如何反转 Graphviz(点语言)图中每条边的方向?
【发布时间】:2012-04-13 20:07:18
【问题描述】:

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

digraph G { A -> B [label="foo"]; A -> B [label="bar"]; B -> A; C; }

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

digraph G { B -> A [label="foo"]; B -> A [label="bar"]; A -> B; C; }

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

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

【问题讨论】:

    标签: graphviz dot


    【解决方案1】:

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

    你现在拥有的是这样的:

    digraph G
    {
        edge [dir="forward"]; /* implied */
        A -> B [label="foo"];
        A -> B [label="bar"];
        B -> A;
        C;
    }
    

    你想要的是这个:

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

    【讨论】:

    • 我认为你必须在边上设置属性,而不是整个图。像这样:edge [dir="back"];
    • 是的,@ScottMcIntyre 说得对:您必须在图表主体的开头放置一个 edge [dir="back"]; 指令才能使其工作。
    【解决方案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;
    }
    

    然后我用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;
    }
    

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

    【讨论】:

      【解决方案3】:

      Python 库 NetworkX 有一个有向多图类型 MultiDiGraph,它有一个 reverse() 方法。它还使用 pydot 来加载和写入 DOT 文件。

      【讨论】:

        猜你喜欢
        • 2012-01-26
        • 2011-03-28
        • 2012-08-03
        • 1970-01-01
        • 2013-01-30
        • 1970-01-01
        • 2021-07-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多