diff --git a/README.md b/README.md index 3ef8bb1..a614731 100644 --- a/README.md +++ b/README.md @@ -1,47 +1,45 @@ -# Dynamic Reachability Algorithms -The goal of this project is to implement a collection of dynamic -reachability algorithms covered in "Improved Dynamic Reachability -Algorithms for Directed Graphs" by Liam Roditty and Uri Zwick. +# Dynamic Reachability Algorithms [DRA] +The goal of this project is to implement a collection of dynamic reachability +algorithms covered in "Improved Dynamic Reachability Algorithms for Directed Graphs" +by Liam Roditty and Uri Zwick. +In more detail, the algorithms implemented, include a decremental reachability +algorithm for the transitive closure of a directed acyclic graph, a decremental +reachability algorithm for the transitive closure of a general directed graph, a +dynamic reachability algorithm of a directed acyclic graph and a dynami reachability +algorithm of a general directed graph. +The core algorithm of Roditty and Zwick is a decremental reachability algorithm for +the strongly connected components of the general directed graph, on which all +reachability algorithms for general directed graphs are based. -## Usage/Examples +## A code example ```cpp #include "roditty_zwick.h" int main() { - // Initialize a graph G + // Initialize directed graph G graph::Digraph G( - {1, {2}}, - {2, {3, 4}}, - {3, {1, 5, 9}}, + {1, {2}}, {2, {3, 4}}, {3, {1, 5, 9}}, {4, {5, 6}}, - {5, {6, 7}}, - {6, {8}}, - {7, {8, 9}}, - {8, {9}}, - {9, {5}} + {5, {6, 7}}, {6, {8}}, {7, {8, 9}}, {8, {9}}, {9, {5}} ); - // Initialize dynamic reachability algorithm for general graphs - algo::HenzingerKing hk(G); - hk.init(); + // Initialize dynamic reachability algorithm for general directed graphs + auto hk = new algo::HenzingerKing(G); + hk->init(); - // Query - std::cout << "Path from 4 to 8 exists: " << dr.query(4, 8); - - std::vector> edges( - {4, 6}, {5, 6}, {3, 1} - ); + // Query the dynamic reachability algorithm + std::cout << "Path from 4 to 8 exists: " << hk.query(4, 8) << '\n'; // Remove edges - for (const auto& [u, v] : edges) - dk.remove(u, v); + std::vector> delEdges( {4, 6}, {5, 6}, {3, 1} ); + for (const auto& [u, v] : delEdges) + hk.remove(u, v); std::cout << "Path from 4 to 8 exists: " << dr.query(4, 8); - // Insert edges - for (const auto& [u, v] : edges) - dk.insert(u, v); + std::pair> addEdges( { 1 , {2, 3, 4, 5} } ); + hk.insert(u, { v }); std::cout << "Path from 4 to 8 exists: " << dr.query(4, 8); @@ -50,21 +48,11 @@ int main() { ``` ## Run Locally - Clone the repository with submodules (doctest/nanobench): ```bash git clone --recurse-submodules https://github.com/stefiosif/dynamic-reachability-algorithms ``` -Run with CMake: - -``` bash -> mkdir build && cd build -> cmake .. -> make -> ./main -``` - ## References * [Improved Dynamic Reachability Algorithms for Directed Graphs](www.google.com) diff --git a/src/random_example.cc b/src/example.cc similarity index 58% rename from src/random_example.cc rename to src/example.cc index d8d1a43..154ed1a 100644 --- a/src/random_example.cc +++ b/src/example.cc @@ -4,11 +4,12 @@ int main() { graph::Digraph G; - auto gen = std::bind(std::uniform_real_distribution<>(0, 1), - std::default_random_engine()); - std::vector> dl_set; std::vector> qr_set; + std::vector> in_set; + auto gen = std::bind(std::uniform_real_distribution<>(0, 1), + std::default_random_engine()); + for (int i = 0; i <= 100; ++i) { for (int j = 0; j <= 100; ++j) { auto rand = gen(); @@ -22,22 +23,20 @@ int main() { } } - // Initialize the Roditty and Zwick's dynamic reachability algorithm - // for general directed graphs inspired by Henzinger and King algo::HenzingerKing* dr = new algo::HenzingerKing(G); dr->init(); - // Remove a random collection of edges from the digraph dr->remove(dl_set); - // Answer queries using the maintained transitive closure, if the - // queried edge has been deleted, insert it into the digraph again - for (const auto& q : qr_set) { - if (dr->query(q.first, q.second)) + for (const auto& [u, v] : qr_set) { + if (dr->query(u, v)) ; else - dr->insert(q.first, q.second); + in_set.push_back({ u, v }); } + for (const auto& [u, v] : in_set) + dr->insert(u, { v }); + return 0; } \ No newline at end of file