From c525aeaa4351dfe8f57e14d94c3f80c049eee4a0 Mon Sep 17 00:00:00 2001 From: stefiosif Date: Wed, 12 Oct 2022 16:57:48 +0300 Subject: [PATCH] Refactor: Rename adjMatrix to adjList --- algorithm/breadth_first_search.h | 10 +++++----- algorithm/frigioni.h | 10 +++++----- algorithm/henzinger_king.h | 4 ++-- algorithm/italiano.h | 8 ++++---- algorithm/roditty_zwick.h | 8 ++++---- algorithm/tarjan.h | 10 +++++----- graph/breadth_first_tree.h | 2 +- graph/digraph.h | 12 ++++++------ graph/graph.h | 14 +++++++------- graph/scc.h | 8 ++++---- test/algorithm_test.cc | 14 +++++++------- test/decremental_reachability_test.cc | 6 +++--- test/dynamic_reachability_test.cc | 4 ++-- test/graph_test.cc | 2 +- 14 files changed, 56 insertions(+), 56 deletions(-) diff --git a/algorithm/breadth_first_search.h b/algorithm/breadth_first_search.h index aa8706e..de71d0e 100644 --- a/algorithm/breadth_first_search.h +++ b/algorithm/breadth_first_search.h @@ -14,8 +14,8 @@ class BreadthFirstSearch { public: BreadthFirstSearch() = default; - BreadthFirstSearch(std::map> adjMatrix) - : adjMatrix(adjMatrix) {} + BreadthFirstSearch(std::map> adjList) + : adjList(adjList) {} // Traverse whole graph using the BFS search, and save the tree graph // which is created when visiting new vertices (Breadth First Tree) @@ -25,7 +25,7 @@ public: bool query(const T& root, const T& target); private: // Represents the graph on which the algorithm will be executed - std::map> adjMatrix; + std::map> adjList; }; template @@ -40,7 +40,7 @@ std::map> BreadthFirstSearch::execute(const T& root) { const auto v = Q.front(); Q.pop(); - for (const auto& u : adjMatrix[v]) { + for (const auto& u : adjList[v]) { if (!visited[u]) { visited[u] = true; tree[v].insert(u); @@ -65,7 +65,7 @@ bool BreadthFirstSearch::query(const T& root, const T& target) { if (v == target) return true; - for (const auto& u : adjMatrix[v]) { + for (const auto& u : adjList[v]) { if (!visited[u]) { visited[u] = true; Q.push(u); diff --git a/algorithm/frigioni.h b/algorithm/frigioni.h index 9cb6c78..86e3bc5 100644 --- a/algorithm/frigioni.h +++ b/algorithm/frigioni.h @@ -50,14 +50,14 @@ private: template void Frigioni::init() { - auto SCCs = Tarjan(this->G.adjMatrix).execute(); + auto SCCs = Tarjan(this->G.adjList).execute(); rodittyZwick = RodittyZwick(this->G); rodittyZwick.init(); for (auto& scc : SCCs) { RT[scc.id] = BreadthFirstTree(this->G, scc.id); for (const auto& u : this->G.vertices()) { - for (const auto& v : this->G.adjMatrix[u]) { + for (const auto& v : this->G.adjList[u]) { if (scc.member(u)) { if (scc.member(v)) E[scc.id].in.insert(std::make_pair(u, v)); @@ -126,7 +126,7 @@ void Frigioni::remove(const std::vector>& edges) { for (const auto& c : E[v].out) H[id].push(C[c.second].id); } - RT[id].adjMatrix[u].erase(v); + RT[id].adjList[u].erase(v); } } @@ -165,7 +165,7 @@ void Frigioni::remove(const std::vector>& edges) { for (const auto& c : E[v].out) H[id].push(C[c.second].id); } - RT[id].adjMatrix[u].erase(v); + RT[id].adjList[u].erase(v); } } } @@ -178,7 +178,7 @@ void Frigioni::remove(const std::vector>& edges) { for (const auto& [u, v] : E[h].inc) { if (RT[id].contains(id, u)) { - RT[id].adjMatrix[u].insert(h); + RT[id].adjList[u].insert(h); found = true; break; } diff --git a/algorithm/henzinger_king.h b/algorithm/henzinger_king.h index 601ac80..c2c8603 100644 --- a/algorithm/henzinger_king.h +++ b/algorithm/henzinger_king.h @@ -65,8 +65,8 @@ bool HenzingerKing::query(const T& u, const T& v) { return std::any_of(S.begin(), S.end(), [&](const T& w) { - return In[w].adjMatrix.contains(u) && - Out[w].adjMatrix.contains(v); + return In[w].adjList.contains(u) && + Out[w].adjList.contains(v); }); } diff --git a/algorithm/italiano.h b/algorithm/italiano.h index 1bfa2cc..0eb4917 100644 --- a/algorithm/italiano.h +++ b/algorithm/italiano.h @@ -47,7 +47,7 @@ private: template void Italiano::init() { for (const auto& u : this->G.vertices()) { - for (const auto& v : this->G.adjMatrix[u]) { + for (const auto& v : this->G.adjList[u]) { E[v].inc.insert(u); E[u].out.insert(v); TC[u][v] = false; @@ -66,7 +66,7 @@ bool Italiano::query(const T& u, const T& v) { template void Italiano::remove(const T& u, const T& v) { - if (!this->G.adjMatrix[u].contains(v)) return; + if (!this->G.adjList[u].contains(v)) return; std::map> H; for (const auto& w : this->G.vertices()) { @@ -78,7 +78,7 @@ void Italiano::remove(const T& u, const T& v) { for (const auto& c : E[v].out) H[w].push(c); } - RT[w].adjMatrix[u].erase(v); + RT[w].adjList[u].erase(v); } } E[u].out.erase(v); @@ -97,7 +97,7 @@ void Italiano::repairTrees(std::map>& H) { for (const auto& i : E[h].inc) { if (RT[z].contains(z, i)) { - RT[z].adjMatrix[i].insert(h); + RT[z].adjList[i].insert(h); found = true; break; } diff --git a/algorithm/roditty_zwick.h b/algorithm/roditty_zwick.h index 6064359..40a8968 100644 --- a/algorithm/roditty_zwick.h +++ b/algorithm/roditty_zwick.h @@ -48,7 +48,7 @@ void RodittyZwick::init() { template void RodittyZwick::findSCC() { - auto SCCs = Tarjan(this->G.adjMatrix).execute(); + auto SCCs = Tarjan(this->G.adjList).execute(); for (auto& SCC : SCCs) { const auto& w = SCC.id; @@ -78,8 +78,8 @@ void RodittyZwick::remove(const T& u, const T& v) { if (A[u] != A[v]) return; // If edge (u,v) is not contained in both inTree and outTree do nothing - if (!In[w].adjMatrix[u].contains(v) && - !Out[w].adjMatrix[u].contains(v)) + if (!In[w].adjList[u].contains(v) && + !Out[w].adjList[u].contains(v)) return; // Update In(w) and Out(w) @@ -87,7 +87,7 @@ void RodittyZwick::remove(const T& u, const T& v) { In[w] = BreadthFirstTree(C[w].reverse(), w); // If a SCC is broken, compute all SCCs again - if (!In[w].adjMatrix.count(u) || !Out[w].adjMatrix.count(v)) + if (!In[w].adjList.count(u) || !Out[w].adjList.count(v)) findSCC(); } diff --git a/algorithm/tarjan.h b/algorithm/tarjan.h index 78f4a4c..29a479e 100644 --- a/algorithm/tarjan.h +++ b/algorithm/tarjan.h @@ -16,7 +16,7 @@ class Tarjan { public: Tarjan() = default; - Tarjan(std::map> adjMatrix) : adjMatrix(adjMatrix) {} + Tarjan(std::map> adjList) : adjList(adjList) {} // auto execute(); @@ -24,7 +24,7 @@ public: // void strongConnect(const T& u); private: - std::map> adjMatrix; + std::map> adjList; std::stack S; std::int16_t index = 0; std::vector> SCCs; @@ -44,7 +44,7 @@ void Tarjan::strongConnect(const T& u) { S.push(u); vmap[u].onStack = true; - for (const auto& w : adjMatrix[u]) { + for (const auto& w : adjList[u]) { if (vmap[w].index == -1) { strongConnect(w); vmap[u].lowlink = std::min(vmap[u].lowlink, vmap[w].lowlink); @@ -63,7 +63,7 @@ void Tarjan::strongConnect(const T& u) { const auto w = S.top(); S.pop(); vmap[w].onStack = false; - scc[w] = adjMatrix[w]; + scc[w] = adjList[w]; finished = (w == u); } while (!finished); @@ -73,7 +73,7 @@ void Tarjan::strongConnect(const T& u) { template auto Tarjan::execute() { - for (const auto& u : std::views::keys(adjMatrix)) { + for (const auto& u : std::views::keys(adjList)) { if (vmap[u].index == -1) strongConnect(u); } diff --git a/graph/breadth_first_tree.h b/graph/breadth_first_tree.h index 296ef04..1262400 100644 --- a/graph/breadth_first_tree.h +++ b/graph/breadth_first_tree.h @@ -20,7 +20,7 @@ public: template BreadthFirstTree::BreadthFirstTree(Digraph G, T root) { - this->adjMatrix = algo::BreadthFirstSearch(G.adjMatrix).execute(root); + this->adjList = algo::BreadthFirstSearch(G.adjList).execute(root); } } // namespace graph diff --git a/graph/digraph.h b/graph/digraph.h index 21dba0c..b2f76b0 100644 --- a/graph/digraph.h +++ b/graph/digraph.h @@ -28,23 +28,23 @@ public: template Digraph::Digraph(std::map> G) { - this->adjMatrix = G; + this->adjList = G; } template bool Digraph::contains(const T& u, const T& v) { - return algo::BreadthFirstSearch(this->adjMatrix).query(u, v); + return algo::BreadthFirstSearch(this->adjList).query(u, v); } template void Digraph::insert(const T& u, const T& v) { - this->adjMatrix[u].insert(v); - this->adjMatrix[v]; + this->adjList[u].insert(v); + this->adjList[v]; } template void Digraph::remove(const T& u, const T& v) { - this->adjMatrix[u].erase(v); + this->adjList[u].erase(v); } template @@ -52,7 +52,7 @@ auto Digraph::reverse() { std::map> revMatrix; for (const auto& u : this->vertices()) { - for (const auto& v : this->adjMatrix[u]) { + for (const auto& v : this->adjList[u]) { revMatrix[v].insert(u); } } diff --git a/graph/graph.h b/graph/graph.h index 7b7738b..29546f8 100644 --- a/graph/graph.h +++ b/graph/graph.h @@ -36,31 +36,31 @@ public: std::uint16_t E(); // Adjacency matrix representation - std::map> adjMatrix; + std::map> adjList; friend std::ostream& operator<<<>(std::ostream& os, Graph& G); }; template Graph::~Graph() { - adjMatrix.clear(); + adjList.clear(); } template auto Graph::vertices() { - return std::views::keys(adjMatrix); + return std::views::keys(adjList); } template std::uint16_t Graph::V() { - return static_cast(adjMatrix.size()); + return static_cast(adjList.size()); } template std::uint16_t Graph::E() { std::uint16_t edges = 0; for (const auto& u : vertices()) { - edges += static_cast(adjMatrix[u].size()); + edges += static_cast(adjList[u].size()); } return static_cast(edges); } @@ -69,8 +69,8 @@ template std::ostream& operator<<(std::ostream& os, Graph& G) { os << "V: " << G.V() << " E: " << G.E() << '\n'; for (const auto& u : this->vertices()) { - if (!this->adjMatrix[u].empty()) { - for (const auto& v : this->adjMatrix[u]) { + if (!this->adjList[u].empty()) { + for (const auto& v : this->adjList[u]) { os << u << "->" << v << ' '; } os << '\n'; diff --git a/graph/scc.h b/graph/scc.h index 3ede212..a228726 100644 --- a/graph/scc.h +++ b/graph/scc.h @@ -32,10 +32,10 @@ private: template void SCC::normalize() { for (const auto& u : this->vertices()) { - for (const auto& v : this->adjMatrix[u]) { - if (!this->adjMatrix.count(v)) { - this->adjMatrix[u].erase(v); - this->adjMatrix.erase(v); + for (const auto& v : this->adjList[u]) { + if (!this->adjList.count(v)) { + this->adjList[u].erase(v); + this->adjList.erase(v); } } } diff --git a/test/algorithm_test.cc b/test/algorithm_test.cc index 8b13889..aee7fa1 100644 --- a/test/algorithm_test.cc +++ b/test/algorithm_test.cc @@ -40,9 +40,9 @@ TEST_SUITE("Algorithm") { G.insert(13, 9); G.insert(12, 10); - REQUIRE_EQ(G.adjMatrix.size(), 13); + REQUIRE_EQ(G.V(), 13); - auto SCCs = algo::Tarjan(G.adjMatrix).execute(); + auto SCCs = algo::Tarjan(G.adjList).execute(); std::vector> expected = { {9, 10, 11, 12, 13}, @@ -51,7 +51,7 @@ TEST_SUITE("Algorithm") { }; for (auto i = 0; i < SCCs.size(); i++) { - auto kv = std::views::keys(SCCs[i].adjMatrix); + auto kv = std::views::keys(SCCs[i].adjList); CHECK_EQ(std::is_permutation(kv.begin(), kv.end(), expected[i].begin()), true); } @@ -67,12 +67,12 @@ TEST_SUITE("Algorithm") { } } - auto SCCs = algo::Tarjan(G.adjMatrix).execute(); + auto SCCs = algo::Tarjan(G.adjList).execute(); // Testing whether an scc is a 1-vertex scc which after the normalization // has no edges, in this case we know tgat there exist no 2-vertex sccs for (auto& scc : SCCs) { - CHECK_EQ(std::all_of(scc.adjMatrix.begin(), scc.adjMatrix.end(), + CHECK_EQ(std::all_of(scc.adjList.begin(), scc.adjList.end(), [](const auto& p) { return p.second.size() == 0; }), true); @@ -107,7 +107,7 @@ TEST_SUITE("Algorithm") { G.insert(12, 10); auto tree = - algo::BreadthFirstSearch(G.adjMatrix).execute(1); + algo::BreadthFirstSearch(G.adjList).execute(1); std::map> expected = { {1, {2}}, @@ -155,7 +155,7 @@ TEST_SUITE("Algorithm") { G.insert(13, 9); G.insert(12, 10); - algo::BreadthFirstSearch bfs(G.adjMatrix); + algo::BreadthFirstSearch bfs(G.adjList); CHECK_EQ(bfs.query(1, 5), true); CHECK_EQ(bfs.query(1, 10), true); diff --git a/test/decremental_reachability_test.cc b/test/decremental_reachability_test.cc index 12c6731..252b3dc 100644 --- a/test/decremental_reachability_test.cc +++ b/test/decremental_reachability_test.cc @@ -33,7 +33,7 @@ TEST_SUITE("Decremental Reachability Test") { G.insert(8, 9); G.insert(9, 5); - REQUIRE_EQ(G.adjMatrix.size(), 9); + REQUIRE_EQ(G.V(), 9); algo::RodittyZwick rodittyZwick(G); rodittyZwick.init(); @@ -85,7 +85,7 @@ TEST_SUITE("Decremental Reachability Test") { G.insert(7, 9); G.insert(8, 9); - REQUIRE_EQ(G.adjMatrix.size(), 9); + REQUIRE_EQ(G.V(), 9); algo::Italiano italiano(G); italiano.init(); @@ -142,7 +142,7 @@ TEST_SUITE("Decremental Reachability Test") { G.insert(8, 9); G.insert(9, 5); - REQUIRE_EQ(G.adjMatrix.size(), 9); + REQUIRE_EQ(G.V(), 9); algo::Frigioni frigioni(G); frigioni.init(); diff --git a/test/dynamic_reachability_test.cc b/test/dynamic_reachability_test.cc index d1adecd..818c15f 100644 --- a/test/dynamic_reachability_test.cc +++ b/test/dynamic_reachability_test.cc @@ -28,7 +28,7 @@ TEST_SUITE("Dynamic Reachability Test") { G.insert(7, 9); G.insert(8, 9); - REQUIRE_EQ(G.adjMatrix.size(), 9); + REQUIRE_EQ(G.V(), 9); algo::King king(G); king.init(); @@ -92,7 +92,7 @@ TEST_SUITE("Dynamic Reachability Test") { G.insert(8, 9); G.insert(9, 5); - REQUIRE_EQ(G.adjMatrix.size(), 9); + REQUIRE_EQ(G.V(), 9); algo::HenzingerKing henzingerKing(G); henzingerKing.init(); diff --git a/test/graph_test.cc b/test/graph_test.cc index 9b7bc89..f512cb7 100644 --- a/test/graph_test.cc +++ b/test/graph_test.cc @@ -116,7 +116,7 @@ TEST_SUITE("Graph") { REQUIRE_EQ(G.V(), 9); - auto SCCs = algo::Tarjan(G.adjMatrix).execute(); + auto SCCs = algo::Tarjan(G.adjList).execute(); std::vector> expected = { {5, 6, 7, 8, 9},