From b9cd1a1cbd9ae8dcd03865cac768aebbd7ea5071 Mon Sep 17 00:00:00 2001 From: stefiosif Date: Sun, 10 Jul 2022 15:32:13 +0300 Subject: [PATCH] Split graph folder into graph and tree --- algorithm/bfs.h | 10 +++++---- algorithm/decremental_scc.h | 6 ++--- graph/dag.h | 17 -------------- graph/directed_acyclic_graph.h | 16 +++++++++++++ test/algorithm_test.cc | 2 +- test/tree_test.cc | 41 ++++++++++++++++++++++++++++++++++ tree/breadth_first_tree.h | 30 +++++++++++++++++++++++++ tree/directed_rooted_tree.h | 20 +++++++++++++++++ tree/in_tree.h | 20 +++++++++++++++++ tree/out_tree.h | 20 +++++++++++++++++ tree/tree.h | 19 ++++++++++++++++ 11 files changed, 176 insertions(+), 25 deletions(-) delete mode 100644 graph/dag.h create mode 100644 graph/directed_acyclic_graph.h create mode 100644 test/tree_test.cc create mode 100644 tree/breadth_first_tree.h create mode 100644 tree/directed_rooted_tree.h create mode 100644 tree/in_tree.h create mode 100644 tree/out_tree.h create mode 100644 tree/tree.h diff --git a/algorithm/bfs.h b/algorithm/bfs.h index 739cac3..c0de6ff 100644 --- a/algorithm/bfs.h +++ b/algorithm/bfs.h @@ -12,10 +12,12 @@ namespace algo { template class BFS { public: - BFS(Graph G) : G(G) {} + BFS() = default; + + BFS(Digraph G) : G(G) {} // - Digraph run(const T& root); + std::map> run(const T& root); // Initialize the lookup table that is used to // show which vertices have been traversed @@ -34,7 +36,7 @@ std::map BFS::initExplore() { } template -Digraph BFS::run(const T& root) { +std::map> BFS::run(const T& root) { std::map> tree; std::map graphExplore = initExplore(); std::queue Q; @@ -54,7 +56,7 @@ Digraph BFS::run(const T& root) { } } - return Digraph(tree); + return tree; } } // namespace algo diff --git a/algorithm/decremental_scc.h b/algorithm/decremental_scc.h index b91f36d..e0574ef 100644 --- a/algorithm/decremental_scc.h +++ b/algorithm/decremental_scc.h @@ -55,7 +55,7 @@ void DecrementalSCC::findSCC() { const auto& w = C.representative(); // Create shortest-paths out-tree/in-tree - auto outTree = BFS(C).run(w); + auto outTree = Digraph(BFS(C).run(w)); SPT[w] = std::make_pair(outTree, outTree.reverse()); // Update A with current SCCs vertices @@ -89,13 +89,13 @@ void DecrementalSCC::remove(const T& u, const T& v) { // Update In(w) and Out(w) connection[w].adjMatrix[u].erase(v); G.adjMatrix[u].erase(v); - auto inTree = BFS(connection[w]).run(w); + auto inTree = Digraph(BFS(connection[w]).run(w)); SPT[w] = std::make_pair(inTree, inTree.reverse()); // If a SCC is broken, compute all SCCs again if (!SPT[w].second.vertices.contains(u) || !SPT[w].first.vertices.contains(v)) { - auto SCCs = Tarjan(G).findSCC(); + findSCC(); } } diff --git a/graph/dag.h b/graph/dag.h deleted file mode 100644 index 4883425..0000000 --- a/graph/dag.h +++ /dev/null @@ -1,17 +0,0 @@ -#ifndef DAG_H_ -#define DAG_H_ - -#include "digraph.h" - -namespace graph { - -// Directed Acyclic Graph -template -class DAG { -public: - DAG() = default; -}; - -} // namespace graph - -#endif \ No newline at end of file diff --git a/graph/directed_acyclic_graph.h b/graph/directed_acyclic_graph.h new file mode 100644 index 0000000..145f589 --- /dev/null +++ b/graph/directed_acyclic_graph.h @@ -0,0 +1,16 @@ +#ifndef DIRECTED_ACYCLIC_GRAPH_H_ +#define DIRECTED_ACYCLIC_GRAPH_H_ + +#include "digraph.h" + +namespace graph { + +template +class DirectedAcyclicGraph { +public: + DirectedAcyclicGraph() = default; +}; + +} // namespace graph + +#endif \ No newline at end of file diff --git a/test/algorithm_test.cc b/test/algorithm_test.cc index c5477fb..30d67dd 100644 --- a/test/algorithm_test.cc +++ b/test/algorithm_test.cc @@ -112,7 +112,7 @@ TEST_SUITE("Algorithm") { {5, {7}} }; - CHECK_EQ(tree.adjMatrix, exp); + CHECK_EQ(tree, exp); } TEST_CASE("Roditty Zwick A1 T1 ") { diff --git a/test/tree_test.cc b/test/tree_test.cc new file mode 100644 index 0000000..30057d8 --- /dev/null +++ b/test/tree_test.cc @@ -0,0 +1,41 @@ +#include + +#include "graph/scc.h" +#include "graph/digraph.h" +#include "algorithm/tarjan.h" +#include "tree/breadth_first_tree.h" + +#include + +using namespace graph; +using namespace tree; + +TEST_SUITE("Tree") { + TEST_CASE("Breadth First Tree") { + + // 1 --> 2 --> 5 --> 7 --> 2 + // 1 --> 4 --> 3 --> 1 + // 4 --> 6 --> 3 + Digraph 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); + + BreadthFirstTree tree(G); + + std::map> exp = { + {1, {2, 4}}, + {2, {5}}, + {4, {3, 6}}, + {5, {7}} + }; + + CHECK_EQ(tree.adjMatrix, exp); + } +} \ No newline at end of file diff --git a/tree/breadth_first_tree.h b/tree/breadth_first_tree.h new file mode 100644 index 0000000..c2c006d --- /dev/null +++ b/tree/breadth_first_tree.h @@ -0,0 +1,30 @@ +#ifndef BREADTH_FIRST_TREE_H_ +#define BREADTH_FIRST_TREE_H_ + +#include "algorithm/bfs.h" +#include "out_tree.h" +using namespace graph; + +namespace tree { + +template +class BreadthFirstTree : public OutTree { +public: + BreadthFirstTree() = default; + + BreadthFirstTree(Digraph G); + + BreadthFirstTree(std::map> G) + : OutTree::OutTree(G) {} +}; + +template +BreadthFirstTree::BreadthFirstTree(Digraph G) { + auto bfs = algo::BFS(G).run(1); + + Graph::adjMatrix = bfs; +} + +} // namespace tree + +#endif \ No newline at end of file diff --git a/tree/directed_rooted_tree.h b/tree/directed_rooted_tree.h new file mode 100644 index 0000000..c8b77ce --- /dev/null +++ b/tree/directed_rooted_tree.h @@ -0,0 +1,20 @@ +#ifndef DIRECTED_ROOTED_TREE_H_ +#define DIRECTED_ROOTED_TREE_H_ + +#include "tree.h" +using namespace graph; + +namespace tree { + +template +class DirectedRootedTree : public Tree { +public: + DirectedRootedTree() = default; + + DirectedRootedTree(std::map> G) + : Tree::Tree(G) {} +}; + +} // namespace tree + +#endif \ No newline at end of file diff --git a/tree/in_tree.h b/tree/in_tree.h new file mode 100644 index 0000000..2470692 --- /dev/null +++ b/tree/in_tree.h @@ -0,0 +1,20 @@ +#ifndef IN_TREE_H_ +#define IN_TREE_H_ + +#include "directed_rooted_tree.h" +using namespace graph; + +namespace tree { + +template +class InTree : public DirectedRootedTree { +public: + InTree() = default; + + InTree(std::map> G) + : DirectedRootedTree::DirectedRootedTree(G) {} +}; + +} // namespace tree + +#endif \ No newline at end of file diff --git a/tree/out_tree.h b/tree/out_tree.h new file mode 100644 index 0000000..9e0cda7 --- /dev/null +++ b/tree/out_tree.h @@ -0,0 +1,20 @@ +#ifndef OUT_TREE_H_ +#define OUT_TREE_H_ + +#include "directed_rooted_tree.h" +using namespace graph; + +namespace tree { + +template +class OutTree : public DirectedRootedTree { +public: + OutTree() = default; + + OutTree(std::map> G) + : DirectedRootedTree::DirectedRootedTree(G) {} +}; + +} // namespace tree + +#endif \ No newline at end of file diff --git a/tree/tree.h b/tree/tree.h new file mode 100644 index 0000000..44447ce --- /dev/null +++ b/tree/tree.h @@ -0,0 +1,19 @@ +#ifndef TREE_H_ +#define TREE_H_ + +#include "graph/digraph.h" +using namespace graph; + +namespace tree { + +template +class Tree : public Digraph { +public: + Tree() = default; + + Tree(std::map> G) : Digraph::Digraph(G) {} +}; + +} // namespace tree + +#endif \ No newline at end of file