From 9723bad855c44a0c6f8eaf2819e8b0eedbc071e3 Mon Sep 17 00:00:00 2001 From: Boris Galochkin Date: Thu, 4 Nov 2021 17:13:58 +0300 Subject: [PATCH 1/6] Fix finding_bridges algorithms + tests --- graphs/finding_bridges.py | 63 ++++++++++++++++++++++++++------------- 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/graphs/finding_bridges.py b/graphs/finding_bridges.py index 6555dd7bc29e..9ff86b4fa343 100644 --- a/graphs/finding_bridges.py +++ b/graphs/finding_bridges.py @@ -1,5 +1,42 @@ -# Finding Bridges in Undirected Graph -def computeBridges(graph): +def __get_demo_graph(index): + return [ + { + 0: [1, 2], + 1: [0, 2], + 2: [0, 1, 3, 5], + 3: [2, 4], + 4: [3], + 5: [2, 6, 8], + 6: [5, 7], + 7: [6, 8], + 8: [5, 7], + }, + { + 0: [6], + 1: [9], + 2: [4, 5], + 3: [4], + 4: [2, 3], + 5: [2], + 6: [0, 7], + 7: [6], + 8: [], + 9: [1], + }, + ][index] + + +def compute_bridges(graph: dict) -> list: + """ + Return the list of undirected graph bridges [(a1, b1), ..., (ak, bk)]; ai <= bi + >>> compute_bridges(__get_demo_graph(0)) + [(3, 4), (2, 3), (2, 5)] + >>> compute_bridges(__get_demo_graph(1)) + [(6, 7), (0, 6), (1, 9), (3, 4), (2, 4), (2, 5)] + >>> compute_bridges({}) + [] + """ + id = 0 n = len(graph) # No of vertices in graph low = [0] * n @@ -15,28 +52,14 @@ def dfs(at, parent, bridges, id): elif not visited[to]: dfs(to, at, bridges, id) low[at] = min(low[at], low[to]) - if at < low[to]: - bridges.append([at, to]) + if id <= low[to]: + bridges.append((at, to) if at < to else (to, at)) else: # This edge is a back edge and cannot be a bridge - low[at] = min(low[at], to) + low[at] = min(low[at], low[to]) bridges = [] for i in range(n): if not visited[i]: dfs(i, -1, bridges, id) - print(bridges) - - -graph = { - 0: [1, 2], - 1: [0, 2], - 2: [0, 1, 3, 5], - 3: [2, 4], - 4: [3], - 5: [2, 6, 8], - 6: [5, 7], - 7: [6, 8], - 8: [5, 7], -} -computeBridges(graph) + return bridges From 58c7d268dce83a7862a8224271649969a767af57 Mon Sep 17 00:00:00 2001 From: Boris Galochkin Date: Thu, 4 Nov 2021 17:26:49 +0300 Subject: [PATCH 2/6] update type hints --- graphs/finding_bridges.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphs/finding_bridges.py b/graphs/finding_bridges.py index 9ff86b4fa343..fe864f485b76 100644 --- a/graphs/finding_bridges.py +++ b/graphs/finding_bridges.py @@ -26,7 +26,7 @@ def __get_demo_graph(index): ][index] -def compute_bridges(graph: dict) -> list: +def compute_bridges(graph: dict[int, list[int]]) -> list[tuple[int, int]]: """ Return the list of undirected graph bridges [(a1, b1), ..., (ak, bk)]; ai <= bi >>> compute_bridges(__get_demo_graph(0)) From bdf8d997f679688ec343554019a1d2bd450f45e6 Mon Sep 17 00:00:00 2001 From: Boris Galochkin Date: Thu, 4 Nov 2021 17:33:43 +0300 Subject: [PATCH 3/6] Better, more obvious condition fix --- graphs/finding_bridges.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/graphs/finding_bridges.py b/graphs/finding_bridges.py index fe864f485b76..bfc446bb959a 100644 --- a/graphs/finding_bridges.py +++ b/graphs/finding_bridges.py @@ -52,7 +52,7 @@ def dfs(at, parent, bridges, id): elif not visited[to]: dfs(to, at, bridges, id) low[at] = min(low[at], low[to]) - if id <= low[to]: + if low[at] < low[to]: bridges.append((at, to) if at < to else (to, at)) else: # This edge is a back edge and cannot be a bridge From 09a9f18156946e296094e1dbd39a6f5eb11756b1 Mon Sep 17 00:00:00 2001 From: Boris Galochkin Date: Thu, 4 Nov 2021 17:58:04 +0300 Subject: [PATCH 4/6] fix prev commit + more tests --- graphs/finding_bridges.py | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/graphs/finding_bridges.py b/graphs/finding_bridges.py index bfc446bb959a..53bc2c7e5505 100644 --- a/graphs/finding_bridges.py +++ b/graphs/finding_bridges.py @@ -23,6 +23,25 @@ def __get_demo_graph(index): 8: [], 9: [1], }, + { + 0: [4], + 1: [6], + 2: [], + 3: [5, 6, 7], + 4: [0, 6], + 5: [3, 8, 9], + 6: [1, 3, 4, 7], + 7: [3, 6, 8, 9], + 8: [5, 7], + 9: [5, 7], + }, + { + 0: [1, 3], + 1: [0, 2, 4], + 2: [1, 3, 4], + 3: [0, 2, 4], + 4: [1, 2, 3], + }, ][index] @@ -33,6 +52,10 @@ def compute_bridges(graph: dict[int, list[int]]) -> list[tuple[int, int]]: [(3, 4), (2, 3), (2, 5)] >>> compute_bridges(__get_demo_graph(1)) [(6, 7), (0, 6), (1, 9), (3, 4), (2, 4), (2, 5)] + >>> compute_bridges(__get_demo_graph(2)) + [(1, 6), (4, 6), (0, 4)] + >>> compute_bridges(__get_demo_graph(3)) + [] >>> compute_bridges({}) [] """ @@ -52,7 +75,7 @@ def dfs(at, parent, bridges, id): elif not visited[to]: dfs(to, at, bridges, id) low[at] = min(low[at], low[to]) - if low[at] < low[to]: + if id <= low[to]: bridges.append((at, to) if at < to else (to, at)) else: # This edge is a back edge and cannot be a bridge From 5d74ac160c41aacf3d896bb00a0cea5fe487c407 Mon Sep 17 00:00:00 2001 From: Boris Galochkin Date: Thu, 4 Nov 2021 19:23:33 +0300 Subject: [PATCH 5/6] Short explanation + url --- graphs/finding_bridges.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/graphs/finding_bridges.py b/graphs/finding_bridges.py index 53bc2c7e5505..39486b9778c8 100644 --- a/graphs/finding_bridges.py +++ b/graphs/finding_bridges.py @@ -1,3 +1,14 @@ +""" +An edge is a bridge if, after removing it count of connected components in graph will +be increased by one. Bridges represent vulnerabilities in a connected network and are +useful for designing reliable networks. For example, in a wired computer network, an +articulation point indicates the critical computers and a bridge indicates the critical +wires or connections. + +For more details, refer this article: +https://www.geeksforgeeks.org/bridge-in-a-graph/ +""" + def __get_demo_graph(index): return [ { @@ -44,7 +55,6 @@ def __get_demo_graph(index): }, ][index] - def compute_bridges(graph: dict[int, list[int]]) -> list[tuple[int, int]]: """ Return the list of undirected graph bridges [(a1, b1), ..., (ak, bk)]; ai <= bi From 04afda8742258b4412c0361a08c026bbabc938f8 Mon Sep 17 00:00:00 2001 From: Christian Clauss Date: Thu, 4 Nov 2021 17:42:15 +0100 Subject: [PATCH 6/6] Update finding_bridges.py --- graphs/finding_bridges.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/graphs/finding_bridges.py b/graphs/finding_bridges.py index 39486b9778c8..a877a97489be 100644 --- a/graphs/finding_bridges.py +++ b/graphs/finding_bridges.py @@ -9,6 +9,7 @@ https://www.geeksforgeeks.org/bridge-in-a-graph/ """ + def __get_demo_graph(index): return [ { @@ -55,6 +56,7 @@ def __get_demo_graph(index): }, ][index] + def compute_bridges(graph: dict[int, list[int]]) -> list[tuple[int, int]]: """ Return the list of undirected graph bridges [(a1, b1), ..., (ak, bk)]; ai <= bi