-
Notifications
You must be signed in to change notification settings - Fork 0
/
adjacencygraph.py
165 lines (129 loc) · 5.25 KB
/
adjacencygraph.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
'''Last change: 9:10am Jan 28, 2017. add_edge implements additional checks.
'''
class AdjacencyGraph:
'''Type to represent directed graphs using adjacency storage.
Attributes:
_vertices (dict): mapping vertex identifiers to a list of vertices.
'''
def __init__(self):
self._vertices = dict()
def add_vertex(self, v):
''' Adds a new vertex with identifier v to the graph.
Args:
v (hashable type): the vertex identifier to be added.
Raises:
RuntimeError: If the vertex was already in the graph.
'''
if v in self._vertices:
raise RuntimeError("Bad argument:"
" Vertex {} already in the graph".format(v))
self._vertices[v] = list()
def is_vertex(self, v):
'''Checks whether v is a vertex of the graph.
Args:
v (hashable type): the vertex identifier to be added.
Returns:
bool: True if v is a vertex of the graph, False otherwise.
'''
return v in self._vertices
def add_edge(self, e, autocreation=False):
''' Adds edge e to the graph.
Args:
e (tuple of two hashables): The edge to be added as a tuple. The
edge goes from e[0] to e[1]
autocreation (bool, default: False): Should the verticies of the
edge be automatically added to the set of verticies if they are
not there?
Raises:
RuntimeError: When one of the verticies is not a vertex yet
and autocreation is off
'''
if autocreation:
self._vertices.setdefault(e[0], list())
self._vertices.setdefault(e[1], list())
else:
if not self.is_vertex(e[0]):
raise RuntimeError("Attempt to create an edge with"
"non-existent vertex: {}".format(e[0]))
if not self.is_vertex(e[1]):
raise RuntimeError("Attempt to create an edge with"
"non-existent vertex: {}".format(e[1]))
self._vertices[e[0]].append(e[1])
def is_edge(self, e):
''' Checks whether an edge e exists in self._edges
Args:
e (tuple of two hashables): The edge to be added as a tuple. The
edge goes from e[0] to e[1]
Returns:
bool: True if e is an edge of the graph, False otherwise.
'''
# @TODO Homework!
return False
def neighbours(self, v):
'''Returns the list of vertices that are neighbours to v.'''
return self._vertices[v]
def vertices(self):
'''Returns the set of vertices.
Note that the set returned is a copy of the set of vertices
in the graph, i.e., modifying the returned set won't change
the set of vertices.
'''
return set(self._vertices.keys())
class UndirectedAdjacencyGraph:
'''Type to represent directed graphs using adjacency storage.
Attributes:
_digraph (AdjacencyGraph): The underlying directed graph that stores
the data associated with the graph.
'''
def __init__(self):
self._digraph = AdjacencyGraph()
def add_vertex(self, v):
''' Adds a new vertex with identifier v to the graph.
Args:
v (hashable type): the vertex identifier to be added.
Raises:
RuntimeError: If the vertex was already in the graph.
'''
self._digraph.add_vertex(v)
def is_vertex(self, v):
'''Checks whether v is a vertex of the graph.
Args:
v (hashable type): the vertex identifier to be added.
Returns:
bool: True if v is a vertex of the graph, False otherwise.
'''
return self._digraph.is_vertex(v)
def add_edge(self, e, autocreation=False):
''' Adds edge e to the graph.
Args:
e (tuple of two hashables): The edge to be added as a tuple. The
edge goes from e[0] to e[1]
autocreation (bool, default: False): Should the verticies of the
edge be automatically added to the set of verticies if they are
not there?
Raises:
RuntimeError: When one of the verticies is not a vertex yet
and autocreation is off
'''
self._digraph.add_edge(e, autocreation)
# no need for autocreation on second call:
self._digraph.add_edge((e[1], e[0]))
def is_edge(self, e):
''' Checks whether an edge e exists in self._edges
Args:
e (tuple of two hashables): The edge to be added as a tuple. The
edge goes from e[0] to e[1]
Returns:
bool: True if e is an edge of the graph, False otherwise.
'''
return self._digraph.is_edge(e)
def neighbours(self, v):
'''Returns the list of vertices that are neighbours to v.'''
return self._digraph.neighbours(v)
def vertices(self):
'''Returns the set of vertices.
Note that the set returned is a copy of the set of vertices
in the graph, i.e., modifying the returned set won't change
the set of vertices.
'''
return self._digraph.vertices()