Python
Python

 

 

Topological Sorting is a fundamental algorithmic technique used in various applications such as task scheduling, dependency resolution, and build systems. It provides a linear ordering of vertices in a Directed Acyclic Graph (DAG) where for every directed edge from vertex U to vertex V, vertex U comes before vertex V in the ordering. This article offers a comprehensive guide to implementing Topological Sorting in Python, complete with detailed explanations, program structure, and documentation.

Understanding Topological Sorting

Topological Sorting applies to Directed Acyclic Graphs (DAGs). A DAG is a graph with directed edges and no cycles. Topological Sorting is essential in scenarios where certain tasks must be performed before others, such as:

  • Task Scheduling: Determining the order of tasks based on dependencies.
  • Build Systems: Compiling source code by respecting file dependencies.
  • Course Prerequisites: Ordering courses based on prerequisite requirements.

Properties of Topological Sorting

  • The graph must be a DAG.
  • There may be multiple valid topological orderings for a single graph.
  • If the graph contains a cycle, topological sorting is not possible.

Approaches to Topological Sorting

There are two primary algorithms to perform Topological Sorting:

  • Depth-First Search (DFS) Based: Performs a DFS traversal and records the vertices in the order of completion.
  • Kahn’s Algorithm (BFS Based): Utilizes a queue to process vertices with no incoming edges iteratively.

This article focuses on Kahn’s Algorithm due to its intuitive use of in-degree and queue mechanisms.

Program Structure and Explanation

The Python program to perform Topological Sorting using Kahn’s Algorithm is structured into several key components:

  • Graph Representation: The graph is represented using an adjacency list, where each vertex maps to a list of its adjacent vertices.
  • In-Degree Calculation: Computes the number of incoming edges for each vertex.
  • Kahn’s Algorithm Implementation: Processes vertices with zero in-degree, updating in-degrees of adjacent vertices, and building the topological order.
  • Main Function: Executes the algorithm on example graphs and displays the results.

Python Program: Topological Sorting Using Kahn’s Algorithm


# Topological Sorting of a Directed Acyclic Graph (DAG) using Kahn's Algorithm

from collections import defaultdict, deque

def topological_sort_kahn(graph, vertices):
    """
    Performs topological sorting on a DAG using Kahn's Algorithm.
    
    Parameters:
    graph (dict): The graph represented as an adjacency list where keys are vertices and values are lists of adjacent vertices.
    vertices (list): A list of all vertices in the graph.
    
    Returns:
    list: A list representing the topological order of the vertices. Returns an empty list if a cycle is detected.
    """
    # Initialize in-degree of all vertices to 0
    in_degree = {vertex: 0 for vertex in vertices}
    
    # Compute in-degree by counting incoming edges
    for vertex in graph:
        for neighbor in graph[vertex]:
            in_degree[neighbor] += 1
    
    # Initialize a queue with all vertices having in-degree of 0
    queue = deque([vertex for vertex in vertices if in_degree[vertex] == 0])
    
    top_order = []
    
    while queue:
        current_vertex = queue.popleft()
        top_order.append(current_vertex)
        
        # Iterate through all neighbors and reduce their in-degree by 1
        for neighbor in graph[current_vertex]:
            in_degree[neighbor] -= 1
            # If in-degree becomes 0, add it to the queue
            if in_degree[neighbor] == 0:
                queue.append(neighbor)
    
    # Check if topological sort is possible (i.e., no cycles)
    if len(top_order) == len(vertices):
        return top_order
    else:
        # Cycle detected; topological sort not possible
        return []

def main():
    """
    Main function to execute the Topological Sorting program with example graphs.
    """
    # Example 1
    print("Example 1:")
    graph1 = {
        'A': ['C'],
        'B': ['C', 'D'],
        'C': ['E'],
        'D': ['F'],
        'E': ['H', 'F'],
        'F': ['G'],
        'G': [],
        'H': []
    }
    vertices1 = ['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H']
    order1 = topological_sort_kahn(graph1, vertices1)
    if order1:
        print(f"Topological Order: {' -> '.join(order1)}\n")
    else:
        print("Cycle detected. Topological sorting not possible.\n")
    
    # Example 2
    print("Example 2:")
    graph2 = {
        '5': ['11'],
        '7': ['11', '8'],
        '3': ['8', '10'],
        '11': ['2', '9', '10'],
        '8': ['9'],
        '2': [],
        '9': [],
        '10': []
    }
    vertices2 = ['5', '7', '3', '11', '8', '2', '9', '10']
    order2 = topological_sort_kahn(graph2, vertices2)
    if order2:
        print(f"Topological Order: {' -> '.join(order2)}\n")
    else:
        print("Cycle detected. Topological sorting not possible.\n")
    
    # Example 3 (Cycle Detection)
    print("Example 3:")
    graph3 = {
        'A': ['B'],
        'B': ['C'],
        'C': ['A'],  # Cycle here
        'D': ['C']
    }
    vertices3 = ['A', 'B', 'C', 'D']
    order3 = topological_sort_kahn(graph3, vertices3)
    if order3:
        print(f"Topological Order: {' -> '.join(order3)}\n")
    else:
        print("Cycle detected. Topological sorting not possible.\n")

if __name__ == "__main__":
    main()
    

Program Documentation

Function: topological_sort_kahn

Implements Kahn’s Algorithm to perform topological sorting on a Directed Acyclic Graph (DAG).

  • Parameters:
    • graph (dict): The graph represented as an adjacency list where each key is a vertex and its value is a list of adjacent vertices.
    • vertices (list): A list containing all vertices in the graph.
  • Returns:
    • list: A list representing the topological order of the vertices. Returns an empty list if a cycle is detected.

Function: main

Serves as the entry point of the program. It defines example graphs, executes the topological sorting function, and displays the results.

How to Run the Program

    1. Ensure you have Python installed on your system (Python 3.x recommended).
    2. Copy the provided Python code into a file named topological_sort.py.
    3. Open a terminal or command prompt and navigate to the directory containing the topological_sort.py file.
    4. Run the program using the command:
python topological_sort.py
  1. The program will execute the defined examples and output the topological orders or indicate if a cycle is detected.

Example Output


Example 1:
Topological Order: A -> B -> C -> D -> E -> F -> H -> G

Example 2:
Topological Order: 5 -> 7 -> 3 -> 11 -> 8 -> 2 -> 9 -> 10

Example 3:
Cycle detected. Topological sorting not possible.
    

Customization

To use the program with different graphs, modify the graph and vertices variables within the main function. Ensure that:

  • All vertices are listed in the vertices list.
  • Each key in the graph dictionary maps to a list of its adjacent vertices.

For example, to represent a new graph with vertices [‘P’, ‘Q’, ‘R’, ‘S’, ‘T’] and edges:


# New Example
graph = {
    'P': ['Q', 'R'],
    'Q': ['R', 'S'],
    'R': ['S'],
    'S': ['T'],
    'T': []
}
vertices = ['P', 'Q', 'R', 'S', 'T']
order = topological_sort_kahn(graph, vertices)
if order:
    print(f"Topological Order: {' -> '.join(order)}\n")
else:
    print("Cycle detected. Topological sorting not possible.\n")
    

Adding this new example to the main function will allow you to compute the topological order for the specified graph.

Conclusion

Topological Sorting is an indispensable tool in various computational and real-world applications where dependency resolution is critical. Kahn’s Algorithm provides an efficient and intuitive method to perform this sorting on Directed Acyclic Graphs. This Python implementation not only demonstrates the core principles of the algorithm but also offers a foundation for tackling more complex dependency and scheduling problems. By mastering Topological Sorting, you equip yourself with the ability to design and analyze systems where orderly execution based on dependencies is paramount.


Discover how to perform topological sorting on a DAG using Kahn’s Algorithm in Python. This guide includes detailed program structure, comprehensive documentation, and example usage.

 

By Aditya Bhuyan

I work as a cloud specialist. In addition to being an architect and SRE specialist, I work as a cloud engineer and developer. I have assisted my clients in converting their antiquated programmes into contemporary microservices that operate on various cloud computing platforms such as AWS, GCP, Azure, or VMware Tanzu, as well as orchestration systems such as Docker Swarm or Kubernetes. For over twenty years, I have been employed in the IT sector as a Java developer, J2EE architect, scrum master, and instructor. I write about Cloud Native and Cloud often. Bangalore, India is where my family and I call home. I maintain my physical and mental fitness by doing a lot of yoga and meditation.

Leave a Reply

Your email address will not be published. Required fields are marked *

error

Enjoy this blog? Please spread the word :)