-
-
Notifications
You must be signed in to change notification settings - Fork 46.2k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Improve comments, add doctests for kahns_algorithm_topo.py (#11668)
* Improve comments, add doctests for kahns_algorithm_topo.py * Improve function docstring * [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci * Rename variables, remove print --------- Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
- Loading branch information
1 parent
40f65e8
commit e20b503
Showing
1 changed file
with
46 additions
and
21 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,36 +1,61 @@ | ||
def topological_sort(graph): | ||
def topological_sort(graph: dict[int, list[int]]) -> list[int] | None: | ||
""" | ||
Kahn's Algorithm is used to find Topological ordering of Directed Acyclic Graph | ||
using BFS | ||
Perform topological sorting of a Directed Acyclic Graph (DAG) | ||
using Kahn's Algorithm via Breadth-First Search (BFS). | ||
Topological sorting is a linear ordering of vertices in a graph such that for | ||
every directed edge u → v, vertex u comes before vertex v in the ordering. | ||
Parameters: | ||
graph: Adjacency list representing the directed graph where keys are | ||
vertices, and values are lists of adjacent vertices. | ||
Returns: | ||
The topologically sorted order of vertices if the graph is a DAG. | ||
Returns None if the graph contains a cycle. | ||
Example: | ||
>>> graph = {0: [1, 2], 1: [3], 2: [3], 3: [4, 5], 4: [], 5: []} | ||
>>> topological_sort(graph) | ||
[0, 1, 2, 3, 4, 5] | ||
>>> graph_with_cycle = {0: [1], 1: [2], 2: [0]} | ||
>>> topological_sort(graph_with_cycle) | ||
""" | ||
|
||
indegree = [0] * len(graph) | ||
queue = [] | ||
topo = [] | ||
cnt = 0 | ||
topo_order = [] | ||
processed_vertices_count = 0 | ||
|
||
# Calculate the indegree of each vertex | ||
for values in graph.values(): | ||
for i in values: | ||
indegree[i] += 1 | ||
|
||
# Add all vertices with 0 indegree to the queue | ||
for i in range(len(indegree)): | ||
if indegree[i] == 0: | ||
queue.append(i) | ||
|
||
# Perform BFS | ||
while queue: | ||
vertex = queue.pop(0) | ||
cnt += 1 | ||
topo.append(vertex) | ||
for x in graph[vertex]: | ||
indegree[x] -= 1 | ||
if indegree[x] == 0: | ||
queue.append(x) | ||
|
||
if cnt != len(graph): | ||
print("Cycle exists") | ||
else: | ||
print(topo) | ||
|
||
|
||
# Adjacency List of Graph | ||
graph = {0: [1, 2], 1: [3], 2: [3], 3: [4, 5], 4: [], 5: []} | ||
topological_sort(graph) | ||
processed_vertices_count += 1 | ||
topo_order.append(vertex) | ||
|
||
# Traverse neighbors | ||
for neighbor in graph[vertex]: | ||
indegree[neighbor] -= 1 | ||
if indegree[neighbor] == 0: | ||
queue.append(neighbor) | ||
|
||
if processed_vertices_count != len(graph): | ||
return None # no topological ordering exists due to cycle | ||
return topo_order # valid topological ordering | ||
|
||
|
||
if __name__ == "__main__": | ||
import doctest | ||
|
||
doctest.testmod() |