A simple way to represent a graph is with a data structure of the form:
{1:[2,3],
2:[1,3],
3:[1,2]}
Where the keys in this dictionary are nod
You could implement it as a basic graph with nodes and edges. In each node, store a list of edges. For each of those edges, store a mapping from that "entry" edge, to the valid exit edges.
I should point out that the image you posted isn't a graph, since A, F, and D do not connect to any nodes (unless they're just off-screen).
Represent your graph as a mapping of strings to mapping of strings to sets.
To be more clear, in python you would have:
graph = {
'A': {
'B': set(['C', 'D', ...]),
'E': set(['F']),
},
...
}
An edge exists between A
and B
if the key B
is contained by the entry A
in the graph
mapping.
This edge can be walked if the node from which we come from is contained in the set mapped to by graph['A']['B']
.
The following python class implements this specification (you can find a commented version on 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)
This class can be used like this:
>>> 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')
The chosen data structures and their usage already allows to build a directed graph, only the addEdge
method would need to be adapted.
This could be represented by a directed graph.
Nodes in your graph could be represented as two nodes in the graph. Think of the nodes as representing locations on particular sides of a street -- the edges being like inbound and outbound lanes.