Graphviz --- случайный порядок узлов и ребра, проходящие через метки

У меня есть следующий точечный файл:

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" ];
    }
}

У меня создалось впечатление, что узлы появятся в том порядке, в котором они упоминаются. Но порядок мне кажется случайным. Я хочу, чтобы порядок слева направо был в порядке нижних индексов. Кроме того, края проходят сквозь этикетки, как этого избежать?

Это текущее изображение: текущий вывод


person oskarkv    schedule 05.10.2012    source источник


Ответы (2)


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, чтобы не обрывались некоторые ярлыки.

person marapet    schedule 05.10.2012
comment
Спасибо, но я сделал это, и все мои ребра входят в линию узлов или под ней, но ни один не выходит за нее. Как этот i.imgur.com/1Xj8n.png Ваш выглядит лучше. - person oskarkv; 09.10.2012
comment
Вы пробовали именно этот сценарий? Какая версия графвиза? - person marapet; 09.10.2012
comment
Да, точный сценарий. Версия 2.26.3 (20100126.1600) - person oskarkv; 09.10.2012
comment
Я использовал версию 2.28, так что вы можете попробовать обновиться. - person marapet; 09.10.2012

Вот одна из идей.

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) Снова запустите точку, на этот раз для создания выходного файла.

Результат можно увидеть здесь:

Вывод Graphviz

person maths-help-seeker    schedule 05.10.2012