From a2bc786543c9194354dcf8d8fe5fdb241691930c Mon Sep 17 00:00:00 2001 From: GregorSamsa42 Date: Wed, 24 Jul 2024 15:54:43 +0200 Subject: [PATCH] Restructured folders, added topological order alg --- Kosaraju/CMakeLists.txt | 6 +-- Kosaraju/digraph.cpp => digraph.cpp | 23 ++++++++++++ Kosaraju/digraph.h => digraph.h | 3 ++ top_order/CMakeLists.txt | 6 +++ top_order/top_order.cpp | 58 +++++++++++++++++++++++++++++ 5 files changed, 93 insertions(+), 3 deletions(-) rename Kosaraju/digraph.cpp => digraph.cpp (68%) rename Kosaraju/digraph.h => digraph.h (85%) create mode 100644 top_order/CMakeLists.txt create mode 100644 top_order/top_order.cpp diff --git a/Kosaraju/CMakeLists.txt b/Kosaraju/CMakeLists.txt index 43eceba..1cac620 100644 --- a/Kosaraju/CMakeLists.txt +++ b/Kosaraju/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required(VERSION 3.10) project(Kosaraju) add_executable(Kosaraju - digraph.cpp - digraph.h - main.cpp) \ No newline at end of file + ../digraph.cpp + ../digraph.h + main.cpp) diff --git a/Kosaraju/digraph.cpp b/digraph.cpp similarity index 68% rename from Kosaraju/digraph.cpp rename to digraph.cpp index 87c00d4..b18103e 100644 --- a/Kosaraju/digraph.cpp +++ b/digraph.cpp @@ -10,6 +10,11 @@ void Node::add_edge(int v) neighbours.push_back(v); } +int Node::outdeg() const +{ + return neighbours.size(); +} + Digraph::Digraph(size_t num_nodes) : nodes(num_nodes) { @@ -30,6 +35,24 @@ bool Digraph::isEdge(int from, int to) const return (std::find(adjList(from).begin(), adjList(from).end(), to) != adjList(from).end()); } +int Digraph::outdeg(int node_id) const +{ + return nodes[node_id].outdeg(); +} + +std::vector Digraph::indegrees() const +{ + std::vector indegs (num_nodes(),0); + for(int i = 0; i < num_nodes(); i++) + { + for (auto const& j: ((nodes[i]).neighbours)) + { + indegs[j]++; + } + } + return indegs; +} + size_t Digraph::num_nodes() const { return nodes.size(); diff --git a/Kosaraju/digraph.h b/digraph.h similarity index 85% rename from Kosaraju/digraph.h rename to digraph.h index e573121..751d89e 100644 --- a/Kosaraju/digraph.h +++ b/digraph.h @@ -12,6 +12,7 @@ struct Node { Node() = default; Node(std::list neighbours); void add_edge(int v); + int outdeg() const; }; class Digraph { @@ -22,6 +23,8 @@ public: size_t num_nodes() const; Digraph transpose() const; bool isEdge(int from, int to) const; + int outdeg(int v) const; + std::vector indegrees() const; private: std::vector nodes; diff --git a/top_order/CMakeLists.txt b/top_order/CMakeLists.txt new file mode 100644 index 0000000..dc41842 --- /dev/null +++ b/top_order/CMakeLists.txt @@ -0,0 +1,6 @@ +cmake_minimum_required(VERSION 3.10) +project(top_order) +add_executable(top_order + ../digraph.cpp + ../digraph.h + top_order.cpp) diff --git a/top_order/top_order.cpp b/top_order/top_order.cpp new file mode 100644 index 0000000..cfd7d33 --- /dev/null +++ b/top_order/top_order.cpp @@ -0,0 +1,58 @@ +// Kosaraju’s algorithm to find strongly connected components of a directed graph +// Authors: Georǵi Kocharyan, Maximilian Keßler + +#include +#include +#include +#include + +#include "../digraph.h" + + +int main() { + int size = 10; + Digraph G(size); + G.add_edge(3,4); + // G.add_edge(4,3); + // G.add_edge(5,6); + G.add_edge(6,7); + G.add_edge(7,5); + // G.add_edge(7,3); + // G.add_edge(0,3); + // G.add_edge(3,0); + + std::stack zero_indegree; + std::vector indegs = G.indegrees(); + int amount = 0; + + for(int i = 0; i < size; i++) + { + if (indegs[i] == 0) + { + zero_indegree.push(i); + amount++; + } + } + + while(!zero_indegree.empty()) + { + int node_id = zero_indegree.top(); + zero_indegree.pop(); + std::cout << node_id << ' '; + for(auto i: G.adjList(node_id)) + { + if (indegs[i] = 1) + { + zero_indegree.push(i); + amount++; + } + indegs[i]--; + } + } + if (!(amount == size)) + { + std::cout << '\n' << "The graph contains cycles and thus has no topological order." << std::endl; + } + + return 0; +} \ No newline at end of file