-
Notifications
You must be signed in to change notification settings - Fork 0
/
8.1-Graph-AdjList.py
137 lines (108 loc) · 3.46 KB
/
8.1-Graph-AdjList.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
import queue
class DirectedGraph(object):
"""
directed graph, with adj list
"""
def __init__(self) :
self.adjacency_list={}
def add_edge(self,source,destination):
"""_summary_
adds an edge defined by vertices source and destination
Args:
source (_type_): adds an edge defined by vertices source and destination
destination (_type_): _description_
"""
if source not in self.adjacency_list:
self.adjacency_list[source] = set()
self.adjacency_list[source].add(destination)
def get_vertex(self):
"""
Generator for returning the next vertex from the adjacency list
:return:
"""
for v in self.adjacency_list:
yield v
def get_neighbor(self,vertex):
"""
Generator for returning vertex's neighbors to the given vertex
Args:
vertex (_type_): _description_
Yields:
_type_: _description_
"""
if vertex in self.adjacency_list:
for u in self.adjacency_list[vertex]:
yield u
def get_reverse_neighbor(self,vertex):
if vertex in self.adjacency_list:
r_stack=[]
for i in self.get_neighbor(vertex):
r_stack.append(i)
r_stack=r_stack[::-1]
for i in r_stack:
yield i
def dfs(self):
seen = {}
vertexcantbereached = set()
to_visit = []
for vertex in self.get_vertex():
if vertex not in seen:
vertexcantbereached.add(vertex)
else:
continue
to_visit.append(vertex)
while to_visit:
v = to_visit.pop()
for neighbor in self.get_neighbor(v):
if neighbor not in seen:
seen[neighbor] = v
to_visit.append(neighbor)
return vertexcantbereached, seen
def bfs(self):
seen={}
to_visit= queue.Queue()
for vertex in self.get_vertex():
to_visit.put(vertex)
while not to_visit.empty():
v=to_visit.get()
for neighbor in self.get_neighbor(v):
if neighbor not in seen:
seen[neighbor]=v
to_visit.put(neighbor)
return seen
def listprinter(self):
print(self.adjacency_list)
def get_test_graph_1():
dg = DirectedGraph()
dg.add_edge(0, 1)
dg.add_edge(0, 5)
dg.add_edge(1, 2)
dg.add_edge(2, 4)
dg.add_edge(2, 6)
dg.add_edge(3, 2)
dg.add_edge(5, 8)
dg.add_edge(6, 5)
dg.add_edge(7, 5)
dg.add_edge(8, 7)
return dg
def test_dfs():
dg1 = get_test_graph_1()
c1, p1 = dg1.dfs()
assert (c1 == {0, 3, 7})
assert (p1 == {1: 0, 2: 1, 4: 2, 5: 0, 6: 2, 8: 5})
def main():
dg=get_test_graph_1()
dg.listprinter()
print("DFS",dg.dfs())
print("BFS",dg.bfs())
# print(dg.get_neighbor(0))
# print(dg.get_reverse_neighbor(0))
test_dfs()
# test_dfs()
# test_bfs()
# test_contains_cycle()
# test_topological_sort()
# test_strongly_connected_components()
print("Tests complete.")
if __name__ == "__main__":
main()