Как разобрать файл DOT в Python

У меня есть преобразователь, сохраненный в виде файла DOT. Я могу увидеть графическое представление графиков с помощью gvedit, но что, если я хочу преобразовать файл DOT в исполняемый преобразователь, чтобы я мог протестировать преобразователь и посмотреть, какие строки он принимает, а какие нет.

В большинстве инструментов, которые я видел в Openfst, Graphviz и их расширениях Python, файлы DOT используются только для создания графического представления, но что, если я хочу проанализировать файл, чтобы получить интерактивную программу, в которой я могу проверить строки на соответствие? преобразователь?

Существуют ли какие-либо библиотеки, которые выполнят эту задачу, или я должен просто написать ее с нуля?

Как я уже сказал, файл DOT связан с разработанным мной преобразователем, который имитирует морфологию английского языка. Это огромный файл, но чтобы дать вам представление о том, на что он похож, я привожу образец. Допустим, я хочу создать преобразователь, который моделировал бы поведение английского языка в отношении существительных и с точки зрения множественности. Мой лексикон состоит всего из трех слов (книга, мальчик, девочка). Мой преобразователь в этом случае будет выглядеть примерно так:

введите здесь описание изображения

который создается непосредственно из этого файла DOT:

digraph A {
rankdir = LR;
node [shape=circle,style=filled] 0
node [shape=circle,style=filled] 1
node [shape=circle,style=filled] 2
node [shape=circle,style=filled] 3
node [shape=circle,style=filled] 4
node [shape=circle,style=filled] 5
node [shape=circle,style=filled] 6
node [shape=circle,style=filled] 7
node [shape=circle,style=filled] 8
node [shape=circle,style=filled] 9
node [shape=doublecircle,style=filled] 10
0 -> 4 [label="g "];
0 -> 1 [label="b "];
1 -> 2 [label="o "];
2 -> 7 [label="y "];
2 -> 3 [label="o "];
3 -> 7 [label="k "];
4 -> 5 [label="i "];
5 -> 6 [label="r "];
6 -> 7 [label="l "];
7 -> 9 [label="<+N:s> "];
7 -> 8 [label="<+N:0> "];
8 -> 10 [label="<+Sg:0> "];
9 -> 10 [label="<+Pl:0> "];
}

Теперь проверка этого преобразователя на слова означает, что если вы накормите его book+Pl, он должен выплюнуть books, и наоборот. Я хотел бы посмотреть, как можно преобразовать точечный файл в формат, позволяющий проводить такой анализ и тестирование.


person Morteza R    schedule 04.02.2015    source источник
comment
Есть ли шанс, что мы сможем увидеть файл .dot?   -  person Hugh Bothwell    schedule 04.02.2015
comment
Файл DOT представляет собой граф, состоящий из узлов и ребер. Я предполагаю, что узлы являются точкой входа или выхода, а ребро между двумя узлами представляет собой транспорт. Если вы покажете файл .dot, вы сможете получить более полезный комментарий и/или ответ.   -  person Fumu 7    schedule 04.02.2015
comment
Я только что обновил и добавил образец.   -  person Morteza R    schedule 04.02.2015


Ответы (6)


Вы можете начать с загрузки файла с помощью https://code.google.com/p/pydot/ . Оттуда должно быть относительно просто написать код для обхода графа в памяти в соответствии с входной строкой.

person John Zwinck    schedule 04.02.2015
comment
Не могли бы вы рассказать об этом немного подробнее? Я знаю о pydot и знаю, что туда можно загрузить точечный файл. dot_parser в pydot преобразует точечный файл в какое-то внутреннее представление класса. Но я не уверен, как я могу использовать это. Pydot — это, по сути, интерфейс для Graphviz afaik. - person Morteza R; 04.02.2015
comment
@schmutter: см. здесь: stackoverflow.com/a/22935664/4323 - вы можете загружать края. Если вам нужна более полнофункциональная библиотека графов, см. code.google.com/p/python. -graph, который также может загружать файлы Dot и включает алгоритмы. - person John Zwinck; 04.02.2015
comment
Я не могу использовать (текущую версию) pydot; он говорит, что требует pyparsing. Я скачал последнюю версию pyparsing, но pydot попытался импортировать из pyparsing что-то несуществующее. Грр › :( - person allyourcode; 09.02.2016

Установите библиотеку graphviz. Затем попробуйте следующее:

import graphviz
graphviz.Source.from_file('graph4.dot')
person Geovanny    schedule 03.04.2016
comment
На самом деле это не разбор файла DOT. - person Juan Leni; 17.03.2017
comment
Вы правы, это не анализирует файл в полезную структуру, как спрашивал ОП. Однако достаточно отрендерить график (в Spyder), что и решило мою проблему! - person Leo; 03.01.2019
comment
Если я это сделаю, технически я разбираю файл с помощью Python, теперь я могу выгрузить его в других форматах. Таким образом, ответ верен, ОП не просил избегать использования сторонних библиотек. - person Ariel M.; 22.01.2021

Используйте это, чтобы загрузить файл .dot в python:

graph = pydot.graph_from_dot_file(apath)

# SHOW as an image
import tempfile, Image
fout = tempfile.NamedTemporaryFile(suffix=".png")
graph.write(fout.name,format="png")
Image.open(fout.name).show()
person jeff wang    schedule 30.04.2019

Другой путь и простой способ поиска циклов в файле dot:

import pygraphviz as pgv
import networkx as nx

gv = pgv.AGraph('my.dot', strict=False, directed=True)
G = nx.DiGraph(gv)

cycles = nx.simple_cycles(G)
for cycle in cycles:
    print(cycle)
person dsz    schedule 01.07.2020
comment
Выглядит хорошо, но не может быть установлен в данный момент. pip install pygraphviz терпит неудачу так же, как pip3 install pygraphviz. - person JohnnyFromBF; 22.09.2020
comment
@JohnnyFromBF - на какой платформе? У меня он работает на Mac и Linux, но у меня были проблемы с конфигурациями Windows (с использованием Anaconda). - person dsz; 23.09.2020
comment
У меня последний Debian Buster. - person JohnnyFromBF; 23.09.2020
comment
@JohnnyFromBF - по памяти вам нужно установить как Graphviz, так и что-то вроде libgraphviz-dev, чтобы получить предварительные условия сборки. Если это не сработает, пожалуйста, опубликуйте ошибку, которую вы видите. - person dsz; 24.09.2020

Ответа Гийома достаточно, чтобы отобразить график в Spyder (3.3.2), что может решить некоторые проблемы людей.

Если вам действительно нужно манипулировать графиком, как это необходимо OP, это будет немного сложно. Часть проблемы заключается в том, что Graphviz представляет собой библиотеку для рендеринга графиков, а вы пытаетесь анализировать график. То, что вы пытаетесь сделать, похоже на обратное проектирование документа Word или LateX из файла PDF.

Если вы можете принять красивую структуру примера OP, тогда регулярные выражения работают. Мне нравится афоризм, что если вы решаете проблему с помощью регулярных выражений, то теперь у вас есть две проблемы. Тем не менее, это может быть наиболее практичным решением для таких случаев.

Вот выражения для захвата:

  • информация о вашем узле: r"node.*?=(\w+).*?\s(\d+)". Группы захвата — это вид и метка узла.
  • информация о вашем крае: r"(\d+).*?(\d+).*?\"(.+?)\s". Группы захвата: источник, приемник и метка края.

Чтобы опробовать их, см. https://regex101.com/r/3UKKwV/1/ и https://regex101.com/r/Hgctkp/2/.

person Leo    schedule 03.01.2019
comment
Ну, нет, это не совсем то же самое, что пытаться реконструировать PDF-файл. По крайней мере, не в файл Word или латекс. Здесь мы хотим построить внутреннее компьютерное представление, дерево синтаксического анализа, из файла. Именно эту операцию выполняет программа graphviz перед генерацией своего вывода. - person JohanL; 16.01.2019

Я еще не пробовал это с приведенным выше примером, но NetworkX имеет read_dot, которая могла быть хорошим способом решить эту проблему путем преобразования файла в объект графика с хорошими возможностями для последующего анализа и тестирования графика.

person Alnilam    schedule 06.04.2020