From 4a2ce7eaca70deaa05a53a1032559f67126a0bcd Mon Sep 17 00:00:00 2001 From: Dhandeep Date: Sun, 1 Oct 2023 17:55:11 +0530 Subject: [PATCH] added kahn algorithm --- README.md | 1 + .../algorithm/topological_sorting/kahn.cpp | 51 +++++++++++++++++++ .../algorithm/topological_sorting/kahn.h | 19 +++++++ 3 files changed, 71 insertions(+) create mode 100644 include/graaflib/algorithm/topological_sorting/kahn.cpp create mode 100644 include/graaflib/algorithm/topological_sorting/kahn.h diff --git a/README.md b/README.md index 5a714804..aec71938 100644 --- a/README.md +++ b/README.md @@ -107,6 +107,7 @@ take a look at the [docs](https://bobluppes.github.io/graaf/docs/algorithms/intr - Tarjan's Strongly Connected Components 6. [**Topological Sorting Algorithms**](https://bobluppes.github.io/graaf/docs/category/topological-sorting): - Topological sorting DFS-based + - Kahn's Algorithm 7. [**Traversal Algorithms**](https://bobluppes.github.io/graaf/docs/category/traversal-algorithms): - Breadth-First Search (BFS) - Depth-First Search (DFS) diff --git a/include/graaflib/algorithm/topological_sorting/kahn.cpp b/include/graaflib/algorithm/topological_sorting/kahn.cpp new file mode 100644 index 00000000..9fad8526 --- /dev/null +++ b/include/graaflib/algorithm/topological_sorting/kahn.cpp @@ -0,0 +1,51 @@ +// graaflib/algorithm/topological_sorting/kahn.cpp +#include "kahn.h" + +namespace graaflib::algorithm::topological_sorting { + + template + std::optional> kahns_topological_sort( + const graph& graph + ) { + std::vector topological_order; + std::vector in_degree(graph.num_vertices(), 0); + + //calculate in-degrees for all vertices + for (const auto& edge : graph.edges()) { + in_degree[edge.target()]++; + } + + //queue to store vertices with in-degree 0 + std::queue zero_in_degree_vertices; + + //initialize the queue with vertices having in-degree 0 + for (vertex_id_t vertex = 0; vertex < graph.num_vertices(); ++vertex) { + if (in_degree[vertex] == 0) { + zero_in_degree_vertices.push(vertex); + } + } + + while (!zero_in_degree_vertices.empty()) { + vertex_id_t current_vertex = zero_in_degree_vertices.front(); + zero_in_degree_vertices.pop(); + + topological_order.push_back(current_vertex); + + //remove the current vertex and its outgoing edges + for (const auto& edge : graph.edges_from(current_vertex)) { + vertex_id_t neighbor = edge.target(); + if (--in_degree[neighbor] == 0) { + zero_in_degree_vertices.push(neighbor); + } + } + } + + //check for the presence of a cycle + if (topological_order.size() != graph.num_vertices()) { + return std::nullopt; //graph contains a cycle + } + + return topological_order; + } + +} diff --git a/include/graaflib/algorithm/topological_sorting/kahn.h b/include/graaflib/algorithm/topological_sorting/kahn.h new file mode 100644 index 00000000..3bdfeaea --- /dev/null +++ b/include/graaflib/algorithm/topological_sorting/kahn.h @@ -0,0 +1,19 @@ +// graaflib/algorithm/topological_sorting/kahn.h +#ifndef GRAAF_KAHN_H +#define GRAAF_KAHN_H + +#include +#include +#include // Include graph header +#include "graaf/properties/vertex_properties.h" // Include vertex properties header + +namespace graaflib::algorithm::topological_sorting { + + template + std::optional> kahns_topological_sort( + const graph& graph + ); + +} + +#endif