From b5b031db7f5ec1a3962c97328dec7e1145e499ca Mon Sep 17 00:00:00 2001 From: stefiosif Date: Sat, 11 Jun 2022 19:27:03 +0300 Subject: [PATCH] Add BFS tree --- algorithm/bfs.h | 62 ++++++++++++++++++++++++++++++++++++++++++ graph/graph.h | 21 ++++++++++++++ test/algorithm_test.cc | 34 +++++++++++++++++++---- test/graph_test.cc | 40 +++++++++++++++++---------- 4 files changed, 138 insertions(+), 19 deletions(-) create mode 100644 algorithm/bfs.h diff --git a/algorithm/bfs.h b/algorithm/bfs.h new file mode 100644 index 0000000..463614f --- /dev/null +++ b/algorithm/bfs.h @@ -0,0 +1,62 @@ +#ifndef BFS_H_ +#define BFS_H_ + +#include "graph/graph.h" +using namespace graph; + +#include +#include + +namespace algo { + +template +class BFS { +public: + BFS(Graph G, T root) : G(G), root(root) {} + + // + std::map> run(); + + // + std::map initExplore(); +private: + Graph G; + T root; +}; + +template +std::map BFS::initExplore() { + std::map graphExplore; + for (const auto& v : G.vertices) { + graphExplore[v] = false; + } + return graphExplore; +} + +template +std::map> BFS::run() { + std::map> tree; + std::map graphExplore = initExplore(); + std::queue Q; + Q.push(root); + graphExplore[root] = true; + + while (!Q.empty()) { + const auto v = Q.front(); + Q.pop(); + + for (const auto& u : G.adjMatrix[v]) { + if (!graphExplore[u]) { + graphExplore[u] = true; + tree[v].insert(u); + Q.push(u); + } + } + } + + return tree; +} + +} // namespace algo + +#endif \ No newline at end of file diff --git a/graph/graph.h b/graph/graph.h index 7e3ecf2..60efc58 100644 --- a/graph/graph.h +++ b/graph/graph.h @@ -23,6 +23,13 @@ public: // Reverse graph directions Graph reverse(); + // Number of vertices + std::uint16_t V(); + + // Number of edges + // TODO: Calculate bidirectional edges once + std::uint16_t E(); + // Adjacency matrix representation std::set vertices; std::map> adjMatrix; @@ -45,6 +52,20 @@ Graph Graph::reverse() { return Graph(); } +template +std::uint16_t Graph::V() { + return vertices.size(); +} + +template +std::uint16_t Graph::E() { + std::uint16_t edges = 0; + for (const auto& v : vertices) { + edges += adjMatrix[v].size(); + } + return edges; +} + } // namespace graph #endif \ No newline at end of file diff --git a/test/algorithm_test.cc b/test/algorithm_test.cc index e36d5d1..ae3d0ce 100644 --- a/test/algorithm_test.cc +++ b/test/algorithm_test.cc @@ -3,15 +3,18 @@ #include "graph/graph.h" using namespace graph; #include "algorithm/tarjan.h" +#include "algorithm/bfs.h" -TEST_SUITE("Algorithms") { +TEST_SUITE("Algorithm.") { TEST_CASE("Tarjan T_1") { - + // 1 --> 2 --> 4 --> 1 + // 2 --> 3 --> 5 --> 7 --> 3 + // 5 --> 9 --> 6 --> 8 --> 9 Graph G; G.insert(1, 2); - G.insert(2, 4); G.insert(2, 3); + G.insert(2, 4); G.insert(3, 5); G.insert(4, 1); G.insert(5, 7); @@ -41,10 +44,12 @@ TEST_SUITE("Algorithms") { } TEST_CASE("Tarjan T_2") { - + // 1 --> 2 --> 5 --> 7 --> 2 + // 1 --> 4 --> 3 --> 1 + // 4 --> 6 --> 3 Graph G; - G.insert(1, 4); G.insert(1, 2); + G.insert(1, 4); G.insert(2, 5); G.insert(3, 1); G.insert(4, 3); @@ -70,4 +75,23 @@ TEST_SUITE("Algorithms") { CHECK_EQ(expected, result); } + + TEST_CASE("BFS T_1") { + // 1 --> 2 --> 5 --> 7 --> 2 + // 1 --> 4 --> 3 --> 1 + // 4 --> 6 --> 3 + Graph G; + G.insert(1, 2); + G.insert(1, 4); + G.insert(2, 5); + G.insert(3, 1); + G.insert(4, 3); + G.insert(4, 6); + G.insert(5, 7); + G.insert(6, 3); + G.insert(7, 2); + + algo::BFS bfs(G, 1); + auto bfsTree = bfs.run(); + } } \ No newline at end of file diff --git a/test/graph_test.cc b/test/graph_test.cc index 0244e0a..c038a45 100644 --- a/test/graph_test.cc +++ b/test/graph_test.cc @@ -1,23 +1,35 @@ #include -#include "graph/graph.h" +#include "graph/scc.h" using namespace graph; +#include "algorithm/tarjan.h" -TEST_SUITE("Graph test.") { +TEST_SUITE("Graph.") { - TEST_CASE("Insertion.") { + TEST_CASE("SCC") { + // 1 --> 2 --> 4 --> 1 + // 2 --> 3 --> 5 --> 7 --> 3 + // 5 --> 9 --> 6 --> 8 --> 9 Graph G; - //G.insert(1); - //G.insert(1, 2); - //G.insert(1, 4); - //G.insert(1, 6); - //G.insert(2, 4); - //G.insert(2, 5); - //G.insert(3, 4); - //G.insert(3, 6); - //G.insert(4, 6); - //G.insert(5, 6); + G.insert(1, 2); + G.insert(2, 3); + G.insert(2, 4); + G.insert(3, 5); + G.insert(4, 1); + G.insert(5, 7); + G.insert(5, 9); + G.insert(6, 8); + G.insert(7, 3); + G.insert(8, 9); + G.insert(9, 6); + + algo::Tarjan tarjan(G); + auto tarjanOutput = tarjan.run(); + + std::vector> SCCs; + for (const auto& scc : tarjanOutput) { + SCCs.push_back(scc); + } - } } \ No newline at end of file