-
-
Notifications
You must be signed in to change notification settings - Fork 46.8k
Create gabows_algorithm.py #12300
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Create gabows_algorithm.py #12300
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,121 @@ | ||
""" | ||
This is a pure Python implementation of | ||
Gabow's algorithm for finding | ||
strongly connected components (SCCs) | ||
in a directed graph. | ||
|
||
For doctests run: | ||
python -m doctest -v gabow_algorithm.py | ||
or | ||
python3 -m doctest -v gabow_algorithm.py | ||
For manual testing run: | ||
python gabow_algorithm.py | ||
""" | ||
|
||
from collections import defaultdict | ||
from typing import List, Dict | ||
Check failure on line 16 in graphs/gabows_algorithm.py
|
||
|
||
|
||
class Graph: | ||
""" | ||
Graph data structure to represent | ||
a directed graph and find SCCs | ||
using Gabow's algorithm. | ||
|
||
Attributes: | ||
vertices (int): Number of | ||
vertices in the graph. | ||
graph (Dict[int, List[int]]): | ||
Adjacency list of the graph. | ||
|
||
Methods: | ||
add_edge(u, v): Adds an edge | ||
from vertex u to vertex v. | ||
find_sccs(): Finds and returns | ||
all SCCs in the graph. | ||
|
||
Examples: | ||
>>> g = Graph(5) | ||
>>> g.add_edge(0, 2) | ||
>>> g.add_edge(2, 1) | ||
>>> g.add_edge(1, 0) | ||
>>> g.add_edge(0, 3) | ||
>>> g.add_edge(3, 4) | ||
>>> sorted(g.find_sccs()) | ||
[[0, 1, 2], [3], [4]] | ||
""" | ||
|
||
def __init__(self, vertices: int) -> None: | ||
self.vertices = vertices | ||
self.graph: Dict[int, List[int]] = defaultdict(list) | ||
Check failure on line 50 in graphs/gabows_algorithm.py
|
||
self.index = 0 | ||
self.stack_s = [] # Stack S | ||
self.stack_p = [] # Stack P | ||
self.visited = [False] * vertices | ||
self.result = [] | ||
|
||
def add_edge(self, u: int, v: int) -> None: | ||
""" | ||
Adds a directed edge from vertex u to vertex v. | ||
|
||
:param u: Starting vertex of the edge. | ||
:param v: Ending vertex of the edge. | ||
""" | ||
self.graph[u].append(v) | ||
|
||
def _dfs(self, v: int) -> None: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please provide descriptive name for the parameter: |
||
""" | ||
Depth-first search helper function to | ||
process each vertex and identify SCCs. | ||
:param v: The current vertex to process in DFS. | ||
""" | ||
self.visited[v] = True | ||
self.stack_s.append(v) | ||
self.stack_p.append(v) | ||
|
||
for neighbor in self.graph[v]: | ||
if not self.visited[neighbor]: | ||
self._dfs(neighbor) | ||
elif neighbor in self.stack_p: | ||
while self.stack_p and self.stack_p[-1] != neighbor: | ||
self.stack_p.pop() | ||
if self.stack_p and self.stack_p[-1] == v: | ||
scc = [] | ||
while True: | ||
node = self.stack_s.pop() | ||
scc.append(node) | ||
if node == v: | ||
break | ||
self.stack_p.pop() | ||
self.result.append(scc) | ||
|
||
def find_sccs(self) -> List[List[int]]: | ||
Check failure on line 92 in graphs/gabows_algorithm.py
|
||
""" | ||
Finds all strongly connected components | ||
in the directed graph. | ||
:return: List of SCCs, where each SCC | ||
is represented as a list of vertices. | ||
""" | ||
for v in range(self.vertices): | ||
if not self.visited[v]: | ||
self._dfs(v) | ||
return self.result | ||
|
||
|
||
if __name__ == "__main__": | ||
import doctest | ||
|
||
doctest.testmod() | ||
# Example usage for manual testing | ||
try: | ||
vertex_count = int(input("Enter the number of vertices: ")) | ||
g = Graph(vertex_count) | ||
edge_count = int(input("Enter the number of edges: ")) | ||
print("Enter each edge as a pair of vertices (u v):") | ||
for _ in range(edge_count): | ||
u, v = map(int, input().split()) | ||
g.add_edge(u, v) | ||
sccs = g.find_sccs() | ||
print("Strongly Connected Components:", sccs) | ||
except ValueError: | ||
print("Invalid input. Please enter valid integers.") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please provide descriptive name for the parameter:
u
Please provide descriptive name for the parameter:
v