Key Concepts of Kahn’s Algorithm

  1. Directed Acyclic Graph (DAG): Kahn’s Algorithm can only be applied to DAGs. If the graph has cycles, it cannot be sorted topologically.
  2. In-degree: Each vertex has an in-degree that counts how many edges are directed toward it.
  3. Steps of Kahn’s Algorithm:
    • Calculate the in-degree of each vertex.
    • Initialize a queue with all vertices that have an in-degree of zero.
    • Repeatedly remove a vertex from the queue, add it to the topological order, and decrease the in-degree of its neighbors. If a neighbor’s in-degree becomes zero, add it to the queue.

C Program for Topological Sort Using Kahn’s Algorithm

#include <stdio.h>
#include <stdlib.h>

#define MAX 100

// Structure for the adjacency list node
struct Node {
    int vertex;
    struct Node* next;
};

// Structure for the graph
struct Graph {
    int numVertices;
    struct Node* adjList[MAX];
};

// Function to create a new adjacency list node
struct Node* createNode(int vertex) {
    struct Node* newNode = (struct Node*)malloc(sizeof(struct Node));
    newNode->vertex = vertex;
    newNode->next = NULL;
    return newNode;
}

// Function to create a graph with a given number of vertices
struct Graph* createGraph(int vertices) {
    struct Graph* graph = (struct Graph*)malloc(sizeof(struct Graph));
    graph->numVertices = vertices;

    for (int i = 0; i < vertices; i++) {
        graph->adjList[i] = NULL; // Initialize adjacency list
    }
    return graph;
}

// Function to add an edge to the graph
void addEdge(struct Graph* graph, int src, int dest) {
    struct Node* newNode = createNode(dest);
    newNode->next = graph->adjList[src];
    graph->adjList[src] = newNode;
}

// Function to perform topological sort using Kahn’s Algorithm
void topologicalSort(struct Graph* graph) {
    int inDegree[MAX] = {0}; // Array to store in-degrees of all vertices
    int topologicalOrder[MAX]; // Array to store the topological order
    int index = 0;

    // Calculate in-degrees of all vertices
    for (int i = 0; i < graph->numVertices; i++) {
        struct Node* temp = graph->adjList[i];
        while (temp) {
            inDegree[temp->vertex]++;
            temp = temp->next;
        }
    }

    // Initialize queue for vertices with in-degree of 0
    int queue[MAX], front = 0, rear = 0;
    for (int i = 0; i < graph->numVertices; i++) {
        if (inDegree[i] == 0) {
            queue[rear++] = i; // Enqueue vertex with in-degree 0
        }
    }

    // Process the queue
    while (front < rear) {
        int currentVertex = queue[front++]; // Dequeue vertex
        topologicalOrder[index++] = currentVertex; // Store in topological order

        // Decrease in-degree for all neighbors
        struct Node* temp = graph->adjList[currentVertex];
        while (temp) {
            inDegree[temp->vertex]--;
            // If in-degree becomes 0, enqueue the neighbor
            if (inDegree[temp->vertex] == 0) {
                queue[rear++] = temp->vertex;
            }
            temp = temp->next; // Move to next neighbor
        }
    }

    // Check if there was a cycle
    if (index != graph->numVertices) {
        printf("The graph has a cycle. Topological sort is not possible.\n");
        return;
    }

    // Print the topological order
    printf("Topological Sort: ");
    for (int i = 0; i < index; i++) {
        printf("%d ", topologicalOrder[i]);
    }
    printf("\n");
}

// Main function
int main() {
    struct Graph* graph = createGraph(6); // Create a graph with 6 vertices

    // Adding edges to the graph
    addEdge(graph, 5, 2);
    addEdge(graph, 5, 0);
    addEdge(graph, 4, 0);
    addEdge(graph, 4, 1);
    addEdge(graph, 2, 3);
    addEdge(graph, 3, 1);

    // Perform topological sort
    topologicalSort(graph);

    return 0;
}

Explanation of the Code

  1. Graph Representation:
    • The graph is represented using an adjacency list. Each vertex points to a list of its adjacent vertices using the Node structure.
  2. Graph Functions:
    • createNode: Creates a new node for the adjacency list.
    • createGraph: Initializes a graph with a specified number of vertices.
    • addEdge: Adds a directed edge from src to dest.
  3. Kahn’s Algorithm:
    • The topologicalSort function calculates the in-degrees of all vertices and initializes a queue with vertices that have an in-degree of zero.
    • It processes the queue by repeatedly dequeuing a vertex, adding it to the topological order, and reducing the in-degrees of its neighbors. If a neighbor’s in-degree becomes zero, it is added to the queue.
    • After processing, if the number of vertices in the topological order does not match the total number of vertices, it indicates a cycle.
  4. Main Function:
    • In the main function, we create a graph with 6 vertices and add directed edges. We then call the topologicalSort function to perform the sorting and print the result.

Input and Output

Input (Edges of the graph):

The directed edges added to the graph are:
5 → 2
5 → 0
4 → 0
4 → 1
2 → 3
3 → 1

When you run the program, you will see the following output:

mathematicaCopy codeTopological Sort: 4 5 0 2 3 1 

Conclusion

This program effectively implements Kahn’s Algorithm to perform a topological sort on a directed acyclic graph. It checks for cycles, ensuring that the sort can only be performed on valid DAGs. You can modify the graph structure by changing the edges to observe different topological sorts. This implementation provides a clear understanding of Kahn’s Algorithm and its applications in scheduling and task ordering problems.

Leave a Reply

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

Verified by MonsterInsights