gpt4 book ai didi

graphviz - 为什么Graphviz在引入子图时不再最小化边长

转载 作者:行者123 更新时间:2023-12-01 11:02:22 27 4
gpt4 key购买 nike

我有这个 Graphviz 图:

digraph
{
rankdir="LR";
overlap = true;
Node[shape=record, height="0.4", width="0.4"];
Edge[dir=none];

A B C D E F G H I

A -> B -> C
D -> E -> F
G -> H -> I

Edge[constraint=false]

A -> D -> G

subgraph clusterX
{
A
B
}

subgraph clusterY
{
E
H
F
I
}
}

产生这个输出:

Graphviz output

我本来希望 A 和 D 之间的边的长度最小化,以便节点排列为:
A B C
D E F
G H I

而不是
D E F
G H I
A B C

如果我删除子图定义,这将按预期工作。

为什么Graphviz在引入子图时将A B C放在底部?

最佳答案

这实际上并不是关于最小化边长,特别是因为在示例中,边是用属性 constraint=false 定义的。 .

虽然这不是一个完整的答案,但我认为可以在以下两点中找到它:

  • 出场顺序图中节点的数量很重要。
  • rankdirLR包含不可预测(或至少难以预测)的行为,和/或可能仍然是一两个错误( search rankdir )。

  • 我会尽力解释并理解graphviz,但您可能想继续阅读 this reply of Emden R. Gansner on the graphviz mailing list以及斯蒂芬诺斯的以下回答 - 他们应该知道,所以我会引用其中的一些......

    为什么是 出场顺序节点重要吗?默认情况下,在自顶向下的图中,首先提到的节点将出现在后续节点的左侧,除非边和约束导致更好的布局。

    因此,没有集群和 rankdir=LR ,图形看起来像这样(不出所料):
    A D G
    B E H
    C F I

    到现在为止还挺好。但是当 rankdir=LR 时会发生什么被申请;被应用?

    ERG 写道:

    Dot handles rankdir=LR by a normal TB layout and then rotating the layout counterclockwise by 90 degrees (and then, of course, handling node rotation, edge direction, etc.). Thus, subgraph one is positioned to the left of subgraph two in the TB layout as you would expect, and then ends up lower than it after rotation. If you want subgraph one to be on top, list it second in the graph.



    所以如果这是正确的,没有集群,节点应该如下所示:
    G H I
    D E F
    A B C

    实际上,它们确实是这样的:
    A B C
    D E F
    G H I

    为什么?斯蒂芬·诺斯 回复:

    At some point we decided that top-to-bottom should be the default,
    even if the graph is rotated, so there's code that flips the flat edges internally.



    因此,该图以 TB 布局,逆时针旋转,平边翻转:
    A D G     G H I     A B C
    B E H --> D E F --> D E F
    C F I A B C G H I

    虽然这对于简单的图形非常有效,但似乎当涉及到集群时,情况就有些不同了。通常边缘也在簇内翻转(如 clusterY ),但在某些情况下,平坦边缘翻转并不像人们想象的那样工作。你的例子就是其中一种情况。

    为什么在翻转这些边缘时会出现错误或限制?因为使用 rankdir=TB 时通常会正确显示相同的图形.

    幸运的是,解决方法通常很容易——例如,您可以使用节点的出现顺序来影响布局:
    digraph
    {
    rankdir="LR";
    node[shape=record, height="0.4", width="0.4"];
    edge[dir=none];

    E; // E is first node to appear
    A -> B -> C;
    D -> E -> F;
    G -> H -> I;

    edge[constraint=false]
    A -> D -> G;

    subgraph clusterX { A; B; }
    subgraph clusterY { E; F; H; I; }
    }

    关于graphviz - 为什么Graphviz在引入子图时不再最小化边长,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9587468/

    27 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com