Представьте свой график как отображение строк в сопоставлении строк и множеств.
Чтобы быть более понятным, в python у вас будет:
graph = {
'A': {
'B': set(['C', 'D', ...]),
'E': set(['F']),
},
...
}
Между A
и B
существует ребро, если ключ B
содержится в записи A
в отображении graph
.
По этому краю можно пройти, если узел, из которого мы пришли, содержится в наборе, сопоставленном graph['A']['B']
.
Следующий класс python реализует эту спецификацию (вы можете найти закомментированную версию в this gist ):
class Graph(object):
def __init__(self):
self.nodes = {}
def addEdge(self, (node1, comingFrom1), (node2, comingFrom2)):
self.nodes.setdefault(node1, {})[node2] = comingFrom1
self.nodes.setdefault(node2, {})[node1] = comingFrom2
def isEdge(self, comingFrom, passingBy, goingTo):
try:
return comingFrom in self.nodes[passingBy][goingTo]
except KeyError:
return False
def destinations(self, comingFrom, passingBy):
dests = set()
try:
for node, directions in self.nodes[passingBy].iteritems():
if comingFrom in directions:
dests.add(node)
except KeyError:
pass
return dests
def sources(self, passingBy, goingTo):
return self.destinations(goingTo, passingBy)
Этот класс можно использовать так:
>>> graph = Graph()
>>> graph.addEdge(('0', set([ ])), ('1', set(['3', '2'])))
>>> graph.addEdge(('1', set(['0' ])), ('3', set(['4' ])))
>>> graph.addEdge(('1', set(['0' ])), ('2', set(['5' ])))
>>> graph.addEdge(('3', set(['1', '2'])), ('4', set([ ])))
>>> graph.addEdge(('3', set(['4' ])), ('2', set(['5' ])))
>>> graph.addEdge(('2', set(['1', '3'])), ('5', set([ ])))
>>> print graph.isEdge('0', '1', '3')
True
>>> print graph.isEdge('1', '3', '2')
False
>>> print graph.isEdge('1', '2', '5')
True
>>> print graph.isEdge('5', '2', '3')
True
>>> print graph.isEdge('3', '2', '5')
True
>>> print graph.destinations('0', '1')
set(['3', '2'])
>>> print graph.destinations('1', '3')
set(['4'])
>>> print graph.destinations('3', '4')
set([])
>>> print graph.sources('0', '1')
set([])
>>> print graph.sources('1', '3')
set(['0'])
>>> print graph.sources('3', '4')
Выбранные структуры данных и их использование уже позволяют построить ориентированный граф, необходимо адаптировать только метод addEdge
.