Add BFS tree

This commit is contained in:
stefiosif
2022-06-11 19:27:03 +03:00
parent dfa8e649ee
commit b5b031db7f
4 changed files with 138 additions and 19 deletions

62
algorithm/bfs.h Normal file
View File

@@ -0,0 +1,62 @@
#ifndef BFS_H_
#define BFS_H_
#include "graph/graph.h"
using namespace graph;
#include <algorithm>
#include <queue>
namespace algo {
template<typename T>
class BFS {
public:
BFS(Graph<T> G, T root) : G(G), root(root) {}
//
std::map<T, std::set<T>> run();
//
std::map<T, bool> initExplore();
private:
Graph<T> G;
T root;
};
template<typename T>
std::map<T, bool> BFS<T>::initExplore() {
std::map<T, bool> graphExplore;
for (const auto& v : G.vertices) {
graphExplore[v] = false;
}
return graphExplore;
}
template<typename T>
std::map<T, std::set<T>> BFS<T>::run() {
std::map<T, std::set<T>> tree;
std::map<T, bool> graphExplore = initExplore();
std::queue<T> 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

View File

@@ -23,6 +23,13 @@ public:
// Reverse graph directions // Reverse graph directions
Graph<T> reverse(); Graph<T> reverse();
// Number of vertices
std::uint16_t V();
// Number of edges
// TODO: Calculate bidirectional edges once
std::uint16_t E();
// Adjacency matrix representation // Adjacency matrix representation
std::set<T> vertices; std::set<T> vertices;
std::map<T, std::set<T>> adjMatrix; std::map<T, std::set<T>> adjMatrix;
@@ -45,6 +52,20 @@ Graph<T> Graph<T>::reverse() {
return Graph<T>(); return Graph<T>();
} }
template<typename T>
std::uint16_t Graph<T>::V() {
return vertices.size();
}
template<typename T>
std::uint16_t Graph<T>::E() {
std::uint16_t edges = 0;
for (const auto& v : vertices) {
edges += adjMatrix[v].size();
}
return edges;
}
} // namespace graph } // namespace graph
#endif #endif

View File

@@ -3,15 +3,18 @@
#include "graph/graph.h" #include "graph/graph.h"
using namespace graph; using namespace graph;
#include "algorithm/tarjan.h" #include "algorithm/tarjan.h"
#include "algorithm/bfs.h"
TEST_SUITE("Algorithms") { TEST_SUITE("Algorithm.") {
TEST_CASE("Tarjan T_1") { TEST_CASE("Tarjan T_1") {
// 1 --> 2 --> 4 --> 1
// 2 --> 3 --> 5 --> 7 --> 3
// 5 --> 9 --> 6 --> 8 --> 9
Graph<std::uint16_t> G; Graph<std::uint16_t> G;
G.insert(1, 2); G.insert(1, 2);
G.insert(2, 4);
G.insert(2, 3); G.insert(2, 3);
G.insert(2, 4);
G.insert(3, 5); G.insert(3, 5);
G.insert(4, 1); G.insert(4, 1);
G.insert(5, 7); G.insert(5, 7);
@@ -41,10 +44,12 @@ TEST_SUITE("Algorithms") {
} }
TEST_CASE("Tarjan T_2") { TEST_CASE("Tarjan T_2") {
// 1 --> 2 --> 5 --> 7 --> 2
// 1 --> 4 --> 3 --> 1
// 4 --> 6 --> 3
Graph<std::uint16_t> G; Graph<std::uint16_t> G;
G.insert(1, 4);
G.insert(1, 2); G.insert(1, 2);
G.insert(1, 4);
G.insert(2, 5); G.insert(2, 5);
G.insert(3, 1); G.insert(3, 1);
G.insert(4, 3); G.insert(4, 3);
@@ -70,4 +75,23 @@ TEST_SUITE("Algorithms") {
CHECK_EQ(expected, result); CHECK_EQ(expected, result);
} }
TEST_CASE("BFS T_1") {
// 1 --> 2 --> 5 --> 7 --> 2
// 1 --> 4 --> 3 --> 1
// 4 --> 6 --> 3
Graph<std::uint16_t> 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<std::uint16_t> bfs(G, 1);
auto bfsTree = bfs.run();
}
} }

View File

@@ -1,23 +1,35 @@
#include <doctest/doctest.h> #include <doctest/doctest.h>
#include "graph/graph.h" #include "graph/scc.h"
using namespace graph; 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<std::uint16_t> G; Graph<std::uint16_t> G;
//G.insert(1); G.insert(1, 2);
//G.insert(1, 2); G.insert(2, 3);
//G.insert(1, 4); G.insert(2, 4);
//G.insert(1, 6); G.insert(3, 5);
//G.insert(2, 4); G.insert(4, 1);
//G.insert(2, 5); G.insert(5, 7);
//G.insert(3, 4); G.insert(5, 9);
//G.insert(3, 6); G.insert(6, 8);
//G.insert(4, 6); G.insert(7, 3);
//G.insert(5, 6); G.insert(8, 9);
G.insert(9, 6);
algo::Tarjan<std::uint16_t> tarjan(G);
auto tarjanOutput = tarjan.run();
std::vector<SCC<std::uint16_t>> SCCs;
for (const auto& scc : tarjanOutput) {
SCCs.push_back(scc);
}
} }
} }