Skip to content

Commit 3e88c28

Browse files
authored
Write tests for Graph
1 parent 7cd09a5 commit 3e88c28

File tree

1 file changed

+153
-0
lines changed

1 file changed

+153
-0
lines changed

cyaron/tests/graph_test.py

Lines changed: 153 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,153 @@
1+
import unittest
2+
from cyaron import Graph
3+
4+
5+
class UnionFindSet:
6+
def __init__(self, size):
7+
self.father = [0] + [i + 1 for i in range(size)]
8+
9+
def get_father(self, node):
10+
if self.father[node] == node:
11+
return node
12+
else:
13+
self.father[node] = self.get_father(self.father[node])
14+
return self.father[node]
15+
16+
def merge(self, l, r):
17+
l = self.get_father(l)
18+
r = self.get_father(r)
19+
self.father[l] = r
20+
21+
def test_same(self, l, r):
22+
return self.get_father(l) == self.get_father(r)
23+
24+
25+
def tarjan(graph, n):
26+
def new_array(len, val=0):
27+
return [val for _ in range(len+1)]
28+
29+
instack = new_array(n, False)
30+
low = new_array(n)
31+
dfn = new_array(n, 0)
32+
stap = new_array(n)
33+
belong = new_array(n)
34+
cnt = bc = stop = 0
35+
36+
def dfs(cur):
37+
nonlocal cnt, bc, stop
38+
cnt += 1
39+
dfn[cur] = low[cur] = cnt
40+
instack[cur] = True
41+
stap[stop] = cur
42+
stop += 1
43+
44+
for v in graph.edges[cur]:
45+
if dfn[v.end] == 0:
46+
dfs(v.end)
47+
low[cur] = min(low[cur], low[v.end])
48+
elif instack[v.end]:
49+
low[cur] = min(low[cur], dfn[v.end])
50+
51+
if dfn[cur] == low[cur]:
52+
v = cur + 1 # set v != cur
53+
bc += 1
54+
while v != cur:
55+
stop -= 1
56+
v = stap[stop]
57+
instack[v] = False
58+
belong[v] = bc
59+
60+
for i in range(n):
61+
if dfn[i+1] == 0:
62+
dfs(i+1)
63+
64+
return belong
65+
66+
67+
class TestGraph(unittest.TestCase):
68+
69+
def test_self_loop(self):
70+
graph_size = 20
71+
for _ in range(20):
72+
graph = Graph.graph(graph_size, int(graph_size*2), self_loop=True)
73+
has_self_loop = max([e.start == e.end for e in graph.iterate_edges()])
74+
if has_self_loop:
75+
break
76+
self.assertTrue(has_self_loop)
77+
78+
for _ in range(10):
79+
graph = Graph.graph(graph_size, int(graph_size*2), self_loop=False)
80+
self.assertFalse(max([e.start == e.end for e in graph.iterate_edges()]))
81+
82+
def test_repeated_edges(self):
83+
graph_size = 20
84+
for _ in range(20):
85+
graph = Graph.graph(graph_size, int(graph_size*2), repeated_edges=True)
86+
edges = [(e.start, e.end) for e in graph.iterate_edges()]
87+
has_repeated_edges = len(edges) > len(set(edges))
88+
if has_repeated_edges:
89+
break
90+
self.assertTrue(has_repeated_edges)
91+
92+
for _ in range(10):
93+
graph = Graph.graph(graph_size, int(graph_size*2), repeated_edges=False)
94+
edges = list(graph.iterate_edges())
95+
self.assertEqual(len(edges), len(set(edges)))
96+
97+
def test_tree_connected(self):
98+
graph_size = 20
99+
for _ in range(20):
100+
ufs = UnionFindSet(graph_size)
101+
tree = Graph.tree(graph_size)
102+
for edge in tree.iterate_edges():
103+
ufs.merge(edge.start, edge.end)
104+
for i in range(graph_size-1):
105+
self.assertTrue(ufs.test_same(i+1, i+2))
106+
107+
108+
def test_DAG(self):
109+
graph_size = 20
110+
for _ in range(10): # test 10 times
111+
ufs = UnionFindSet(graph_size)
112+
graph = Graph.DAG(graph_size, int(graph_size*1.6), repeated_edges=False, self_loop=False, loop=True)
113+
114+
self.assertEqual(len(list(graph.iterate_edges())), int(graph_size*1.6))
115+
116+
for edge in graph.iterate_edges():
117+
ufs.merge(edge.start, edge.end)
118+
for i in range(graph_size-1):
119+
self.assertTrue(ufs.test_same(i+1, i+2))
120+
121+
def test_DAG_without_loop(self):
122+
graph_size = 20
123+
for _ in range(10): # test 10 times
124+
ufs = UnionFindSet(graph_size)
125+
graph = Graph.DAG(graph_size, int(graph_size*1.6), repeated_edges=False, self_loop=False, loop=False)
126+
127+
self.assertEqual(len(list(graph.iterate_edges())), int(graph_size*1.6))
128+
129+
for edge in graph.iterate_edges():
130+
ufs.merge(edge.start, edge.end)
131+
for i in range(graph_size-1):
132+
self.assertTrue(ufs.test_same(i+1, i+2))
133+
134+
belong = tarjan(graph, graph_size)
135+
self.assertEqual(max(belong), graph_size)
136+
137+
def test_undirected_graph(self):
138+
graph_size = 20
139+
for _ in range(10): # test 10 times
140+
ufs = UnionFindSet(graph_size)
141+
graph = Graph.UDAG(graph_size, int(graph_size*1.6), repeated_edges=False, self_loop=False)
142+
143+
self.assertEqual(len(list(graph.iterate_edges())), int(graph_size*1.6))
144+
145+
for edge in graph.iterate_edges():
146+
ufs.merge(edge.start, edge.end)
147+
for i in range(graph_size-1):
148+
self.assertTrue(ufs.test_same(i+1, i+2))
149+
150+
def test_DAG_boundary(self):
151+
with self.assertRaises(Exception, msg="the number of edges of connected graph must more than the number of nodes - 1"):
152+
Graph.DAG(8, 6)
153+
Graph.DAG(8, 7)

0 commit comments

Comments
 (0)