3

我有以下点文件:

digraph finite_state_machine {
    {
        rank=same;
        node [shape = doublecircle]; q_5;
        node [shape = circle];
        q_1 -> q_2 [ label = "." ];
        q_1 -> q_2 [ label = "\epsilon" ];
        q_2 -> q_1 [ label = "\epsilon" ];
        q_2 -> q_3 [ label = "a" ];
        q_3 -> q_4 [ label = "^\wedge a" ];
        q_3 -> q_4 [ label = "\epsilon" ];
        q_4 -> q_3 [ label = "\epsilon" ];
        q_4 -> q_5 [ label = "b" ];
    }
}

我的印象是节点会按照它们被提及的顺序出现。但是顺序对我来说似乎是随机的。我希望从左到右的顺序是下标的顺序。此外,边缘穿过标签,我该如何避免这种情况?

这是当前图像: 电流输出

4

2 回答 2

7

Graphviz 确实根据彼此之间的边缘而不是按出现顺序来布置节点。如果您希望边不影响任何节点的位置,您可以通过添加constraint=false.

因此,此图:

digraph finite_state_machine {
  pad=0.2;
    {
        rank=same;
        node [shape = doublecircle]; q_5;
        node [shape = circle];
        q_1 -> q_2 [ label = "." ];
        q_1 -> q_2 [ label = "\epsilon", constraint=false ];
        q_2 -> q_1 [ label = "\epsilon", constraint=false ];
        q_2 -> q_3 [ label = "a" ];
        q_3 -> q_4 [ label = "^\wedge a" ];
        q_3 -> q_4 [ label = "\epsilon", constraint=false ];
        q_4 -> q_3 [ label = "\epsilon", constraint=false ];
        q_4 -> q_5 [ label = "b" ];
    }
}

会给你:

graphviz 输出有限状态机

我不得不添加pad,以免一些标签被剪掉。

于 2012-10-05T15:33:37.090 回答
2

这是其中一个想法。

1) 使用以下命令找出点在放置节点时使用的位置。

dot filename.dot

2) 注意生成的输出中每个节点的pos属性。然后根据您在代码中的喜好更改其值。这是您的示例的修改后的点代码。

digraph finite_state_machine {
{
    rank=same;
    node [shape = circle];
    q_1[pos="30"];
    q_2[pos="130"];
    q_3[pos="230"];
    q_4[pos="330"];
    node [shape = doublecircle]; 
    q_5 [pos="430"];
    q_1 -> q_2 [ label = "." ];
    q_1 -> q_2 [ label = "\epsilon" ];
    q_2 -> q_1 [ label = "\epsilon" ];
    q_2 -> q_3 [ label = "a" ];
    q_3 -> q_4 [ label = "^\wedge a" ];
    q_3 -> q_4 [ label = "\epsilon" ];
    q_4 -> q_3 [ label = "\epsilon" ];
    q_4 -> q_5 [ label = "b" ];
}

}

3) 再次运行 dot,这一次生成输出文件。

结果可以在这里看到:

Graphviz 输出

于 2012-10-05T15:34:40.047 回答