From 14a61c92e979ab4a24c948fe22b6734a9bd39357 Mon Sep 17 00:00:00 2001 From: stefiosif Date: Sun, 25 Sep 2022 17:42:00 +0300 Subject: [PATCH] Update decremental algorithms according to project structure changes --- algorithm/frigioni.h | 44 ++++++++++++++++++++++------------------- algorithm/italiano.h | 47 +++++++++++++++++++++++--------------------- graph/digraph.h | 8 +++----- 3 files changed, 52 insertions(+), 47 deletions(-) diff --git a/algorithm/frigioni.h b/algorithm/frigioni.h index 4330a1f..849b253 100644 --- a/algorithm/frigioni.h +++ b/algorithm/frigioni.h @@ -1,32 +1,31 @@ #ifndef FRIGIONI_H_ #define FRIGIONI_H_ +#include "algorithm/decremental_reachability.h" #include "algorithm/roditty_zwick.h" -#include "algorithm/tarjan.h" -#include "graph/breadth_first_tree.h" -#include "algorithm/decremental_scc.h" -#include #include -#include using namespace graph; namespace algo { template -class Frigioni : public RodittyZwick { +class Frigioni : public DecrementalReachability { public: - Frigioni(Digraph G) : G(G) {} + Frigioni() = default; - void init(); + Frigioni(Digraph G) { this->G = G; } - bool query(const T& u, const T& v); + // + void init() override; - void remove(const T& u, const T& v); + // + bool query(const T& u, const T& v) override; + + // + void remove(const T& u, const T& v) override; private: - Digraph G; - // Transitive closure matrix, used to answer reachability queries in O(1) std::map> TC; @@ -36,24 +35,29 @@ private: // Each scc's representative vertex reachability tree std::map> RT; - // Incoming / Outgoing / Internal edges + // Incoming / Outgoing / Internal edges of each SCC + // Maps each SCC representative with struct Edges struct Edges { std::set> in; std::set> inc; std::set> out; }; std::map E; + + // Decremental maintenance of strongly connected components + RodittyZwick decremental; }; template void Frigioni::init() { - auto SCCs = Tarjan(G.adjMatrix).execute(); - + auto SCCs = Tarjan(this->G.adjMatrix).execute(); + decremental = RodittyZwick(this->G); + decremental.init(); + for (auto& scc : SCCs) { - RT[scc.id] = BreadthFirstTree(G, scc.id); - for (const auto& u : G.vertices()) { - C[u] = scc; - for (const auto& v : G.adjMatrix[u]) { + RT[scc.id] = BreadthFirstTree(this->G, scc.id); + for (const auto& u : this->G.vertices()) { + for (const auto& v : this->G.adjMatrix[u]) { TC[u][v] = false; if (scc.member(u)) { if (scc.member(v)) @@ -67,7 +71,7 @@ void Frigioni::init() { } } for (auto& scc : SCCs) { - for (const auto& u : G.vertices()) { + for (const auto& u : this->G.vertices()) { if (scc.member(u)) { for (const auto& v : RT[scc.id].vertices()) { TC[u][v] = true; diff --git a/algorithm/italiano.h b/algorithm/italiano.h index 15d0c1f..806ca5d 100644 --- a/algorithm/italiano.h +++ b/algorithm/italiano.h @@ -1,37 +1,37 @@ #ifndef ITALIANO_H_ #define ITALIANO_H_ -#include "algorithm/roditty_zwick.h" -#include "algorithm/tarjan.h" +#include "algorithm/decremental_reachability.h" #include "graph/breadth_first_tree.h" -#include -#include - using namespace graph; namespace algo { template -class Italiano : public RodittyZwick { +class Italiano : public DecrementalReachability { public: - Italiano(Digraph G) : G(G) {} + Italiano() = default; - void init(); + Italiano(Digraph G) { this->G = G; } - bool query(const T& u, const T& v); + // Initialize the decremental maintenance data structure for DAGs + void init() override; - void remove(const T& u, const T& v); + // Execute reachability query q(u, v) from vertex u to vertex v + // in O(1) using the transitive closure matrix + bool query(const T& u, const T& v) override; + + // Delete edge e(u, v) and explicitely maintain the transitive closure + void remove(const T& u, const T& v) override; private: - Digraph G; - - // Transitive closure matrix, used to answer reachability queries in O(1) + // Transitive closure matrix std::map> TC; - // Each vertex's reachability tree + // For each vertex, store a reachability tree created as a BFS tree std::map> RT; - // Incoming / Outgoing edges + // For each vertex, store collections of its incoming and outgoing edges struct Edges { std::set inc; std::set out; @@ -41,13 +41,13 @@ private: template void Italiano::init() { - for (const auto& u : G.vertices()) { - for (const auto& v : G.adjMatrix[u]) { + for (const auto& u : this->G.vertices()) { + for (const auto& v : this->G.adjMatrix[u]) { E[v].inc.insert(u); E[u].out.insert(v); TC[u][v] = false; } - RT[u] = BreadthFirstTree(G, u); + RT[u] = BreadthFirstTree(this->G, u); TC[u][u] = true; for (const auto& v : RT[u].vertices()) TC[u][v] = true; @@ -63,7 +63,7 @@ template void Italiano::remove(const T& u, const T& v) { std::map> H; - for (const auto& w : G.vertices()) { + for (const auto& w : this->G.vertices()) { if (RT[w].contains(u, v)) { if (E[v].inc.size() > 1) H[w].push(v); @@ -77,9 +77,9 @@ void Italiano::remove(const T& u, const T& v) { E[u].out.erase(v); E[v].inc.erase(u); - G.remove(u, v); + this->G.remove(u, v); - for (const auto& z : G.vertices()) { + for (const auto& z : this->G.vertices()) { RT[z].adjMatrix[u].erase(v); while (H[z].size() > 0) { auto& h = H[z].top(); @@ -87,11 +87,14 @@ void Italiano::remove(const T& u, const T& v) { for (const auto& i : E[h].inc) { if (RT[z].contains(z, i)) { RT[z].adjMatrix[i].insert(h); - H[z].pop(); + // found = true; break; } } + // + H[z].pop(); + // if (!found) { TC[u][v] = false; for (const auto& o : E[h].out) { diff --git a/graph/digraph.h b/graph/digraph.h index 982816d..0c3bcaf 100644 --- a/graph/digraph.h +++ b/graph/digraph.h @@ -50,17 +50,15 @@ void Digraph::insert(const T& u, const T& v) { template void Digraph::remove(const T& u, const T& v) { this->adjMatrix[u].erase(v); - //if (this->adjMatrix[u].size() == 0) - // this->adjMatrix.erase(u); } template auto Digraph::reverse() { std::map> revMatrix; - for (const auto& u : this->adjMatrix) { - for (const auto& v : u.second) { - revMatrix[v].insert(u.first); + for (const auto& u : vertices()) { + for (const auto& v : this->adjMatrix[u]) { + revMatrix[v].insert(u); } }