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
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<int> 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<int> 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<std::pair<int, int>> 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<std::pair<int, int>> 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<int, std::vector<int>> 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)

View File

@@ -4,11 +4,12 @@
int main() {
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),
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 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<std::uint16_t>* 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;
}