I'm building a epsilon NFA to recognize a regular expression using the canonical construction. I'm using subgraphs to group various parts of the regular expression. The * operator is giving me particular trouble since dot has decided to move the order of the nodes around. I've tried adding edge weights to force particular edges to be short to keep the order of the edges in line but that does not seem to be working.
What I would like to do is force the nodes in a subgraph in to be placed in a particular order so that the output graph is recognizable as a particular type of (well known) construction. In the example below I would like edges 3, 4, 5 and 6 placed in that order, however the dot places them in the order 6, 3, 4, 5. Any pointers appreciated.
Note that the current weight parameter produces no difference than no weight parameter at all.
I have the following
digraph G { rankdir = LR; node [shape = none]; 0 [label = "start"]; node [shape = circle]; 1 [label = "q1"]; 2 [label = "q2"]; 3 [label = "q3"]; 4 [label = "q4"]; 5 [label = "q5"]; node [shape = doublecircle]; 6 [label = "q6"]; subgraph re1 { rank = same; edge[label = "0"]; 1 -> 2; }; subgraph re2 { rank = same; edge[label = "ε"]; 3 -> 4 [weight = 10]; edge[label = "1"]; 4 -> 5 [weight = 10]; edge[label = "ε"]; 5 -> 6 [weight = 10]; 5 -> 4 [weight = 1]; 6 -> 3 [weight = 1]; }; edge[color=black]; 0 -> 1 edge[label = "ε"]; 2 -> 3; }
If ordering="in", then the inedges of a node must appear left-to-right in the same order in which they are defined in the input. If defined as a graph or subgraph attribute, the value is applied to all nodes in the graph or subgraph.
Graphviz (dot) examples Some examples on how to use Graphviz. If the shape attribute is set to record, the text of the label is layouted in tabular form. The vertical bar (|) starts a new row or column. The curly braces { ... } change (flip) the direction of |. Normally, a dependency (an edge) is declared with an arrow: Node1 -> Node2.
The node () method takes a name identifier as first argument and an optional label . The edge () method takes the names of start node and end node, while edges () takes an iterable of name pairs. Keyword arguments are turned into (node and edge) attributes (see extensive Graphviz docs on available attributes ).
If unset, graphviz will set this attribute to the xdot version used for output. External label for a node or edge. For nodes, the label will be placed outside of the node but near it. For edges, the label will be placed near the center of the edge.
Here's how I'd write that graph:
rankdir=LR
and added rank=same
only for nodes 0/1 and nodes 2/3.constraint=false
to the edges going against the direction of the graph - the one going from node 4 to node 5, and the one from node 6 to node 3.Here the source:
digraph G { 0 [label = "start", shape = none]; node [shape = circle]; 1 [label = "q1"]; 2 [label = "q2"]; 3 [label = "q3"]; 4 [label = "q4"]; 5 [label = "q5"]; 6 [label = "q6", shape = doublecircle]; {rank = same; 0 -> 1; } 1 -> 2 [label = "0"]; {rank = same; 2 -> 3 [label = "ε"]; } 4 -> 5 [label = "1"]; edge [label = "ε"]; 3 -> 4; 5 -> 6; 5 -> 4 [constraint = false]; 6 -> 3 [constraint = false]; }
And here's the result:
Now if you want to, you could keep rankdir=LR
, just take the markup you posted, remove the weights and add constraint=false
to the same edges as I did, it works, too.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With