Update README

This commit is contained in:
stefiosif
2022-10-15 11:55:42 +03:00
parent e7fd88f82c
commit 38641ac6f4
2 changed files with 36 additions and 49 deletions

View File

@@ -1,47 +1,45 @@
# Dynamic Reachability Algorithms # Dynamic Reachability Algorithms [DRA]
The goal of this project is to implement a collection of dynamic The goal of this project is to implement a collection of dynamic reachability
reachability algorithms covered in "Improved Dynamic Reachability algorithms covered in "Improved Dynamic Reachability Algorithms for Directed Graphs"
Algorithms for Directed Graphs" by Liam Roditty and Uri Zwick. 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 ```cpp
#include "roditty_zwick.h" #include "roditty_zwick.h"
int main() { int main() {
// Initialize a graph G // Initialize directed graph G
graph::Digraph<int> G( graph::Digraph<int> G(
{1, {2}}, {1, {2}}, {2, {3, 4}}, {3, {1, 5, 9}},
{2, {3, 4}},
{3, {1, 5, 9}},
{4, {5, 6}}, {4, {5, 6}},
{5, {6, 7}}, {5, {6, 7}}, {6, {8}}, {7, {8, 9}}, {8, {9}}, {9, {5}}
{6, {8}},
{7, {8, 9}},
{8, {9}},
{9, {5}}
); );
// Initialize dynamic reachability algorithm for general graphs // Initialize dynamic reachability algorithm for general directed graphs
algo::HenzingerKing<int> hk(G); auto hk = new algo::HenzingerKing(G);
hk.init(); hk->init();
// Query // Query the dynamic reachability algorithm
std::cout << "Path from 4 to 8 exists: " << dr.query(4, 8); std::cout << "Path from 4 to 8 exists: " << hk.query(4, 8) << '\n';
std::vector<std::pair<int, int>> edges(
{4, 6}, {5, 6}, {3, 1}
);
// Remove edges // Remove edges
for (const auto& [u, v] : edges) std::vector<std::pair<int, int>> delEdges( {4, 6}, {5, 6}, {3, 1} );
dk.remove(u, v); for (const auto& [u, v] : delEdges)
hk.remove(u, v);
std::cout << "Path from 4 to 8 exists: " << dr.query(4, 8); std::cout << "Path from 4 to 8 exists: " << dr.query(4, 8);
// Insert edges // Insert edges
for (const auto& [u, v] : edges) std::pair<int, std::vector<int>> addEdges( { 1 , {2, 3, 4, 5} } );
dk.insert(u, v); hk.insert(u, { v });
std::cout << "Path from 4 to 8 exists: " << dr.query(4, 8); std::cout << "Path from 4 to 8 exists: " << dr.query(4, 8);
@@ -50,21 +48,11 @@ int main() {
``` ```
## Run Locally ## Run Locally
Clone the repository with submodules (doctest/nanobench): Clone the repository with submodules (doctest/nanobench):
```bash ```bash
git clone --recurse-submodules https://github.com/stefiosif/dynamic-reachability-algorithms git clone --recurse-submodules https://github.com/stefiosif/dynamic-reachability-algorithms
``` ```
Run with CMake:
``` bash
> mkdir build && cd build
> cmake ..
> make
> ./main
```
## References ## References
* [Improved Dynamic Reachability Algorithms for Directed Graphs](www.google.com) * [Improved Dynamic Reachability Algorithms for Directed Graphs](www.google.com)

View File

@@ -4,11 +4,12 @@
int main() { int main() {
graph::Digraph<std::uint16_t> G; graph::Digraph<std::uint16_t> G;
std::vector<std::pair<std::uint16_t, std::uint16_t>> dl_set;
std::vector<std::pair<std::uint16_t, std::uint16_t>> qr_set;
std::vector<std::pair<std::uint16_t, std::uint16_t>> in_set;
auto gen = std::bind(std::uniform_real_distribution<>(0, 1), auto gen = std::bind(std::uniform_real_distribution<>(0, 1),
std::default_random_engine()); std::default_random_engine());
std::vector<std::pair<std::uint16_t, std::uint16_t>> dl_set;
std::vector<std::pair<std::uint16_t, std::uint16_t>> qr_set;
for (int i = 0; i <= 100; ++i) { for (int i = 0; i <= 100; ++i) {
for (int j = 0; j <= 100; ++j) { for (int j = 0; j <= 100; ++j) {
auto rand = gen(); 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<std::uint16_t>* dr = new algo::HenzingerKing(G); algo::HenzingerKing<std::uint16_t>* dr = new algo::HenzingerKing(G);
dr->init(); dr->init();
// Remove a random collection of edges from the digraph
dr->remove(dl_set); dr->remove(dl_set);
// Answer queries using the maintained transitive closure, if the for (const auto& [u, v] : qr_set) {
// queried edge has been deleted, insert it into the digraph again if (dr->query(u, v))
for (const auto& q : qr_set) {
if (dr->query(q.first, q.second))
; ;
else 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; return 0;
} }