Ecosyste.ms: Awesome

An open API service indexing awesome lists of open source software.

Awesome Lists | Featured Topics | Projects

https://github.com/wangtz0607/graph

C++20 header-only generic graph library
https://github.com/wangtz0607/graph

Last synced: about 1 month ago
JSON representation

C++20 header-only generic graph library

Awesome Lists containing this project

README

        

# Graph

C++20 header-only generic graph library.

## Supported Algorithms

- `DepthFirstSearch`
- `BreadthFirstSearch`
- `KahnTopologicalSort`
- `KruskalMinimumSpanningTree`
- `PrimMinimumSpanningTree`
- `BFSShortestPaths`
- `DAGShortestPaths`
- `DijkstraShortestPaths`
- `BellmanFordShortestPaths`
- `DFSConnectedComponents`
- `BFSConnectedComponents`
- `DisjointSetsConnectedComponents`
- `TarjanCutVertices`
- `TarjanBridges`
- `TarjanStronglyConnectedComponents`
- `DFSBipartitenessCheck`
- `BFSBipartitenessCheck`

## Examples

### `DepthFirstSearch`

```cpp
#include
#include

#include "graph/DefaultDigraph.h"
#include "graph/DepthFirstSearch.h"
#include "graph/DefaultVisitor.h"
#include "graph/Color.h"

class CustomVisitor : public graph::DefaultVisitor {
public:
template
void onDiscoverVertex(Graph &g, typename Graph::Vertex v) {
// ...
}
};

int main() {
using Vertex = size_t;

graph::DefaultDigraph g;

g.addVertex(0);
g.addVertex(1);
g.addVertex(2);

g.addEdge(0, 1);
g.addEdge(1, 2);
g.addEdge(0, 2);

std::unordered_map colors;
CustomVisitor visitor;

graph::DepthFirstSearch(g, &colors)(visitor);

return 0;
}
```

### `BreadthFirstSearch`

```cpp
#include
#include

#include "graph/DefaultDigraph.h"
#include "graph/BreadthFirstSearch.h"
#include "graph/DefaultVisitor.h"
#include "graph/Color.h"

class CustomVisitor : public graph::DefaultVisitor {
public:
template
void onDiscoverVertex(Graph &g, typename Graph::Vertex v) {
// ...
}
};

int main() {
using Vertex = size_t;

graph::DefaultDigraph g;

g.addVertex(0);
g.addVertex(1);
g.addVertex(2);

g.addEdge(0, 1);
g.addEdge(1, 2);
g.addEdge(0, 2);

std::unordered_map colors;
CustomVisitor visitor;

graph::BreadthFirstSearch(g, &colors)(visitor);

return 0;
}
```

### `KahnTopologicalSort`

```cpp
#include
#include
#include

#include "graph/DefaultDigraph.h"
#include "graph/KahnTopologicalSort.h"

int main() {
using Vertex = size_t;

graph::DefaultDigraph g;

g.addVertex(0);
g.addVertex(1);
g.addVertex(2);

g.addEdge(0, 1);
g.addEdge(1, 2);
g.addEdge(0, 2);

std::vector sorted = graph::KahnTopologicalSort(g)();

assert(sorted == std::vector{0, 1, 2});

return 0;
}
```

### `KruskalMinimumSpanningTree`

```cpp
#include
#include
#include

#include "graph/DefaultDigraph.h"
#include "graph/Empty.h"
#include "graph/KruskalMinimumSpanningTree.h"

int main() {
using Vertex = size_t;

struct EdgeProps {
int weight;
};

graph::DefaultDigraph g;

g.addVertex(0);
g.addVertex(1);
g.addVertex(2);

g.addEdge(0, 1, {1}); g.addEdge(1, 0, {1});
g.addEdge(1, 2, {2}); g.addEdge(2, 1, {2});
g.addEdge(0, 2, {4}); g.addEdge(2, 0, {4});

std::unordered_set mstEdges;

graph::KruskalMinimumSpanningTree(g, g[&EdgeProps::weight], &mstEdges)();

int weight = 0;
for (auto e : mstEdges) {
weight += g[e].weight;
}
assert(weight == 3);

return 0;
}
```

### `PrimMinimumSpanningTree`

```cpp
#include
#include
#include
#include

#include "graph/DefaultDigraph.h"
#include "graph/Empty.h"
#include "graph/PrimMinimumSpanningTree.h"

int main() {
using Vertex = size_t;

struct EdgeProps {
int weight;
};

graph::DefaultDigraph g;

g.addVertex(0);
g.addVertex(1);
g.addVertex(2);

g.addEdge(0, 1, {1}); g.addEdge(1, 0, {1});
g.addEdge(1, 2, {2}); g.addEdge(2, 1, {2});
g.addEdge(0, 2, {4}); g.addEdge(2, 0, {4});

Vertex s = 0;

std::unordered_map dists;
std::unordered_map> preds;

graph::PrimMinimumSpanningTree(g, s, g[&EdgeProps::weight], &dists, &preds)();

int weight = 0;
for (Vertex v : g.vertices()) {
weight += dists[v];
}
assert(weight == 3);

return 0;
}
```

### `BFSShortestPaths`

```cpp
#include
#include
#include
#include

#include "graph/DefaultDigraph.h"
#include "graph/BFSShortestPaths.h"

int main() {
using Vertex = size_t;

graph::DefaultDigraph g;

g.addVertex(0);
g.addVertex(1);
g.addVertex(2);

g.addEdge(0, 1);
g.addEdge(1, 2);
g.addEdge(0, 2);

Vertex s = 0;

std::unordered_map dists;
std::unordered_map> preds;

graph::BFSShortestPaths(g, s, &dists, &preds)();

assert(dists[0] == 0);
assert(dists[1] == 1);
assert(dists[2] == 1);

assert(preds[0] == std::nullopt);
assert(preds[1] == 0);
assert(preds[2] == 0);

return 0;
}
```

### `DAGShortestPaths`

```cpp
#include
#include
#include
#include

#include "graph/DefaultDigraph.h"
#include "graph/Empty.h"
#include "graph/DAGShortestPaths.h"

int main() {
using Vertex = size_t;

struct EdgeProps {
int weight;
};

graph::DefaultDigraph g;

g.addVertex(0);
g.addVertex(1);
g.addVertex(2);

g.addEdge(0, 1, {10});
g.addEdge(1, 2, {100});
g.addEdge(0, 2, {1000});

Vertex s = 0;

std::unordered_map dists;
std::unordered_map> preds;

graph::DAGShortestPaths(g, s, g[&EdgeProps::weight], &dists, &preds)();

assert(dists[0] == 0);
assert(dists[1] == 10);
assert(dists[2] == 110);

assert(preds[0] == std::nullopt);
assert(preds[1] == 0);
assert(preds[2] == 1);

return 0;
}
```

### `DijkstraShortestPaths`

```cpp
#include
#include
#include
#include

#include "graph/DefaultDigraph.h"
#include "graph/Empty.h"
#include "graph/DijkstraShortestPaths.h"

int main() {
using Vertex = size_t;

struct EdgeProps {
int weight;
};

graph::DefaultDigraph g;

g.addVertex(0);
g.addVertex(1);
g.addVertex(2);

g.addEdge(0, 1, {10});
g.addEdge(1, 2, {100});
g.addEdge(0, 2, {1000});

Vertex s = 0;

std::unordered_map dists;
std::unordered_map> preds;

graph::DijkstraShortestPaths(g, s, g[&EdgeProps::weight], &dists, &preds)();

assert(dists[0] == 0);
assert(dists[1] == 10);
assert(dists[2] == 110);

assert(preds[0] == std::nullopt);
assert(preds[1] == 0);
assert(preds[2] == 1);

return 0;
}
```

### `BellmanFordShortestPaths`

```cpp
#include
#include
#include
#include

#include "graph/DefaultDigraph.h"
#include "graph/Empty.h"
#include "graph/BellmanFordShortestPaths.h"

int main() {
using Vertex = size_t;

struct EdgeProps {
int weight;
};

graph::DefaultDigraph g;

g.addVertex(0);
g.addVertex(1);
g.addVertex(2);

g.addEdge(0, 1, {-10});
g.addEdge(1, 2, {-100});
g.addEdge(0, 2, {-1000});

Vertex s = 0;

std::unordered_map dists;
std::unordered_map> preds;

graph::BellmanFordShortestPaths(g, s, g[&EdgeProps::weight], &dists, &preds)();

assert(dists[0] == 0);
assert(dists[1] == -10);
assert(dists[2] == -1000);

assert(preds[0] == std::nullopt);
assert(preds[1] == 0);
assert(preds[2] == 0);

return 0;
}
```

### `DFSConnectedComponents`

```cpp
#include
#include
#include

#include "graph/DefaultDigraph.h"
#include "graph/DFSConnectedComponents.h"

int main() {
using Vertex = size_t;

graph::DefaultDigraph g;

g.addVertex(0);
g.addVertex(1);
g.addVertex(2);

g.addEdge(0, 1); g.addEdge(1, 0);

std::unordered_map componentNumbers;

size_t componentCount = graph::DFSConnectedComponents(g, &componentNumbers)();

assert(componentCount == 2);

assert(componentNumbers[0] == componentNumbers[1]);
assert(componentNumbers[2] != componentNumbers[0]);
assert(componentNumbers[2] != componentNumbers[1]);

return 0;
}
```

### `BFSConnectedComponents`

```cpp
#include
#include
#include

#include "graph/DefaultDigraph.h"
#include "graph/BFSConnectedComponents.h"

int main() {
using Vertex = size_t;

graph::DefaultDigraph g;

g.addVertex(0);
g.addVertex(1);
g.addVertex(2);

g.addEdge(0, 1); g.addEdge(1, 0);

std::unordered_map componentNumbers;

size_t componentCount = graph::BFSConnectedComponents(g, &componentNumbers)();

assert(componentCount == 2);

assert(componentNumbers[0] == componentNumbers[1]);
assert(componentNumbers[2] != componentNumbers[0]);
assert(componentNumbers[2] != componentNumbers[1]);

return 0;
}
```

### `DisjointSetsConnectedComponents`

```cpp
#include
#include
#include

#include "graph/DefaultDigraph.h"
#include "graph/DisjointSetsConnectedComponents.h"

int main() {
using Vertex = size_t;

graph::DefaultDigraph g;

g.addVertex(0);
g.addVertex(1);
g.addVertex(2);

g.addEdge(0, 1); g.addEdge(1, 0);

std::unordered_map representativeVertices;

size_t componentCount =
graph::DisjointSetsConnectedComponents(g, &representativeVertices)();

assert(componentCount == 2);

assert(representativeVertices[0] == representativeVertices[1]);
assert(representativeVertices[2] != representativeVertices[0]);
assert(representativeVertices[2] != representativeVertices[1]);

return 0;
}
```

### `TarjanCutVertices`

```cpp
#include
#include
#include

#include "graph/DefaultDigraph.h"
#include "graph/TarjanCutVertices.h"

int main() {
using Vertex = size_t;

graph::DefaultDigraph g;

g.addVertex(0);
g.addVertex(1);
g.addVertex(2);

g.addEdge(0, 1); g.addEdge(1, 0);
g.addEdge(1, 2); g.addEdge(2, 1);

std::unordered_set cutVertices;

graph::TarjanCutVertices(g, &cutVertices)();

assert(cutVertices == std::unordered_set{1});

return 0;
}
```

### `TarjanBridges`

```cpp
#include
#include

#include "graph/DefaultDigraph.h"
#include "graph/TarjanBridges.h"

int main() {
using Vertex = size_t;

graph::DefaultDigraph g;

g.addVertex(0);
g.addVertex(1);
g.addVertex(2);
g.addVertex(3);

g.addEdge(0, 1); g.addEdge(1, 0);
g.addEdge(0, 2); g.addEdge(2, 0);
g.addEdge(1, 2); g.addEdge(2, 1);
g.addEdge(2, 3); g.addEdge(3, 2);

auto isBridge = graph::TarjanBridges(g)();

assert(isBridge(0, 1) == false);
assert(isBridge(0, 2) == false);
assert(isBridge(1, 2) == false);
assert(isBridge(2, 3) == true);

return 0;
}
```

### `TarjanStronglyConnectedComponents`

```cpp
#include
#include
#include

#include "graph/DefaultDigraph.h"
#include "graph/TarjanStronglyConnectedComponents.h"

int main() {
using Vertex = size_t;

graph::DefaultDigraph g;

g.addVertex(0);
g.addVertex(1);
g.addVertex(2);

g.addEdge(0, 1);
g.addEdge(1, 0);
g.addEdge(0, 2);

std::unordered_map sccNumbers;

size_t sccCount = graph::TarjanStronglyConnectedComponents(g, &sccNumbers)();

assert(sccCount == 2);

assert(sccNumbers[0] == sccNumbers[1]);
assert(sccNumbers[2] != sccNumbers[0]);
assert(sccNumbers[2] != sccNumbers[1]);

return 0;
}
```

### `DFSBipartitenessCheck`

```cpp
#include
#include

#include "graph/DefaultDigraph.h"
#include "graph/DFSBipartitenessCheck.h"

int main() {
using Vertex = size_t;

graph::DefaultDigraph g;

g.addVertex(0);
g.addVertex(1);

g.addEdge(0, 1); g.addEdge(1, 0);

assert(graph::DFSBipartitenessCheck(g)() == true);

return 0;
}
```

### `BFSBipartitenessCheck`

```cpp
#include
#include

#include "graph/DefaultDigraph.h"
#include "graph/BFSBipartitenessCheck.h"

int main() {
using Vertex = size_t;

graph::DefaultDigraph g;

g.addVertex(0);
g.addVertex(1);

g.addEdge(0, 1); g.addEdge(1, 0);

assert(graph::BFSBipartitenessCheck(g)() == true);

return 0;
}
```

## License

Graph is licensed under the [MIT license](https://opensource.org/licenses/MIT).