-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGraph.py
More file actions
151 lines (123 loc) · 4.37 KB
/
Graph.py
File metadata and controls
151 lines (123 loc) · 4.37 KB
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
#TODO (maybe) : add ability for nodes to have values, and member functions to
#get/set these
class Graph(object):
def __init__(self):
'''Initialised an empty graph (i.e. no vertices or edges) '''
self.vertex_list = []
self.adjacency_list = {}
def _is_node(self, v):
'''Returns true if vertex v is in the graph'''
if (v in self.vertex_list):
return True
else:
return False
def is_adjacent(self, v, w):
'''Returns true if there is an edge connecting vertex x to y in
the direction x -> y. Note that a vertex is not adjacent to
itself unless there is a loop at that vertex.'''
if self._is_node(v) and self._is_node(w):
if not self.adjacency_list[v]:
return False
if (w in list(zip(*self.adjacency_list[v]))[0]):
return True
else:
return False
else: #Error statements
print("Invalid vertex index")
if self._is_node(v):
pass
else:
print("Vertex " + str(v) + " does not exist")
if self._is_node(w):
pass
else:
print("Vertex " + str(w) + " does not exist")
def get_neighbors(self, v):
'''Returns a list of all vertices w such that there is an edge
v -> w'''
try:
return list(list(zip(*self.adjacency_list[v]))[0])
except KeyError:
print("Invalid vertex index")
print("Vertex " + str(v) + " does not exist")
except IndexError:
return []
def add_vertex(self, v): #TODO add requirement v is int (not important)
'''Adds a vertex v to the graph if it does not already exist. If
it does exist, throws an error.
If v is a list, add each vertex within the list to the graph'''
if type(v) is list:
for vertex in v:
self.add_vertex(vertex)
else:
try:
if self._is_node(v):
raise IndexError("Vertex " + str(v) + " exists already")
elif v <= 0 or not (type(v) is int):
raise IndexError("Index must be a positive integer")
else:
self.adjacency_list[v] = []
self.vertex_list.append(v)
except IndexError as msg:
print("Invalid vertex index")
print(msg)
print("Vertex was not added")
def remove_vertex(self, v):
'''Removes a vertex v and all the associated edges from the
graph, if the vertex v exists.'''
if self._is_node(v):
for vertex in self.vertex_list:
if self.is_adjacent(vertex, v):
self.remove_edge(vertex, v)
del self.adjacency_list[v]
self.vertex_list.remove(v)
else:
print("Node " + str(v) + "does not exist")
def add_edge(self, v, w, weight=1, directed=True):
'''Adds an edge from v to w if both v and w exist. If
directed=False, the edge also goes from w to v. The default
weight is 1, but can be specified'''
if self._is_node(v) and self._is_node(w) \
and not self.is_adjacent(v, w):
self.adjacency_list[v].append((w, weight))
if not directed:
_weight = weight
self.add_edge(w, v, _weight, True)
else:
if not self._is_node(v):
print("Node " + str(v) + " does not exist")
if not self._is_node(w):
print("Node " + str(w) + " does not exist")
if self._is_node(v) and self._is_node(w):
print("Edge from " + str(v) + " to " + str(w)
+ " already exists")
def remove_edge(self, v, w, directed=True):
'''Removes the edge from v to w if it exists. If directed=False,
the edge from w to v is also removed if it exists, or nothing
is removed if not'''
if self.is_adjacent(v, w) and (directed or self.is_adjacent(w,v)):
self.adjacency_list[v] = [i for i in self.adjacency_list[v] if i[0]!=w]
if not directed:
self.adjacency_list[w] = [i for i in self.adjacency_list[w] if i[0]!=v]
else:
print("Invalid edge")
if not self.is_adjacent(v, w):
print("Edge from " + str(v) + " to " + str(w) + " does not exist")
if not directed and not self.is_adjacent(w,v):
print("Edge from " + str(w) + " to " + str(v) + " does not exist")
def get_edge_value(self, v, w):
'''Gets the value associated with the edge from v to w'''
if self.is_adjacent(v,w):
return [i for i in self.adjacency_list[v]].pop()[1]
else:
print("Invalid edge")
print("Edge from " + str(v) + " to " + str(w) + " does not exist")
def set_edge_value(self, v, w, val):
'''Sets the value associated with the edge from v to w, if the
edge already exists'''
if self.is_adjacent(v,w):
self.remove_edge(v,w)
self.add_edge(v, w, val)
else:
print("Invalid edge")
print("Edge from " + str(v) + " to " + str(w) + " does not exist")