Skip to content

Commit 2c262e8

Browse files
committed
feat(algs/aps): add backedge method of finding articulation points
1 parent 4fca28b commit 2c262e8

File tree

1 file changed

+45
-7
lines changed

1 file changed

+45
-7
lines changed

algorithms/articulation_points.py

Lines changed: 45 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,13 @@ class find_articulation_points(Graph):
1616
def __init__(self, adjacency_matrix, num_vertices):
1717
Graph.__init__(self, adjacency_matrix, num_vertices)
1818
self.saved_adj_mat = self.adj_mat
19+
self.backedges = np.zeros(num_vertices)
20+
self.potential_articulation_points = [[] for i in range(num_vertices)]
21+
self.articulation_points = []
22+
# self.min_discovery_time = np.full(num_vertices, num_vertices)
1923

2024
def brute_force(self):
2125
"""Alternative brute force approach: find islands using a DFS for each vertex."""
22-
self.articulation_points = []
2326
original_islands = self.find_num_islands()
2427
print("Original number of islands: ", original_islands)
2528
for vertex in range(self.v):
@@ -32,10 +35,45 @@ def brute_force(self):
3235
self.adj_mat = self.saved_adj_mat
3336
return self.articulation_points
3437

35-
adjmat = np.zeros((6,6))
36-
edges = [[0,1],[0,5],[1,2],[1,3],[2,3],[2,4],[3,4]]
37-
test1 = find_articulation_points(adjmat, 6)
38-
test1.add_edges(edges)
39-
test1.brute_force()
40-
print(test1.articulation_points)
38+
def back_edge(self, start):
39+
""" Back edge method of finding articulation points.
40+
41+
Back edge: an edge that connects a node to an ancestor of its parent.
42+
43+
Claim: If a vertex u has a child v and none of the vertices in the v-subtree have a back edge to ANY vertex discovered before u (this works bc data structure is a tree), u is an articulation point.
44+
- i.e. if u is removed, then the v-subtree will be disconnected from the graph.
45+
"""
46+
# print("at vertex", start)
47+
if self.visited[start]:
48+
# print("Already visited")
49+
return
50+
51+
# print("mark as visited")
52+
# Mark current cell as visited
53+
self.visited[start] = True
54+
self.steps_taken[start] = self.steps
55+
self.steps += 1
56+
# print(self.visited)
57+
58+
# Visit every neighbouring cell
59+
for cell in self.neighbour(start):
60+
if self.steps_taken[start] > self.steps_taken[cell]:
61+
self.backedges[start] += 1
62+
self.potential_articulation_points[start].append(cell)
63+
self.back_edge(cell)
64+
if self.backedges[start] == 1:
65+
ap = self.potential_articulation_points[start][0]
66+
if ap not in self.articulation_points:
67+
self.articulation_points.append(ap)
68+
69+
70+
def test1():
71+
adjmat = np.zeros((6,6))
72+
edges = [[0,1],[0,5],[1,2],[1,3],[2,3],[2,4],[3,4]]
73+
test1 = find_articulation_points(adjmat, 6)
74+
test1.add_edges(edges)
75+
test1.back_edge(1)
76+
# test1.brute_force()
77+
print("Articulation points:", test1.articulation_points)
4178

79+
test1()

0 commit comments

Comments
 (0)