From 56a5b594e4b4bc2cd4071fa315089b23bce2cc66 Mon Sep 17 00:00:00 2001 From: GregorSamsa42 Date: Sun, 14 Jul 2024 16:44:12 +0200 Subject: [PATCH] Kosaraju added --- Kosaraju/CMakeLists.txt | 6 +++ Kosaraju/digraph.cpp | 49 ++++++++++++++++++++++++ Kosaraju/digraph.h | 32 ++++++++++++++++ Kosaraju/main.cpp | 84 +++++++++++++++++++++++++++++++++++++++++ 4 files changed, 171 insertions(+) create mode 100644 Kosaraju/CMakeLists.txt create mode 100644 Kosaraju/digraph.cpp create mode 100644 Kosaraju/digraph.h create mode 100644 Kosaraju/main.cpp diff --git a/Kosaraju/CMakeLists.txt b/Kosaraju/CMakeLists.txt new file mode 100644 index 0000000..43eceba --- /dev/null +++ b/Kosaraju/CMakeLists.txt @@ -0,0 +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 diff --git a/Kosaraju/digraph.cpp b/Kosaraju/digraph.cpp new file mode 100644 index 0000000..87c00d4 --- /dev/null +++ b/Kosaraju/digraph.cpp @@ -0,0 +1,49 @@ +#include "digraph.h" + +Node::Node(std::list neighbours_) : neighbours(std::move(neighbours_)) +{ + +} + +void Node::add_edge(int v) +{ + neighbours.push_back(v); +} + +Digraph::Digraph(size_t num_nodes) : nodes(num_nodes) +{ + +} + +void Digraph::add_edge(int from, int to) +{ + nodes[from].add_edge(to); +} + +std::list Digraph::adjList(int node_id) const +{ + return (nodes[node_id]).neighbours; +} + +bool Digraph::isEdge(int from, int to) const +{ + return (std::find(adjList(from).begin(), adjList(from).end(), to) != adjList(from).end()); +} + +size_t Digraph::num_nodes() const +{ + return nodes.size(); +} + +Digraph Digraph::transpose() const +{ + Digraph G(num_nodes()); + for (int i = 0; i < num_nodes(); i++) + { + for (auto const& j: ((nodes[i]).neighbours)) + { + G.add_edge(j,i); + } + } + return G; +} diff --git a/Kosaraju/digraph.h b/Kosaraju/digraph.h new file mode 100644 index 0000000..e573121 --- /dev/null +++ b/Kosaraju/digraph.h @@ -0,0 +1,32 @@ +#ifndef C___DIGRAPH_H +#define C___DIGRAPH_H + +#include +#include +#include + + +struct Node { + std::list neighbours; + + Node() = default; + Node(std::list neighbours); + void add_edge(int v); +}; + +class Digraph { +public: + Digraph(size_t num_nodes); + void add_edge(int from, int to); + std::list adjList(int node_id) const; + size_t num_nodes() const; + Digraph transpose() const; + bool isEdge(int from, int to) const; + +private: + std::vector nodes; +}; + +#endif //C___DIGRAPH_H + + diff --git a/Kosaraju/main.cpp b/Kosaraju/main.cpp new file mode 100644 index 0000000..9574d8d --- /dev/null +++ b/Kosaraju/main.cpp @@ -0,0 +1,84 @@ +// 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" + +// push nodes in post-order +void dfs1(Digraph const & G, int n, std::vector & vis, std::stack & node_order) { + if (vis[n]) + { + return; //if node is already visited don't + } + + vis[n] = true; + + for(auto i: G.adjList(n)) + { + dfs1(G, i, vis, node_order); + } + + node_order.push(n); +} + +//this function traverses the transpose graph +void dfs2(Digraph const & G, int n, std::vector & vis2, std::stack & node_order){ + if (vis2[n]) + { + return; // if node is already visited + } + + std::cout << n << " "; + vis2[n] = true; + + for(auto i: G.adjList(n)) + { + dfs2(G, i, vis2, node_order); + } +} + +// print each component in seperate line, output amount +int kosaraju(Digraph const & G) { + int scc_count = 0; //keep count of strongly connected components + std::stack node_order; + std::vector vis2 (G.num_nodes(), false); + std::vector vis (G.num_nodes(), false); //store node visit stat for dfs + for(int i = 0; i < G.num_nodes(); i++) + { + dfs1(G, i, vis, node_order); + } + while(!node_order.empty()) { + int node_id = node_order.top(); + node_order.pop(); + if (vis2[node_id] == false) + { + dfs2(G.transpose(), node_id, vis2, node_order); + scc_count++; + std::cout << std::endl; + } + } + return scc_count; +} + +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); + + int components= kosaraju(G); + std::cout<< "Components: "<< components << std::endl; + + + return 0; +} \ No newline at end of file