From 371104a33712a4a71bbb3dfa3bfa6aa3c83e1835 Mon Sep 17 00:00:00 2001 From: stefiosif Date: Thu, 29 Sep 2022 23:34:42 +0300 Subject: [PATCH] Complete RZ dynamic algorithm inspired by henzinger and king, TODO: finish frigioni --- algorithm/henzinger_king.h | 97 +++++++++++++++++++++++++------------- 1 file changed, 65 insertions(+), 32 deletions(-) diff --git a/algorithm/henzinger_king.h b/algorithm/henzinger_king.h index f6d90a1..2b51d78 100644 --- a/algorithm/henzinger_king.h +++ b/algorithm/henzinger_king.h @@ -6,6 +6,8 @@ using namespace graph; +constexpr int max_set_size = 5; + namespace algo { template @@ -15,63 +17,94 @@ public: HenzingerKing(Digraph G) { this->G = G; } - // 1. Initialize a decremental reachability data structure. - // 2. Let S <- phi. - - // In the beginning of each phase, a decremental reachability data structure - // is initialized. We let S be the set of vertices that were centers of - // insertions during this phase. Initially S = phi. When a set of edges Ev, all - // touching v, is inserted, we add v to S and construct reachability trees In(v) - // and Out(v) rooted at v. When the size of S, the set of insertion centers, - // reaches t, a parameter fixed in advance, the phase is declared over, and - // all the data structures are reinitialized. + // Initialize decremental maintenance data structure and the empty set S void init() override; - // 1. Query the decremental reachability data structure. - // 2. For each w in S check if u in In(w) and v in Out(w). - - // First the decremental data structure is queried to see whether there is a - // directed path from u to v composed solely of edges that were present in the - // graph at the start of the current phase. If not, it is checked whether there - // exists w in S such that u in In(w) and v in Out(w). If such a vertex w exists, - // then the answer is YES. + // Execute query q(u, v) from vertex u to vertex v by querying the + // decremental reachability data structure at the start of the phase + // and then if necessary check the set S bool query(const T& u, const T& v) override; - // 1. Let E <- E - E'. - // 2. Delete E' from the decremental data structure. - // 3. For every w in S, rebuilt the trees In(w) and Out(w). - - // First, the edges of E' are removed from the decremental data structure. Next, - // for every w in S, the shortest-paths trees In(w) and Out(w) are built from - // scratch. + // Delete edge e(u, v) void remove(const T& u, const T& v) override; - - // 1. Let E <- E union Ev. - // 2. Let S <- S union {v}. - // 3. If |S| > t, then call init. - // 4. Otherwise, construct the trees In(v) and Out(v). + + // Remove collection of edges from the decremental maintenance data structure + // and for every vertex in set S, rebuilt reachability trees from scratch + void remove(const std::vector>& edges); + + // Add edge e(u, v) void insert(const T& u, const T& v) override; + + // Insert collection of edges in set S, if threshold is reached re-initialize + // algorithm, otherwise construct reachability trees for the vertex that is + // the center-of-insertions + void insert(const T& c, const std::vector& vertices); +private: + // Decremental maintenance data structure + Frigioni frigioni; + + // Collection of vertices that have been centers of insertions in this phase + std::set S; + + // Maintain in-out bfs trees + std::map> In; + std::map> Out; }; template void HenzingerKing::init() { - + S.clear(); + frigioni = Frigioni(this->G); + frigioni.init(); } template bool HenzingerKing::query(const T& u, const T& v) { + if (frigioni.query(u, v)) + return true; - return false; + return std::any_of(S.begin(), S.end(), + [&](const T& w) { + return In[w].contains(w, u) && Out[w].contains(w, v); + }); } template void HenzingerKing::remove(const T& u, const T& v) { + this->G.remove(u, v); +} +template +void HenzingerKing::remove(const std::vector>& edges) { + for (const auto& [u, v]: edges) { + remove(u, v); + } + frigioni.remove(edges); + + for (const auto& w : S) { + In[w] = BreadthFirstTree(this->G.reverse(), w); + Out[w] = BreadthFirstTree(this->G, w); + } } template void HenzingerKing::insert(const T& u, const T& v) { + this->G.insert(u, v); +} +template +void HenzingerKing::insert(const T& c, const std::vector& vertices) { + for (const auto& w : vertices) + insert(c, w); + + S.insert(c); + if (S.size() > max_set_size) { + init(); + return; + } + + In[c] = BreadthFirstTree(this->G.reverse(), c); + Out[c] = BreadthFirstTree(this->G, c); } } // namespace algo