Перевод графов на классы Python

perevod grafov na klassy python Структуры данных

Использование словарей для представления графов эффективно: поиск смежных узлов выполняется быстрой операцией хеширования. Но для некоторых приложений более оправданными могут оказаться другие представления. Например, для моделирования узлов в сети могут также использоваться классы, как и для двоичных деревьев в более раннем примере. Узлы, реализованные в виде классов, могут содержать дополнительную информацию, полезную при более сложном поиске. Они могут также участвовать в иерархиях наследования и приобретать дополнительные особенности поведения. Для иллюстрации этой идеи в примере 18.19 показана альтернативная реализация поиска на графе — используемый алгоритм ближе всего к gsearchl.

Пример 18.19. PP4E\Dstruct\Classics\graph.py

"конструирует граф из объектов, способных выполнять поиск"

class Graph:

def __init__(self, label, extra=None):

self.name = label # узлы = объекты экземпляров

self.data = extra # граф = связанные объекты

self.arcs = []

def __repr__(self): return self.name

def search(self, goal):

Graph.solns = []

self.generate([self], goal)

Graph.solns.sort(key=lambda x: len(x))

return Graph.solns

def generate(self, path, goal):

if self == goal: # класс == цель

Graph.solns.append(path) # или self.solns: то же самое else:

for arc in self.arcs:

if arc not in path:

arc.generate(path + [arc], goal)

В этой версии графы представляются как сеть вложенных объектов экземпляров класса. Каждый узел в графе содержит список объектов узлов, к которым он ведет (arcs) и в котором он умеет выполнять поиск. Метод generate выполняет обход объектов в графе. Но на этот раз переходы прямо доступны в списке arcs каждого узла — нет необходимости индексировать (или передавать) словарь, чтобы найти связанные объекты.

Для проверки в примере 18.20 представлен модуль, который снова строит контрольный граф, на этот раз с помощью связанных экземпляров класса Graph. Обратите внимание на вызов функции exec в коде самотестирования: он выполняет динамически создаваемые строки, чтобы осуществить семь присваиваний (A=Graph(‘A’), B=Graph(‘B’) и так далее).

Пример 18.20. PP4E\Dstruct\Classics\gtestobj1.py

"создает граф на основе класса и выполняет контрольный поиск"

from graph import Graph

# этот фрагмент не работает внутри инструкции def в 3.1: Bне определено

for name in "ABCDEFG": # создать сначала объект

exec("%s = Graph(‘%s’)" % (name, name)) # метка = имя переменной

A.arcs = [B, E, G]

B.arcs = [C] # теперь настроить связи:

C.arcs = [D, E] # вложенный список экземпляра

D.arcs = [F]

E.arcs = [C, F, G]

G.arcs = [A]

A.search(G)

for (start, stop) in [(E,D), (A,G), (G,F), (B,A), (D,A)]: print(start.search(stop))

Этот сценарий выполняет тот же самый обход графа, но на этот раз всю работу выполняют методы объектов:

C:\\PP4E\Dstruct\Classics> python gtestobj1.py

[[E, C, D], [E, G, A, B, C, D]]

[[A, G], [A, E, G], [A, B, C, E, G]]

[[G, A, E, F], [G, A, B, C, D, F], [G, A, B, C, E, F], [G, A, E, C, D, F]] [[B, C, E, G, A]] []

Результат получается такой же, как при использовании функций, но имена узлов выводятся без кавычек: узлы в списках путей теперь являются экземплярами класса Graph, а метод __repr__ класса подавляет вывод кавычек. Перед тем как двинуться дальше, рассмотрим еще один сценарий проверки графов, представленный в примере 18.21, — набросайте узлы и дуги на бумаге, если проследить пути вам труднее, чем интерпретатору Python.

Пример 18.21. PP4E\Dstruct\Classics\gtestobj2.py

from graph import Graph

S = Graph(‘s’)

P = Graph(‘p’) # граф spam

A = Graph(‘a’) # создать объекты узлов

M = Graph(‘m‘)

S.arcs = [P, M] # S ведет к P и M

P.arcs = [S, M, A] # дуги: встроенные объекты

A.arcs = [M]

print(S.search(M)) # найти все пути из S в M

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

C:\\PP4E\Dstruct\Classics> python gtestobj2.py [[s, m], [s, p, m], [s, p, a, m]]

Использованная литература:

Марк Лутц — Программирование на Python, 4-е издание, II том, 2011

Каталог сайтов Всего.ру
Оцените статью
Секреты программирования
Добавить комментарий